我正在寻找一个返回数字最近邻居的 JavaScript 函数。例如:我有一个坐标 12,323432/12,234223,我想知道数据库中一组 20 个其他坐标的最近坐标。如何处理?
问问题
3137 次
2 回答
4
以下 3 个函数使用Haversine公式从 javascript 数组中查找最近的坐标。
function toRad(Value) {
/** Converts numeric degrees to radians */
return Value * Math.PI / 180;
}
function haversine(lat1,lat2,lng1,lng2){
rad = 6372.8; // for km Use 3961 for miles
deltaLat = toRad(lat2-lat1);
deltaLng = toRad(lng2-lng1);
lat1 = toRad(lat1);
lat2 = toRad(lat2);
a = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) + Math.sin(deltaLng/2) * Math.sin(deltaLng/2) * Math.cos(lat1) * Math.cos(lat2);
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return rad * c;
}
function calculate(){
var result = haversine(lat1,coordArray [0][0],lng1,coordArray [0][1]);
for (var i=1;i<coordArray.length;i++){
var ans = haversine(lat1,coordArray [i][0],lng1,coordArray [i][1]);
if (ans < result){//nearest
result = ans;
}
}
document.write("Result " +result);
}
于 2013-05-28T18:16:08.277 回答
1
使用 Vincenty 公式减少舍入误差
Haversine 公式在对映点的特殊(并且有些不寻常)情况下(在球体的两端)存在舍入误差。
因此,对于球体的特殊情况,更好的选择是文森蒂公式。它在计算上的要求并不高,但受机器舍入误差的影响较小。
这是我的 Python3 实现,它可以在任何使用Brython的浏览器中运行,或者可以轻松地手动转码为 JavaScript:
from math import radians, sin, cos, atan2, sqrt
def vincenty_sphere(lat1,lat2,lon1,lon2):
lat1 = radians(lat1)
lat2 = radians(lat2)
delta_lon = radians(lon2-lon1)
term1 = (cos(lat2) * sin(delta_lon))**2
term2 = (cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_lon))**2
numerator = sqrt(term1 + term2)
denominator = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(delta_lon)
central_angle = atan2(numerator, denominator)
radius = 6372.8 # km
return radius * central_angle
def station_near(geo):
lat = geo['latitude']
lon = geo['longitude']
nearest = 40042.0 # km
for s in range(len(STATIONS)):
distance = vincenty_sphere(lat, STATIONS[s].lat, lon, STATIONS[s].lon)
if(distance < nearest):
nearest = distance
station = s
return station
于 2017-01-06T20:12:55.653 回答