如何查询从一个区域到另一个区域的所有空间轨迹
Posted
技术标签:
【中文标题】如何查询从一个区域到另一个区域的所有空间轨迹【英文标题】:How to query all spatial trajectories that go from one region to another 【发布时间】:2022-01-04 16:57:54 【问题描述】:考虑一个 mongo db,其中每个文档对应一个空间轨迹。也就是说,有一个字段包含每个文档的数组。每个数组是表示地理轨迹的纬度/经度对序列。给定由 geojson 多边形定义的两个地理区域 R1、R2,找到与第一个 R1 和第二个 R2 相交的所有轨迹。考虑到数据库的大小,计算时间非常重要。
我的第一次尝试有效,但没有考虑方向。而且,它非常慢。我使用聚合框架(区域 gjs[i])。我当前的管道包含以下内容。
"$match":"location.lonlat":'$geoIntersects':'$geometry':gjs[0], "$match":"location.lonlat":'$geoIntersects':'$geometry':gjs[1]
【问题讨论】:
【参考方案1】:来自the MongoDB manual:
$geoIntersects 使用球面几何。 $geoIntersects 不需要地理空间索引。但是,地理空间索引将提高查询性能。只有 2dsphere 地理空间索引支持 $geoIntersects。
所以你有一个问题:你的查询有效,因为$geoIntersects
确实不需要索引,但它很慢,因为没有索引。为了加快速度,您必须创建一个2dsphere
索引,因为这是$geoIntersects
使用的唯一索引(即不是2d
索引)——不幸的是,它在遗留数组上不起作用坐标点(你的“轨迹”)。
我的建议是使用完整的 GeoJSON:
-
将您的
location.lonlat
点数组转换为 GeoJSON LineString
对象,例如
location:
"trajectory" :
"type" : "LineString",
"coordinates" : [ [10,60] , [10,61] , [10,62] ]
,
您可以通过非破坏性更新来做到这一点,以在location
对象中创建一个新字段trajectory
作为lonlat
的对等体。注意update()
数组形式的使用允许管道,因此$location.lonlat
数组可以复制到新字段中:
db.foo.update(, [ $set: "location.trajectory": type: "LineString", coordinates: "$location.lonlat" ], multi:true);
-
在
location.trajectory
上创建2dsphere
索引:
db.foo.createIndex("location.trajectory":"2dsphere");
您的查询现在可以执行了。
【讨论】:
感谢您的回答。线的方向呢?不幸的是,我无权修改集合,所以我无法添加索引... 这是您必须使用从查询返回的材料在代码中计算并遵守您的规则的东西。关于“方向”与“方位”以及如何为与一条线(您的轨迹)相交的多边形找到合适的“针点”有太多细微差别。如果您对如何计算此类事物的想法感兴趣,请查看github.com/buzzm/hurricane。一个快速的想法?假设一个区域不包含另一个 AND 轨迹在经度 (X) 上单调递增,然后将 R1 的最左边点与 R2 进行比较以获得方向。以上是关于如何查询从一个区域到另一个区域的所有空间轨迹的主要内容,如果未能解决你的问题,请参考以下文章
MFC中,如何将CBitmap中的图片复制到另一CBitmap的一块区域中,即如何读取一个CBit