Jour 13 – La récursion sélective

Partons de la requête décrite hier, qui trouve les randonnées passant par une rue :

area["ref:INSEE"=44005];
way[name="Avenue Arthus-Princé"](area);
<;
rel._[route=hiking];
out geom;

Cette requête applique la récursion ascendante avec < puis un filtre de tags sur les relations. Ces deux opérations peuvent être combinées en une seule avec la syntaxe suivante :

area["ref:INSEE"=44005];
way[name="Avenue Arthus-Princé"](area);
rel(bw)[route=hiking];
out geom;

L'instruction rel(bw) produit les relations référençant les ways du lot de données en entrée. Il s'agit d'une récursion ascendante sélective, où le mot-clef bw signifie “backward from ways”. Il est bien sûr possible d'utiliser des variables :

area["ref:INSEE"=44005];
way[name="Avenue Arthus-Princé"](area)->.rues;
rel(bw.rues)[route=hiking];
out geom;

Oui “.rues” au pluriel : n'oublions pas qu'on manipule des lots de données (Overpass est un langage de programmation ensembliste), et que les rues sont souvent découpées en de multiples sections dans OpenStreetMap.

Il existe plusieurs filtres de récursion, 4 pour la récursion descendante :

node(w) : nodes référencés par les ways

node(r) : nodes référencés par les relations

way(r) : ways référencés par les relations

rel(r) : relations référencées par les relations

et 4 pour la récursion ascendante :

way(bn) : ways référençant les nodes

rel(bn) : relations référençant les nodes

rel(bw) : relations référençant les ways

rel(br) : relations référençant les relations

La récursion sélective est particulièrement utile pour les données de transport en commun. Prenons par exemple une ligne de bus à Nantes. Nous pouvons obtenir les arrêts de la ligne C2, c'est-à-dire les nodes référencés par la relation :

rel[route=bus][operator=SEMITAN][ref="C2"];
node(r);
out;

Notez qu'on obtient les arrêts et trajets dans les deux sens de la ligne, car nous partons en réalité de deux relations, une pour chaque sens. Ajouter un filtre sur les tags from et/ou to permet de sélectionner un trajet de la ligne.

En remplaçant node(r) par way(r), on obtient les ways référencés qui forment le trajet de la ligne. Mais observons le résultat avec cette ligne de tramway :

rel[route=tram][operator=SEMITAN][ref="2"];
way(r);
out geom;

On obtient en fait les rails et les quais de la ligne. Ces quais sont référencés par la relation avec le rôle platform. Les filtres de récursion permettent également de filtrer sur le rôle des membres. Cet exemple retourne les quais de la ligne, c'est-à-dire les ways références avec le rôle platform :

rel[route=tram][operator=SEMITAN][ref="2"];
way(r:"platform");
out geom;

Si on veut obtenir les points d'arrêts (nodes) et les quais (ways), nous devons appliquer une union donc utiliser une variable :

rel[route=tram][operator=SEMITAN][ref="2"]->.ligne;
(
node(r.ligne:"stop");
way(r.ligne:"platform");
);
out geom;

Pour obtenir le trajet, il est possible de filtrer sur les membres dont le rôle est vide :

rel[route=tram][operator=SEMITAN][ref="2"]->.ligne;
way(r.ligne:"");
out geom;

On peut également filtrer sur le rôle dans une récursion ascendante, ce qui permet de trouver les lignes passant par un arrêt de bus :

node
[highway=bus_stop]
[network=TAN]
[name="50 Otages"];
rel(bn:"stop")
[type=route];
out geom;

Notez l'application du filtre de tag [type=route] qui permet d'éliminer la relation stop_area.

Exercices

Trouvez toutes les adresses (numéros) de votre rue.

Trouvez les lignes de transport en commun passant par l'arrêt le plus proche de chez vous.

Trouvez les arrêts desservis par ces lignes.

© CC-by-sa Carto’Cité