Stocker un lieu : le format GeoJSON
On stocke une position dans un champ au format GeoJSON : un objet { type, coordinates }. Attention à l'ordre : longitude d'abord, puis latitude.
{
"zone": "Ladignac-le-Long",
"localisation": {
"type": "Point",
"coordinates": [ 1.1367, 45.6006 ] // [lon, lat]
}
}
[longitude, latitude], l'inverse de ce qu'on dit à l'oral (« latitude, longitude »). Une inversion place le point à l'autre bout du monde.L'index 2dsphere
Les requêtes géospatiales exigent un index 2dsphere sur le champ de localisation (il modélise la Terre comme une sphère).
db.campagnes.createIndex({ localisation: "2dsphere" })
$near — les plus proches
$near renvoie les documents triés du plus proche au plus lointain d'un point, avec une distance maximale (en mètres).
db.campagnes.find({
localisation: {
$near: {
$geometry: { type: "Point", coordinates: [1.1367, 45.6006] },
$maxDistance: 20000 // 20 km
}
}
})
$near trie automatiquement par distance croissante : idéal pour « les campagnes les plus proches d'abord ».$geoWithin — à l'intérieur d'une zone
$geoWithin renvoie les points situés dans une forme (cercle, polygone). Ici, un cercle défini par un centre et un rayon en radians.
db.campagnes.find({
localisation: {
$geoWithin: {
$centerSphere: [ [1.1367, 45.6006], 20/6378.1 ] // 20 km / rayon Terre
}
}
})
$geoIntersects — qui croise une forme
$geoIntersects renvoie les documents dont la géométrie croise un polygone donné — utile pour « quels points tombent dans le périmètre de cette commune ? » (défini par un polygone).
db.campagnes.find({
localisation: {
$geoIntersects: {
$geometry: { type: "Polygon", coordinates: [ [ /* sommets */ ] ] }
}
}
})
Application au fil rouge
La géolocalisation donne à l'appli une fonctionnalité forte : proposer au particulier les campagnes autour de lui.
Ajoute un champ localisation (Point GeoJSON) à chaque campagne et un index 2dsphere. Écris la requête $near « campagnes ouvertes à moins de 20 km de ma position ». Côté appli, la position vient du GPS du téléphone (chapitre Flutter 16), passe par l'API Spring, et déclenche cette requête. La carte (Google Maps) affichera les résultats.
- Position au format GeoJSON
{type:"Point", coordinates:[lon,lat]}— longitude d'abord ! - Index obligatoire :
2dsphere. $near(proximité triée),$geoWithin(dans une forme),$geoIntersects(croise une forme).