搜索和排序大量的经纬度

时间:2011-03-10 12:29:15

标签: php sql database algorithm

所以我有一个纬度/经度数组(你可以看到它的假纬度/经度,但只是为了说明点和原始数组的大小比这大得多):

<?php
$my_nodes = array(
1=> array(273078.139,353257.444),
2=> array(273122.77,352868.571),
3=> array(272963.687,353782.863),
4=> array(273949.566,353370.127),
5=> array(274006.13,352910.551),
6=> array(273877.095,353829.704),
7=> array(271961.898,353388.245),
8=> array(272839.07,354303.863),
9=> array(273869.141,354417.432),
10=> array(273207.173,351797.405),
11=> array(274817.901,353466.462),
12=> array(274862.533,352958.718),
13=> array(272034.812,351852.642),
14=> array(274128.978,354676.828),
15=> array(271950.85,354370.149),
16=> array(275087.902,353883.617),
17=> array(275545.711,352969.325)));

?>

我希望能够找到给定纬度X和纬度Y的最近节点(在这种情况下节点是1,2,3,4,5 ......)。我知道最简单的方法这样做是为了做一个for循环,然后做一个边距误差(abs(latitude_X - latitude_X_array)+ abs(latitude_Y - latitude_Y_array))但随着数组大小的增加,这将是非常低效的。

我正在考虑进行二分搜索,但是数组需要先在二进制搜索中进行排序,但是很难对纬度/经度进行排序,最后我们在数组中找到CLOSEST纬度/经度给定的纬度X,长Y.我应该采取什么方法?

UPDATE:

Mark有一个有效点,这些数据可以存储在数据库中。但是,如果我想要最接近的数据,如何从数据库获取此类信息?

4 个答案:

答案 0 :(得分:2)

阅读this article,其中解释了使用存储在数据库中的记录中使用纬度和经度查找最近点的所有内容,并且还提供了很多有关如何使其高效的帮助....代码示例。

答案 1 :(得分:0)

当我想重新采样大量的纬度/长点以创建高度场网格时,我遇到了类似的问题。我找到的最简单的方法是这样的:

  1. 将纬度/经度空间划分为常规网格
  2. 为每个网格方块创建一个存储桶
  3. 浏览列表,将每个点添加到存储桶中,以便将网格划分为
  4. 然后找到你的X,Y点落入的网格方格,并从那里向外搜索

答案 2 :(得分:0)

我假设您将数据存储在这样的数据库表中?

id | lat   | long   | data
------------------------------------------------
1 | 123.45 | 234.56 | A description of the item
2 | 111.11 | 222.22 | A description of another item

在这种情况下,您可以使用SQL来缩小结果集范围。

如果要查找接近网格参考20,40的项目,可以执行以下查询:

SELECT * 
FROM locations
WHERE lat BETWEEN 19 AND 21
AND long BETWEEN 39 AND 41

这将返回指定网格ref附近的2x2网格中的所有tiems。

有几个数据库也提供了空间数据类型(MySQL和Postgres都这样做),他们可能值得研究这项工作。但是,我没有这方面的经验,所以我担心我无法帮助那些。

答案 3 :(得分:0)

要在PHP中对多维数组进行排序,您必须迭代所有元素并一次比较两个。对于大小为n的数组,进行O(n)比较。查找排序数组中最近的节点需要O(log n)距离计算 如果迭代所有元素,计算到目标节点的距离并记住最接近的元素,则需要完成O(n)距离计算。
假设比较两个节点意味着比较lat和lon值,因此是O(2),并且进一步假设计算两个节点之间的距离是O(3),你以 O(2n + 3 log n)用于二分搜索,O(3n)用于幼稚搜索 因此,二进制搜索需要n - 3 log n的操作,并且速度快约33%。

根据节点的分布情况,将列表排序到存储桶可能会更快。在填充桶期间,您还可以丢弃将进入桶中的所有节点,这些节点永远不会占用最近的节点。如果你愿意,我可以更详细地解释一下。