Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Encontre a distância entre dois pontos usando latitude e longitude no mysql


Acho que sua pergunta diz que você tem a city valores para as duas cidades entre as quais você deseja calcular a distância.

Esta consulta fará o trabalho para você, fornecendo a distância em km. Ele usa a fórmula da lei do cosseno esférico.

Observe que você une a tabela a ela mesma para poder recuperar dois pares de coordenadas para o cálculo.
SELECT a.city AS from_city, b.city AS to_city, 
   111.111 *
    DEGREES(ACOS(LEAST(1.0, COS(RADIANS(a.Latitude))
         * COS(RADIANS(b.Latitude))
         * COS(RADIANS(a.Longitude - b.Longitude))
         + SIN(RADIANS(a.Latitude))
         * SIN(RADIANS(b.Latitude))))) AS distance_in_km
  FROM city AS a
  JOIN city AS b ON a.id <> b.id
 WHERE a.city = 3 AND b.city = 7

Observe que a constante 111.1111 é o número de quilômetros por grau de latitude, baseado na antiga definição napoleônica do metro como um décimo de milésimo da distância do equador ao pólo. Essa definição é próxima o suficiente para o trabalho de localização.

Se você quiser milhas terrestres em vez de quilômetros, use 69.0 em vez de.

http://sqlfiddle.com/#!9/21e06/412/0

Se você estiver procurando por pontos próximos, pode ficar tentado a usar uma cláusula mais ou menos assim:
   HAVING distance_in_km < 10.0    /* slow ! */
    ORDER BY distance_in_km DESC

Isso é (como dizemos perto de Boston MA USA) muito lento.

Nesse caso, você precisa usar um cálculo de caixa delimitadora. Veja este artigo sobre como fazer isso. http://www.plumislandmedia.net/mysql/haversine-mysql- local-proximo/

A fórmula contém um LEAST() função. Por quê? Porque o ACOS() a função lança um erro se seu argumento for um pouco maior que 1. Quando os dois pontos em questão estiverem muito próximos, a expressão com o COS() e SIN() os cálculos às vezes podem gerar um valor ligeiramente maior que 1 devido a floating-point epsilon (imprecisão ). A LEAST(1.0, dirty-great-expression) chamada lida com esse problema.

Existe uma maneira melhor, uma fórmula por Thaddeus Vincenty . Ele usa ATAN2() em vez de ACOS() por isso é menos suscetível a problemas de epsilon.