如何使用 GeoIntersects 在 MongoDB 中检查一个点是否在多边形内

9

我正在尝试学习如何在MongoDB中使用地理空间查询,但似乎我无法真正做到!因此,为了论证,我在mongo中有我的瓷砖集合,假设我只有一个文档,更准确地说,是这个:

{
    "_id" : "-180-9018090",
    "geometry" : {
        "type" : "Polygon",
        "coordinates" : [
            [
                [
                    -180,
                    -90
                ],
                [
                    180,
                    -90
                ],
                [
                    180,
                    90
                ],
                [
                    -180,
                    90
                ],
                [
                    -180,
                    -90
                ]
            ]
        ]
    },
    "type" : "Feature",
    "properties" : {
        "zoom-level" : 0,
        "center" : [
            0,
            0
        ]
    }
}

这代表了基本上整个世界。现在我想看看一个特定的点,比如(0,0)是否在这个区域内。我的理解是应该使用geointersects来完成这个任务,所以查询应该像这样(?):

db.tiles.find({
  geometry: {
     $geoIntersects: {
        $geometry: {
           type: "Point" ,
           coordinates: [ 0,0]
        }
     }
  }
});

当然,结果集为空,就像我的头脑中对于这种情况发生的原因的想法一样。你能帮我理解我做错了什么吗?
编辑:
经过进一步尝试,查询似乎是正确的,所以肯定是我错过了关于$geointersects如何工作的某些东西。我通过一个示例找到了一些结果:
假设我们的数据库中有5个文档:
          *-----*
          | 4|3 | => whole world tile: from [-90,-180] to [90,180]
          | 1|2 |
          *-----* 

let's take this tile and divide it in 4:

*---*  *---*  *---*  *---*
| 1 |  | 2 |  | 3 |  | 4 | => 1) [-90,-180]-> [0,0]   (lower left)
*---*  *---*  *---*  *---*    2) [0,-90]   -> [180,0] (lower right)
                              3) [0,0]     -> [180,90](upper right)
                              4) [-180,0]  -> [0,90]  (upper left)

所以,正如不完善的模式所显示的那样,我们有5个文档,每个文档代表一个由4个顶点组成的多边形(在geoJson中变成了5个,因为你必须在末尾添加初始点)。

现在,使用相同的查询实际上会产生这个结果:

> db.tiles.find({ geometry: { $geoIntersects: { $geometry: { type: "Point", coordinates: [ 0,0 ] } } } }).sort({"zoom": 1})
    { "_id" : "0.0-90.0180.00.0", "geometry" : { "type" : "Polygon", "coordinates" : [ [ [ 0, -90 ], [ 180, -90 ], [ 180, 0 ], [ 0, 0 ], [ 0, -90 ] ] ] }, "zoom" : 1 }
    { "_id" : "-180.00.00.090.0", "geometry" : { "type" : "Polygon", "coordinates" : [ [ [ -180, 0 ], [ 0, 0 ], [ 0, 90 ], [ -180, 90 ], [ -180, 0 ] ] ] }, "zoom" : 1 }
    { "_id" : "0.00.0180.090.0", "geometry" : { "type" : "Polygon", "coordinates" : [ [ [ 0, 0 ], [ 180, 0 ], [ 180, 90 ], [ 0, 90 ], [ 0, 0 ] ] ] }, "zoom" : 1 }

这些瓷砖是2、3、4号。换句话说,这两个文件被遗留下来了。
    {
        "_id" : "-180-9018090",   ---> world wide tile
        "geometry" : {
            "type" : "Polygon",
            "coordinates" : [
                [
                    [
                        -180,
                        -90
                    ],
                    [
                        180,
                        -90
                    ],
                    [
                        180,
                        90
                    ],
                    [
                        -180,
                        90
                    ],
                    [
                        -180,
                        -90
                    ]
                ]
            ]
        },
        "zoom" : 0
    }
{
    "_id" : "-180.0-90.00.00.0",  ----> tile number 1 of the example
    "geometry" : {
        "type" : "Polygon",
        "coordinates" : [
            [
                [
                    -180,
                    -90
                ],
                [
                    0,
                    -90
                ],
                [
                    0,
                    0
                ],
                [
                    -180,
                    0
                ],
                [
                    -180,
                    -90
                ]
            ]
        ]
    },
    "zoom" : 1
}

现在,我的第一个猜想是全球文档由于太大而未被选择,而另一个由于传统原因未被选择?有人可以验证或否定这一点吗?谢谢。
编辑: 这个可能是解释更大的那个没有被选中的原因,我会测试一下。
编辑:
看起来并不是。如页面所示,CRS仅在尝试相交两个多边形时才起作用,因此输入查询不能是点。

现在我明白为什么它不起作用了。请检查http://stackoverflow.com/questions/7810008/mongodb-and-querying-that-searching-polygons-that-intersect-a-polygon。 - amitava
@AMITAVA 另外,你能不能更清楚一些?“当你在文档中插入一个位置点并尝试用多边形找到它”并没有太多意义。你确定你没有混淆 geoIntersects 和 geoWithin 吗? - darkpirate
@AMITAVA 哦,我认为你链接的帖子已过时。 - darkpirate
我按照以下方式使用了geoIntersects(来自我的旧练习集合),并且它给出了正确的输出。> db.places.find({loc:{$geoIntersects:{$geometry:{type:“Polygon”,coordinates:[[[-75,70],[-75,-70],[75,-70],[75,70],[-75,70]]]}}}})。pretty(); - amitava
请参考此链接:https://docs.mongodb.com/v3.0/tutorial/geospatial-tutorial/,这是我之前所说的内容的另一个参考。 - darkpirate
显示剩余12条评论
1个回答

0

这不是一个解决方案,只是一个通知,确实mongodb只允许在查询多边形时使用CRS(请参见此处)。但即使您查询了多边形,我也看不出它会有什么帮助:您想指定在数据库中的多边形是“大”的,比半球还要大(跨越地球表面一半以上的多边形)。因此,在插入时启用CRS对我来说是有意义的。

我已在mongodb Jira上提出了一个问题


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接