Ho provato diversi modi per misurare la distanza tra due punti nella mia applicazione Django e confrontare i risultati con una misurazione affidabile. i numeri sono molto diversi. Ad esempio, presumo che la distanza reale tra Dublino e Liverpool sia ~ 217 km come riportato da Google Maps:
Utilizzando geopy
(dovrebbe essere estremamente accurato ):
>>> from geopy.distance import distance >>> dublin = (-6.270447, 53.339791) >>> liverpool = (-2.991028, 53.402061) >>> distance(dublin, liverpool).km 362.70989455939394
Utilizzo dellAPI GEOS di Django (calcolo lineare meno accurato):
>>> 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: Utilizzo di una proiezione migliore per questarea (UTM 30N) produce quasi lo stesso risultato:
>>> dublin.transform(32630) >>> liverpool.transform(32630) >>> dublin.distance(liverpool)*100 328.32200116442266
In entrambi i casi ho “m off di oltre 100 km! Misurazione di piccole distanze (< 1km) è altrettanto impreciso. Che cosa sto sbagliando qui !?
Commenti
Rispondi
Se inverti le coordinate, non funziona (geopy usa (latitudine, longitudine) in 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 ( formoso , django ) utilizza un piano cartesiano e la distanza euclidea. Con pyproj (django utilizza (longitude, latitude))
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
Ma, come Vince dice, la proiezione di Mercatore non dovrebbe mai essere utilizzata per la misurazione della distanza.
Con 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
E tutti i risultati (geopy e django) sono confrontabili con la distanza di Google o la Distanza da Liverpool a Dublino (218 km)
Commenti
- La confusione lon, lat / lat, lon colpisce ancora! Ero sicuro di averlo trovato proprio lì.
geopy
documenti o in altre risposte e la distanza Vincenty che ottengo dovrebbe essere precisa a livello di mm .dublin.distance(liverpool)*100
< – Il fatto che hai dovuto moltiplicare per 100 invece di 1000 dovrebbe dirti qualcosa sospetto sta succedendo qui.