GPX Track verschieben, Hintergrundinformationen:

Alle Punkte eines Tracks in die gleiche Richtung um den gleichen Offset zu verschieben ist relativ einfach.
Das war aber nicht mein Ziel. Ich wollte einen neuen Track, der einen definierten Abstand zum Originaltrack hat.
Der neue Track soll parallel zum Originaltrack verlaufen, und wahlweise eine andere Farbe mitbringen.
Man kann wahlweise:
 ⇒⇒ Nur den verschobenen Track anzeigen um den Weg auf der Karte noch erkennen zu können.
 ⇒⇒ Beide Tracks mit unterschiedlicher Farbe zur besseren Erkennbarkeit anzeigen.
Achtung: es werden nur Tracks verschoben, keine Routen!
Verschobener_Track.jpg Beide_Tracks.jpg

 Struktur und Parsen der .gpx Datei:

Neben vielen proprietären Formaten hat sich .gpx als Standard für GPS-Tracks, -Routen und -Wegepunkte durchgesetzt.
Erste Aufgabe ist also, eine .gpx-Datei vom lokalen Rechner zu laden und die Trackpunkte auszuwerten.
Da ich das Tool als Web-Lösung implementieren wollte, habe ich mich für Javascript als Programmiersprache entschieden.
Seit HTML5 ist sowohl das Laden einer lokalen Datei, als auch das Parsen einer XML-Datei wie .gpx möglich.
In einer .gpx-Datei können mehrere Tracks mit jeweils mehreren Tracksegmenten mit etlichen Informationen zu den Trackpunkten enthalten sein.
Da es uns nur um die Darstellung geht, interessiert uns nur die Position der Trackpunkte.
Alle anderen Informationen, wie Höhe, Geschwindigkeit, Richtung, und auch evtl. Wegepunkte und Routen beachten wir nicht.
Die Position eines Trackpunktes sieht wie folgt aus:
<trkpt lat="47.852157969027758" lon="16.830248180776834">
<ele="125.25">
</trkpt>
latist die geografische Breite von -  90° (Südpol) ...  + 90° (Nordpol)
lonist die geografische Länge von -180° (Westen) ... +180° (Osten)
eleist die geografische Höhe in Meter
Nach dem Parsen erhalten wir ein Array mit allen Trackpunkten, wobei jeder Trackpunkt nur die Informationen "lat", "lon" und "ele" enthält.

 Winkel zwischen 2 Trackpunkten vs. Entfernung:

Da der Winkel zwischen 2 Trackpunkten proportional zur Länge des Kreissegmentes ist, also zur Entfernung auf der Erdoberfläche, können wir teilweise direkt mit diesem Winkel rechnen.
Wir benötigen aber auch die Entfernung in Meter, konkret für den den gewünschten Offset von z.B. 20m.
Während der Abstand zwischen zwei Breitenkreisen (lat) immer konstant 111.319m beträgt, (Erdumfang von 40.075.017m geteilt durch 360°), variiert der Abstand zwischen zwei Längenkreisen (lon) in Abhängigkeit von der geografischen Breite (lat), am Äquator ist er ebenfalls 111.319m, an den Polen hingegen 0m.
Konkret berechnet sich der Abstand zwischen zwei Längenkreisen (lon) nach der Formel 111.319 * cos(lat).

 Track-Linien verschieben:

howToShift.jpg Jeder Track besteht aus einer Anzahl von Linien, wobei jeder Punkt sowohl das Ende einer Linie als auch der Anfang der nächsten Linie ist.
Da wir jede dieser Linien in eine andere Richtung verschieben wollen, erstellen wir zunächst ein Array mit allen Track-Linien.
Nun verschieben wir alle Linien im rechten Winkel um den gewünschten Abstand, da helfen uns Tangens und Pythagoras.
Durch das Verschieben entstehen Lücken bzw. Überlappungen !
Aber immerhin, wir haben schon ansatzweise einen verschobenen Track :-)

 Track-Linien verbinden:

howToJoin.jpg Wir machen aus den verschobenen Linien wieder einen Track, indem wir die Gleichungen für jeweils 2 Linien gleichsetzen.
Der Schnittpunkt ist jeweils ein Trackpunkt unseres verschobenen Tracks.
Für parallele Linien und Linien, die sich in spitzem Winkel kreuzen, ist Sonderbehandlung erforderlich, da der Schnittpunkt evtl. recht weit vom Track entfernt liegen würde.
Ganz enge Serpentinen im Bereich der Verschiebedistanz sehen auch nicht gut aus, dafür ist mir aber keine Sonderbehandlung eingefallen.

Den verschobenen Track speichern wir als .gpx-Datei ab.

Wenn wir nun beide Tracks auf das GPS-Gerät laden haben wir einen 2-farbigen Track, wenn weit genug reingezoomt wurde, ca. 200m.

Anmerkungen an Peter