---
term: 'Requêtes Géospatiales et Indexation par Localisation'
seoTitle: 'Requêtes géospatiales et indexation par localisation en BaaS'
headline: "Qu'est-ce qu'une requête géospatiale ?"
slug: requetes-geospatiales
category: database
shortDefinition: "Une requête géospatiale est une recherche en base de données qui filtre et trie les enregistrements par position — près d'un point, dans un rayon ou une zone."
relatedTerms:
  - database-index
  - database-queries
  - relational-queries-document-databases
  - auto-generated-database-apis
contrastsWith:
  - database-index
faq:
  - question: "Qu'est-ce qu'une requête géospatiale ?"
    answer: "Une recherche en base de données dont le filtre est spatial plutôt que fondé sur une valeur : elle renvoie les enregistrements proches d'un point, situés dans un rayon ou à l'intérieur d'une boîte ou d'un polygone, généralement triés du plus proche au plus lointain. La base stocke les coordonnées comme un type à part entière — un GeoPoint de latitude et de longitude — et un index spatial répond à la question sans calculer la distance vers chaque ligne."
  - question: "Qu'est-ce qu'un champ GeoPoint ?"
    answer: "Un type de colonne qui contient une paire latitude/longitude, avec une latitude comprise entre -90 et 90 et une longitude entre -180 et 180. Comme la base sait que le champ est géographique — et pas simplement deux flottants —, elle peut l'indexer spatialement et exposer des opérateurs de distance : à moins de X kilomètres ou miles d'ici, dans cette boîte englobante (bounding box), contenu dans ce polygone, trié par proximité."
  - question: 'Comment fonctionne un index géographique de type 2dsphere ?'
    answer: "Il projette la surface courbe de la Terre sur des cellules triées et indexables — des cellules grossières subdivisées en cellules plus fines —, de sorte que la proximité sur le globe devient une adjacence dans l'index. Une requête near inspecte la poignée de cellules qui couvrent la zone de recherche au lieu de chaque ligne, et la géométrie sphérique garde des distances exactes, y compris de part et d'autre de l'antiméridien et près des pôles."
  - question: 'Pourquoi une recherche de proximité est-elle lente sans index géographique ?'
    answer: "Parce que, sans lui, le moteur doit calculer la distance entre votre point et chaque ligne, puis trier le tout — un parcours complet déguisé en trigonométrie, répété à chaque requête. Un index géographique inverse le travail : il va droit aux cellules qui couvrent le rayon de recherche et ne touche que les candidats plausibles. L'écart se creuse avec la taille de la table, exactement comme pour n'importe quel index manquant, mais avec un coût par ligne plus élevé."
  - question: 'Quelle est la différence entre une requête near et une requête within ?'
    answer: "Une requête near répond à « qu'est-ce qui est le plus proche ? » — elle trie par distance depuis un point et plafonne généralement les résultats par une limite ou un rayon maximal. Une requête within répond à « qu'est-ce qui se trouve à l'intérieur ? » — elle filtre par inclusion dans un rayon, une boîte ou un polygone, sans impliquer d'ordre. Les listes de cafés à proximité sont des requêtes near ; « les magasins dans cette vue de la carte » et les contrôles de géorepérage sont des requêtes within."
  - question: 'Peut-on combiner des filtres géographiques avec des filtres de requête ordinaires ?'
    answer: "Oui, et les vraies features le font presque toujours : à moins de 2 km *et* ouvert maintenant *et* noté plus de quatre étoiles. La contrainte géographique se compose avec des filtres d'égalité, de plage et de pointer dans une seule requête. Surveillez l'interaction avec l'indexation — l'index spatial restreint d'abord par localisation, et les filtres ordinaires très sélectifs peuvent mériter leur propre index pour que la requête combinée reste bon marché."
  - question: 'Quelle est la précision des requêtes par rayon sur de grandes distances ?'
    answer: "Les calculs sphériques modélisent la Terre comme une sphère, qui s'écarte de l'ellipsoïde réel d'environ un tiers de pour cent au maximum — quelques mètres à l'échelle d'une ville, et généralement sans incidence sur la logique produit. Ce qui pose problème plus tôt, c'est la précision des points stockés eux-mêmes : les coordonnées du GPS d'un téléphone portent des mètres d'erreur en extérieur, et davantage en intérieur. Pour « trouver X à proximité », les deux effets relèvent du bruit."
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'MongoDB geospatial queries'
    url: 'https://www.mongodb.com/docs/manual/geospatial-queries/'
  - name: 'Parse SDK guide — GeoPoints'
    url: 'https://docs.parseplatform.org/js/guide/'
  - name: 'PostGIS — spatial extension for PostgreSQL'
    url: 'https://postgis.net/'
  - name: 'Spatial database (Wikipedia)'
    url: 'https://en.wikipedia.org/wiki/Spatial_database'
