14

我有一组点代表一条街道(黑线)和点,代表地图上的一个地方(红点)。我想找到指定街道附近的所有点,按距离排序。我还需要能够指定最大距离(蓝色和绿色区域)。这是一个简单的例子:

在此处输入图像描述

我想过使用$near运算符,但它只接受Point作为输入,而不是LineString.

mongodb 如何处理这种类型的查询?

4

2 回答 2

7

正如您所提到的,Mongo 目前不支持Point. 你遇到过路线拳击手的概念吗?1几年前,它在 Google 地图上非常流行。给定您绘制的线,找到 内的停靠点dist(x)。这是通过在行中的每个点周围创建一系列边界框并搜索落入桶内的点来完成的。

在我刚刚意识到 Mongo 仅适用于积分后,我偶然发现了您的问题,我认为这是合理的。

我已经有了一些如何做的选择(他们扩展了@mnemosyn 在评论中所说的内容)。对于我正在处理的数据集,它都在客户端,所以我可以使用 routeboxer,但出于性能原因,我想在服务器端实现它。以下是我的建议:

  1. LineString分解分解为其单独的坐标集,并查询$near使用其中的每一个,组合结果并提取一个独特的集合。有一些算法可以通过减少点的数量来简化复杂的线,但简单的算法很容易编写。

  2. 执行与上述相同的操作,但作为存储过程/函数。我没有玩过 Mongo 的存储函数,我不知道它们与驱动程序的工作情况如何,但这可能比上面的第一个选项更快,因为您不必进行往返,并且取决于机器您的 Mongo 实例是托管的,计算速度可能会快几微秒。

  3. 在服务器端实现 routeboxer 方法(已在 PHP 中完成),然后使用上述 2 中的任何一个来查找$within作为结果边界框的停靠点。哎呀,由于 routeboxer 方法返回矩形,因此可以将所有这些矩形合并为一个覆盖您的路线的多边形,然后$within对其进行操作。(@mnemosyn 的建议)。

  4. 编辑:我想到了这一点,但忘记了,但使用聚合框架可能实现上述一些。

这是我将很快着手处理的事情(希望如此),我将根据我最终得到的结果开源我的结果。

编辑:我必须提到,虽然 1 和 2 有一个缺陷,即如果您在一条相距 2 公里的线上有 2 个点,并且您想要距离您的线 1.8 公里以内的点,那么您显然会错过之间的所有点你线路的那一部分。解决方案是在简化时将点注入到您的线上(我知道,在添加新点时会达到减少点的目标)。

那么 3 的缺陷是它并不总是准确的,因为多边形中的某些点的距离可能大于您的限制,尽管差异不会是您限制的很大百分比。

[ 1 ] google maps utils routeboxer

于 2013-11-23T00:16:58.550 回答
0

正如您所说,Mongo 的 $near 仅适用于点而不是线作为中心点,但是如果您将前提从在线附近的查找点翻转到该点附近的线,那么您可以使用您的点作为中心和线作为目标

这是之间的区别

foreach line find points near it

foreach point find line near it

如果您有大量要检查的点,您可以将其与 nevi_me 的答案结合起来,以将需要检查的点列表减少到更小的子集

于 2018-01-08T10:19:23.370 回答