sql >> Base de Datos >  >> RDS >> Mysql

Encuentre la distancia entre dos puntos usando latitud y longitud en mysql

Creo que tu pregunta dice que tienes la city valores para las dos ciudades entre las que desea calcular la distancia.

Esta consulta hará el trabajo por usted, dando la distancia en km. Utiliza la fórmula de la ley del coseno esférico.

Observe que une la tabla a sí misma para que pueda recuperar dos pares de coordenadas para el 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 la constante 111.1111 es el número de kilómetros por grado de latitud, basado en la antigua definición napoleónica del metro como una diezmilésima parte de la distancia del ecuador al polo. Esa definición es lo suficientemente cercana para el trabajo de búsqueda de ubicación.

Si desea millas terrestres en lugar de kilómetros, use 69.0 en su lugar.

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

Si está buscando puntos cercanos, puede tener la tentación de usar una cláusula como esta:

   HAVING distance_in_km < 10.0    /* slow ! */
    ORDER BY distance_in_km DESC

Eso es (como decimos cerca de Boston MA EE. UU.) muy lento.

En ese caso, debe utilizar un cálculo de cuadro delimitador. Vea este artículo sobre cómo hacerlo. http://www.plumislandmedia.net/mysql/haversine-mysql- ubicación-más-cercana/

La fórmula contiene un LEAST() función. ¿Por qué? Porque el ACOS() La función arroja un error si su argumento es incluso ligeramente mayor que 1. Cuando los dos puntos en cuestión están muy cerca, la expresión con el COS() y SIN() los cálculos a veces pueden arrojar un valor ligeramente superior a 1 debido a punto flotante épsilon (inexactitud ). El LEAST(1.0, dirty-great-expression) call hace frente a ese problema.

Hay una mejor manera, una fórmula por Thaddeus Vincenty . Utiliza ATAN2() en lugar de ACOS() por lo que es menos susceptible a los problemas de épsilon.