基于纬度/经度求两点间距离

2024-10-06 07:59:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着实现这个公式:http://andrew.hedges.name/experiments/haversine/ aplet对我正在测试的两点有好处:

enter image description here

但我的代码不起作用。

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。为什么?


Tags: httpsqrtsincos公式distanceprintandrew
3条回答

对于那些通过搜索引擎来这里寻找解决方案的人(比如我),我建议安装^{}。通过pip install mpu --user安装它,并像这样使用它来获得haversine distance

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.

另一个包是^{}

如果不需要依赖项,可以使用:

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()

编辑:作为一个注释,如果您只需要一个快速简便的方法来找到两点之间的距离,我强烈建议您使用下面Kurt's answer中描述的方法,而不是重新实现Haversine——请参阅他的文章以了解其基本原理。

这个答案集中在回答操作遇到的特定错误上。


这是因为在Python中,所有的trig函数都是use 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。

更新:2018年4月:请注意,由于GeoPy版本1.13,Vincenty distance已被弃用-您应该改用GeoPy.distance.distance()!


上面的答案是基于Haversine formula,它假设地球是一个球体,结果误差高达0.5%(根据help(geopy.distance))。Vincenty distance使用更精确的椭球模型,如WGS-84,并在geopy中实现。例如

import geopy.distance

coords_1 = (52.2296756, 21.0122287)
coords_2 = (52.406374, 16.9251681)

print geopy.distance.vincenty(coords_1, coords_2).km

将使用默认椭球WGS-84打印279.352901604公里的距离。(您也可以选择.miles或其他几个distance units之一)。

相关问题 更多 >