Kleine Sachen mit Python

Von GPX über XML elegant nach KML



Der Anstoß


Sie wollen im Frühjahr eine Wanderwoche auf Mallorca zubringen und haben sich dazu mehrere Handvoll Wanderrouten im GPX-Format besorgt, die Sie allerdings gerne auch im KML-Format verwenden möchten.

Die GPX-Dateien, die hier Ausgangspunkt sind, sind solche, wie man sie sie allenthalben für Wanderrouten benutzt; sie enthalten einzelne, benannte Wegpunkte mit ihren Koordinaten und die eine benannte Route als Liste von einzelnen Wegspurpunkten ('track points'), ein Anschauungsbeispiel wäre:

Ausgangsformat-Route.gpx.html

[Die gewöhnungsbedürftige Einfärbung der XML-Datei verdanken wir dem Editor Notepad++.]

Die Zieldatei im KML-Format soll die oben erwähnten benannten Wegpunkte enthalten sowie natürlich die Route, die hier als kommaseparierte Liste der Koordinatenpaare (Länge,Breite) Eingang findet. Die Struktur dieser Zieldatei ist im Wesentlichen die, wie sie vom unten erwähnten GPSBabel erzeugt wird, bis auf die ebenfalls unten erwähnte Namenskorrektur und die Elemination von einigen überflüssigen Beschreibungselementen. Testwerkzeug für die KML-Datei ist die Android-App MapsMe. Ein Anschauungsbeispiel wäre:

Zielformat-Route.kml.html

Das Ziel vor Augen stöbern Sie nun im Internet und hoffen auf ein Werkzeug, welches Ihnen die Konvertierung abnimmt. Sie stoßen unweigerlich auf GPSBabel und stellen schnell fest, dass Sie, wenn Sie mehrere Dateien auf einen Schwung konvertieren wollen, die Konsole ('Eingabeaufforderung') bemühen müssen.

Gesagt und kurzerhand - mit viel Geduld und Ausdauer - getan:

FOR %%i IN (*.gpx) DO gpsbabel -w -t -i gpx -f "%%i"…
  -o kml,points=0,line_color=C81400FF,trackdata=0,labels=0 -F "%%~Ni.kml"

[Die horizonzale Ellipse '' am Zeilenende soll andeuten, dass die Zeile ohne Umbruch fortgesetzt werden soll.]

Dieses Batch-Skript tut in der Tat, was es soll, mit der einen ärgerlichen Ausnahme, dass statt des jeweiligen Namens der Route stereotyp ein "GPS device" als Dokumentname eingetragen wird, womit die dargestellten Routen auf der Präsentations-App MapsMe nicht unterscheidbar sind. Sehr ärgerlich bei all der aufgewendeten Mühe - und das kurz vor Reiseantritt. Immerhin, die Struktur passt.

Daraufhin äußern Sie sich ermattet und gefrustet mit den Worten:

"Möööööööh, ich hab keine Lust mehr jetzt. Hast du ne Idee - oder Lust auf Forschen und Basteln? :D"


Etwas Python


Der Angesprochene mochte sich nun nicht schon wieder zurückhalten, so wie bei der ersten Ansprache, und zimmerte im Nu ein passgenaues Python-Skript, welches das ominöse "GPS device" durch den Routennamen austauscht. Damit das alles, die ganze Konvertiererei, auch in einem Rutsch vonstatten geht, wird die Python-Skriptdatei dem vorhandenen Shell-Skript einfach in einer neuen Zeile hinzugefügt (in blau).

FOR %%i IN (*.gpx) DO gpsbabel -w -t -i gpx -f "%%i"…
  -o kml,points=0,line_color=C81400FF,trackdata=0,labels=0 -F "%%~Ni.kml"
py ./adapt-kml-files-of-gpsbabel.py

Das Python-Skript selbst ist schlichteste Hausmannskost und kann hier bei Bedarf inspiziert werden:

adapt-kml-files-of-gpsbabel.py.html

[Das bunte HTML-Bild des Quellcodes erzeugt das wunderbare Entwicklungswerkzeug für Python PyCharm. Ich werkelte lange mit dem bescheidenen Idle herum, ein Dank an die unvergessene Verona K. für den Tipp.]


Python zum Glänzen gebracht


Seit ich mein erstes GPS-Gerät, das selige Explorist 600, auf Wander- und Radltouren einsetzte, habe ich mir verschiedene Konvertierungsroutinen zusammengeschraubt, zuerst in der wahrlich typstrengen Programmiersprache Ada, dann in der (durchaus auch allzu) lockeren Interpretersprache Python. Allerdings schreckte ich bisher vor dem Einsatz von wiederverwendbaren XML-Bibliotheken zurück, weil ich meinte, handgestrickter Quellcode würde schneller zum banalen Ziel führen, nur eben das Format zu wechseln.

Jetzt allerdings packte mich der Ehrgeiz - und das Ergebnis entzückt mich. Allerdings wollte ich nicht gleich so weit gehen, dass ich für die gewünschte Formattransformation von GPX nach KML auch XSL Transformationen und dergleichen einsetze.

Das erste Unterprogramm extrahiert aus der GPX-Datei die benötigten KML-Daten:

extract_kmldata_outof_gpxfile.py.html

Das zweite Unterprogramm fügt die extrahierten GPX-Daten jeweils in die unten aufgeführte KML-Muster-Datei ('template') ein und speichert die erzeugte KML-Datei auch gleich ab:

generate_kmlfile_from_gpxdata.py.html

template_from_gpx_to_kml.kml.html

Die Knoten eines XML-Strukturbaumes werden durch ein Nummernschema identifizierbar gemacht. Die Numerierung beginnt jeweils mit der 0. Ein Beispiel:

outerTrackFolder=findKmlFolder(doc,'Tracks',ns);
outerTrackFolder[1][0].text=trackName;

Auf das 2. Kind des Wurzelelements outerTrackFolder greift man mit outerTrackFolder[1] zu, auf das 1. Kind dieses 2. Kindes mit outerTrackFolder[1][0], um an dieser Stelle dann den aktuellen Namen der Wegspur einzutragen.

Hilfestellung zur Durchnumerierung
der Baumstrukturelemente
(PDF-Datei)

Das Hauptprogramm liest zunächst die Namen aller GPX-Dateien aus einem vorgegebenen Verzeichnis ein und wendet die beiden Unterprogramme auf jede der vorgefundenen GPX-Dateien an:

transform_gpx_to_kml_files.py.html


Quellcode für Python 3


Mein Entwicklungsverzeichnis enthält alle notwendigen Dateien, ich habe es zum Herunterladen gepackt, zum Entpacken müssen Sie das Passwort test eingeben. Ich selbst benutze für die Python-Entwicklung die (aktuelle) Python-Version 3.8.


gpx2kml.zip



© 2020 Bernd Ragutt
Alle Rechte vorbehalten
 ... hier kann man hinschreiben letzte Änderung: 20.06.2020
Kruschtkiste