Eu tenho um script PHP que obtém os valores de Longitude e Latitude e os insere em uma consulta MySQL. Eu gostaria de torná-lo apenas MySQL. Aqui está o meu código PHP atual:
if ($distance != "Any" && $customer_zip != "") { //get the great circle distance
//get the origin zip code info
$zip_sql = "SELECT * FROM zip_code WHERE zip_code = '$customer_zip'";
$result = mysql_query($zip_sql);
$row = mysql_fetch_array($result);
$origin_lat = $row['lat'];
$origin_lon = $row['lon'];
//get the range
$lat_range = $distance/69.172;
$lon_range = abs($distance/(cos($details[0]) * 69.172));
$min_lat = number_format($origin_lat - $lat_range, "4", ".", "");
$max_lat = number_format($origin_lat + $lat_range, "4", ".", "");
$min_lon = number_format($origin_lon - $lon_range, "4", ".", "");
$max_lon = number_format($origin_lon + $lon_range, "4", ".", "");
$sql .= "lat BETWEEN '$min_lat' AND '$max_lat' AND lon BETWEEN '$min_lon' AND '$max_lon' AND ";
}
Alguém sabe como fazer isso inteiramente MySQL? Eu naveguei um pouco na Internet, mas a maioria da literatura é bastante confusa.
php
mysql
great-circle
Nick Woodhams
fonte
fonte
Respostas:
Do FAQ do Google Code - Criando um localizador de lojas com PHP, MySQL e Google Maps :
fonte
markers
tabela com os campos id, lan e lng.$greatCircleDistance = acos( cos($latitude0) * cos($latitude1) * cos($longitude0 - $longitude1) + sin($latitude0) * sin($latitude1));
com latitude e longitude em radiano.
tão
é sua consulta SQL
para obter seus resultados em km ou milhas, multiplique o resultado pelo raio médio da Terra (
3959
milhas,6371
km ou3440
milhas náuticas)O que você está calculando no seu exemplo é uma caixa delimitadora. Se você colocar seus dados de coordenadas em uma coluna do MySQL espacial , poderá usar a funcionalidade de compilação do MySQL para consultar os dados.
fonte
Se você adicionar campos auxiliares à tabela de coordenadas, poderá melhorar o tempo de resposta da consulta.
Como isso:
Se você estiver usando o TokuDB, obterá um desempenho ainda melhor se adicionar índices de cluster em qualquer um dos predicados, por exemplo, assim:
Você precisará do lat e lon básico em graus, bem como do pecado (lat) em radianos, cos (lat) * cos (lon) em radianos e cos (lat) * sin (lon) em radianos para cada ponto. Então você cria uma função mysql, algo assim:
Isso lhe dá a distância.
Não se esqueça de adicionar um índice em lat / lon, para que o boxe delimitador possa ajudar na pesquisa, em vez de diminuí-la (o índice já foi adicionado na consulta CREATE TABLE acima).
Dada uma tabela antiga com apenas coordenadas lat / lon, você pode configurar um script para atualizá-lo assim: (php usando meekrodb)
Em seguida, você otimiza a consulta real para fazer o cálculo da distância apenas quando realmente necessário, por exemplo, delimitando o círculo (bem, oval) por dentro e por fora. Para isso, você precisará pré-calcular várias métricas para a própria consulta:
Dadas essas preparações, a consulta é mais ou menos assim (php):
EXPLAIN na consulta acima pode dizer que não está usando índice, a menos que haja resultados suficientes para acioná-lo. O índice será usado quando houver dados suficientes na tabela de coordenadas. Você pode adicionar o FORCE INDEX (lat_lon_idx) ao SELECT para fazer com que ele use o índice sem considerar o tamanho da tabela, para verificar com EXPLAIN se está funcionando corretamente.
Com os exemplos de código acima, você deve ter uma implementação funcional e escalável da pesquisa de objetos à distância com um erro mínimo.
fonte
Eu tive que resolver isso com mais detalhes, então vou compartilhar meu resultado. Isso usa uma
zip
tabela comlatitude
elongitude
tabelas. Não depende do Google Maps; em vez disso, você pode adaptá-lo a qualquer tabela que contenha lat / long.Veja esta linha no meio dessa consulta:
zip
Ele procura as 30 entradas mais próximas na tabela a 50,0 milhas do ponto lat / long 42,81 / -70,81. Quando você cria isso em um aplicativo, é aí que você coloca seu próprio ponto e raio de pesquisa.Se você deseja trabalhar em quilômetros, e não em milhas, mude
69
para111.045
e mude3963.17
para6378.10
na consulta.Aqui está um artigo detalhado. Espero que ajude alguém. http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/
fonte
Eu escrevi um procedimento que pode calcular o mesmo, mas você deve inserir a latitude e longitude na respectiva tabela.
fonte
Não posso comentar a resposta acima, mas tenha cuidado com a resposta de @Pavel Chuchuva. Essa fórmula não retornará um resultado se as duas coordenadas forem iguais. Nesse caso, a distância é nula e, portanto, a linha não será retornada com a fórmula como está.
Eu não sou um especialista em MySQL, mas isso parece estar funcionando para mim:
fonte
ACOS(1)
é 0). Você pode encontrar problemas de arredondamento com os zaxis xaxis * xaxis + yaxis * yaxis + zaxis * fora do intervalo para o ACOS, mas você não parece se proteger disso?para distância de 25 km
fonte
Eu pensei que minha implementação javascript seria uma boa referência para:
fonte
calcular distância no Mysql
assim, o valor da distância será calculado e qualquer pessoa poderá aplicar conforme necessário.
fonte