OSM-XML-Datei in CSV umwandeln

Hallo!

Wie würdet Ihr eine .osm-Datei ins CSV-Format umwandeln? Gefunden hab ich auf die Schnelle nur das hier:
http://sourceforge.net/projects/xml2csv/

Gibt es auch andere Linux-Tools dafür?
Mir käms drauf an, dass alle Keys in unterschiedliche Spalten kommen. Beispiel:

Aus

<node id="123"> <tag k="name" v="Hans"/> <tag k="note" v="sowieso"/> </node>
<node id="124"> <tag k="name" v="Ludwig"/> <tag k="note" v="nix"/> </node>

soll das hier werden:

id    name     note
----------------------
123   Hans     sowieso
124   Ludwig   nix

warum? was willst du denn mit dem csv machen?
eventuell kann das nächste Programm auch xml verarbeiten, dann könntest du dir die Umwandlung sparen.

Gruss
walter

Moin,

das einfachste wird sein Du spielst die OSM-XML mit Osmosis in eine PostgreSQL und dann kannst Du die Spalten alle selektieren wie Du gern möchtest.

LG,

-moenk

Hier gibt’s ein Perl-Script: http://svn.openstreetmap.org/applications/utils/export/osm2csv/
Passt das von der Ausgabe her?

leider nicht so doll, alles in einer Zeile, keine Überschriften

9.423462,7.001750,recycling,recycling:paper=yes,recycling:clothes=yes,recycling:glass=yes
49.422147,6.990318,Geisberg,ele=355.5,natural=peak

ich hatte mal ein Skript geschrieben, was mir xml lesbarer ausgibt, also bspw


node
  id=1326762432
  lat=50.841063
  lon=-0.1458532
  uid=10291
  user=Stephen
  version=2
  changeset=8450101
  timestamp=2011-06-15T19:21:37Z
  ->tag
     k=is_in
     v=East Sussex, UK
  ->tag
     k=name
     v=Brighton
  ->tag
     k=note
     v=Didn't seem to be an existing place marker on the map. Seems odd - maybe I missed it...!?
  ->tag
     k=place
     v=city

Das Problem bei csv dürfte sein, dass Du eine sehr große Menge an Spalten haben wirst und erst nach einem kompletten Parsen feststeht, welche Spalten es überhaupt gibt. Man müsste also mindestens zweimal durch die xml Datei. Wenn Du vorher weißt, was Du ausgeben willst, würde es das ganze vereinfachen

Genau anders herum macht es Spreadnik. Vielleicht kann man sich aus dem Code was abgucken.

Hallo und danke für die vielen Ideen!

Die Anforderung ist leider etwas speziell. Wie Thomas schon angedeutet hat, muss man sich sinnvollerweise auf die Spalten einigen - das heißt, die Spalten-Überschriften sollten feststehen. Der Rest ist dann irgendwie hinzubekommen.

Wahrscheinlich ließe sich die Aufgabe sehr gut mit Osmium realisieren. Da ich den Sourcecode von osmconvert aber besser kenne als den von Osmium, denk ich über die zweitbeste Lösung nach, eine Erweiterung für osmconvert. Mal schauen, was dabei rauskommt. :slight_smile:

sag mal welche Spalten Du brauchst.

tja, wenn du meine Frage nicht beantwortest, kann ich dir auch nicht helfen.

wirst dich schon irgendwie durchwursteln.

Gruss
walter

Hallo Walter, stimmt, sorry. :slight_smile:
Die Ausgabe ist für Listen bestimmt. Zum Teil auf Papier. Man soll sie aber auch per Textverarbeitung oder Libre Office Calc weiterverarbeiten können.

Thomas: das wechselt leider. Deswegen würde ich es gern universell halten.

Wahrscheinlich bau ich in osmconvert etwas ein. Das sollte dann auch einigermaßen schnell laufen. Wenns fertig ist, sag ich Bescheid, vielleicht kann die Erweiterung ja auch wer anders brauchen.

ok, dann ist meine erste Wahl XSLT https://de.wikipedia.org/wiki/XSL_Transformation mit einem XSLT-Prozessor deiner Wahl. siehe https://de.wikipedia.org/wiki/XSLT-Prozessor
Ich benutze dafür XALAN.
Damit kann man aus xml-Dateien relativ einfach andere Datenformate erstellen. csv wäre damit auch kein Problem.

Gruss
walter

Danke, XALAN klingt interessant. Mit XSLT habe ich vor ca. einem Jahr schon einmal experimentiert, leider stürzten meine Versuche immer ab. Lag vielleicht an den Dateigrößen (viele 100 MB bis mehrere GB).
Ich werde mir die XALAN-Seiten anschauen. Auf den ersten Blick siehts für mich etwas kryptisch aus - liegt aber auch an der Uhrzeit. :slight_smile:

XSLT funktioniert nur für kleine Dateien und es ist außerdem ein ziemlicher Krampf, XSLT-Transformationen zu schreiben.

ich empfehle das Programm osmjs, das zu Osmium gehört. Dem gibste ein Javascript-Schnipsel:

osmjs -j osm2csv.js file.osm

Die Datei osm2csv.js sieht so aus:

====
var out = Osmium.Output.CSV.open(‘out.csv’);

Osmium.Callbacks.node = function() {
out.print(this.id, this.tags[‘name’], this.tags[‘note’]);
}

Osmium.Callbacks.end = function() {
out.close();
}

Das wars. Kannst das Javascript leicht anpassen, wenn Du andere Spalten willst oder sonstwelche Transformationen machen willst. Tabs in den Tags werden nicht escaped, d.h. das musste ggf. selbst machen.

So schnell schießen die Preußen, ähem, Badener dann doch nicht :wink:

Wer Markus’ Beispiel aus Post#1 nachspielen möchte, darf nicht vergessen, ein


<?xml version='1.0' encoding='UTF-8'?>
<osm version="0.6" generator="osmconvert 0.6>

vor- und


</osm>

nachzustellen, also eine valide osm-Datei zu verwenden, wer er/sie kein
terminate called after throwing an instance of ‘std::runtime_error’
what(): XML parsing error at line 2:0: junk after document element
erhalten möchte.

Im Gegensatz zu Deinem Blog-Eintrag “Osmium Packages” finde ich in “libosmium-dev” kein osmjs,
so dass man es doch zusammenbasteln muss mit nicht wenigen Abhängikeiten…

osmjs ist in einem eigenen Paket mit dem Namen ‘osmjs’. Ich hab den Blog-Eintrag ergänzt, damit das klarer wird.

(Generell empfehle ich das Osmium aus dem git-Repository zu verwenden und nicht von diesen Paketen, weil die recht alt sind. Bei osmjs ist es aber egal, da hat sich nicht so viel getan in letzter Zeit.)

Hallo nochmal,

danke für die vielen Tipps!

Nach genauerem Hinschauen sind für meinen Fall Jochens Tools am besten geeignet. Sie sind echt universell, und man kann sich genau die Ausgabe zusammenbauen, die man braucht.

Den Standard-Fall, nämlich eine per Tab-Zeichen getrennte Liste zu erstellen, habe ich trotzdem in osmconvert eingebaut – kann man immer mal brauchen, wenn das Ausgabeformat nicht allzu ausgefeilt sein muss.

Markus