如何快速估算两个(纬度,经度)点之间的距离?

问题描述 投票:52回答:7

我希望能够估计两个(纬度,经度)点之间的距离。我想低估,因为这将是A *图搜索,我希望它快。这些点最多相距800公里。

python math maps mapping latitude-longitude
7个回答
105
投票

Haversine Formula in Python (Bearing and Distance between two GPS points)的答案提供了回答您问题的Python实现。

使用下面的实现,我在一台旧笔记本电脑上在不到1秒的时间内完成了100,000次迭代。我认为,为了你的目的,这应该足够了。但是,在优化性能之前,您应该分析任何内容。

from math import radians, cos, sin, asin, sqrt
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])
    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    # Radius of earth in kilometers is 6371
    km = 6371* c
    return km

要低估haversine(lat1, long1, lat2, long2) * 0.90或你想要的任何因素。我没有看到如何将错误引入低估是有用的。


35
投票

由于距离相对较小,因此可以使用等距离近似。这种近似比使用Haversine公式更快。因此,要获得从参考点(lat1 / lon1)到您正在测试的点(lat2 / lon2)的距离,请使用下面的公式。重要说明:您需要将所有纬度/经度点转换为弧度:

R = 6371  // radius of the earth in km
x = (lon2 - lon1) * cos( 0.5*(lat2+lat1) )
y = lat2 - lat1
d = R * sqrt( x*x + y*y )

由于'R'以km为单位,因此距离'd'将以km为单位。

参考:http://www.movable-type.co.uk/scripts/latlong.html


7
投票

速度的一个想法是将长/纬协调变换为3D(x,y,z)坐标。在预处理点之后,使用点之间的欧几里德距离作为实际距离的快速计算下冲。


3
投票

对于最大速度,您可以为坐标距离创建类似rainbow table的东西。听起来你已经知道你正在使用的区域,所以看起来预先计算它们可能是可行的。然后,您可以加载最近的组合,然后使用它。

例如,在美国大陆,经度是55度跨度,纬度是20,这将是1100整数点。所有可能组合之间的距离是handshake problem,其由(n-1)(n)/ 2或约600k组合回答。存储和检索似乎非常可行。如果您提供有关您的要求的更多信息,我可能会更具体。


1
投票

如果点之间的距离相对较小(米到几公里范围),则可以采用其中一种快速方法

from math import cos, sqrt
def qick_distance(Lat1, Long1, Lat2, Long2):
    x = Lat2 - Lat1
    y = (Long2 - Long1) * cos((Lat2 + Lat1)*0.00872664626)  
    return 111.138 * sqrt(x*x + y*y)

Lat,Long以弧度为单位,距离以km为单位。

与Haversine距离的偏差大约为1%,而速度增益大于~10x。

0.00872664626 = 0.5 * 皮/180,

111.138 - 对应于赤道1degree的距离,您可以将其替换为中值,如https://www.cartographyunchained.com/cgsta1/或用简单的查找表替换它。


0
投票

请使用以下代码。

def distance(lat1, lng1, lat2, lng2):
    #return distance as meter if you want km distance, remove "* 1000"
    radius = 6371 * 1000 

    dLat = (lat2-lat1) * math.pi / 180
    dLng = (lng2-lng1) * math.pi / 180

    lat1 = lat1 * math.pi / 180
    lat2 = lat2 * math.pi / 180

    val = sin(dLat/2) * sin(dLat/2) + sin(dLng/2) * sin(dLng/2) * cos(lat1) * cos(lat2)    
    ang = 2 * atan2(sqrt(val), sqrt(1-val))
    return radius * ang

0
投票

要计算2点之间的半径距离你可以简单地使用mpu.haversine_distance()库,如下所示:

>>> import mpu
>>> munich = (48.1372, 11.5756)
>>> berlin = (52.5186, 13.4083)
>>> round(mpu.haversine_distance(munich, berlin), 1)
>>> 504.2
© www.soinside.com 2019 - 2024. All rights reserved.