x

Länge von Ways in einer OSM-Datei ermitteln?


  1. Länge von Ways in einer OSM-Datei ermitteln? · margin-auto (Gast) · 11.02.2017 10:03 · [flux]

    Hallo,

    gibt es ein Tool, das anhand der Daten in einer .osm-Datei die Länge (in km, Meilen, oder was auch immer) aller darin enthaltenen Ways berechnet und ausgibt?

    Optimal wäre ein CSV-Output mit allen tags und einer weiteren Spalte für die Länge. Also bspw:

    Name highway length
    Schlossallee primary 3.141
    Parkstraße secondary 2.718

    Gibt es hierfür ein handliches Tool, ohne ganze Datenbanken- oder GIS-Systeme installieren zu müssen?

    TIA


    • Re: Länge von Ways in einer OSM-Datei ermitteln? · Harald Hartmann (Gast) · 11.02.2017 10:17 · [flux]

      Jepp, gibt es: https://github.com/osmcode/libosmium welches auch direkt mit PBF arbeiten kann.
      Und in den Examples findest du dann auch ein Skript für die Länge(nermittlung)


    • Re: Länge von Ways in einer OSM-Datei ermitteln? · margin-auto (Gast) · 12.02.2017 08:27 · [flux]

      Danke, werde ich mir anschauen.


    • Re: Länge von Ways in einer OSM-Datei ermitteln? · margin-auto (Gast) · 02.04.2017 07:33 · [flux]

      Hallo,

      ich bin nun endlich mal dazu gekommen, mich näher damit zu beschäftigen. Wenn ich das recht verstehe, ist das eine Library für die Verwendung in C(++). Richtig?
      Das übersteigt allerdings meine Programmierfähigkeiten. Gibt es eine Möglichkeit, diese Library aus anderen Sprachen anzusteuern? Perl? Ruby?
      Das verwandte osmium-Kommandozeilentool kann die Längen nicht ermitteln, oder?
      Gibt es noch andere Lösungsmöglichkeiten für mein Problem (s.o.)?

      TIA und Gruß


    • Re: Länge von Ways in einer OSM-Datei ermitteln? · mmd (Gast) · 02.04.2017 10:09 · [flux]

      Quick&Dirty mit libosmium würde das so aussehen: https://gist.github.com/mmd-osm/d069197 … 5bdc76ea56

      Dazu müsstest du zunächst libosmium herunterladen, kompilieren wie in https://github.com/osmcode/libosmium#building beschrieben und dann im cmake Verzeichnis ein

      examples/osmium_road_length meine_osm_datei.osm

      aufrufen.

      Achja, ebenfalls müsstest du noch den Code in libosmium/examples/osmium_road_length.cpp durch die Version oben ersetzen.

      Wenn du dein File irgendwo hochladen kannst, kann ich das auch gerne hier laufen lassen.

      BTW: Es gibt auch ein Issue für die Overpass API dazu: https://github.com/drolbr/Overpass-API/issues/237


    • Re: Länge von Ways in einer OSM-Datei ermitteln? · Marqqs (Gast) · 02.04.2017 15:15 · [flux]

      margin-auto wrote:

      gibt es ein Tool, das anhand der Daten in einer .osm-Datei die Länge (in km, Meilen, oder was auch immer) aller darin enthaltenen Ways berechnet und ausgibt?

      Ich hätte auf den ersten Blick auch Osmium empfohlen. Die Sache ist aber nicht ganz so einfach.

      Zum einen bestehen Straßen oft aus mehreren Ways, das heißt, man muss die Längen dieser Ways addieren. Hierbei reicht es aber nicht aus, einfach nach Ways mit gleichem Namen zu suchen, denn in manchen Städten gibt es gleichnamige Straßen, die in unterschiedlichen Ortsteilen liegen. Man muss wirklich schauen, die betreffenden Ways aneinanderhängen.

      Zusätzlich muss man prüfen, ob gleichnamige Ways nahe beieinander liegen, denn es ist nicht zwingen, dass eine direkte Verbindung besteht.

      Und als weitere Schwierigkeit müssen auch die Fälle berücksichtigt werden, bei denen der Straßenname gar nicht am Way-Objekt hängt, sondern an einer Relation die mehrere dieser Ways zusammenfasst.

      Eine entsprechende Auswertung könnte man natürlich mit der Osmium-Bibliothek bauen, aber vielleicht wär dann doch der Weg über eine Datenbank einfacher...


    • Re: Länge von Ways in einer OSM-Datei ermitteln? · margin-auto (Gast) · 03.04.2017 18:21 · [flux]

      Hallo,

      Marqqs wrote:

      Man muss wirklich schauen, die betreffenden Ways aneinanderhängen.
      [...]
      Und als weitere Schwierigkeit müssen auch die Fälle berücksichtigt werden, bei denen der Straßenname gar nicht am Way-Objekt hängt, sondern an einer Relation die mehrere dieser Ways zusammenfasst.

      Nein, das brauche ich alles gar nicht. Mir reicht wirklich ein Datensatz je OSM-Objekt. Die Längen aller Einträge mit Namen "Schlossallee" zu addieren, kriege ich dann schon selbst in der CSV-Datei hin. Im Gegenteil *darf* das Tool gar nichts zusammenfassen, da ja sonst Unterschiede bei anderen Tags (primary/secondary oder surface) verloren gehen könnten. Ich will ja die Längen nach allen verfügbaren Tags gruppieren können. Also bspw. auch ermitteln, welcher Anteil der Straßen asphaltiert ist (über die Einträge im Surface-Tag)
      Auf die Tags, die "indirekt" über Relationen an einem Objekt hängen, kann ich ebenfalls gerne verzichten. Mir reichen alle "direkten".

      Gibt es da kein anderes fertiges Tool, wo man nicht erst rumkompilieren muss?

      Ich hatte ansonsten noch irgendwo einen Perl-Code rumfliegen, mit dem man die Entfernung zwischen zwei Koordinaten ermitteln kann. Damit müsste man sich ja den Way nur entlanghangeln. Das erscheint mir momentan fast einfacher... 😐

      Gruß


    • Re: Länge von Ways in einer OSM-Datei ermitteln? · mmd (Gast) · 03.04.2017 18:35 · [flux]

      Achso, wenn du eine Lösung in Perl suchst, frag doch am besten mal bei Netzwolf nach. Der kann dir bestimmt weiterhelfen.


    • Re: Länge von Ways in einer OSM-Datei ermitteln? · margin-auto (Gast) · 17.04.2017 09:59 · [flux]

      Hallo,

      ich habe die verregneten Feiertage genutzt, was in Perl zusammenzustümpern. Das folgende Skript erwartet auf der Kommandozeile eine *.osm-Datei (bspw. aus JOSM abgespeichert) und gibt alle darin enthaltenen Ways in eine gleichnamige *.csv-Datei aus inkl. aller Tags und der berechneten Länge in Kilometern. Letztere landet in der Spalte 'calculated_length' um Konflikte mit dem gelegentlich verwendeten Tag 'length' zu vermeiden. Einzelne Nodes sowie Relationen werden (derzeit noch) ignoriert.

      use␣strict;
      use␣XML::Simple␣qw(:strict);
      use␣Math::Trig;
      
      my␣$wayid;
      my␣$key;
      my␣$lastpoint;
      my␣$outfile;
      my␣$point;
      my␣$subpoint;
      my␣$lastpont;
      my␣$length;
      
      my␣%keys;
      
      my␣$xml␣=␣new␣XML::Simple;
      my␣$infile␣=␣$ARGV[0];
      my␣$osm␣=␣$xml->XMLin($infile,␣KeyAttr␣=>␣{␣node␣=>␣'id',␣way␣=>␣'id',␣tag␣=>␣'k'},␣ForceArray␣=>␣[␣'node',␣'way',␣'tag'␣])␣or␣die␣"Fehler␣beim␣Öffnen␣der␣Datei␣$infile␣:␣$!\n";
      
      $keys{'id'}=1;
      
      #Alle␣Daten␣einsammeln␣und␣die␣Längen␣berechnen
      foreach␣$wayid␣(keys(%{␣$osm->{'way'}␣}␣)){
      
      #Längenfeld␣vorbereiten
      $osm->{'way'}->{$wayid}->{'tag'}->{'calculated_length'}->{'v'}=0;
      
      #Merken␣aller␣vorkommenden␣Keys
      foreach␣$key␣(keys(%{$osm->{'way'}->{$wayid}->{'tag'}}))␣{
      $keys{$key}=1;
      }
      
      #Laengenberechnung
      $lastpoint=undef;
      $length=0;
      
      foreach␣$point␣($osm->{'way'}->{$wayid}->{'nd'})␣{
      foreach␣$subpoint␣(@$point){
      if␣($lastpoint){
      $length+=&calcDist($osm->{'node'}->{$lastpoint->{'ref'}}->{'lat'},␣$osm->{'node'}->{$lastpoint->{'ref'}}->{'lon'},␣$osm->{'node'}->{$subpoint->{'ref'}}->{'lat'},␣$osm->{'node'}->{$subpoint->{'ref'}}->{'lon'});
      }
      $lastpoint=$subpoint;
      }
      }
      #Länge␣in␣der␣Datenstruktur␣ablegen
      $osm->{'way'}->{$wayid}->{'tag'}->{'calculated_length'}->{'v'}=$length;
      
      }
      
      #Daten␣ausgeben
      $outfile=$infile;
      $outfile=~s/\.osm$/.csv/;
      
      open␣OUTFILE,␣">$outfile"␣or␣die␣"Fehler␣beim␣Öffnen␣der␣Outputdatei␣$outfile␣:␣$!\n";
      
      #Header␣schreiben
      foreach␣$key␣(sort(keys(%keys))){
      $_.="$key;";
      }
      print␣OUTFILE␣"$_\n";
      
      #Daten␣schreiben
      foreach␣$wayid␣(keys(%{$osm->{'way'}})){
      $_=undef;
      foreach␣$key␣(sort(keys(%keys)))␣{
      if␣($key␣ne␣1␣and␣$key␣ne␣'nd'){
      if␣($key␣eq␣'id')␣{
      $_.=$wayid.';';
      }else{
      $_.="'".$osm->{'way'}->{$wayid}->{'tag'}->{$key}->{'v'}."';";
      }
      }
      }
      print␣OUTFILE␣"$_\n";
      }
      
      close␣OUTFILE;
      
      #-----------------------------------------------------------------------------------------------
      sub␣calcDist{
      my␣$lat1=shift;
      my␣$lon1=shift;
      
      my␣$lat2=shift;
      my␣$lon2=shift;
      
      my␣$R␣=␣6371;␣#km
      
      my␣$dLat␣=␣&deg2rad($lat2-$lat1);
      my␣$dLon␣=␣&deg2rad($lon2-$lon1);
      my␣$lat1␣=␣&deg2rad($lat1);
      my␣$lat2␣=␣&deg2rad($lat2);
      
      my␣$a␣=␣sin($dLat/2)␣*␣sin($dLat/2)␣+␣sin($dLon/2)␣*␣sin($dLon/2)␣*␣cos($lat1)␣*␣cos($lat2);
      my␣$c␣=␣2␣*␣atan2(␣$a**(0.5),␣(1-$a)**(0.5)␣);
      my␣$d␣=␣$R␣*␣$c;
      return␣$d;
      }
      

      Kommentare sind immer willkommen! 😄

      Gruß


    • Re: Länge von Ways in einer OSM-Datei ermitteln? · Martieu (Gast) · 26.04.2017 18:30 · [flux]

      Hallo an alle,

      ich hätte eine Frage zu Libosmium, da es hier im Thread erwähnt wurde. Habt ihr Erfahrung mit der Einrichtung der Libosmium-Lib auf Windows? Ich versuche schon seit längerer Zeit es einzurichten, aber es gelingt mir einfach nicht. Ich bekomme beim bauen mit git cmd die Meldung, dass der angegebene Pfad zu vcvarsall.bat nicht gefunden werden kann. Vielen Dank im Voraus.