x

[OverpassAPI/JavaScript] Relationsmitglieder aus JSON verarbeiten


  1. [OverpassAPI/JavaScript] Relationsmitglieder aus JSON verarbeiten · rayquaza (Gast) · 27.01.2013 02:24 · [flux]

    Ich möchte eine vom Nutzer definierte Relation und ihre Member analysieren. Bisher habe ich es geschafft, die Relation zu laden und ihre Tags zu analysieren (z.B. relJSON[0].elements[0].tags.name). Nun möchte ich im Prinzip genauso mit ihren Mitgliedern weitermachen. Wenn ich mir mit <recurse type="relation-relation"> (bzw. der OP-QL Entsprechung) ihre Angehörigen von der Overpass-API abfrage, habe ich das Problem, dass die Elemente in der JSON-Datei durcheinander sind und nur über die Kombination aus relJSON[0].elements[0].members[j].ref und subrelsJSON[0].elements[j].idnicht einander zugeordnet werden können. Wie kann ich eine Zuordnung so herstellen, dass ich die Daten sinnvoll weiterverarbeiten kann?

    Das Ergebnis soll (erstmal) folgendes sein:

    • vom Nutzer angegebene Hauptrelation

    • Unterrelation(en)

    • Anzahl der verschiedenen Rollen

    /e: Korrektur: ..members[j].ref und ..elements[j].id passen nicht zusammen. Wie ist das überhaupt gedacht?


    • Re: [OverpassAPI/JavaScript] Relationsmitglieder aus JSON verarbeiten · tyr_asd (Gast) · 27.01.2013 11:07 · [flux]

      rayquaza wrote:

      members[j].ref und ..elements[j].id passen nicht zusammen. Wie ist das überhaupt gedacht?

      Doch doch, genau so ist es gedacht, und genau so funktioniert es auch. Ich kenne jetzt nicht genau deine Query, aber was du wahrscheinlich nicht bedacht hast, ist, dass wenn du eine <query type="relation"> und ein <recurse type="relation-relation"/> über eine <union> zusammenfasst, das Reihenfolge der Elemente i.d.R. durcheinander kommt. D.h., dass relJSON[0].elements[0] nicht der als Erstes über <query type="relation"> selektierten Hauptrelation entsprechen wird. Um das aber zu erreichen (ohne zwei getrennte API-Anfragen stellen zu müssen) verwendet man am Besten zwei <print> Statements (siehe Beispiel unten). Zusätzlich musst du noch bedenken, dass die Hauptrelation ja auch noch ways oder nodes als members haben kann (die du ja nicht geladen hast). Dagegen hilft eine zusätzliche Abfrage auf relJSON[0].elements[0].members[j].type == "relation".


      <osm-script␣output="json">
      <id-query␣type="relation"␣ref="2171699"␣/>
      <print␣mode="body"/>
      <recurse␣type="relation-relation"/>
      <print␣mode="body"␣order="id"/>
      </osm-script>
      

    • Re: [OverpassAPI/JavaScript] Relationsmitglieder aus JSON verarbeiten · rayquaza (Gast) · 27.01.2013 18:04 · [flux]

      tyr_asd wrote:

      Doch doch, genau so ist es gedacht, und genau so funktioniert es auch. Ich kenne jetzt nicht genau deine Query, aber was du wahrscheinlich nicht bedacht hast, ist, dass wenn du eine <query type="relation"> und ein <recurse type="relation-relation"/> über eine <union> zusammenfasst, das Reihenfolge der Elemente i.d.R. durcheinander kommt. D.h., dass relJSON[0].elements[0] nicht der als Erstes über <query type="relation"> selektierten Hauptrelation entsprechen wird. Um das aber zu erreichen (ohne zwei getrennte API-Anfragen stellen zu müssen) verwendet man am Besten zwei <print> Statements (siehe Beispiel unten).

      Mein Fehler war nahe da dran: Ich lasse die Hauptrelation zuvor schon in einer eigenen Anfrage übermitteln, habe dann aber vor Ausgabe der Relationsliste das Objekt mit dem neuen Überschrieben und damit natürlich die falschen OSM-IDs ausgegeben. Dank deines Tipps mit dem zweiten out; kommen die IDs jetzt in beiden Listen vor. Nur bei der Zuordung habe ich wohl noch ein Verständnisproblem.

      Kann ich irgendwie einfacher die verschachtelten Elemente erhalten als bei jedem Objekt alle Objekte durchzugehen bis das richtige dabei ist? Sowas wie z.B. VVrelJSON[0].elements[0].members[j].tags.name wäre super (dabei dann mit nur einem VVrelJSON[0].elements) - kann man die OP-API sowas ausgeben lassen?

      tyr_asd wrote:

      Zusätzlich musst du noch bedenken, dass die Hauptrelation ja auch noch ways oder nodes als members haben kann (die du ja nicht geladen hast). Dagegen hilft eine zusätzliche Abfrage auf relJSON[0].elements[0].members[j].type == "relation".

      Danke für den Hinweis. Die Hauptrelation enthält in dem Fall, für den ich das schreibe zwar keine Nodes oder Ways, aber theoretisch möglich wäre es natürlich und wird auch bei "niedrigeren" Relationen vorkommen, für die ich soweit möglich den selben Code nutzen möchte.

      mfg~ray

      P.S.: Falls jemand genau wissen will was ich mache hier der JS-Teil meines Quelltextes (noch ohne OSM-Objekt-Typ-Prüfung):

      <script␣type="text/javascript">
      var␣page␣=␣{
      basetitle:␣"Seitentitel"
      };
      var␣Overpass␣=␣{
      APIs:␣[
      {
      name:␣"overpass-api.de",
      baseURI:␣"http://www.overpass-api.de/api/interpreter?"
      },
      {
      name:␣"rambler.ru",
      baseURI:␣"http://overpass.osm.rambler.ru/cgi/interpreter?"
      },
      {
      name:␣"osm.fr",
      baseURI:␣"http://api.openstreetmap.fr/oapi/interpreter?"
      }
      ],
      activeAPI:␣0,
      performRequest:␣null,	//␣Prototyp␣for␣Function
      getObjById:␣null,		//␣Prototyp␣for␣Function
      getRelMembers:␣null		//␣Prototyp␣for␣Function
      };
      var␣VVrelJSON␣=␣"";
      
      Overpass.performRequest␣=␣function␣(request)␣{
      var␣xhr␣=␣new␣XMLHttpRequest({␣mozAnon:␣true,␣mozSystem:␣true␣});
      xhr.open("GET",␣Overpass.APIs[Overpass.activeAPI].baseURI␣+␣"data=[out:json];"␣+␣request␣+␣"out;",␣false);
      /*␣Eventlistener␣for␣xhr:␣*/
      xhr.send();
      try␣{
      //alert(xhr.responseText);
      document.getElementById("debugview").innerHTML␣=␣document.getElementById("debugview").innerHTML␣+␣"<br/><br/><br/><br/><br/>"␣+␣xhr.responseText;
      return␣eval("["␣+␣xhr.responseText␣+␣"]");
      }
      catch(e)␣{
      document.getElementsByTagName("body")[0].innerHTML␣=␣document.getElementsByTagName("body")[0].innerHTML␣+␣"<div␣class=\"error\">Die␣Antwort␣des␣Overpass-Servers␣ist␣ungültig.␣Die␣Antwort␣ist:␣<div␣class=\"code\">"␣+␣xhr.responseText␣+␣"</div></div>";
      return␣null;
      }
      }
      Overpass.getObjById␣=␣function␣(type,␣ID){
      return␣Overpass.performRequest(type␣+␣"("␣+␣ID␣+␣");");
      }
      Overpass.getRelWithMembers␣=␣function␣(RelID){
      return␣Overpass.performRequest("relation("␣+␣RelID␣+␣")->.ursprung;.ursprung␣out;(rel(r.ursprung);way(r.ursprung);node(r.ursprung););");
      }
      
      function␣init()␣{
      document.title␣=␣page.basetitle;
      document.getElementById("buttonParseVVrel").disabled=true;
      }
      
      function␣recieveVVrel()␣{
      if␣(!isNaN(document.getElementById("inputVVsearch").value))␣{
      VVrelJSON␣=␣Overpass.getObjById("relation",␣document.getElementById("inputVVsearch").value);
      }␣else␣{
      VVrelJSON␣=␣Overpass.performRequest("(relation[public_transport=network]"␣+
      "[abbreviation=\""␣+␣document.getElementById("inputVVsearch").value␣+␣"\"];"␣+
      "relation[public_transport=network]"␣+␣"[name=\""␣+␣document.getElementById("inputVVsearch").value␣+
      "\"];);");
      }
      
      document.title␣=␣page.basetitle␣+␣":␣"␣+␣VVrelJSON[0].elements[0].tags.name;
      document.getElementById("basedata-VVname").innerHTML␣=␣VVrelJSON[0].elements[0].tags.name␣+␣"␣("␣+␣VVrelJSON[0].elements[0].tags.abbreviation␣+␣")";
      document.getElementById("buttonParseVVrel").disabled=false;
      }
      
      function␣parseVVrel()␣{
      VVrelJSON␣=␣Overpass.getRelWithMembers(VVrelJSON[0].elements[0].id);
      for␣(var␣i=0;␣i<VVrelJSON[0].elements[0].members.length;␣i++)␣{
      var␣element␣=␣document.createElement("li");
      document.getElementById("VVcontent").appendChild(element);
      element.innerHTML␣=␣VVrelJSON[0].elements[0].members[i].ref␣+␣"␣-␣"␣+
      VVrelJSON[0].elements[i].id␣+␣"␣("␣+
      VVrelJSON[0].elements[i].tags.type␣+␣":␣"␣+
      VVrelJSON[0].elements[i].tags.name␣+␣")";
      }
      }
      </script>