Próbowałem kilku sposobów zmierzenia odległości między dwoma punktami w mojej aplikacji Django i porównania wyników z wiarygodnym pomiarem. liczby są bardzo błędne. Na przykład zakładam, że rzeczywista odległość między Dublinem a Liverpoolem wynosi ~ 217 km, zgodnie z danymi z Map Google:
Używając geopy
(powinno być wyjątkowo dokładne ):
>>> from geopy.distance import distance >>> dublin = (-6.270447, 53.339791) >>> liverpool = (-2.991028, 53.402061) >>> distance(dublin, liverpool).km 362.70989455939394
Korzystanie z interfejsu API GEOS firmy Django (mniej dokładne obliczenia liniowe):
>>> 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
EDYCJA: Korzystanie z lepszej projekcji dla ten obszar (UTM 30N) daje prawie taki sam wynik:
>>> dublin.transform(32630) >>> liverpool.transform(32630) >>> dublin.distance(liverpool)*100 328.32200116442266
W obu przypadkach I „m off o ponad 100 km! Pomiar małych odległości (< 1 km) jest tak samo niedokładne. Co ja tu robię źle !?
Komentarze
Odpowiedź
Jeśli odwrócisz współrzędne, to nie działa (geopy używa (szerokość i długość geograficzna) w crs WGS84)
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 ( zgrabnie , django ) wykorzystuje płaszczyznę kartezjańską i odległość euklidesową. Z pyproj (używa django (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
Ale jak Vince mówi, że odwzorowanie Mercatora nigdy nie powinno być używane do pomiaru odległości.
Z EPSG: 32630 (strefa 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
A wszystkie wyniki (geopy i django) są porównywalne z odległością Google lub odległością z Liverpoolu do Dublina (218 km)
Komentarze
- Znów pojawia się zamieszanie lon, lat / lat, lon! Byłem pewien, że mam to właśnie tam.
geopy
ani w innych odpowiedziach ' nie ma nic o projekcji, a odległość Vincentyego, którą otrzymuję, powinna być dokładna na poziomie milimetrów .dublin.distance(liverpool)*100
< – Fakt, że trzeba było pomnożyć przez 100 zamiast 1000, powinien coś powiedzieć dzieje się tu podejrzanie.