Daten gefiltert über Overpass API herunterladen

Hallo margin-auto,

Es gibt zwei Verfahren die API abzufragen, einmal mit der XAPI Variante und einmal mit dem XML Konstrukt. Dort gibt es auch die Möglichkeit eines UNION Blockes.

Für die Möglichkeiten auf der Clientseite die Ergebnisse zusammenzuführen müsstest Du uns schon etwas mehr von Deiner Umgebung und Deine Kenntnissen sagen.

MfG. Georg V.

Das müsste mit osmosis gehen. http://wiki.openstreetmap.org/wiki/Osmosis/Detailed_Usage

Chris

Geht wahrscheinlich auch so, falls es mit Osmosis nicht klappen sollte:
http://wiki.openstreetmap.org/wiki/DE:Osmconvert#Zwei_oder_mehr_geographische_Bereiche_zusammenf.C3.BChren

Und falls das mit der API aus irgendeinem Grund gar nicht klappt, dann besser die regionale Datei von download.geofabrik.de runterladen und lokal filtern:
http://wiki.openstreetmap.org/wiki/DE:Osmfilter#Objekt-Filter

Hallo,

Vielen Dank für eure Hinweise. Ich habe nun testweise über zwei separate API-Aufrufe zwei Dateien heruntergeladen: Landuse und Rail. Diese habe dann gemäß der verlinkten Anleitung mit osmconvert zusammengeführt. Im so erzeugten Output sind mir jedoch zwei kleinere Fehler aufgefallen:

  1. osmconvert erzeugt zu Anfang ein Objekt mit der Id=0, das man manuell entfernen muss, um die Daten in Osmarender verarbeiten zu können.
  2. osmconvert entfernt offenbar die zuvor mühsam heruntergeladenen Metainformationen. Beim Versuch, den Output in JOSM zu öffnen, kam die Fehlermeldung, dass er das Attribut “version” vermisst.

Kann man diesen Fehlerchen noch irgendwie beikommen?

TIA und Gruß

Ich habs bisher immer so gemacht: von download.geofabrik.de die betreffende Region runtergeladen und danach auf meinem PC gefiltert.
Trotzdem müsste dein Weg natürlich auch gehen.

Sollte natürlich nicht passieren. Hast du die genauen Aufrufe, so dass ich den Fall einmal nachstellen kann?

Kann normalerweise nur dann sein, wenn du die Option --drop-version verwendest. Das solltest du nicht machen, wenn du die Daten später mit JOSM öffnen willst. Falls du die Datei nun trotzdem noch verwenden willst, kannst du den Version-Tag mit --fake-version wieder hinzufügen. Hochladen in die OSM-Datenbank mit JOSM geht dann natürlich nicht, aber das war ja auch nicht dein Ziel, wenn ich das richtig verstanden habe.

Das Problem ist, dass die overpass-Api die Meta-Daten nicht mitliefert.

Ah, danke, das erklärt die Schwierigkeiten natürlich.

@margin-auto:

Dann bleiben die beiden Wege:

  1. lokal filtern, wie ursprünglich von mir vorgeschlagen,
    ODER
  2. den Version-Tag mit osmconvert und der Option “–fake-version” wieder (gefaket) hinzufügen.

Tut sie schon, aber nur wenn per “[@meta]” extra angefordert, siehe:

http://wiki.openstreetmap.org/wiki/Overpass_API#Meta_data

Edit: Etwas ausführlicher:

wget -O 0.osm “http://www.overpass-api.de/api/xapi?*[bbox=5.291,47.200,7.367,47.786][landuse=residential|industrial|military][@meta]
wget -O 1.osm “http://www.overpass-api.de/api/xapi?*[bbox=5.291,47.200,7.367,47.786][landuse=forest][@meta]
osmconvert32 0.osm 1.osm --fake-version -o=summe.osm

produziert bei mir eine Datei, die folgendermaßen beginnt:

<?xml version='1.0' encoding='UTF-8'?>

Der erste node mit id=0 ist das Problem für Osmarender. Nach seiner manuellen Entfernung funktioniert alles wie gewünscht.

Danke, damit funktioniert das nun zumindest. Die Metainformationen hatte ich zuvor mit [@meta] erfolgreich aus dem API gezogen gehabt.

Ah, wieder was gelernt, ich hatte immer die Version von 0.6 auf 0.5 geändert um die Dateien
in JOSM öffnen zu können. :wink:

Ui, auch ein guter Trick - wieder was Neues für mich. :slight_smile:

Zu dem Knoten mit ID 0:

Die Overpass-API nutzt einen XML-Tag, der in OSM-Dateien nicht vorgesehen ist:
The data included in this document is from www.openstreetmap.org. It has there been collected by a large group of contributors. For individual attribution of each item please refer to http://www.openstreetmap.org/api/0.6/[node|way|relation]/id/history

