Eu tentei várias maneiras de medir a distância entre dois pontos em meu aplicativo Django e comparar os resultados com uma medição confiável. os números estão muito errados. Por exemplo, suponho que a distância real entre Dublin e Liverpool seja de aproximadamente 217 km, conforme relatado pelo Google Maps:

insira a descrição da imagem aqui

Usando geopy (deve ser extremamente preciso ):

>>> from geopy.distance import distance >>> dublin = (-6.270447, 53.339791) >>> liverpool = (-2.991028, 53.402061) >>> distance(dublin, liverpool).km 362.70989455939394 

Usando a API GEOS do Django (cálculo linear 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 

EDITAR: Usando uma projeção melhor para esta área (UTM 30N) produz quase o mesmo resultado:

>>> dublin.transform(32630) >>> liverpool.transform(32630) >>> dublin.distance(liverpool)*100 328.32200116442266 

Em ambos os casos, estou desligado por mais de 100 km! Medindo pequenas distâncias (< 1km) é igualmente impreciso. O que estou fazendo de errado aqui !?

Comentários

  • Para seu exemplo do django, não ' t EPSG: 3857 usa metros em vez de graus ?
  • Mercator nunca deve ser usado para medição de distâncias, especialmente tão ao norte.
  • Tentei transformar os pontos em 32630 (zona UTM 30N) e consegui 328,3 km. Quase nenhuma diferença neste caso. Não há ' nada sobre projeção nos geopy documentos ou em outras respostas, e a distância de Vincenty que obtenho deve ser precisa no nível de mm .
  • dublin.distance(liverpool)*100 < – O fato de você ter que multiplicar por 100 em vez de 1000 deve lhe dizer algo suspeito está acontecendo aqui.

Resposta

Se você inverter as coordenadas, não funciona (geopy usa (latitude, longitude) nos 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 ( bem feito , django ) usa um plano cartesiano e a distância euclidiana. Com pyproj (django usa (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 

Mas, como Vince diz, a projeção de Mercator nunca deve ser usada para medição de distância.

Com o 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 todos os resultados (geopy e django) são comparáveis com a distância do Google ou a Distância de Liverpool a Dublin (218 km)

Comentários

  • A confusão lon, lat / lat, lon volta a acontecer! Eu tinha certeza que estava lá.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *