Jag har provat flera sätt att mäta avståndet mellan två punkter i min Django-applikation och jämföra resultaten med en tillförlitlig mätning. siffrorna är långt av. Jag antar till exempel att det verkliga avståndet mellan Dublin och Liverpool är ~ 217 km som rapporterats av Google Maps:
Använda geopy
(ska vara extremt exakt ):
>>> from geopy.distance import distance >>> dublin = (-6.270447, 53.339791) >>> liverpool = (-2.991028, 53.402061) >>> distance(dublin, liverpool).km 362.70989455939394
Med hjälp av Django ”s GEOS API (mindre exakt linjär beräkning):
>>> 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: Använd en bättre projektion för detta område (UTM 30N) ger nästan samma resultat:
>>> dublin.transform(32630) >>> liverpool.transform(32630) >>> dublin.distance(liverpool)*100 328.32200116442266
I båda fallen är jag av över 100 km! Mätning av små avstånd (< 1 km) är lika felaktig. Vad gör jag fel här !?
Kommentarer
Svar
Om du inverterar koordinaterna fungerar det inte (geopy använder (latitud, longitud) i 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 ( välformad , django ) använder ett kartesiskt plan och det euklidiska avståndet. Med pyproj (django använder (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
Men, som Vince säger att Mercator-projektionen aldrig ska användas för avståndsmätning.
Med EPSG: 32630 (UTM-zon 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
Och alla resultat (geopy och django) är jämförbara med Googles avstånd eller Avstånd från Liverpool till Dublin (218 km)
Kommentarer
- Lon, lat / lat, lon förvirring slår igen! Jag var säker på att jag hade det precis där.
geopy
docs eller i andra svar, och Vincenty-avståndet jag får ska vara exakt på mm-nivån .dublin.distance(liverpool)*100
< – Det faktum att du var tvungen att multiplicera med 100 istället för 1000 borde berätta något misstänksam pågår här.