您不能完全这样做——通常,您的 MongoDB 查询中的任何内容都不能基于集合中的值。
但是,从 MongoDB 2.4 开始,我们支持一个名为的新索引2dsphere
,它不仅允许您在数据库中存储点,还可以存储多边形。您可以将该信息存储在一个文档中,例如:
db.so.ensureIndex( { loc: '2dsphere' } );
db.so.insert( {
name: "Firestation 1",
loc: {
type: "Polygon",
coordinates: [ [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [ 0, 0 ] ] ]
}
} );
然后您可以使用“相交”查询来确定一个点是否被每个多边形覆盖:
db.so.find( {
'loc' : {
$geoIntersects: {
$geometry: { type: 'Point', coordinates: [ 0, 0 ] }
}
}
} );
然后返回:
{
"_id" : ObjectId("51f24d566775068ab0b786f0"),
"name" : "Firestation 1",
"loc" : {
"type" : "Polygon",
"coordinates" : [ [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [ 0, 0 ] ] ]
}
}
在这里它找到了消防站,因为 0, 0 在多边形的中间。现在,诀窍当然是计算构成距离中心点“半径”(例如 10 公里)的圆的多边形点。您将无法获得真正的圆形,但六边形或八边形应该足够好。数学并不是非常简单,但http://www.movable-type.co.uk/scripts/latlong.html#destPoint有一个 JavaScript 示例。只需从 0 到 2PI 分 8 步循环您的方位,即可计算圆周上的点,并将它们放入坐标中。确保将它们嵌入到双重嵌套数组中,并使第一个和最后一个相同:
{
name: "Firestation 1",
loc: {
type: "Polygon",
coordinates: [ [
[ point1-lon, point1-lat ],
[ point2-lon, point2-lat ],
[ point3-lon, point3-lat ],
...
[ point1-lon, point1-lat ],
] ]
}
}