MongoDB'接近'地理空间查询GeoJSON多边形数组

时间:2018-02-23 22:16:30

标签: mongodb mongodb-query

我想要做的是查询找到具有 a 音量(音量中的任意点)的文档,该文档在一定距离内。我遗憾地无法修改我正在使用的文档结构而没有进行相当大的改造。我可以在应用程序端实现这一点,但这需要大量的数据传输。

我有一个包含此格式数据的文档:

{  
   "volumes":[  
      {  
         "volume":{  
            "type":"Polygon",
            "coordinates":[  
               [  

               ]
            ]
         }
      }
   ]
}

不起作用的示例查询:

{  
   'volumes.volume':{  
      '$geoWithin':{  
         '$centerSphere':[  
            [  
               0,
               0
            ],
            3.14159
         ]
      }
   }
}

这种做了我想要的,但做'内'而不是'交叉',我也不相信它适用于任何卷,但仅限于所有卷(正确)我,如果我错了)在里面。

我可能会让我的无知在这里显示一点,但一般来说,最佳查询会做类似的事情(虽然我知道这不起作用):

{  
   'volumes':{  
      '$elemMatch':{  
         'volume':{  
            '$near':{  
               '$geometry':reference_point,
               '$maxDistance':distance
            }
         }
      }
   }
}

1 个答案:

答案 0 :(得分:1)

我认为你已经有两个坐标和距离,首先你需要使用$geoNear来找到给定坐标的最近位置,例如:

db.places.aggregate([
{
 $geoNear: {
    near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },
    distanceField: "dist.calculated",
    query: { type: "public" },
    includeLocs: "dist.location",
    num: 1,
    spherical: true
 }
}
])

它为您提供了从给定位置到近处的位置。之后你需要使用npm模块geoLib https://www.npmjs.com/package/geolib 在该模块中使用geolib.isPointInCircle函数,其中前3个参数为2,是lat& lng和third是半径(距离)并给出布尔值。如果location1和location2在距离上,则返回true,否则为false。

const geolib = require('geolib');

db.places.aggregate([{
    $geoNear: {
        near: {
            type: "Point",
            coordinates: [-73.99279, 40.719296]
        },
        distanceField: "dist.calculated",
        query: {
            type: "public"
        },
        includeLocs: "dist.location",
        num: 1,
        spherical: true
    } 
}]).then((result) => {
    if (result) {
        const isMatch = geolib.isPointInCircle({
                latitude: 51.525,
                longitude: 7.4575
            }, {
                latitude: 51.5175,
                longitude: 7.4678
            },
           5000 //Your distance in meters
        );
        if (isMatch === true) {
            console.log('You are near to me');
        } else {
            console.log('You are far from me');
        }
    }
});