MongoDB $geowithin 未按预期运行

MongoDB $geowithin not acting as expected

我正在将位置存储到一个集合中,并且基于边界框,我想检索该边界框内的位置。 对于小边界框,一切似乎都工作正常,但对于较大的边界框,我没有得到预期的结果。我找到了一些关于在边界框面积大于半球面积时指定 CRS 的信息:https://docs.mongodb.com/manual/reference/operator/query/geoWithin/

虽然我的大边界框的面积不大于半球的面积,但我使用小边界框的查询没有得到任何结果。

有关我的位置和下面使用的边界框的直观表示,请参阅以下网站和地理点详细信息:https://mobisoftinfotech.com/tools/plot-multiple-points-on-map/

小边界框:

32.441459,-39.891999,blue,marker,""
32.441459,80.332689,blue,marker,""
67.613969,80.332689,blue,marker,""
67.613969,-39.891999,blue,marker,""
50.850189,2.887406,green,marker,"Ypres"
29.780336,-95.359167,red,marker,"Houston"

大边界框:

32.441459,-79.891999,blue,marker,""
32.441459,80.332689,blue,marker,""
67.613969,80.332689,blue,marker,""
67.613969,-79.891999,blue,marker,""
50.850189,2.887406,green,marker,"Ypres"
29.780336,-95.359167,red,marker,"Houston"

我正在尝试获取蓝色标记边界框内的数据,结果应该是带有绿色标记的位置; Ypres.

所以在MongoDB,我有这两个位置:

db.getCollection("positions").insertOne(
{
    "name" : "Ypres, Belgium",
    "pos" : {
        "type" : "Point",
        "coordinates" : [ 
            2.887406, 
            50.850189
        ]
    }
})

db.getCollection("positions").insertOne(
{
    "name" : "Houston, Texas, US",
    "pos" : {
        "type" : "Point",
        "coordinates" : [ 
            -95.359167, 
            29.780336
        ]
    }
})

按逆时针顺序指定坐标的小多边形;结果正常:Ypres

db.getCollection("positions").find({
    "pos": {
        "$geoWithin": {
            "$geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [-39.891999, 32.441459], 
                    [80.332689, 32.441459], 
                    [80.332689, 67.613969], 
                    [-39.891999, 67.613969], 
                    [-39.891999, 32.441459]]]
            }
        }
    }
})

同一个小多边形,按顺时针顺序指定坐标;结果正常:Ypres

db.getCollection("positions").find({
    "pos": {
        "$geoWithin": {
            "$geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [-39.891999, 32.441459], 
                    [-39.891999, 67.613969], 
                    [80.332689, 67.613969], 
                    [80.332689, 32.441459], 
                    [-39.891999, 32.441459]]]
            }
        }
    }
})

按逆时针顺序指定坐标的更大多边形;结果不好;没有地点。

db.getCollection("positions").find({
    "pos": {
        "$geoWithin": {
            "$geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [-79.891999, 32.441459], 
                    [80.332689, 32.441459], 
                    [80.332689, 67.613969], 
                    [-79.891999, 67.613969], 
                    [-79.891999, 32.441459]]]
            }
        }
    }
})

所以在这里我想我可能需要CRS,但是当添加它时,我得到了相同的结果;没有地点。

db.getCollection("positions").find({
    "pos": {
        "$geoWithin": {
            "$geometry": {
                "type": "Polygon",
                "crs": {
                    "type": "name",
                    "properties": {
                        "name": "urn:x-mongodb:crs:strictwinding:EPSG:4326"
                    }
                },
                "coordinates": [[
                    [-79.891999, 32.441459], 
                    [80.332689, 32.441459], 
                    [80.332689, 67.613969], 
                    [-79.891999, 67.613969], 
                    [-79.891999, 32.441459]]]
            }
        }
    }
})

由于在使用 CRS 时我不完全确定 clockwise/counter-clockwise 规范,因此我尝试颠倒多边形角的顺序。所以现在按顺时针顺序。但在这里我得到了两个位置,而我只期待 Ypres。

db.getCollection("positions").find({
    "pos": {
        "$geoWithin": {
            "$geometry": {
                "type": "Polygon",
                "crs": {
                    "type": "name",
                    "properties": {
                        "name": "urn:x-mongodb:crs:strictwinding:EPSG:4326"
                    }
                },
                "coordinates": [[
                    [-79.891999, 32.441459], 
                    [-79.891999, 67.613969], 
                    [80.332689, 67.613969], 
                    [80.332689, 32.441459], 
                    [-79.891999, 32.441459]]]
            }
        }
    }
})

当省略 CRS 时,我找不到这个位置。

所以,我不完全确定这里发生了什么。我的查询有问题吗?

显然 $geoWithin 运算符与多边形 $geometry 相结合会受到 'great circle distance' 'distortion' 的影响(不确定正确的术语如何,但这是我的理解方式) 在计算一个点是否在多边形内部时。为了我的目的和预期结果,我不得不将查询更改为 $geoWithin 结合 $box

db.getCollection("positions").find({ "pos" : { "$geoWithin" : { "$box" : [[-79.891999, 32.441459], [80.3326890, 67.613969]] } } })