2016-04-22 21 views

回答

2

首先,我們必須寫一個基本功能,計算2點之間的距離:

function distance(lat1, lon1, lat2, lon2) {} 

在這個例子中首先,我們必須計算delta(經度和緯度之間的距離)和平均緯度(緯度的平均值)之間的距離(delta):

var dLat = lat1 - lat2; 
var dLon = lon1 - lon2; 
var mLat = (lat1 + lat2)/2; 
var earthRadius = 3959; //in miles 

然後我們把那些弧度使用d=180/PI rad

dLat = dLat * 180/3.1415926535; 
dLon = dLon * 180/3.1415926535; 
mLat = mLat * 180/3.1415926535; 

現在,我們用公式來我們的數據轉換成距離:

var distance = earthRadius * (dLat * dLat + Math.pow(Math.cos(mLat) * dLon, 2)); 

,並返回的距離

return distance; 

現在,只需遍歷所有的點和ch如果每個人的距離都沒有問題,那麼就去吃。比方說,一個點這樣描述:

var p = { 
    lat = ... 
    lon = ... 
} 

而且假定是一個點的列表(例如,名爲點)和參考點(例如,名爲REF)。

var result = [] 
points.forEach(function (d) { 
    if (distance(d.lat, d.lon, ref.lat, ref.lon) <= 1) { 
     result.push(d); 
    } 
}; 

您還可以檢查緯度邊界框 - 經度需要更復雜的計算,這只是浪費時間。你可以確定一英里的度數爲1/69 deg/mile(大約0.1449度)。所以,你可以檢查哪些點是這個邊界框之外:

var result = [] 
var maxLat = ref.lat + 0.1449; 
var minLat = ref.lat - 0.1449; 
points.forEach(function (d) { 
    if (d.lat > maxLat || d.lat < minLat) continue; 
    if (distance(d.lat, d.lon, ref.lat, ref.lon) <= 1) { 
     result.push(d); 
    } 
}; 

然後你應該完成與距離參考點越接近1英里點的數組。

我可能在公式中有一個錯誤(我更像是一個程序員而不是數學家)。因此,仔細檢查他們是否與我添加了鏈接的維基百科文章一起工作。

+0

將1英里距離轉換爲「度數距離」,而不是轉換每個座標點的速度會更快嗎?假設1英里對應於0.001度的距離,那麼我們只需檢查'(d.lat-ref.lat)** 2 +(d.lon-ref.lon)** 2 <0.001 ** 2',這需要較少的整數計算。我的提議可能是錯的,只是問。 – Delgan

+0

爲了提高速度,您可以根據最小/最大拉特進行簡單的「提早離開」邊界框檢查,並且長時間丟棄大多數點,並且只對通過它的人進行昂貴的距離計算。 – samgak

+0

@Delgan不完全 - 不同緯度的一英里距離不同。例如,在北緯38N/S處,經度爲69英里,而在北緯90N/S處,經度達到0英里。 –

相關問題