Nie możesz tego zrobić w ten sposób — ogólnie rzecz biorąc, nie możesz oprzeć niczego w swoich zapytaniach MongoDB na wartościach w kolekcjach.
Jednak od MongoDB 2.4 obsługujemy nowy indeks o nazwie 2dsphere
co pozwala na przechowywanie nie tylko punktów w bazie, ale również wielokątów. Możesz przechowywać te informacje w dokumencie, takim jak:
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 ] ] ]
}
} );
Następnie możesz użyć zapytania „przecinającego”, aby dowiedzieć się, czy dany punkt jest objęty każdym z wielokątów:
db.so.find( {
'loc' : {
$geoIntersects: {
$geometry: { type: 'Point', coordinates: [ 0, 0 ] }
}
}
} );
Który następnie powraca:
{
"_id" : ObjectId("51f24d566775068ab0b786f0"),
"name" : "Firestation 1",
"loc" : {
"type" : "Polygon",
"coordinates" : [ [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [ 0, 0 ] ] ]
}
}
Tutaj znajduje remizę, ponieważ 0, 0 znajduje się w środku wielokąta. Teraz sztuczka polega oczywiście na obliczeniu punktów wielokąta, które tworzą okrąg oddalony o „promień” (powiedzmy 10 km) od punktu środkowego. Nie będziesz w stanie uzyskać prawdziwego okręgu, ale sześciokąt lub ośmiokąt powinien wystarczyć. Matematyka nie jest bardzo prosta, ale http:// www.movable-type.co.uk/scripts/latlong.html#destPoint ma przykład w JavaScript. Po prostu zapętl swój kierunek w 8 krokach od 0 do 2PI, aby obliczyć punkty na obwodzie okręgu i umieścić je we współrzędnych. Upewnij się, że osadziłeś je w podwójnie zagnieżdżonej tablicy i zrób taki sam pierwszy i ostatni:
{
name: "Firestation 1",
loc: {
type: "Polygon",
coordinates: [ [
[ point1-lon, point1-lat ],
[ point2-lon, point2-lat ],
[ point3-lon, point3-lat ],
...
[ point1-lon, point1-lat ],
] ]
}
}