cta:
  title: 'Livrez « à proximité » dès cet après-midi'
  text: "Back4app dote chaque classe de champs GeoPoint avec des requêtes par rayon, par boîte et par proximité intégrées aux API générées automatiquement et à chaque SDK — la feature de localisation qui exige d'ordinaire un détour par une base de données spatiale tient en trois lignes de requête."
  linkText: 'Commencez gratuitement'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-09-16'
translationKey: geospatial-queries-indexing
---

**Une requête géospatiale est une recherche en base de données qui filtre et trie les enregistrements par position — près d'un point, dans un rayon ou une zone.** C'est elle qui alimente la demande de feature qui arrive dans le deuxième mois de presque tous les produits : *trouver X à proximité* — cafés, chauffeurs, magasins, autres utilisateurs. Et c'est le cas le plus net d'une catégorie de requêtes que l'[indexation B-tree ordinaire](/glossary/fr/index-de-base-de-donnees/) ne sait pas servir : la proximité est bidimensionnelle, et une structure triée sur une seule dimension ne peut pas la voir.

## Points clés

| Question | Réponse |
| --- | --- |
| Le type de champ | GeoPoint — une paire latitude/longitude que la base comprend |
| Les requêtes | Near (triée par distance), dans un rayon, dans une boîte/un polygone |
| L'index | Type 2dsphere : le globe projeté sur des cellules indexables |
| Sans lui | Distance calculée vers chaque ligne — un parcours complet avec trigonométrie |
| La feature canonique | « Trouver X à proximité », combinée à des filtres ordinaires |

## La requête de proximité, écrite et ressentie

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// "Find cafes within 2 km, nearest first" — the canonical geo query
const here = new Parse.GeoPoint({ latitude: 40.7484, longitude: -73.9857 });

const query = new Parse.Query('Cafe');
query.withinKilometers('location', here, 2); // radius filter, nearest-first
query.equalTo('openNow', true);              // geo + ordinary filters compose
query.limit(20);
const cafes = await query.find();

cafes.forEach((c) => {
  const km = here.kilometersTo(c.get('location'));
  console.log(`${c.get('name')} — ${km.toFixed(2)} km away`);
});
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// "Find cafes within 2 km, nearest first" — the canonical geo query
final here = ParseGeoPoint(latitude: 40.7484, longitude: -73.9857);

final query = QueryBuilder<ParseObject>(ParseObject('Cafe'))
  ..whereWithinKilometers('location', here, 2) // radius filter, nearest-first
  ..whereEqualTo('openNow', true)              // geo + ordinary filters compose
  ..setLimit(20);
final response = await query.query();

for (final result in response.results ?? []) {
  final cafe = result as ParseObject;
  final loc = cafe.get<ParseGeoPoint>('location');
  print('${cafe.get<String>('name')} at '
      '${loc?.latitude}, ${loc?.longitude}');
}
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// "Find cafes within 2 km, nearest first" — the canonical geo query
let here = try ParseGeoPoint(latitude: 40.7484, longitude: -73.9857)

let query = Cafe.query(
  withinKilometers(key: "location", geoPoint: here, distance: 2),
  "openNow" == true                 // geo + ordinary filters compose
).limit(20)

query.find { result in
  if case .success(let cafes) = result {
    for cafe in cafes {
      print("\(cafe.name ?? "?") — \(String(describing: cafe.location))")
    }
  }
}
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// "Find cafes within 2 km, nearest first" — the canonical geo query
val here = ParseGeoPoint(40.7484, -73.9857)

val query = ParseQuery.getQuery<ParseObject>("Cafe")
query.whereWithinKilometers("location", here, 2.0) // radius, nearest-first
query.whereEqualTo("openNow", true)                // geo + filters compose
query.limit = 20