Natürlich ist dieser Tag als XML-Tag zulässig, einzelne Programme werden ihn aber nicht erwarten und möglicherweise damit Probleme haben. osmconvert ist geschwindigkeitsoptimiert und spart dadurch Zeit, dass es den Syntax der .osm-Dateien nicht komplett prüft, sondern davon ausgeht, dass er stimmt:

Nach “<no” denkt sich das Programm “Das muss ein Node sein!” und rechnet nicht damit, dass es danach mit “te>” und nicht mit “de>” weitergeht. :slight_smile:
Ich hab das eben geändert: die Version 0.5W fragt auch den dritten Buchstaben ab und sollte nicht mehr damit auf die Nase fallen.

Danke für den Fix, jetzt funktioniert es.

Zu der Strategie, nur die ersten paar Zeichen zu vergleichen, sage ich jetzt mal nix… :wink:

Gruß

Meine Erfahrung mit der Vervollständigung bei JOSM lehrte mich, dass zwei oft genug nicht reicht (noexit/note) aber auch drei zu wenig sein können (landuse/lanes).

Von daher würde ich sage, immer einen mehr als man denkt, dass es reicht.

Edbert (EvanE)

Hi marqqs,
muss man denn noch angeben, ob das File in JOSM Syntax ist, also ’ statt " als
Stringdelimiter? Oder ist die Option -in-josm obsolet ?

Chris

Naja, das ist entweder schlampiges Programmieren oder der Versuch, das Programm bis zum letzten Bit auf Geschwindigkeit hin zu optimieren. Du kannst es so oder so sehen - und beide Sichtweisen sind irgendwie richtig. :slight_smile:

Muss inzwischen ohne diese Option klappen. Die Option wird nach wie vor akzeptiert, aber ignoriert:

    if(strcmp(a,"--in-josm")==0) {
      // deprecated;
      // this option is still accepted for compatibility reasons;
  continue;  // take next parameter
      }

Grund für diese Änderung waren konkrete Ergänzungsvorschläge für den Quellcode, weil die FOSM-Dateien Hochkommas an Stelle von Anführungszeichen verwendeten. Die Programme sollen ja grundsätzlich für beide Lizenzarten verwendet werden können.

Aber wir schweifen vom Thread-Thema ab. :slight_smile:

Gratulation, du hast es in Fefes Blog geschafft:
http://blog.fefe.de/?ts=b1fa9d42
http://refefe.de/?ts=b1fa9d42
:slight_smile:

Gruß,
Mondschein

Ui, das Programm wird berühmt! :wink:

Ich steh trotzdem zu diesem Weg. Bei Milliarden von Einzelvergleichen macht es halt schon etwas aus, ob man nur den relevanten Teil einer Zeichenkette vergleicht oder immer die komplette Zeichenkette. osmconvert ist ein Kompromiss, der auf Geschwindigkeit ausgelegt ist. Wer XML-Dateien auf XML-Syntax-Treue parsen will oder damit rechnet, dass das vorausgehende Schreibprogramm einen XML-Syntax verwendet, der für OSM nicht definiert bzw. dokumentiert ist, muss eben ein anderes Programm verwenden - welches dann natürlicherweise langsamer läuft.

Manche Software bietet sogar beide Wege an: einen vollwertigen XML-Parser und eine Art “Abkürzung”, die den XML-Syntax nicht komplett prüft, aber eben schneller ist. Wenn ich mich recht erinnere, macht das osm2pgsql so. Den Luxus dieser Auswahl hab ich mir gespart, weil die “Abkürzung” sehr zuverlässig funktioniert und halt einfach flott arbeitet.

Ich kenne den Code deines Programms nicht.

Aber wenn ich es richtig verstehe, dann musst du vergleichen, ob ein gegebener String einem von n gegebenen Werten entspricht. Dazu eignet sich ein TreeSearch Algorithmus. Ich habe es mit solch einem Algorithmus geschafft, ca. 800 MB/sec auf 10000 Suchbegriffe GLEICHZEITUNG zu untersuchen (single thread).

Dazu muss die Liste der Suchbegriffe in eine Baumstruktur umgewandelt werden. Jeder Node besteht aus einem Array von z.B. 256 (für 1 Byte) Child Nodes. Am Anfang sind alle Childnodes null. Nun wird für jeden Buchstaben des Suchwortes nacheinander ausgehend vom root-Node ein neuer Knoten erzeugt (falls noch keiner existiert).

Beispiel: Begriff “node” einfügen:
node1: [a]=null, … [n]=node2, … [z]=null, hit=null
node2: [a]=null, … [o]=node3, … [z]=null, hit=null
node3: [a]=null, … [d]=node4, … [z]=null, hit=null
node4: [a]=null, … [e]=node5, … [z]=null, hit=null
node5: [a]=null, … [z]=null, hit=‘node’

