为啥这个 Python Haversine 公式会产生不正确的答案?

Posted

技术标签:

【中文标题】为啥这个 Python Haversine 公式会产生不正确的答案?【英文标题】:Why is this Python Haversine formula producing incorrect answers?为什么这个 Python Haversine 公式会产生不正确的答案? 【发布时间】:2017-07-20 13:25:00 【问题描述】:

我在堆栈溢出时发现了这段代码:

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

def haversine(lon1, lat1, lon2, lat2):
        """
        Calculate the great circle distance between two points 
        on the earth (specified in decimal degrees)
        """
        # convert decimal degrees to radians 
        lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

        print(lon1, lat1, lon2, lat2)

        # haversine formula 
        dlon = abs(lon2 - lon1) 
        dlat = abs(lat2 - lat1) 
        a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
        c = 2 * atan2(sqrt(a), sqrt(1-a)) 
        r = 6371 # Radius of earth in kilometers. Use 3956 for miles
        return c * r

当我使用具有这些坐标的函数时:haversine(-94.5930, 39.1230, -94.4839, 39.1561),它返回10.103458011601726

当我通过在线 gps 坐标距离计算器运行这些坐标时,它们都会产生大约 12 公里的答案。

我找不到此代码与找到 here 的 hasrsine 公式之间有任何区别,所以我不知道为什么它产生的答案与在线计算器(包括链接中的那个)不同

【问题讨论】:

【参考方案1】:

在您的在线验证和使用您的功能之间,您混淆了纬度和经度的顺序。这个函数需要 lon/lat 对,而 lat/long 是更典型的对的排序。如果您在线输入错误here,您的观察是可重复的。

print haversine(-94.5930, 39.1230, -94.4839, 39.1561) # 10.1034580116
print haversine(39.1230, -94.5930, 39.1561, -94.4839) # 12.1348612974

【讨论】:

【参考方案2】:
from math import sin, cos, sqrt, atan2, radians

# approximate radius of earth in km
R = 6373.0

lat1 = radians(-94.5930)
lon1 = radians(39.1230)
lat2 = radians(-94.4839)
lon2 = radians( 39.1561)

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)

结果:1​​2.138670702897617

【讨论】:

以上是关于为啥这个 Python Haversine 公式会产生不正确的答案?的主要内容,如果未能解决你的问题,请参考以下文章

Haversine 公式和 Python 3 - 数学域错误

在带有变量的javascript中使用haversine公式

Java中的Haversine公式产生不正确的结果

Haversine 公式 - 数学略有偏差,不确定原因

球形余弦Haversine公式

MySQL 函数 ST_Distance_Sphere 没有使用 Haversine 公式?