问题 找到与给定点最近的点


我已经搜遍了这个,但我似乎无法找到最好的方法。我有大约22000纬度/经度点,我想找到最接近iPhone当前位置的点。我见过有人问过Quad Trees,Dijkstra算法和空间数据库。哪款最适合iPhone?空间数据库似乎最简单,但我不确定。

编辑:实际上有超过20,000点。您认为迭代所有这些是实现它的方法吗?但是谢谢你的投入。

谢谢。


9904
2018-05-27 01:41


起源

过早优化是万恶之源。特别是,我认为你不能找到小于O(n)的最小值(你必须至少检查一次元素以检查它是否是最接近的),所以我认为你唯一可以优化的是距离计算(仍然应该非常快)。 - las3rjock
看看这个答案 stackoverflow.com/a/12997900/779408 - Bobs


答案:


实际上,最好使用Haversine(大圆)计算Lat / Long点,否则越来越大的距离将是错误的,特别是如果你使用简单的触发器,如 Jherico的回答

快速搜索提供了这个javascript示例:

var R = 6371; // km Radius of earth
var dLat = (lat2-lat1).toRad();
var dLon = (lon2-lon1).toRad(); 
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * 
        Math.sin(dLon/2) * Math.sin(dLon/2); 
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
var d = R * c;

在数据结构方面, 地理散列 值得一看。


5
2018-05-27 01:51



很高兴知道。但是,最初的问题不是关于距离的计算,而是关于要使用的数据结构。除非应用程序需要实时进行不间断的重新计算,否则我同意Jherico:简单的线性搜索就足够了。 - Igor Krivokon
@ raindog-2:Jherico和Chaos的答案都假定线性搜索 - O(N)。只是Chaos的答案给出了准确的计算,而Jherico的假设是平坦的地球。 - Smashery
非常正确 - 我使用了一组有序的距离,然后第一个(或最后一个)点就是您感兴趣的点。 - Chaos
我只是想找到地球上最近的点~2k点可供选择意味着大圆路线与简单三角形之间不断增加的不准确性不会产生影响 - Jherico
那么,在经度的环绕点,你仍然可以选择非常糟糕的选择,即使是2000分。特别是靠近两极。 - Nosredna


如果你需要比O(N)更好,你只能在你第一次支付N lg N来构建某种空间哈希(四叉树,八叉树,哈希网格或类似物)时才能得到它。然后每个测试将大约为O(lg N),并且通常通过缓存您检查的最后位置可以更好,如果存在很多一致性(通常,有)。

我可能会在Euler(地心,XYZ)空间中构建一个八叉树,因为这样可以让我获得“真实”距离,而不是“扭曲”纬度/经度距离。但是,实际上,lat / lon空间中的四叉树可能运行得很好。一旦你有一个命中,你坚持到那个树节点(假设树没有在运行时重建),下一个查询开始从该树节点走,只需要担心可能更近的节点前一点远离前一个答案。


5
2018-05-29 04:09





就像在iPhone上一样,您可以使用CoreLoaction来执行地理距离 - 使用CLLocation – getDistanceFrom:

我会想要使用蛮力线性搜索尽管所有2k点nad,如果还不够快,切换到像GeoHash这样的东西来存储元数据对你的搜索点。


2
2018-05-27 09:42





为什么不将地球平铺到地区? (想想咒语。)然后,无论是在列表中添加点还是在一个大的预处理循环中,对于每个点,都要存储它所在的区域。

然后,当在十六进制X中搜索A点附近的点时,您只需要检查十六进制X中的点和最多三个相邻的十六进制。

如果仍有太多要检查的点,请添加子区域。


1
2018-05-29 07:01





你必须考虑使用Dijkstra,你必须知道图中的节点位置,而不是你想要解决的问题;你不在图表中,但你想知道最接近你的点

很简单,正如Chaos告诉你的那样,你必须计算你的位置和所有20.000点之间的所有距离,然后对它们进行排序


0
2018-02-19 09:30





我认为这个算法有效:

创建一个按纬度排序的数组 创建一个按经度排序的数组

要找到最接近的,首先按纬度找到最近的 在纬度数组中进行二进制搜索。做的 对于经度数组也是如此。现在你有2分,一分 最接近纬度,另一个最接近经度。 通过毕达哥拉斯定理计算到每个点的距离。 最近的一点获胜。

罗杰


-3
2017-09-19 21:47



那是不对的。想象一下你的参考点是(0,0)。 y上的最近点可能是(100,10),最接近x(10,100)。你可能有一个点(11,11)比这两个更接近,但算法会错过它 - Mihai Damian
算法确实是不正确的。 - Gaetano Mendola