Estoy trabajando en un proyecto de Python donde tengo dos pares de lat / long y quiero calcular la distancia entre ellos. En otros proyectos, he calculado la distancia en Postgres usando ST_Distance_Sphere (a.loc_point, b.loc_point), pero me gustaría evitar tener que cargar todos mis datos en Postgres para poder calcular las diferencias de distancia. He buscado, pero no he podido encontrar lo que me gustaría, que es una implementación puramente de Python para no tener que cargar mis datos en Postgres.

Sé que hay otros cálculos de distancia que tratan a la Tierra como una esfera perfecta, pero esos no son lo suficientemente buenos debido a la poca precisión, por eso me gustaría usar la función PostGIS ST_Distance_Sphere () (o un equivalente).

Aquí hay un par de Lat / Longs de muestra que me gustaría calcular la distancia de:

Lat, Long 1: (49.8755, 6.07594)
Lat, Long 2: (49.87257, 6.0784)

No puedo imaginar que soy la primera persona en preguntar esto, pero ¿alguien sabe de una manera de usar ST_Distance_Sphere () para cálculos de larga / larga distancia puramente desde un script de Python?

1
Chris Nielsen 16 feb. 2017 a las 18:03

4 respuestas

La mejor respuesta

Esta es una función rudimentaria utilizada para calcular la distancia entre dos coordenadas en una esfera perfecta con Radio = Radio de la Tierra

from math import pi , acos , sin , cos
def calcd(y1,x1, y2,x2):
   #
   y1  = float(y1)
   x1  = float(x1)
   y2  = float(y2)
   x2  = float(x2)
   #
   R   = 3958.76 # miles
   #
   y1 *= pi/180.0
   x1 *= pi/180.0
   y2 *= pi/180.0
   x2 *= pi/180.0
   #
   # approximate great circle distance with law of cosines
   #
   x = sin(y1)*sin(y2) + cos(y1)*cos(y2)*cos(x2-x1)
   if x > 1:
       x = 1
   return acos( x ) * R

¡Espero que esto ayude!

1
Sishaar Rao 16 feb. 2017 a las 15:20

Desde entonces he encontrado otra forma además de las respuestas proporcionadas aquí. Utilizando el módulo pyvers haversine.

from haversine import haversine as h

# Return results in meters (*1000)
print '{0:30}{1:12}'.format("haversine module:", h(a, b)*1000)

Probé las tres respuestas más el módulo haversine contra lo que obtuve usando ST_Distance_Sphere (a, b) en Postgres. Todas las respuestas fueron excelentes (gracias), pero la respuesta matemática (calculada) de Sishaar Rao fue la más cercana. Aquí están los resultados:

# Short Distance Test
ST_Distance_Sphere(a, b):     370.43790478    
vincenty:                     370.778186438
great_circle:                 370.541763803
calcd:                        370.437386736
haversine function:           370.20481753
haversine module:             370.437394767

#Long Distance test:
ST_Distance_Sphere(a, b):     1011734.50495159
vincenty:                     1013450.40832
great_circle:                 1012018.16318
calcd:                        1011733.11203
haversine function:           1011097.90053
haversine module:             1011733.11203
0
Chris Nielsen 16 feb. 2017 a las 20:05

Vea esto ¿Cómo puedo calcular rápidamente el distancia entre dos puntos (latitud, longitud)?

from math import radians, cos, sin, asin, sqrt
def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    km = 6367 * c
    return km

Por Aaron D

Puede modificarlo para devolver millas agregando miles = km * 0.621371

1
Community 23 may. 2017 a las 11:53

Recomendaría el paquete geopy ; consulte la sección Distancia de medición en la documentación ...

Para su caso particular:

from geopy.distance import great_circle

p1 = (49.8755, 6.07594)
p2 = (49.87257, 6.0784)

print(great_circle(p1, p2).kilometers)
3
ewcz 16 feb. 2017 a las 15:53