找到与给定点最近的点

时间:2009-05-27 01:41:58

标签: iphone objective-c gps

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

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

感谢。

6 个答案:

答案 0 :(得分:5)

实际上,最好对纬度/长点使用Haversine(大圆)计算,否则越来越大的距离将是错误的,特别是如果你使用Jherico's answer中的简单触发。

快速搜索提供了这个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;

就数据结构而言,Geohash值得关注。

答案 1 :(得分:5)

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

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

答案 2 :(得分:2)

当您使用iPhone时,可以使用CoreLoaction执行地理距离 - 使用CLLocation的– getDistanceFrom:

我很想使用蛮力线性搜索尽管所有2k点nad,如果不够快,切换到类似GeoHash的东西来存储元数据与你的搜索点。

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:-3)

我认为这个算法有效:

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

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

罗杰