我有一系列代表街道(黑线)和点的点,代表地图上的位置(红点)。我想找到指定街道附近的所有点,按距离排序。我还需要能够指定最大距离(蓝色和绿色区域)。这是一个简单的例子:
我想过使用$near
运算符,但它只接受Point
作为输入,而不是LineString
。
mongodb如何处理这类查询?
答案 0 :(得分:7)
正如您所提到的,Mongo目前不支持Point
以外的任何其他内容。你有没有遇到过路线拳击手的概念? 1 几年前谷歌地图上非常受欢迎。给定您绘制的线条,找到dist(x)
内的止损。这是通过在线中的每个点周围创建一系列边界框,并搜索落在存储桶中的点来完成的。
在我意识到Mongo只适用于积分之后我偶然发现了你的问题,我认为这是合理的。
我已经有了一些如何做的选项(他们扩展了@mnemosyn在评论中所说的内容)。使用我正在处理的数据集,它都在客户端,所以我可以使用routeboxer,但我想在服务器端实现性能原因。以下是我的建议:
将LineString
分解为各自的坐标集,并使用其中的每一个查询$near
,合并结果并提取唯一的集合。有一些算法可以通过减少点数来简化复杂的线条,但是一个简单的算法很容易编写。
执行与上面相同的操作,但作为存储过程/函数。我没有使用Mongo的存储函数,我不知道它们与驱动程序的工作情况如何,但这可能比上面的第一个选项更快,因为你不必进行往返,并且取决于机器你的Mongo实例是托管的,计算速度可以快几微秒。
实现routeboxer方法服务器端(已在PHP中完成),然后使用上述2中的任何一个来查找$within
结果边界框的停靠点。因为routeboxer方法返回矩形,所以可以将所有这些矩形合并到覆盖路线的一个多边形中,并且只需对其进行$within
。 (@mnemosyn的建议)。
编辑:我想到了这一点但忘记了这一点,但有可能使用聚合框架来实现上述目标。
这是我即将开始工作的事情(希望如此),我将根据我的结果开源我的结果。
编辑:我必须提一下,虽然1和2有一个缺陷,如果你在一条线上有2个点,相距2公里,你想要的线距你的线1.8公里,你显然会错过你那一行之间的所有要点。解决方案是在简化时将点注入你的线上(我知道,当重新添加新点时,可以减少点的目标。)
然后3的缺陷是它并不总是准确的,因为你的多边形中的某些点可能有一个大于你的极限的距离,尽管差异不会是你的极限的重要百分比。
答案 1 :(得分:0)
正如你所说,Mongo的$ near仅适用于以点为中心的点,但如果你从线附近的找到点翻转你的前提以找到该点附近的线,那么你可以使用你的点作为中心和线作为目标
这是
之间的区别foreach line find points near it
和
foreach point find line near it
如果你有大量的要检查点,你可以将它与nevi_me的答案结合起来,以减少需要检查更小子集的点列表