🛢️Parcours Fioul GroupéMongoDB · Chapitre 13
Accueil › MongoDB › Chapitre 13
Chapitre 13 / 17

Les recherches géospatiales

MongoDB sait stocker des coordonnées et répondre à des questions de proximité : « qu'y a-t-il à moins de 20 km ? », « quels points sont dans cette zone ? ». Parfait pour trouver les campagnes de fioul autour de chez soi.

1 Notion

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]
  }
}
Piège classique — l'ordre est [longitude, latitude], l'inverse de ce qu'on dit à l'oral (« latitude, longitude »). Une inversion place le point à l'autre bout du monde.
2 Étape

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" })
3 Requête

$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
    }
  }
})
Bonus — $near trie automatiquement par distance croissante : idéal pour « les campagnes les plus proches d'abord ».
4 Requête

$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
    }
  }
})
5 Requête

$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 */ ] ] }
    }
  }
})
6 Projet

Application au fil rouge

La géolocalisation donne à l'appli une fonctionnalité forte : proposer au particulier les campagnes autour de lui.

🛢️ Sur le projet Fioul Groupé

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.

Ce qu'il faut retenir du chapitre
  • 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).
← Chapitre 12