找到重叠的轨迹

时间:2016-02-26 16:11:04

标签: mongodb gis geospatial

考虑以下情况:enter image description here

我已将mongodb中的行程/轨迹存储为LineString,索引为2dsphere

根据提供的图像,Trip 1是用户想要搜索的轨迹,Trip2-6是已存储在mongodb上的行程。

鉴于$ near附近的maxDistance,Trip1应该是"匹配"如图所示,使用Trip 3和4。

然而,$geointersects似乎接受Polygon or Multipolygon作为$ geometry类型而$near似乎只接受Point

使用mongo查询实现以下方案是否有时间效率方式?

谢谢!

编辑:我将几何体更改为Polygon,正如Alex Blex所说。

数据的可视化(Trip 1是搜索Trip,Trip2-3存储在db中)

Visualisation of Trips

所以我们在mongo上存储了以下文件:

TRIP2

  tripData: Object
 {
   type: Polygon
   coordinates: [ 
      [ [8,2] , [7,3] , [7,4], [8,2] ] 
   ]
 }

TRIP3

  tripData: Object
 {
   type: Polygon
   coordinates: [ 
      [ [3,1], [4,1], [4,1.9999], [3,1] ] 
   ]
 }

旅程1是我们搜索的行程

  tripData: Object
 {
   type: Polygon
   coordinates: [ 
      [ [2,2] , [1,4] , [3,5] , [4,2] , [2,2] ] 
   ]
 }

我运行的查询如下:

 db.trips.find({ tripData: { $geoIntersects : { $geometry : trip1 } } } )

此查询没有按预期返回任何内容,因为您可以在Visualization中看到行程不相交。如何修改查询以使用$ near运算符将Trip1与Trip3匹配?

1 个答案:

答案 0 :(得分:1)

geoIntersects要求查询中的多边形或多边形 ,即问题中的Trip1。 Trip2-6是LineString存储在文档中,非常好。所以唯一要做的就是使用偏移将Trip1转换为多边形,在问题中显示为lime near

让我们先考虑直线。将行[[x1,y1][x2,y2]]转换为偏移d的多边形的功能可以简单如下:

function LineToPolyWithFalsePositive(line, d) {
    var teta = Math.atan2(line[1][0] - line[0][0], line[1][1] - line[0][1]);
    var s = Math.sin(teta);
    var c = Math.cos(teta);
    return [
        [line[0][0] - d*s - d*c, line[0][1] - d*c + d*s], 
        [line[1][0] + d*s - d*c, line[1][1] + d*c + d*s], 
        [line[1][0] + d*s + d*c, line[1][1] + d*c - d*s], 
        [line[0][0] - d*s + d*c, line[0][1] - d*c - d*s]
    ];
}

function LineToPolyWithFalseNegative(line, d) {
    var teta = Math.atan2(line[1][0] - line[0][0], line[1][1] - line[0][1]);
    var s = Math.sin(teta);
    var c = Math.cos(teta);
    return [
        [line[0][0] - d*s, line[0][1] - d*c], 
        [line[0][0] - d*c, line[0][1] + d*s], 
        [line[1][0] - d*c, line[1][1] + d*s], 
        [line[1][0] + d*s, line[1][1] + d*c], 
        [line[1][0] + d*c, line[1][1] - d*s], 
        [line[0][0] + d*c, line[0][1] - d*s]
    ];
}

生成石灰多边形如下图所示:

enter image description here

返回的值可用于geoIntersects查询LineString位置的文档。

有问题的区域以红色突出显示。第一个多边形在边缘情况下覆盖的距离大于d,而在相同的边缘情况下,第二个多边形覆盖的距离小于d

如果这是唯一的问题,我会采用假阴性方法,对点near[x1,y1]再进行2次[x2,y2]次查询,以检查是否有任何错过的文件突出显示的区域。

如果Trip1是复杂的LineString,则需要进行更多的计算才能将其转换为多边形。见图:

enter image description here

除了第一点和最后一点的边缘情况之外,每个段的开始和结束都存在类似的问题。基本上,您需要计算每个段与多边形的锻炼对应顶点之间的角度。你仍然可以。在多边形的假阴性版本中,应该切割用红色圈出的顶点,再次考虑段之间的角度。

如果查询中的Trip1行有很多段,则可能非常昂贵,因为您需要为每个顶点运行near查询+ 2作为终点。

作为一种实用的方法,如果 可接受,则误报版本可能会非常快,因为它是单个查询。