query.findInBackground { cafes, e ->
    if (e == null) cafes.forEach { cafe ->
        val loc = cafe.getParseGeoPoint("location")
        val km = loc?.distanceInKilometersTo(here)
        println("${cafe.getString("name")} — ${"%.2f".format(km)} km away")
    }
}
```

La même physique en SQL, via [PostGIS](https://postgis.net/) — avec l'index qui la rend viable :

```sql
-- Un index spatial sur la colonne geography :
CREATE INDEX cafe_location_gix ON cafe USING GIST (location);

-- "Cafés à moins de 2 km, les plus proches d'abord" :
SELECT name, ST_Distance(location, ST_MakePoint(-73.9857, 40.7484)::geography) AS meters
FROM cafe
WHERE ST_DWithin(location, ST_MakePoint(-73.9857, 40.7484)::geography, 2000)
ORDER BY location <-> ST_MakePoint(-73.9857, 40.7484)::geography
LIMIT 20;
--  avec un index : ne touche que les cellules couvrant le cercle de 2 km
--  sans index :    calcule une distance pour chaque ligne de la table
```

## Comment l'index voit le globe

```mermaid
flowchart TB
  accTitle: Comment un index géographique sphérique répond à une requête par rayon
  accDescr: La surface de la Terre est divisée en cellules hiérarchiques stockées dans un ordre trié. Une requête par rayon sélectionne les quelques cellules qui couvrent le cercle de recherche, ne parcourt que les points candidats qu'elles contiennent et calcule des distances exactes pour cette courte liste.
  G["Globe divisé en<br/>cellules hiérarchiques"] --> C1["Cellule grossière<br/>(échelle d'une ville)"]
  C1 --> F1["Cellules plus fines couvrant<br/>le cercle de 2 km"]
  F1 --> P["Points candidats<br/>dans ces cellules seulement"]
  P --> D["Vérification de la distance exacte<br/>+ tri du plus proche au plus lointain"]
