Du kan inte riktigt göra det här - i allmänhet kan du inte basera något i dina MongoDB-frågor på värden i samlingarna.
Men sedan MongoDB 2.4 stöder vi ett nytt index som heter 2dsphere
som låter dig lagra inte bara punkter i databasen, utan även polygoner. Du skulle lagra den informationen i ett dokument som:
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 ] ] ]
}
} );
Och sedan kan du använda en "skärningsfråga" för att ta reda på om en punkt täcks av var och en av polygonerna:
db.so.find( {
'loc' : {
$geoIntersects: {
$geometry: { type: 'Point', coordinates: [ 0, 0 ] }
}
}
} );
Som sedan returnerar:
{
"_id" : ObjectId("51f24d566775068ab0b786f0"),
"name" : "Firestation 1",
"loc" : {
"type" : "Polygon",
"coordinates" : [ [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [ 0, 0 ] ] ]
}
}
Här hittar den brandstationen, eftersom 0, 0 är i mitten av polygonen. Nu är tricket såklart att beräkna polygonpunkterna som utgör en cirkel som är "radie" (säg 10km) bort från mittpunkten. Du kommer inte att kunna få en riktig cirkel, men en hexagon eller oktagon borde vara tillräckligt bra. Matematiken för det är inte extremt enkel, men http:// www.movable-type.co.uk/scripts/latlong.html#destPoint har ett exempel i JavaScript. Slinga bara din bäring i 8 steg från 0 till 2PI för att beräkna punkterna längs cirkelns omkrets och lägg dem i koordinaterna. Se till att bädda in dem i en dubbelkapslad array och gör den första och den sista likadana:
{
name: "Firestation 1",
loc: {
type: "Polygon",
coordinates: [ [
[ point1-lon, point1-lat ],
[ point2-lon, point2-lat ],
[ point3-lon, point3-lat ],
...
[ point1-lon, point1-lat ],
] ]
}
}