Selon quelles règles l'API Overpass exécute-t-elle une requête? La présentation des différents éléments constitutifs favorise la compréhension, comment ils interagissent dans les requêtes.
La plupart des cas d'utilisation de requêtes avancées nécessitent des sélections relatives. Les supermarchés qui sont près d'une gare en sont un bon exemple. Les supermarchés ne sont reliés aux gares que par cette qualité, qu'ils sont spatialement proches l'un de l'autre.
D'après le tour de phrase, on cherche d'abord les supermarchés, puis cherchez dans tous les supermarchés les gares ferroviaires à proximité et ne garder que les supermarchés où nous avons trouvé une gare. Cette approche conduit rapidement à des monstruosités relatives en langage naturel; même en langage formel, cela ne s'améliore pas.
Par conséquent, le langage de requête de l'API Ovepass suit plutôt un paradigme pas a pas, de la soi-disant programmation impérative. Une seule tâche gérable est résolue à la fois, et maîtrisé la tâche complexe en les enchaînant. L'approche est alors la suivante:
Il en résulte la requête suivante ligne par ligne. Vous pouvez maintenant l'exécuter:
nwr[public_transport=station]({{bbox}}); nwr[shop=supermarket](around:100); out center;
Les détails de la syntaxe seront expliqués plus loin.
Pour des cas plus simples, vous pourriez vouloir une syntaxe encore plus simple, mais la solution à deux lignes qui en résulte reflète la répartition claire des tâches:
nwr[shop=supermarket]({{bbox}}); out center;
Nous comparons la requête pour les supermarchés uniquement dans la zone de visibilité
nwr[shop=supermarket]({{bbox}}); out center;
avec la requête ci-dessus
nwr[public_transport=station]({{bbox}}); nwr[shop=supermarket](around:100); out center;
pour identifier les composants individuels.
Le caractère le plus important est le point-virgule; il termine une instruction à la fois. Les sauts de ligne, les espaces (et les tabulations) ne sont pas pertinents pour ceci et pour la syntaxe dans son ensemble. Ces instructions sont exécutés l'un après l'autre dans l'ordre, où ils sont écrits. Ainsi, dans les deux requêtes, il y a quatre instructions ensemble:
nwr[shop=supermarket]({{bbox}});
nwr[public_transport=station]({{bbox}});
nwr[shop=supermarket](around:100);
out center;
L'instruction out center
est une instruction de sortie sans autres sous-structures.
Les possibilités de contrôle du format de sortie sont discutées dans la section Formats de données.
Les instructions restants sont tous des instructions de type query,
c'est-à-dire qu'ils sont utilisés pour sélectionner des objets.
Ceci s'applique à tous les énoncés commençant par nwr
et autres mots-clés spéciaux:
les mots-clés node
, way
et relation
chacun respectivement restrictent le résultat à des objets de type nœud, chemin et relation,
mais nwr
(acronym de node, way, relation) fournit tous les trois types.
Ils ont plusieurs sous-structures ici:
[shop=supermarket]
et [public_transport=station]
({{bbox}})
(around:100)
Toutes les sous-structures d'une instruction query filtrent les objets à sélectionner et sont donc appelées filter. Il est possible de combiner n'importe quel nombre de filtres dans une instruction de type query; l'instruction sélectionne exactement ces objets, qui remplissent tous les filtres. L'ordre des filtres n'a pas d'importance, car les filtres d'une instruction sont appliqués simultanément.
Alors que [shop=supermarket]
et [public_transport=station]
permettent tous les objets,
qui ont un qualité précis (supermarchés dans un cas, gares dans l'autre),
({{bbox}}})
et (around:100)
sont utilisés pour le filtrage spatial.
Le filtre ({{bbox}})
permet exactement de tels objets,
qui se trouvent en tout ou en partie dans le rectangle englobant.
Le filtre (around:100)
marche un peu plus compliqués.
Il a besoin d'un input et accepte exactement tous les objets,
qui ne sont pas à plus de 100 mètres de l'un des objets de input.
C'est là que l'exécution pas à pas prend effet:
Le filtre (around:100)
reçoit ici comme input exactement les stations sélectionnées dans la ligne précédente.
Comment réaliser une opération ou? De cette façon, vous pouvez trouver tous les objets qui sont un supermarché ou une gare:
( nwr[public_transport=station]({{bbox}}); nwr[shop=supermarket]({{bbox}}); ); out center;
Ici, les deux instructions de requête forment un bloc dans une structure plus grande. La structure indiquée par les crochets s'appelle donc une instruction de bloc.
Cette structure de bloc spéciale s'appelle union, et il est utilisé pour lier plusieurs instructions de cette façon, qu'il sélectionne tous les objets trouvées dans l'une ou plusieurs des instructions du bloc. Il doit y en avoir au moins une et il peut y avoir un nombre illimité d'instructions dans le bloc.
Il y a de nombreuses autres instructions de bloc:
Ce n'est pas encore expliqué, comment les conditions peuvent être formulées dans l'instructions de bloc if ou for.
Toutefois, le mécanisme utilisé à cette fin est également utile pour d'autres tâches. Par exemple, vous pouvez créer une liste de tous les noms de rues dans une zone.
[out:csv(name)]; way[highway]({{bbox}}); for (t["name"]) { make Saisie name=_.val; out; }
Les lignes 2 et 6 contiennent les phrases simples way[highway]({{bbox}})
et out
respectivement.
Avec [out:csv(name)]
dans la ligne 1, le format de sortie est contrôlé (voir là).
Les lignes 3, 4 et 7 forment l'instruction de bloc for (t["name"])
;
elle doit savoir, selon quel critère elle doit regrouper les objets selectionnés.
L'évaluation t["name"]
répond à cette question.
Une évaluation est une expression,
qui est évalués au cours de l'exécution d'une instruction.
C'est une expression qui est évaluée pour chaque élément,
puisque for nécessite des informations par élément.
L'expression t["name"]
évalue la valeur de l'attribut avec la clé name d'un objet.
Si l'objet n'a pas d'attribut avec la clé name,
l'expression évalue à une chaîne des caractère vide.
La ligne 5 contient également une évaluation avec _.val
.
Ceci permet de générer la valeur à éditer.
L'instruction make crée toujours un seul objet à partir de plusieurs objets potentiels,
la valeur de _.val
ne doit donc pas dépendre d'objets individuels.
L'évaluation _.val
retourne la valeur de l'expression de la boucle courante dans une boucle,
ici la valeur de l'attribut name de tous les objets pertinents.
Si une valeur indépendante est attendue, mais qu'une valeur dépendante de l'objet est spécifiée, un message d'erreur s'affiche. Cela se produit, par exemple, si nous voulions afficher la longueur des routes: Essayez-le, s'il vous plaît:
[out:csv(length,name)]; way[highway]({{bbox}}); for (t["name"]) { make Saisie name=_.val,length=length(); out; }
Les différents segments d'une rue portant le même nom peuvent avoir des longueurs différentes. Nous pouvons résoudre ce problème en spécifiant comment les objets doivent être regroupés. Souvent, on veut une liste:
[out:csv(length,name)]; way[highway]({{bbox}}); for (t["name"]) { make Saisie name=_.val,length=set(length()); out; }
Dans ce cas particulier, cependant, la sommation est probablement plus utile:
[out:csv(length,name)]; way[highway]({{bbox}}); for (t["name"]) { make Saisie name=_.val,length=sum(length()); out; }
L'instruction make crée toujours exactement un nouvel objet, appelé dérivée. Pourquoi un objet, pourquoi pas juste un objet OpenStreetMap? Les raisons varient d'un cas d'utilisation à l'autre: ici, nous avons besoin de quelque chose que nous pouvons retourner. Dans d'autres cas, on souhaite modifier et supprimer les attributs des objets OpenStreetMap, ou simplifier la géométrie de l'objet OpenStreetMap, ou a besoin d'un transporteur pour des informations spéciales.
Les objets OpenStreetMap apparents doivent suivre les règles des objets OpenStreetMap et ne permettent donc pas beaucoup de libertés utiles. Surtout, ils pourraient être confondus avec de vrais objets OpenStreetMap et re-téléchargés à openstreetmap.org par erreur.
Vous pouvez voir les objets générés si vous laissez la requête à format de sortie XML:
way[highway]({{bbox}}); for (t["name"]) { make Saisie name=_.val,length=sum(length()); out; }
Dans de nombreux cas, cependant, une seule sélection ne suffit pas. Par conséquent, les sélections peuvent également être stockées dans des variables nommées et ainsi garder plusieurs sélections en même temps.
Nous voulons trouver tous les objets d'un même genre, qui ne sont pas près d'objets de l'autre genre. Des exemples plus proches à la quotidienne sont souvent la recherche d'erreurs, p. ex. quais sans voies ou adresses sans rues. Mais nous n'aborderons pas les subtilités de les attributs maintenant.
Nous enquêtons donc sur tous les supermarchés, qui ne sont pas près des gares:
nwr[public_transport=station]({{bbox}})->.all_stations; ( nwr[shop=supermarket]({{bbox}}); - nwr._(around.all_stations:300); ); out center;
Par la ligne 3, la mention nwr[shop=supermarket]({{bbox}})
sélectionne tous les supermarchés dans le rectangle englobant.
Nous voulons supprimer un sous-ensemble et donc utiliser une instruction de bloc de type difference;
Les trois éléments (
à la ligne 2, -
à la ligne 4 et )
à la ligne 5 permettent de le reconnaître.
Nous devons choisir des supermarchés près des gares.
Pour ce faire, nous devons choisir les stations comme ci-dessus;
mais nous avons aussi besoin de tous les supermarchés comme sélection.
C'est pourquoi nous guidons la sélection des stations par la variable d'ensemble all_stations
.
Dans la ligne 1, la sélection passe d'une instruction ordinaire nwr[public_transport=station]({{bbox}})
à cette variable en utilisant la syntaxe ->.all_stations
.
L'ajout .all_stations
dans (around.all_stations:300)
le fera,
que cette variable est utilisée comme source au lieu de la dernière sélection.
Cela ferait nwr[shop=supermarket]({{bbox}})(around.all_stations:300)
la bonne instruction,
pour appeler les supermarchés exacts à retirer.
Pour raccourcir la durée d'exécution, nous préférons utiliser la sélection de l'instruction précédente à la ligne 3 - c'est exactement là où se trouvent les supermarchés dans la zone de délimitation.
Ceci se fait au moyen de la filtre ._
.
Il limite la sélection à de tels résultats,
qui sont dans l'entrée au début de l'instruction.
Depuis que nous avons utilisé l'entrée standard ici,
nous les appelons par leur nom ._
(trait de soulignement simple).
Le déroulement du processus avec le flux de données en détail:
->.all_stations
, toutes les stations sont alors sélectionnées dans .all_stations
;
la sélection standard, en revanche, reste vide.nwr[shop=supermarket]({{bbox}})
.
La ligne 3 n'a pas de redirection,
pour que tous les supermarchés soient ensuite sélectionnés dans la sélection standard.
La sélection all_stations
n'est pas mentionnée et est donc conservée.._
comme restriction pour son résultat,
et en plus la sélection all_stations
est utilisée comme source pour la recherche around via (around.all_stations:300)
.
Le résultat est la nouvelle sélection standard et remplace donc la sélection standard précédente.
La sélection all_stations
reste inchangée.all_stations
reste inchangée.out
utilise la sélection par défaut comme source.prochaine: Principes