tutorial pygeocoder nominatim geocoder example code python geocoding geo geography

python - pygeocoder - nominatim



Obtener distancia entre dos puntos en funciĆ³n de la latitud/longitud (3)

Intenté implementar esta fórmula: http://andrew.hedges.name/experiments/haversine/ El aplet hace bien en los dos puntos que estoy probando:

Sin embargo, mi código no funciona.

from math import sin, cos, sqrt, atan2 R = 6373.0 lat1 = 52.2296756 lon1 = 21.0122287 lat2 = 52.406374 lon2 = 16.9251681 dlon = lon2 - lon1 dlat = lat2 - lat1 a = (sin(dlat/2))**2 + cos(lat1) * cos(lat2) * (sin(dlon/2))**2 c = 2 * atan2(sqrt(a), sqrt(1-a)) distance = R * c print "Result", distance print "Should be", 278.546

La distancia que devuelve es 5447.05546147 . ¿Por qué?


Es porque en Python, todas las funciones trigonométricas usan radianes , no grados.

Puede convertir los números manualmente a radianes o usar la función radians del módulo matemático:

from math import sin, cos, sqrt, atan2, radians # approximate radius of earth in km R = 6373.0 lat1 = radians(52.2296756) lon1 = radians(21.0122287) lat2 = radians(52.406374) lon2 = radians(16.9251681) dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2 c = 2 * atan2(sqrt(a), sqrt(1 - a)) distance = R * c print("Result:", distance) print("Should be:", 278.546, "km")

La distancia ahora está devolviendo el valor correcto de 278.545589351 km.

Edit: Solo como una nota, si has tropezado con este post porque solo necesitas una manera rápida y fácil de encontrar la distancia entre dos puntos, te recomiendo que utilices el enfoque recomendado en la respuesta de Kurt a continuación: consulta su post para una explicación. .


Para las personas (como yo) que vienen aquí a través del motor de búsqueda y que están buscando una solución que funcione de manera mpu , recomiendo instalar mpu . Instálelo a través de pip install mpu --user y utilícelo de esta manera para obtener la distancia de recorrido :

import mpu # Point one lat1 = 52.2296756 lon1 = 21.0122287 # Point two lat2 = 52.406374 lon2 = 16.9251681 # What you were looking for dist = mpu.haversine_distance((lat1, lon1), (lat2, lon2)) print(dist) # gives 278.45817507541943.

Un paquete alternativo es gpxpy .

Si no quieres dependencias, puedes usar:

import math def distance(origin, destination): """ Calculate the Haversine distance. Parameters ---------- origin : tuple of float (lat, long) destination : tuple of float (lat, long) Returns ------- distance_in_km : float Examples -------- >>> origin = (48.1372, 11.5756) # Munich >>> destination = (52.5186, 13.4083) # Berlin >>> round(distance(origin, destination), 1) 504.2 """ lat1, lon1 = origin lat2, lon2 = destination radius = 6371 # km dlat = math.radians(lat2 - lat1) dlon = math.radians(lon2 - lon1) a = (math.sin(dlat / 2) * math.sin(dlat / 2) + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon / 2) * math.sin(dlon / 2)) c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) d = radius * c return d if __name__ == ''__main__'': import doctest doctest.testmod()


Actualización: 04/2018: Tenga en cuenta que la distancia Vincenty está en desuso desde la versión 1.13 GeoPy. ¡Debe usar geopy.distance.distance () en su lugar!

Las respuestas anteriores se basan en la fórmula de Haversine , que supone que la Tierra es una esfera, lo que produce errores de hasta aproximadamente el 0,5% (según la help(geopy.distance) ). Vincenty distance utiliza modelos elipsoidales más precisos, como WGS-84 , y se implementa en geopy . Por ejemplo,

import geopy.distance coords_1 = (52.2296756, 21.0122287) coords_2 = (52.406374, 16.9251681) print geopy.distance.vincenty(coords_1, coords_2).km

imprimirá la distancia de 279.352901604 kilómetros utilizando el elipsoide predeterminado WGS-84. (También puede elegir .miles o una de varias otras unidades de distancia).