Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

tony_lu

[Resolvido] usuarios mais proximos - Google Maps

Recommended Posts

Ola pessoal, tudo bem?

 

Preciso de uma ajuda, preciso marcar em um app do google maps, os usuarios mais proximos de um determinado endereço...

 

No banco ja consigo gravar a latitude e longitude de todos os usuarios no ato do cadastro, agora preciso saber como selecionar os usuarios sabendo quais os mais proximos de um determinado endereço... ja vi sites que marcam até quantos km um usuario ou empresa esta de um determinado ponto... alguem pode me ajudar?

 

A codificação do app que estou utilizando é esta:

var mrk = [];
mrk.push(new mrkitem('Vit', 'botoi', 'usuario', '20100811123843_boi.jpg', -23.9789580, -46.3121512));
mrk.push(new mrkitem('Rafa', 'rafaelbr', 'usuario', '20100813170104_rafaelbr.jpg', -23.9772151, -46.3082780));
mrk.push(new mrkitem('João', 'c0d3r00t', 'usuario', '20100719235819_c0d3r00t.jpg', -23.9581367, -46.3925527));
mrk.push(new mrkitem('Rodrigo', 'digo.dark', 'usuario', '20100613004027_gen_avatar.gif', -23.9366827, -46.3882702));
mrk.push(new mrkitem('Celso', 'alsa', 'usuario', '20100613004027_geic_avatar.gif', -23.9739162, -46.3122721));
mrk.push(new mrkitem('allex', 'alexalves', 'usuario', '201009131128_alex.jpg', -23.9614568, -46.3247244));

 

Obrigado pessoal!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Faça no próprio MySQL

 

Não esqueça de que precisa converter os graus para radianos:

radiano = graus * PI / 180

 

exemplo prático:

$distance   = 15; // km. Busca os registros com coordenadas num raio de 15 kilômetros

// coordenada atual do usuário
$longitude  = '-23.9789580';
$latitude    = '-46.3121512';

$qry  = " SELECT";
$qry .= " (((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180))+cos((".$latitude."*pi()/180))  * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`)*pi()/180))))*180/pi())*60*1.1515*1.609344) as distance ";
$qry .= " FROM `MyTable`";
$qry .= " WHERE distance <= ".$distance;
echo $qry;

* Considerando que os nomes dos campos na tabela para latitude e longitude, sejam respectivamente "latitude" e "longitude". Portanto, modifique de acordo com as nomenclaturas das sua tabela.

 

Caso queira pesquisar mais sobre o assunto, pesquise por "haversine mysql" ou "haversi mysql"..

Note que o exemplo acima faz o cálculo em kilômetros.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito obrigado pela ajuda hinon!

 

abs!

 

Ola.... fiz o teste agora e ocorreu um erro:

 

Unknown column 'distance' in 'where clause'

 

Sabe como eu posso resolver?

 

Segue abaixo a linha do sql que utilizei...os campos sao lat e long:

SELECT (((acos(sin((-46.3121512*pi()/180)) * sin((`lat`*pi()/180))+cos((-46.3121512*pi()/180)) * cos((`lat`*pi()/180)) * cos(((-23.9789580- `long`)*pi()/180))))*180/pi())*60*1.1515*1.609344) AS distance FROM `usuario` WHERE distance <= 15 

 

Obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

Desculpe, no lugar de WHERE utilize HAVING, porque o MySQL não reconhece alias na cláusula WHERE, mas reconhece se usar HAVING

 

$qry .= " WHERE distance <= ".$distance;

troque por

$qry .= " HAVING distance <= ".$distance;

 

 

Outra solução seria repetir a condicional do alias mas não é conveniente repetir a mesma instrução devido ao seu tamanho.

 

 

Veja também:

http://dev.mysql.com/doc/refman/5.5/en/problems-with-alias.html

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado pela ajuda, agora nao esta dando mais nenhum erro, mas esta retornando vazio... mas o banco tem diversos usuarios com os campos de lat e long... mas nao retorna nada...o que pode ser?

 

Segue:

 

SELECT (((acos(sin((-46.3121512*pi()/180)) * sin((`lat`*pi()/180))+cos((-46.3121512*pi()/180)) * cos((`lat`*pi()/180)) * cos(((-23.9789580- `long`)*pi()/180))))*180/pi())*60*1.1515*1.609344) AS distance FROM `usuario` HAVING distance <= 15 

 

Agradeço se puder me ajudar novamente...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Há outros detalhes importantes, por exemplo, o datatype da coluna no MySQL

 

Precisa definir no mínimo como FLOAT(9,6)

 

Ou seja, um número flutuante (decimal) com capacidade para 9 dígitos, porém, com suporte para 6 casas decimais.

 

A desvantagem é que não poderá obter outros recursos a partir do número original da coordenada, pois gravará somente 9 dígitos, sendo que uma coordenada pode conter 13 casas decimais.

A vantagem é que para servidores em produção, a performance é muito melhor do que usar o "GIS Spatial", que permite guardar os dados em formatos geométricos: http://dev.mysql.com/doc/refman/5.0/en/populating-spatial-columns.html

Mas esse assunto sobre o a extensão GIS Spatial é outra conversa, pois a recomendação de uso depende de cada caso.

 

Por hora, verifique se os seus campos "lat" e "long" estão definidos como FOAT(9,6) e execute a query novamente

 

Apenas para confirmar, fiz um teste rápido, usando coordenadas dentro do raio de 15km

 

USE test;
SELECT
(((acos(sin((136.875195*pi()/180)) * sin((`latitude`*pi()/180))+cos((136.875195*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((35.172259- `longitude`)*pi()/180))))*180/pi())*60*1.1515*1.609344) as distance 
FROM `coords` 
HAVING distance <= 15

 

 

DDL da tabela

USE test;
CREATE TABLE `coords` (
 `id` int(3) NOT NULL AUTO_INCREMENT,
 `longitude` float(9,6) NOT NULL,
 `latitude` float(9,6) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

 

Dummy data, para testes

USE test;
INSERT INTO `coords` VALUES ('1', '35.173237', '136.883179'), ('2', '35.181072', '136.885834'), ('3', '35.172737', '136.892273'), ('4', '35.165745', '136.890549');

 

 

 

obs: "USE test;" é para referenciar uma base de dados. Troque para o nome da sua base de dados caso esteja conectado a múltiplas bases de dados.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.