```

Un [index de type 2dsphere](https://www.mongodb.com/docs/manual/geospatial-queries/) rend la proximité indexable en projetant la surface courbe sur des cellules hiérarchiques dont l'ordre de tri préserve l'adjacence — des points proches sur le globe tombent sur des entrées d'index voisines. Une requête par rayon se lit alors comme n'importe quelle recherche dans un index : identifier les quelques cellules qui couvrent le cercle, parcourir leurs candidats, vérifier les distances exactes sur cette courte liste. La géométrie sphérique — plutôt que les calculs sur un plan — garde des résultats corrects aux échelles réelles, de part et d'autre de l'antiméridien et vers les pôles.

La règle de composition découle de la [mécanique ordinaire des requêtes](/glossary/fr/requetes-de-base-de-donnees/) : les contraintes géographiques se combinent librement avec des filtres d'égalité, de plage et de pointer (`openNow == true` dans les onglets ci-dessus), et les filtres non géographiques sélectifs des requêtes chaudes peuvent mériter leurs propres index.

La pagination mérite une note à part, car les résultats triés par distance cassent l'habitude de l'offset. Sauter la première page d'une requête near oblige le moteur à reclasser tout ce qui a été sauté, et un point qui a bougé entre deux requêtes peut rebattre l'ordre sous les pieds de l'utilisateur. Les patterns plus robustes : élargir le rayon progressivement pour le « charger plus », ou paginer sur une clé stable dans un rayon fixe. Le tri par proximité est un classement sur des données vivantes — traitez les limites de page comme indicatives, pas comme des lignes d'un registre comptable.

## Requêtes near vs. within vs. sur un plan

### Quelle requête géographique utiliser ?

| Forme de la requête | Répond à | Ordre | Usage typique |
| --- | --- | --- | --- |
| Near (proximité) | Qu'est-ce qui est le plus proche d'ici ? | Du plus proche au plus lointain | Listes de « cafés à proximité », attribution de chauffeurs |
| Dans un rayon | Qu'est-ce qui se trouve à moins de r km d'ici ? | Aucun implicite | Éligibilité à la livraison, alertes |
| Dans une boîte | Qu'est-ce qui se trouve dans ce rectangle ? | Aucun | Rendu de la vue de la carte |
| Dans un polygone | Qu'est-ce qui se trouve dans cette forme ? | Aucun | Quartiers, zones, géorepérages |
| Sur un plan (2d) | La même chose, sur un plan projeté | Variable | Cartes de jeu, plans d'étage — pas la Terre |

La distinction near/within relève de la logique produit, pas de la pédanterie : *near* est un classement (plafonnez-le avec une limite et un rayon maximal, sinon les villes denses renvoient des milliers de lignes), *within* est un prédicat (associez-le à la géométrie de la vue ou de la zone). La ligne du plan est la note de bas de page honnête — pour des coordonnées qui ne sont pas sur une sphère, les index sphériques sont le mauvais outil.

## Cas d'usage courants

- **« Trouver X à proximité ».** Cafés, salles de sport, distributeurs, bornes de recharge — la liste de proximité canonique, avec un rayon plafonné et les plus proches d'abord.
- **Mise en relation et dispatch.** Passagers et chauffeurs, livraisons et coursiers — des requêtes near sur des GeoPoints mis à jour fréquemment.
- **Vues de carte.** Des requêtes dans une boîte qui alimentent les épingles à mesure que l'utilisateur déplace la carte — bon marché, non ordonnées, à la taille de la vue.
- **Géorepérage (geofencing).** Des contrôles d'inclusion dans un polygone pour les zones de livraison, les zones de service et la logique déclenchée par la localisation.
- **Features sociales locales.** Personnes à proximité et événements du week-end, combinés à des filtres de confidentialité et à des [relations par pointer](/glossary/fr/jointures-bases-documentaires/).

## Devriez-vous utiliser des requêtes géographiques ou précalculer des régions ? Matrice de décision

| Requêtez en direct avec un index géographique quand… | Précalculez des étiquettes de région quand… |
| --- | --- |
| Les rayons et les formes varient à chaque requête | Les limites sont fixes (magasins, zones, arrondissements) |
| Les points bougent souvent (chauffeurs, utilisateurs) | L'appartenance change rarement |
| Le tri du plus proche au plus lointain compte | Vous ne filtrez jamais que par égalité de région |
| Les formes sont réellement spatiales | Une simple colonne `region` répond à tout |
| Vous disposez d'un index spatial | Vous regroupez, vous ne mesurez pas |

La porte de sortie compte : quand chaque requête se réduit à « dans la zone A ? », une simple colonne texte indexée bat la machinerie spatiale — moins chère, plus simple et couverte par des B-trees ordinaires. L'indexation spatiale se justifie précisément quand la géométrie est dynamique : centres arbitraires, points en mouvement, distances réelles.

## Limites et trade-offs

- **Les index géographiques sont des spécialistes.** Ils ne servent que les prédicats spatiaux ; vos autres filtres ont toujours besoin de leurs propres index, et la maintenance d'un index coûte des écritures — le même impôt, au tarif spatial.
- **Les requêtes near non bornées sont des pièges.** Trier par proximité dans une ville dense sans rayon maximal ni limite revient à classer la moitié de la table. Bornez toujours la recherche.
- **Les points en mouvement écrivent sans arrêt.** Des positions de chauffeurs en direct signifient des mises à jour de GeoPoint à haute fréquence, chacune maintenant l'index — regroupez ou limitez les mises à jour de position quand le produit le permet.
- **Un point par ligne est le modèle de base.** Un magasin avec cinq succursales, ce sont cinq enregistrements ; des formes plus riches que des points (itinéraires, zones de couverture) poussent vers de véritables [bases de données spatiales](https://en.wikipedia.org/wiki/Spatial_database).
- **La précision a un plancher.** L'erreur sphère/ellipsoïde est négligeable, mais le bruit du GPS se compte en mètres dans le meilleur des cas — concevez la logique produit (zones, seuils) pour le tolérer.

## Requêtes géospatiales sur Back4app

Back4app est une plateforme open-source de Backend as a Service (BaaS) qui combine une base de données gérée, des API REST et GraphQL générées automatiquement, l'authentification, le stockage de fichiers et des fonctions serverless avec Cloud Code. GeoPoint est un type de colonne natif du stockage géré propulsé par MongoDB, et les opérateurs de proximité, de rayon et de boîte — `withinKilometers`, `near`, `withinGeoBox` — sont fournis dans les [API générées automatiquement](/glossary/fr/apis-generees-automatiquement/) et dans chaque SDK, exactement comme les utilisent les onglets de code ci-dessus. Les index géographiques se gèrent avec le reste de votre [stratégie d'indexation](/glossary/fr/index-de-base-de-donnees/) dans le dashboard, ce qui transforme le projet d'infrastructure habituel du « trouver X à proximité » en une décision de schéma et trois lignes de requête.
