地理空间$ nearSphere运算符如何与LineString和Polygon交互

时间:2013-10-07 15:54:47

标签: mongodb geojson

根据文档,2dSphere geospatial index也可以用于复杂的GeoJSON形状,如LineString和Polygon,它们由多个节点组成。

当您使用$nearSphere搜索填充了此类复杂形状的字段以接近另一个GeoJSON对象(可能也是一个复杂的形状)时,这些形状的距离将如何计算?

它会比较形状的最近节点吗?最遥远的节点?一些平均的节点?形状任何边缘上的最近点?

1 个答案:

答案 0 :(得分:2)

$nearSphere运算符只允许您指定一个点(您可以通过提供maxDistance参数来定义“球体”的中心)。因此,唯一有意义的答案可能是关于如何最接近最远的形状排序。

答案是所有具有等距“最近”点的形状将在具有最近点的形状之前进行排序。换句话说,点和形状之间的距离是点与形状上最近点之间的距离。

我们可以通过运行$nearSphere的{​​{3}}命令的变体来看到它返回计算出的距离然后我们可以检查。

我们的样本数据:

> db.near.find()
{ "_id" : 10, "loc" : { "type" : "Polygon", "coordinates" : [ [ [ 0, 0 ], [ 0, 5 ], [ 5, 5 ], [ 5, 0 ], [ 0, 0 ] ] ] } }
{ "_id" : 11, "loc" : { "type" : "Polygon", "coordinates" : [ [ [ 1, 1 ], [ 1, 5 ], [ 5, 5 ], [ 5, 1 ], [ 1, 1 ] ] ] } }
{ "_id" : 12, "loc" : { "type" : "Polygon", "coordinates" : [ [ [ 0, 0 ], [ 0, 6 ], [ 6, 6 ], [ 6, 0 ], [ 0, 0 ] ] ] } }
{ "_id" : 13, "loc" : { "type" : "Polygon", "coordinates" : [ [ [ 0, 0 ], [ 0, 6 ], [ 6, 6 ], [ 6, 0 ], [0, 0 ] ], [ [ 1, 1 ], [ 1, 5 ], [ 5, 5 ], [ 5, 1 ], [ 1, 1 ] ] ] } }
{ "_id" : 14, "loc" : { "type" : "Polygon", "coordinates" : [ [ [ 0, 0 ], [ 0, 6 ], [ 6, 6 ], [ 6, 0 ], [ 0, 0 ] ], [ [ 0.1, 0.1 ], [ 0.1, 5 ], [ 5, 5 ], [ 5, 0.1 ], [ 0.1, 0.1 ] ] ] } }
{ "_id" : 15, "loc" : { "type" : "Polygon", "coordinates" : [ [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [0, 0 ] ],  [ [ 0.1, 0.1 ], [ 0.1, 0.5 ], [ 0.5, 0.5 ], [ 0.5, 0.1 ], [ 0.1, 0.1 ] ] ] } }
{ "_id" : 16, "loc" : { "type" : "LineString", "coordinates" : [ [ 0, 0 ], [ 0.1, 0.1 ] ] } }
{ "_id" : 17, "loc" : { "type" : "LineString", "coordinates" : [ [ 0, 0 ], [ 0, 0.1 ] ] } }
{ "_id" : 18, "loc" : { "type" : "LineString", "coordinates" : [ [ 0, 0 ], [ 0.1, 0 ] ] } }

我们使用$ nearSphere的结果:

{ "_id" : 16, "loc" : { "type" : "LineString", "coordinates" : [  [ 0, 0 ],  [  0.1,  0.1 ] ] } }
{ "_id" : 18, "loc" : { "type" : "LineString", "coordinates" : [  [ 0, 0 ],  [  0.1,  0 ] ] } }
{ "_id" : 14, "loc" : { "type" : "Polygon", "coordinates" : [  [  [ 0, 0 ], [ 0, 6 ], [     6,  6 ],    [   6,  0 ],    [   0,  0 ] ],  [   [   0.1,    0.1 ],  [   0.1,    5 ],    [   5,  5 ],    [   5,  0.1 ],  [   0.1,    0.1 ] ] ] } }
{ "_id" : 13, "loc" : { "type" : "Polygon", "coordinates" : [  [  [ 0, 0 ], [ 0, 6 ], [     6,  6 ],    [   6,  0 ],    [   0,  0 ] ],  [   [   1,  1 ],    [   1,  5 ],    [   5,  5 ],    [   5,  1 ],    [   1,  1 ] ] ] } }
{ "_id" : 15, "loc" : { "type" : "Polygon", "coordinates" : [  [  [ 0, 0 ], [ 0, 1 ], [     1,  1 ],    [   1,  0 ],    [   0,  0 ] ],  [   [   0.1,    0.1 ],  [   0.1,    0.5 ],  [   0.5,    0.5 ],  [   0.5,    0.1 ],  [   0.1,    0.1 ] ] ] } }
{ "_id" : 12, "loc" : { "type" : "Polygon", "coordinates" : [  [  [ 0, 0 ],  [  0,  6 ],  [  6,  6 ],  [  6,  0 ],  [  0,  0 ] ] ] } }
{ "_id" : 17, "loc" : { "type" : "LineString", "coordinates" : [  [ 0, 0 ],  [  0,  0.1 ] ] } }
{ "_id" : 10, "loc" : { "type" : "Polygon", "coordinates" : [  [  [ 0, 0 ],  [  0,  5 ],  [  5,  5 ],  [  5,  0 ],  [  0,  0 ] ] ] } }
{ "_id" : 11, "loc" : { "type" : "Polygon", "coordinates" : [  [  [ 1, 1 ],  [  1,  5 ],  [  5,  5 ],  [  5,  1 ],  [  1,  1 ] ] ] } }

运行$geoNear命令,我们可以确认从点到形状的距离(省略空间考虑的坐标):

> db.runCommand({geoNear:"near", near: {type:"Point", coordinates:[0,0]}, spherical:true})
[
    {
        "dis" : 0,
        "obj" : {
            "_id" : 16,
            "loc" : {
                "type" : "LineString"
            }
        }
    },
    {
        "dis" : 0,
        "obj" : {
            "_id" : 18,
            "loc" : {
                "type" : "LineString"
            }
        }
    },
    {
        "dis" : 0,
        "obj" : {
            "_id" : 14,
            "loc" : {
                "type" : "Polygon"
            }
        }
    },
    {
        "dis" : 0,
        "obj" : {
            "_id" : 13,
            "loc" : {
                "type" : "Polygon"
            }
        }
    },
    {
        "dis" : 0,
        "obj" : {
            "_id" : 15,
            "loc" : {
                "type" : "Polygon"
            }
        }
    },
    {
        "dis" : 0,
        "obj" : {
            "_id" : 12,
            "loc" : {
                "type" : "Polygon"
            }
        }
    },
    {
        "dis" : 0,
        "obj" : {
            "_id" : 17,
            "loc" : {
                "type" : "LineString"
            }
        }
    },
    {
        "dis" : 0,
        "obj" : {
            "_id" : 10,
            "loc" : {
                "type" : "Polygon"
            }
        }
    },
    {
        "dis" : 157424.6238723255,
        "obj" : {
            "_id" : 11,
            "loc" : {
                "type" : "Polygon"
            }
        }
    }
]

正如您所看到的,即使形状的大小和形状各不相同,每个形状(从[1,1]开始的最后一个形状除外)到点[0,0]的距离为0。在与指定点具有相同距离的文档中,未定义订单。这意味着,即使看起来确定性,也不能保证是相同的。