Zusätzlich Begriff ‘note’:
node1: [a]=null, … [n]=node2, … [z]=null, hit=null
node2: [a]=null, … [o]=node3, … [z]=null, hit=null
node3: [a]=null, … [d]=node4, … [t]=node6, … [z]=null, hit=null
node4: [a]=null, … [e]=node5, … [z]=null, hit=null
node5: [a]=null, … [z]=null, hit=‘node’
node6: [a]=null, … [e]=node7, … [z]=null, hit=null
node7: [a]=null, … [z]=null, hit=‘note’

Zusätzlich Begriff ‘name’:
node1: [a]=null, … [n]=node2, … [z]=null, hit=null
node2: [a]=node8, … [o]=node3, … [z]=null, hit=null
node3: [a]=null, … [d]=node4, … [t]=node6, … [z]=null, hit=null
node4: [a]=null, … [e]=node5, … [z]=null, hit=null
node5: [a]=null, … [z]=null, hit=‘node’
node6: [a]=null, … [e]=node7, … [z]=null, hit=null
node7: [a]=null, … [z]=null, hit=‘note’
node8: [a]=null, … [m]=node9, … [z]=null, hit=null
node9: [a]=null, … [e]=node10, … [z]=null, hit=null
node10: [a]=null, … [z]=null, hit=‘name’

Beim Suchen:
node = root;
c = firstchar;
while (node!=null && node.hit==null) {
node = node[c];
c = c.next;
}
if (node!=null) {
Treffer mit node.hit !
}

Das schöne ist, das die Anzahl der Suchworte in Baum fast keine Rolle spielt. Man muss für jedes Zeichen des zu untersuchenden Strings immer nur EINEN Vergleich vornehmen!

Falls noch Fragen offen sind, helfe ich dir gerne!

Grüsse

mdk

Hallo mdk, danke für das Angebot und die Mühe, die du dir gemacht hast!

Der Fall ist aber aus meiner Sicht so nicht vergleichbar, weil es in .osm-Dateien auf der äußeren Ebene nur sehr wenige verschiedene XML-Tags gibt. Zum Beispiel: “<node”, “<way”, “<relation”, "<create, “<modify”, “delete”. Hier ist ein hart codierter Vergleich deutlich schneller als die Suche in einem Baum.

Bei anderen Aufgaben (Bounding-Polygon, pbf- und o5m-Stringtabellen, --all-to-nodes usw.) verwendet das Programm je nach Eignung der Methode verkettete Listen, Hash-Tabellen, Binärsuche usw. Wenn du dort trotzdem irgendwo Optimierungsmöglichkeiten entdeckst, immer her damit! :slight_smile:

Hallo,

nach langer Zeit noch etwas Senf von mir zu diesem Thema. Unten mein Perlskript, das ich mir auf die Schnelle zusammengepfuscht habe. Es erwartet als ersten übergebenen Parameter eine Koordinatenbox der Form, wie sie auch für XAPI verwendet wird also bspw. “1.234,56.789,9.876,57.321” und als zweiten Parameter den Pfad zu einer (lokalen) Datei mit Renderregeln für Osmarender. Das Skript lädt dann alle im Rulefile verwendeten Tagklassen für die angegebene Box runter und fasst diese Daten anschließend mit osmconvert zusammen. Im Skript selbst muss nur der korrekte Pfad zu osmconvert eingetragen werden.
Die so entstehende output.osm-Datei kann anschließend an Osmarender zum Rendern übergeben werden. Reduziert die herunterzuladende Datenmenge (und damit auch die Renderzeit) ganz erheblich, wenn man nur sehr wenige Elemente in relativ großen Bereichen rendern will.

Ohne jede Garatie für Funktionieren und eventuell auftretende Probleme oder Schäden. Aber vielleicht hilfts ja dem einen oder anderen:



use strict;

my $coords=$ARGV[0];
my $rulefile=$ARGV[1];
my $osmconvertpath='/pfad/zu/osmconvert/osmconvert32';
my $i=0;
my $wgetcmd;
my $osmconvertcmd;
my $delcmd;
my @elements;

#Koordinaten aus erstem Parameter filtern
$coords=~s/[^\d,.]//g;

#Benötigte Klassen aus der Rule-Datei auslesen
open INPUT, "<$rulefile" or die "Can't open Rulefile $rulefile: $1";
while (<INPUT>){
    if (m!^<rule e=".*?" k="(.*?)" v="(.*?)">!){
        push @elements, "$1=$2";
    }
}
close INPUT;

#Daten herunterladen
foreach (@elements){
    $wgetcmd="wget -O $i.osm \"http://www.overpass-api.de/api/xapi?*[bbox=$coords][$_][\@meta]\"";
    `$wgetcmd`;
    $osmconvertcmd.="$i.osm ";
    $i++;
}

#Einzelne Dateien zusammenführen
$osmconvertcmd="$osmconvertpath $osmconvertcmd--fake-version -o=".'output.osm';
`$osmconvertcmd`;

#Einzeldateien löschen
$i=0;
foreach (@elements){
    $delcmd="rm ".$i.'.osm';
    `$delcmd`;
    $i++;
}


print "Fertig\n";