Geopy / Haversineとは異なる距離


8

特定の分析を実行して、ポイント(店舗の場所)の周囲にバッファーを作成し、そのバッファー値内に他のポイント(ユーザーの場所)が存在するかどうかを確認します。シェイプを使用して距離を確認すると、geopyから取得した距離とは異なることがわかります。hasrsineの式はGeopyと一致し、距離の測定機能を使用したGoogleマップのチェックでもほぼ同じ距離が得られます

次に例を示します。

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
格好の良い:110.02637304449682
半正矢式(http://www.movable-type.co.uk/scripts/latlong.html):84.88

どちらが正しいですか?格好良いですか?また、このような大きな違い(〜22%)が予想されますか?それとも何か不足していますか?

回答:


10

原理とアルゴリズムが異なるため(地理的距離を見てください)

  1. デカルト平面でユークリッド距離を巧みに使用し、平面内の2点間の最短距離は2つの点を含む直線です。
 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、Haversineは、2点間の測地線距離(楕円体、Vincenty)または大円距離(球の表面に沿った最短距離)を使用します。球の表面上の最短距離は、2つの点を含む大円に沿っています。

    したがって、Shapely、Numpy、Scipyのユークリッド距離は、Vincenty、Great Circle、Haversineの距離とは異なり、Vincenty、Great Circles、Haversineの距離の違いは、楕円体などの選択にリンクされているのが普通です。

    楕円体を変更することもできます

 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

または、地理距離として他のライブラリを使用します

 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)

すべての違いがセンチメトリックであることがわかります。メートル単位の精度では、すべての値= 85メートルです。

  1. どちらが正しいですか?すべて、それはコンテキストに依存するためです。投影データ(デカルト平面)で作業する場合は、ユークリッド距離(Shapely、Numpy、Scipyなど)を使用します。そうでない場合は、他の1つを使用します。

    それらは他の多くの距離でもあります(Scipy Spatial distances

新着

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

いい答えです。プロジェクションを使用する際の3 EPSG:3857番目のポイントについての簡単なメモ-Shapelyはここでは間違った選択です。Webメルカトルは非準拠であり、距離の計算に使用しないでください。
Mintx 2016年

3

そして、GeographicLibからの別の距離計算を次に示します。

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

私はこれを15ナノメートル以内の正しいものと考えます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.