232

私はこの式を実装しようとしました: http://andrew.hedges.name/experiments/haversine/ aplet は、私がテストしている 2 つの点でうまくいきます:

ここに画像の説明を入力

しかし、私のコードは機能していません。

from math import sin, cos, sqrt, atan2

R = 6373.0

lat1 = 52.2296756
lon1 = 21.0122287
lat2 = 52.406374
lon2 = 16.9251681

dlon = lon2 - lon1
dlat = lat2 - lat1
a = (sin(dlat/2))**2 + cos(lat1) * cos(lat2) * (sin(dlon/2))**2
c = 2 * atan2(sqrt(a), sqrt(1-a))
distance = R * c

print "Result", distance
print "Should be", 278.546

返される距離は5447.05546147です。なんで?

4

8 に答える 8

271

編集:メモとして、2点間の距離をすばやく簡単に見つける方法が必要な場合は、Haversineを再実装する代わりに、以下のカートの回答で説明されているアプローチを使用することを強くお勧めします-根拠については彼の投稿を参照してください.

この回答は、OP が遭遇した特定のバグへの回答にのみ焦点を当てています。


これは、Python では、すべての三角関数が度数ではなくラジアンを使用するためです。

数値を手動でラジアンに変換するかradians、数学モジュールの関数を使用できます。

from math import sin, cos, sqrt, atan2, radians

# approximate radius of earth in km
R = 6373.0

lat1 = radians(52.2296756)
lon1 = radians(21.0122287)
lat2 = radians(52.406374)
lon2 = radians(16.9251681)

dlon = lon2 - lon1
dlat = lat2 - lat1

a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))

distance = R * c

print("Result:", distance)
print("Should be:", 278.546, "km")

距離が正しい278.545589351km 値を返すようになりました。

于 2013-10-16T19:55:11.853 に答える
107

(私のような)検索エンジン経由でここに来て、すぐに使えるソリューションを探している人には、インストールすることをお勧めしmpuます。経由でインストールし、次のように使用してhasersine 距離pip install mpu --userを取得します。

import mpu

# Point one
lat1 = 52.2296756
lon1 = 21.0122287

# Point two
lat2 = 52.406374
lon2 = 16.9251681

# What you were looking for
dist = mpu.haversine_distance((lat1, lon1), (lat2, lon2))
print(dist)  # gives 278.45817507541943.

代替パッケージはgpxpy.

依存関係が必要ない場合は、次を使用できます。

import math


def distance(origin, destination):
    """
    Calculate the Haversine distance.

    Parameters
    ----------
    origin : tuple of float
        (lat, long)
    destination : tuple of float
        (lat, long)

    Returns
    -------
    distance_in_km : float

    Examples
    --------
    >>> origin = (48.1372, 11.5756)  # Munich
    >>> destination = (52.5186, 13.4083)  # Berlin
    >>> round(distance(origin, destination), 1)
    504.2
    """
    lat1, lon1 = origin
    lat2, lon2 = destination
    radius = 6371  # km

    dlat = math.radians(lat2 - lat1)
    dlon = math.radians(lon2 - lon1)
    a = (math.sin(dlat / 2) * math.sin(dlat / 2) +
         math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) *
         math.sin(dlon / 2) * math.sin(dlon / 2))
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    d = radius * c

    return d


if __name__ == '__main__':
    import doctest
    doctest.testmod()

他の代替パッケージはhaversine

from haversine import haversine, Unit

lyon = (45.7597, 4.8422) # (lat, lon)
paris = (48.8567, 2.3508)

haversine(lyon, paris)
>> 392.2172595594006  # in kilometers

haversine(lyon, paris, unit=Unit.MILES)
>> 243.71201856934454  # in miles

# you can also use the string abbreviation for units:
haversine(lyon, paris, unit='mi')
>> 243.71201856934454  # in miles

haversine(lyon, paris, unit=Unit.NAUTICAL_MILES)
>> 211.78037755311516  # in nautical miles

彼らは、2 つのベクトル内のすべてのポイント間の距離のパフォーマンスが最適化されていると主張しています。

from haversine import haversine_vector, Unit

lyon = (45.7597, 4.8422) # (lat, lon)
paris = (48.8567, 2.3508)
new_york = (40.7033962, -74.2351462)

haversine_vector([lyon, lyon], [paris, new_york], Unit.KILOMETERS)

>> array([ 392.21725956, 6163.43638211])
于 2016-07-04T14:55:35.697 に答える
4

Uber の H3関数を使用して、point_dist()2 つの (緯度、経度) 点間の球面距離を計算できます。戻り値の単位 ('km'、'm'、または 'rads') を設定できます。デフォルトの単位は Km です。

例 :

import h3

coords_1 = (52.2296756, 21.0122287)
coords_2 = (52.406374, 16.9251681)
distance = h3.point_dist(coords_1, coords_2, unit='m') # to get distance in meters

これが役立つことを願っています!

于 2021-02-23T12:19:27.913 に答える
0

最も簡単な方法は、harsine パッケージを使用することです。


import haversine as hs


coord_1 = (lat, lon)
coord_2 = (lat, lon)
x = hs.haversine(coord_1,coord_2)
print(f'The distance is {x} km')
于 2021-08-30T15:34:39.150 に答える