Je kunt dit niet helemaal op deze manier doen - over het algemeen kun je niets in je MongoDB-query's baseren op waarden in de verzamelingen.
Sinds MongoDB 2.4 ondersteunen we echter een nieuwe index genaamd 2dsphere
waarmee u niet alleen punten in de database kunt opslaan, maar ook polygonen. Je zou die informatie opslaan in een document zoals:
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 ] ] ]
}
} );
En dan kun je een "intersect"-query gebruiken om erachter te komen of een punt wordt gedekt door elk van de polygonen:
db.so.find( {
'loc' : {
$geoIntersects: {
$geometry: { type: 'Point', coordinates: [ 0, 0 ] }
}
}
} );
Wat dan terugkeert:
{
"_id" : ObjectId("51f24d566775068ab0b786f0"),
"name" : "Firestation 1",
"loc" : {
"type" : "Polygon",
"coordinates" : [ [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [ 0, 0 ] ] ]
}
}
Hier vindt hij de brandweerkazerne, want 0, 0 staat in het midden van de veelhoek. Nu is de truc natuurlijk om de polygoonpunten te berekenen die een cirkel vormen die "straal" (zeg 10 km) verwijderd is van het middelpunt. Je zult geen echte cirkel kunnen krijgen, maar een zeshoek of achthoek zou goed genoeg moeten zijn. De wiskunde daarvoor is niet extreem eenvoudig, maar http:// www.movable-type.co.uk/scripts/latlong.html#destPoint heeft een voorbeeld in JavaScript. Loop gewoon je peiling in 8 stappen van 0 naar 2PI om de punten langs de omtrek van de cirkel te berekenen en zet die in de coördinaten. Zorg ervoor dat u ze insluit in een dubbel geneste array en zorg ervoor dat de eerste en de laatste hetzelfde zijn:
{
name: "Firestation 1",
loc: {
type: "Polygon",
coordinates: [ [
[ point1-lon, point1-lat ],
[ point2-lon, point2-lat ],
[ point3-lon, point3-lat ],
...
[ point1-lon, point1-lat ],
] ]
}
}