Distância bem torneada diferente de Geopy / Haversine


8

Estou executando uma análise específica em que usamos shapely para criar buffers em torno de pontos (locais da loja) e, em seguida, verificamos se outros pontos (locais do usuário) estão presentes nesse valor do buffer. Quando eu verifico a distância usando formas, ele acaba sendo diferente da distância que recebo do geopy. A fórmula haversine concorda com o Geopy e uma verificação no google maps usando a função medir distância também fornece a mesma distância

Aqui está um exemplo:

from shapely.geometry import Point, shape
from pyproj import Proj, transform
from geopy.distance import vincenty, great_circle

pt_store=Point(transform(Proj(init='EPSG:4326'),Proj(init='EPSG:3857'),-76.799614, 39.435307))

pt_user=Point(transform(Proj(init='EPSG:4326'),Proj(init='EPSG:3857'),-76.79989,39.43604))

vincenty((39.435307,-76.799614),(39.43604,-76.79989)).meters
great_circle((39.435307,-76.799614),(39.43604,-76.79989)).meters
pt_store.distance(pt_user)

Vincenty: 84.77847691521336
Great_circle: 84.90640111682812 Bem torneado: 110.02637304449682
Fórmula de
Haversine ( http://www.movable-type.co.uk/scripts/latlong.html ): 84.88

Qual deles está certo? Bem torneado ou outros? Além disso, é esperada uma diferença tão grande (~ 22%)? Ou eu estou esquecendo de alguma coisa?

Respostas:


10

Como os princípios e os algoritmos são diferentes (veja a distância geográfica )

  1. Use bem a distância euclidiana em um plano cartesiano e a menor distância entre dois pontos em um plano é uma linha reta que contém os dois pontos.
 import numpy as np
 print np.linalg.norm(np.array(pt_user) - np.array(pt_store))
 110.02637304449682 # meters
 from scipy.spatial import distance
 print distance.euclidean(pt_user, pt_store)
 110.02637304449682 # meters
  1. Vincenty, Great Circle e Haversine usam a distância geodésica (em um elipsóide, Vincenty) ou a distância do grande círculo (a distância mais curta ao longo da superfície de uma esfera) entre dois pontos. A menor distância na superfície de uma esfera é ao longo do grande círculo que contém os dois pontos.

    Portanto, é normal que as distâncias euclidianas Shapely, Numpy e Scipy sejam diferentes das distâncias Vincenty, Great Circle e Haversine e as diferenças entre as distâncias Vincenty, Great Circles e Haversine estão ligadas à escolha de um elipsóide e muitas outras coisas.

    Você também pode alterar o elipsóide

 print vincenty((39.435307,-76.799614),(39.43604,-76.79989),ellipsoid='WGS-84')
 0.0847784769149 km
 print vincenty((39.435307,-76.799614),(39.43604,-76.79989),ellipsoid='GRS-80')
 0.0847784769128 km

Ou use outras bibliotecas como geodistância

 print geodistance.distanceVincenty(39.435307,-76.799614,39.43604,-76.79989, ellipsoid='WGS-84')
 (0.08477847691523362, -16.276730447136675) # distance, azimuth
 print geodistance.distanceHaversine(39.435307,-76.799614,39.43604,-76.79989)
 (0.08488248586585143, -16.214988211007256)

Você pode ver que todas as diferenças são centimétricas. Com precisão métrica, todos os valores = 85 metros.

  1. Qual deles está certo? Tudo porque depende do contexto: se você trabalha com dados projetados (plano cartesiano), usa a distância euclidiana (Shapely, Numpy, Scipy e muitas outras), se não, uma das outras.

    Também existem muitas outras distâncias ( distâncias espaciais do Scipy )

Novo

Em apoio à resposta da Mintx

pt_store=Point(transform(Proj(init='EPSG:4326'),Proj(init='EPSG:31370'),-76.799614, 39.435307))
pt_user=Point(transform(Proj(init='EPSG:4326'),Proj(init='EPSG:31370'),-76.79989,39.43604))
pt_store.distance(pt_user)
86.26511001003892

Boa resposta. Apenas uma nota rápida sobre o seu ponto # 3 ao usar a projeção EPSG:3857- Shapely é a escolha errada aqui. O Web Mercator não é conforme e não deve ser usado para calcular distâncias.
Mintx

3

E aqui está outro cálculo de distância do GeographicLib :

from geographiclib.geodesic import Geodesic
g = Geodesic.WGS84.Inverse(39.435307, -76.799614, 39.43604, -76.79989)
print(g['s12'])  # 84.7784769689

Eu consideraria o caminho certo, dentro de 15 nanômetros.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.