Overpass API Multiabfrage Ergebnisse trennen

Hallo,
mittels Overpass API können auch Multi-Abfragen gestartet werden, doch leider werden alle Daten “unsortiert” in einen Dump gepackt. Beispiel mit 4 Abfragen in einer:

https://overpass-api.de/api/interpreter?data=[out:json];is_in(52.301739,13.776934);out;is_in(52.302194,13.775278);rel[boundary=administrative]admin_level=10;%3E;out;is_in(52.302194,13.775278);rel[boundary=administrative]admin_level=9;%3E;out;is_in(52.302194,13.775278);rel[boundary=administrative]admin_level=8;%3E;out;

Nun ist leider alles auf einer Ebene: areas, ALLE nodes, ALLE ways.
areas könnten in ein neues array gefiltert werden, type=area.
ways ebenso, type=way && admin_level=?.
Aber bei nodes keine Chance.

Es gibt zwar die Möglichkeit “make blabla;” einzufügen, sozusagen als Trenner, aber da wird nur ein weiter key:value auf selber Ebene angelegt. Gibt es irgendeine Möglichkeit das Abfrage Ergebnis bereits sortiert zugestellt zu bekommen? so nach dem Muster:

typearea
- ...
adminlevel8
- nodes
- ways
adminlevel9
- nodes
- ways
adminlevel10
- nodes
- ways

Ja, das geht so:


[out:json];is_in(52.301739,13.776934);
rel(pivot)[boundary=administrative][admin_level](if:number(t["admin_level"])>7);
for(10 + number(t["admin_level"])) {
  out;
  >;
  out skel qt;
};

Das Ergebnis solltest du dann von oben nach unten parsen, jeweils mit einer Relation als Startpunkt. In JSON oder XML die Nodes/Ways verschachteln geht allerdings nicht. Das sollte aber auch nicht wirklich notwendig sein.

Aha. Ja, ich sehe, die nodes sind wieder alle auf einer Ebene. So nützt das nichts. Ich wollte das JSON aufsplitten in die Einzelabfragen der Multiabfrage, so dass ich einzelne Objects/Arrays zur separaten Weiterverarbeitung habe. So muss ich erst viel coden um die erstmal zu separieren. Oder mache mehrere Einzelabfragen. Da gibts Mecker in der Konsole:

Synchrone XMLHttpRequests am Haupt-Thread sollte nicht mehr verwendet werden, weil es nachteilige Effekte für das Erlebnis der Endbenutzer hat. Für weitere Hilfe siehe http://xhr.spec.whatwg.org/

“async” funzt wiederum nicht.

Wieso viel coden? Das Separieren geht mit vielleicht 10 Zeilen. :sunglasses:

ZEIG!
Ich schaffs mit 8! hab aber keine Lust, daran scheiterts, momentan.

Naja so was in der Art: Relation id gibt einen Index vor, und alles was dazugehört fliegt dort mit rein:


var id = 0;
var res = [];

jsonContent.elements.forEach(function(element) {
   if (element["type"] === 'relation')
   {
     id = element["id"];
     res[id] = [];
   }
    res[id].push(element);
});

Ach, was für ein schöner code. Wenn es denn immer so einfach wäre, was wäre ich glücklich!
“Use the JavaScript function JSON.stringify() to convert it into a string”
into a String, da war was, beim compare der Strings in den if Regeln. Da brauchts dann localeCompare. Da brauchts dann parseInt. … und es artet in Arbeit aus…

JSON.stringify() hat jetzt mit der eigentlichen Fragestellung aber irgendwie nix mehr zu tun. Es ging ja darum, die Nodes/Ways nach Relation zu gruppieren.

OK, Ausrede genehmigt. Die IDs von den way-node-arrays und den nodes vergleichen, dafür sind die IDs besser als Integer.

Ich habs jetzt dann doch gemacht. Bin mir aber noch unsicher, ob ichs auch verwende. Bzw. hab ichs nur extern getestet, noch nicht in meinem finalen Script.

overpassapijsonarea = {elements: []};
for (let key in overpassapijson.elements) {
if (overpassapijson.elements[key].type == "area") {
overpassapijsonarea.elements.push(overpassapijson.elements[key]);
}}
function filterOverpassAPIboundary(overpassJSON, adminlevelnum) {
filteredJSON = {elements: []};
for (let key in overpassJSON.elements) {
if ((overpassJSON.elements[key].type == "way") && (overpassJSON.elements[key].tags.admin_level == adminlevelnum)) {
filteredJSON.elements.push(overpassJSON.elements[key]);
}}
for (let waykey in filteredJSON.elements) {
for (i = 0; i < filteredJSON.elements[waykey].nodes.length; i++) {
nodenumber = filteredJSON.elements[waykey].nodes[i];
for (let nodekey in overpassJSON.elements) {
if (nodenumber == overpassJSON.elements[nodekey].id) {
filteredJSON.elements.push(overpassJSON.elements[nodekey]);
}}}}
return filteredJSON;
}

Problem!
Es ist nun so, dass für boundarys eines admin_levels auch auch ways von anderen admin_levels genutzt werden. Zudem gehören zu den boundarys auch ways ohne diese tags:
admin_level “?”
boundary “administrative”

Mit einer Multiabfrage und anschließender eigenständiger Sortierung nach admin_level gehen damit ways verloren. Also boundarys nachträglich trennen funktioniert nicht, oder nicht so einfach.