关于如何快速搜索附近地理空间数据的想法

计算科学 优化 算法 计算几何 几何学 空间数据
2021-12-18 04:33:06

我正在研究一个非常简单的问题,但找不到最佳解决方案。我需要接受纬度/经度坐标,并根据该坐标找到大约 1 公里内的所有点(准确性对我来说不太重要)。它也总是大约 1 公里的搜索(固定)。我现在面临如何将这些坐标存储在我的数据库中以及如何快速检索结果。我愿意使用任何数据库或语言来完成这项工作。

目前我正在使用 MongoDB 和 2D 空间索引(http://docs.mongodb.org/manual/applications/geospatial-indexes/)将我的位置存储为平面上的纬度/经度。然后我正在创建一个边界框(准确性对我来说不是很重要,所以我接受一个框,距离在所有方向上都不相同)并使用边界框搜索(http://docs.mongodb.org/manual /reference/operator/query/box/ ) 以获得所有分数。这种方法带来了不错的性能,但我正在寻找更快的速度。

我知道数据库真的很喜欢基于整数的索引。他们执行得最快。我正在寻找一种方法可以将坐标转换为整数或类似的东西?

我知道一些数据库(例如 MySQL 5.7)具有使用 r-trees 的空间索引,这对于大量地理空间操作非常有用,但我有一个我认为可以避免这些索引并利用更快的结构(例如本机整数等)的简单用例.

关于可以使用的算法的一些想法:z-order、hilbert、x-tree、geohash、kd-tree 等。

总结一下我的最终目标:

我想使用接受纬度/经度坐标并转换该坐标,然后最好将其存储在数据库中,以便在数据库上进行非常快速的附近搜索。我对任何方法持开放态度。

干杯

2个回答

我对使用数据库知之甚少,但 kd 树似乎是一种很好的方法。看看下面的链接

http://web.stanford.edu/class/cs106l/handouts/assignment-3-kdtree.pdf

如果您的数据被索引,我不确定第 3 方算法的执行速度是否比 mongoDB 中已经包含的算法快得多。根据你的链接,

在 2.2.3 版更改: 应用程序可以在没有地理空间索引的情况下使用 $box。但是,地理空间索引支持比未索引的等价物更快的查询。在 2.2.3 之前,地理空间索引必须存在于保存坐标的字段上,然后才能使用任何地理空间查询运算符。

但是,如果我要从头开始执行此操作,我会将大地测量数据转换为笛卡尔坐标(例如使用Haversine),然后将它们分类为平衡的kd-treeKd-trees 索引k维点,并使用分而治之的方法相对于根节点(通常是数据集的平均值或中值)对它们进行排序,这使得它们特别适用于最近邻和范围搜索算法。范围搜索将在时间内找到点,这应该足够快。当然,在进行搜索之前,您必须将目标查询转换为笛卡尔坐标。但是,我怀疑 mongoDB 实现了具有相同性能水平的搜索算法,假设您的数据已编入索引。O(logn)

首先转换为笛卡尔坐标很重要,因为大多数 kd-tree 搜索依赖 -norm 作为确定点之间距离的度量标准,这对于地理空间坐标是不正确的。此外,对 kd-tree 的分割平面使用 lat/long 也可能会导致困难,因为经度彼此之间的距离不是等距的(即,经度之间的距离是纬度的函数,这可能使其成为分割 kd- 的糟糕选择树)。L2

Kd-trees 实际上只对批量加载情况有效,在这种情况下,您可以提前了解数据集,并且可以一次性对它们进行排序。可以向 kd-tree 添加新点,但这并不理想。如果您希望您的数据集经常更改,我建议您使用 R-tree。