Overpass

2025-04-13

OpenStreetMap est un projet dans lequel est construit une base de données[1] accessible pour des projets variés telle que l'emprise au sol des courts de tennis[2]. Overpass est le nom de l'API permettant d'extraire les données.

Langages

Les requêtes Overpass sont effectuées selon deux langages :

Le second a été introduit suite à la mise à disposition de données plus riches via la requête HTTP, autrefois impossible. La construction de requête a été ainsi amplement simplifiée, si bien qu'il ne semble pas exister de documentation à destination du public du langage O-XML.

Généralités

Les requêtes se composent de « statements » (d'opérations) séparées par des points-virgules, avec généralement une sortie unique demandé via la commande `out` et correspondant au « set » (jeu) par défaut : `_`.

// Code simple
node(1);
out;
// Code implicite
node(1) -> ._;
._ out;

La sortie peut prendre différentes formes selon l'argument suffixé :

Opérations

À noter que les opérations se font de manière séquentielle. En absence de commande explicite, chaque opération s'effectue sur le jeu par défaut, défini précédemment. Ainsi, des paramètres d'opération peuvent être insérés via parenthèses, tandis que des paramètres globaux sont définis entre crochets. Exemple pour le « bbox » (rectangle englobant) défini dans le sens anti-horaire à commencer par la limite ouest.

// Paramètre global
[bbox:-0.001835, -0.000963, 0.001706, 0.001489];
node;
// Paramètre d'opération
node(-0.001835, -0.000963, 0.001706, 0.001489);
// Alternative via un polygone personnalisé (si le polygone est un chemin fermé OSM, voir section sur fonctions spatiales)
node(poly:"-0.001835, -0.000963, 0.001706, 0.001489")

Les données de plusieurs opérations peuvent être combinées dans le jeu par défaut en les entrant entre parenthèses. C'est utile notamment dans le cas des relations et chemins qui sont définis par des points plutôt que des entités indépendantes, et qui nécessitent d'utiliser `>` ou `>>` comme opérateur de récursivité.

(
	relation(6759865);
	>>;
);

Les opérateurs `<` et `<<` font l'inverse et permettent de remonter aux parents.

Filtres

Un filtre peut être appliqué à une opération. Pour cela il suffit d'entrer les variables entre crochets.

// Nœuds avec la clé amenity
node["amenity"];
// Nœuds sans clé amenity
node[!"amenity"];
// Nœuds dont le nom contient la séquence « Hair », merci les salons de coiffure
node["name"~"Hair"];
// Nœuds dont le nom contient la séquence « Hair », et qui ne sont pas des salons de coiffure
node["name"~"Hair"]["shop"!="hairdresser"];
// Alternative : nœuds dont le nom contient la séquence « Hair », et qui ne sont pas des salons de coiffure
(
	node["name"~"Hair"]
	-
	node["shop"="hairdresser"];
);
// Alternative : création d'un jeu intermédiaire `hair` duquel sont supprimé les salons, avant réinsertion au jeu par défaut
node["name"~"Hair"] -> .hair;
node.hair["shop"!="hairdresser"] -> ._;

Fonctions spatiales

Des fonctions peuvent être appliquées, dont `around`.

// Via un jeu intermédiaire « coiffure »
node["shop"="hairdresser"] -> .coiffure;
node(around.coiffure:100)["barrier"="bollard"];
// Alternative avec le jeu par défaut
node["shop"="hairdresser"];
node(around:100)["barrier"="bollard"];

De la même manière, il est possible de travailler avec des zones. Des « areas » (zones) sont une classe d'éléments (similaires au nœuds, chemins, et relations) générées par Overpass de manière automatique, à défaut d'avoir clairement la main dessus, je préfère éviter de les utiliser et m'appuie exclusivement sur les données OpenStreetMap.

// Utilisation de is_in pour trouver les zones dont fait partie le nœud correspondant à la ville de Besançon, et de pivot pour générer leur géométrie. Preuve concrète du bourbier que sont les areas
(
node["name"="Besançon"]["place"="city"] -> .ville;
.ville is_in -> .areas;
way(pivot.areas);
>;
);
// Recherche des amenity dans Venise, tel que trouvé par Nominatim via la fonction geocodeArea, alors que je cherchais le village du Doubs ref:INSEE=25598
{{geocodeArea:"Venise"}} -> .recherche;
node(area.recherche)["amenity"];
// Recherche à partir de la fonction map_to_area dans laquelle a été insérée la relation avec l'identifiant IRIS d'un quartier
(
  relation["ref:IRIS"="0402"] ->.iris;
  .iris map_to_area ->.battant;
  node["amenity"](area.battant);
  >;
);

Cas d'étude

Si, par le plus grand des hasard une personne avait pour idée de localiser les feux tricolores[4] localisés sur des aménagements cyclables à Besançon, il suffirait ainsi de lancer le code suivant permettant de :

{{geocodeArea:Besançon}}->.searchArea;
(
  (way(area.searchArea)[~"^cycleway.*$"~"."]; -  way(area.searchArea)[~"^cycleway.*$"~"no"];);
  (._ ; - way(area.searchArea)[~"^cycleway.*$"~"separate"];);
  > -> .r11;
);
  node.r11["highway"="traffic_signals"];
out geom;

Références

[1] OpenStreetMap, LeJun 2023
[2] R-OpenStreetMap : Emprise au sol, LeJun 2023
[3] Overpass QL, Overpass 2012
[4] Feu R11v, LeJun 2025