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:

tutaj wprowadź opis obrazu

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

  • W Twoim przykładzie z django nie ' t EPSG: 3857 używaj metrów zamiast stopni ?
  • Mercator nie powinien nigdy być używany do pomiaru odległości, zwłaszcza na dalekiej północy.
  • Próbowałem zamienić punkty na 32630 (strefa UTM 30N) i uzyskałem 328,3 km. W tym przypadku prawie nie ma różnicy. W dokumentach 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.

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.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *