JavaScript 函数最近的地理邻居

Posted

技术标签:

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

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

【问题讨论】:

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

【讨论】:

以上是关于JavaScript 函数最近的地理邻居的主要内容,如果未能解决你的问题,请参考以下文章

点的第 k 个最近邻居的空间查询

用于地理空间点搜索的 kdtree

如何在javascript函数中获取地理位置的值

kNN - 如何根据计算出的距离在训练矩阵中定位最近的邻居

iIam 试图在输入字段中显示地理定位 javascript 函数的结果

地理定位功能中的 JavaScript 变量范围