簡體   English   中英

如何快速估計兩個(緯度、經度)點之間的距離?

[英]How can I quickly estimate the distance between two (latitude, longitude) points?

我希望能夠估計兩個(緯度,經度)點之間的距離。 我想低於,因為這將用於 A* 圖形搜索,並且我希望它很快 這些點最多相距 800 公里。

Python 中Haversine 公式的答案(兩個 GPS 點之間的軸承和距離)提供了 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或您想要的任何因素。 我不明白在你的低估中引入錯誤有什么用。

由於距離相對較小,您可以使用等距柱狀距離近似值。 這種近似比使用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”以公里為單位,因此距離“d”將以公里為單位。

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

速度的一種想法是將經緯度坐標轉換為 3D (x,y,z) 坐標。 對點進行預處理后,使用點之間的歐幾里得距離作為實際距離的快速計算下沖。

如果點之間的距離相對較小(幾米到幾公里的范圍),那么快速方法之一可能是

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.319 * sqrt(x*x + y*y)

Lat, Long 以弧度為單位,距離以公里為單位。

與 Haversine 距離的偏差約為 1%,而速度增益超過 ~10 倍。

0.00872664626 = 0.5 * pi/180,

111.319 - 是對應於赤道 1 度的距離,你可以用你的中值替換它,就像這里https://www.cartographyunchained.com/cgsta1/或用一個簡單的查找表替換它。

為了獲得最大速度,您可以為坐標距離創建類似彩虹表的東西。 聽起來您已經知道您正在使用的領域,因此預先計算它們似乎是可行的。 然后,您可以加載最接近的組合並使用它。

例如,在美國大陸,經度為 55 度跨度,緯度為 20,這將是 1100 個整數點。 所有可能組合之間的距離是一個握手問題,由 (n-1)(n)/2 或大約 600k 組合回答。 存儲和檢索這似乎非常可行。 如果您提供有關您的要求的更多信息,我可以更具體。

您可以使用cdist空間距離類中的scipy

例如

from scipy.spatial.distance import cdist 
df1_latlon = df1[['lat','lon']]
df2_latlon = df2[['lat', 'lon']]
distanceCalc = cdist(df1_latlon, df2_latlon, metric=haversine)

要計算兩點之間的半正弦距離,您可以簡單地使用mpu.haversine_distance()庫,如下所示:

>>> import mpu
>>> munich = (48.1372, 11.5756)
>>> berlin = (52.5186, 13.4083)
>>> round(mpu.haversine_distance(munich, berlin), 1)
>>> 504.2

請使用以下代碼。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM