在 MongoDB 中截取一个 FeatureCollection

Intersept a FeatureCollection in MongoDB

我有一个充满奥地利州的 GeoJson,我想做一个查询,将某些州截获我的多边形作为输出。

这是我的查询:

db.GeoAustria.find(
  {
  'features.geometry':{
    $geoIntersects:{
      $geometry:{
        type: "Polygon",
        coordinates:  [
          [
            [
              16.21685028076172,
              48.007381433478855
            ],
            [
              16.24225616455078,
              47.98716432210271
            ],
            [
              16.256675720214844,
              48.00669234420252
            ],
            [
              16.21685028076172,
              48.007381433478855
            ]
          ]
        ]
        }
      }
    }
  }
)

但它为我提供了所有功能,包括那些不与多边形重叠的功能... 我在这个查询中的错误在哪里?

基本数组匹配误区在这里。输入集是一个文档,在一个 FeatureCollection object 数组中有 95 个多边形。当您对此类事物执行 find() 时,任何相交的单个地理区域都会导致整个文档作为匹配项返回。这与:

完全相同
> db.foo.insert({x:["A","B","C"]})
WriteResult({ "nInserted" : 1 })
> db.foo.find({x:"A"});
{ "_id" : ObjectId("5fb1845b08c09fb8dfe8d1c1"), "x" : [ "A", "B", "C" ] }

返回整个文档,而不仅仅是元素“A”。

让我们假设您的 collection 中可能有不止一个大文档。此管道为 Baden 生成单一目标几何(我在您的输入集上对其进行了测试):

var Xcoords = [
          [
            [
             16.21685028076172,
              48.007381433478855
             ],
            [
             16.24225616455078,
              47.98716432210271
             ],
            [
             16.256675720214844,
              48.00669234420252
             ],
            [
             16.21685028076172,
              48.007381433478855
            ]
          ]
              ];
var targ = {type: "Polygon", coordinates: Xcoords};

db.geo1.aggregate([
// First, eliminate any docs where the geometry array has zero intersects. In this
// context, features.geometry means "for each element of array features get the
// geometry field from the object there", almost like saying "features.?.geometry"
{$match: {"features.geometry": {$geoIntersects: {$geometry: targ}} }}

// Next, break up any passing docs of 95 geoms into 95 docs of 1 geom...
,{$unwind: "$features"}

// .. and run THE SAME $match as before to match just the one we are looking for.
// In this context, the array is gone and "features.geometry" means get JUST the
// object named geometry:
,{$match: {"features.geometry": {$geoIntersects: {$geometry: targ}} }}
  ]);

除此之外,我可能建议将 FeatureCollection 分解为既可索引(FeatureCollection 在 MongoDB 中不可索引)又更易于处理的内容。例如,针对您的 single-doc/many-polys 设计的这个小脚本 运行 将在 95 个文档中转换它并提供额外信息:

db.geo2.drop();

mainDoc = db.geo1.findOne();  // the one Austria doc
mainDoc['features'].forEach(function(oneFeature) {
    var qq = {
            country: "Austria",
            crs: mainDoc['crs'],
            properties: oneFeature['properties'],
            geometry: oneFeature['geometry']
        };
        db.geo2.insert(qq);
    });


db.geo2.aggregate([
{$match: {"geometry": {$geoIntersects: {$geometry: targ}} }}
  ]);
// yields same single doc output (Baden) 

这使得匹配和过滤变得容易。有关 FeatureCollectionGeometryCollection 的更多信息,请参阅 https://www.moschetti.org/rants/hurricane.html