查找重叠轨迹
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 个终点。
作为一种实用的方法,如果 可以接受,则误报版本可能工作得非常快,因为它是单个查询。
考虑以下情况:
我将 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 个终点。
作为一种实用的方法,如果 可以接受,则误报版本可能工作得非常快,因为它是单个查询。