查找重叠轨迹

Find Overlapping Trajectories

考虑以下情况:

我将 trips/trajectories 存储在 mongodb 中作为 LineString 并且索引是 2dsphere.

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

给定 $near 上的 maxDistance,Trip1 应该是 "matched",Trip 3 和 4 如图所示。

然而 $geointersects seem to accept a Polygon or Multipolygon as $geometry type and $near 似乎只接受 Point.

是否有任何省时 的方法来使用mongo 查询来实现以下场景?

谢谢!


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

数据可视化(Trip 1为搜索Trip,Trip2-3存入db)

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

旅行2

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

旅行3

  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] ] 
   ]
 }

查询 i 运行 如下:

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

此查询未按预期返回任何内容,因为行程并不像您在可视化中看到的那样相交。我如何修改查询以便使用 $near 运算符将 Trip1 与 Trip3 匹配?

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]
    ];
}

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

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

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

如果这是唯一的问题,我会采用假阴性方法和 运行 2 个 near[x1,y1][x2,y2] 查询来检查是否存在突出显示的区域是否有遗漏的文件。

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

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

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

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