【问题标题】:JavaScript function nearest geographical neighborJavaScript 函数最近的地理邻居
【发布时间】:2013-05-27 14:04:24
【问题描述】:

我正在寻找一个返回数字最近邻的 JavaScript 函数。例如:我有一个坐标 12,323432/12,234223,我想知道数据库中一组 20 个其他坐标的最近坐标。 如何处理?

【问题讨论】:

  • 如果您没有具有适当功能的空间数据库,您可以“手动”计算所有坐标对之间的距离并取最小的一个。
  • 为什么不在sql里做呢?
  • 向我们展示您迄今为止为完成这项任务所做的工作。
  • 到目前为止,我在代码中什么也没做。 Igor S 如何在 SQL 中做到这一点?
  • 在你的数据库上安装postgis

标签: javascript geolocation


【解决方案1】:

以下 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);
}

【讨论】:

    【解决方案2】:

    使用文森蒂公式减少舍入误差

    Haversine 公式 suffers from rounding errors 用于对映点的特殊(并且有些不寻常)情况(在球体的相对端)。

    因此,更好的选择是the Vincenty formula for the special case of a sphere. 它在计算上的要求并不高,但受到机器舍入误差的影响较小。

    这是我的 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-19
      • 2018-09-06
      • 2020-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-03
      相关资源
      最近更新 更多