He probado varias formas de medir la distancia entre dos puntos en mi aplicación Django y comparar los resultados con una medición confiable. Mi los números están muy desviados. Por ejemplo, supongo que la distancia real entre Dublín y Liverpool es de ~ 217 km según lo informado por Google Maps:
Usando geopy
(debe ser extremadamente preciso ):
>>> from geopy.distance import distance >>> dublin = (-6.270447, 53.339791) >>> liverpool = (-2.991028, 53.402061) >>> distance(dublin, liverpool).km 362.70989455939394
Usando la API de GEOS de Django (cálculo lineal menos preciso):
>>> from django.contrib.gis.geos import Point >>> dublin = Point(-6.270447, 53.339791, srid=3857) >>> liverpool = Point(-2.991028, 53.402061, srid=3857) >>> dublin.distance(liverpool)*100 328.00101418228877
EDIT: Usando una mejor proyección para esta área (UTM 30N) produce casi el mismo resultado:
>>> dublin.transform(32630) >>> liverpool.transform(32630) >>> dublin.distance(liverpool)*100 328.32200116442266
En ambos casos, no por más de 100 km. Medición de distancias pequeñas (< 1km) es igualmente inexacto. ¿¡Qué estoy haciendo mal aquí !?
Comentarios
Respuesta
Si inviertes las coordenadas, no funciona (geopy usa (latitud, longitud) en WGS84 crs)
dublin = (53.33306,-6.24889) liverpool = ( 53.41058,-2.97794) print distance(dublin, liverpool).km 217.863019038 print(vincenty(dublin, liverpool).kilometers) 217.863019038 print(great_circle(dublin, liverpool).kilometers) 217.211596704
GEOS ( bien formado , django ) utiliza un plano cartesiano y la distancia euclidiana. Con pyproj (django usa (longitud, latitud))
from django.contrib.gis.geos import Point dublin = Point(-6.270447, 53.339791, srid=4326) # in degrees liverpool = Point(-2.991028, 53.402061, srid=4326) # in degrees dublin.distance(liverpool)*100 328.00101418228877 # units ? import pyproj # conversion from WGS84 to epsg:3857 p1 = pyproj.Proj(proj="latlong",datum="WGS84") p2 = pyproj.Proj(init="epsg:3857") a = pyproj.transform(p1,p2,-6.270447, 53.339791) b = pyproj.transform(p1,p2,-2.991028, 53.402061) dublin = Point(a) # in meters liverpool = Point(b) # in meters dublin.distance(liverpool)/1000 # Euclidean 365.2480859440489 #in km
Pero, como Vince dice, la proyección de Mercator nunca debe usarse para medir distancias.
Con el EPSG: 32630 (zona UTM 30N):
p3 = pyproj.Proj(init="epsg:32630") a = pyproj.transform(p1,p3,-6.270447, 53.339791) b = pyproj.transform(p1,p3,-2.991028, 53.402061) dublin = Point(a) liverpool = Point(b) dublin.distance(liverpool)/1000 218.32514783088294 #in km
Y todos los resultados (geopy y django) son comparables con la distancia de Google o la Distancia de Liverpool a Dublín (218 km)
Comentarios
- ¡La confusión lon, lat / lat, lon ataca de nuevo! Estaba seguro de que lo tenía allí mismo.
geopy
o en otras respuestas, y la distancia Vincenty que obtengo debería ser precisa en el nivel de mm .dublin.distance(liverpool)*100
< – El hecho de que tuvieras que multiplicar por 100 en lugar de 1000 debería decirte algo sospechoso está sucediendo aquí.