Scalenie tras rowerowych z plików .gpx i .tcx w PHP.
W ostatnich dniach podjąłem się małego projektu, który dłuższy od jakiegoś czasu już chodził mi po głowie.
Celem było wygenerowanie mapy z zaznaczonymi wszystkimi ścieżkami jakie przemierzyłem rowerem mając włączony gps-tracker.
Do dyspozycji miałem mieszankę plików .gpx i .tcx wyeksportowanych z aplikacji Endomondo oraz Strava.
Rezultat prezentuje się jak na poniższym obrazku, a jak tego dokonałem, czytajcie poniżej.
Research
Zacząłem od przestudiowania, czym są pliki .gpx i .tcx, jaką strukturę zawierają, jak mogę je odczytać i zapisać, w efekcie przyjąłem kilka założeń:
– wynikowy plik zawierający wszystkie trasy będzie zapisany w formacie GPX.
– do odczytu i zapisu plików GPX użyję biblioteki Sibyx/phpGPX
– pliki TCX przekonwertuję do GPX aby uprościć scalanie
– do odczytu plików TCX użyję biblioteki duckfusion/Waddle
Kilka słów o zawartości plików
Zarówno GPX jak i TCX są plikami XML zawierającymi informacje o przebytej trasie oraz zestaw metadanych.
W plikach TCX zapisane są okrążenia (laps) a w nich punkty ścieżki (track points).
W plikach GPX zapisane są ścieżki (tracks) a w nich segmenty (segments), a te z kolei zawierają punkty ścieżki (points).
Okazało się również że pliki TCX pochodzące z endomondo nie mogą być wczytane, ponieważ zawierają puste znaki na początku pliku, co powoduje że funkcja simplexml_load_file nie może sparsować XML. Rozwiązanie okazało się jednak dość proste, wystarczyło napisać prosty skrypt który wczytuje plik, usuwa puste znaki z jego początku (i końca) i zapisuje tę poprawioną wersję.
Konwersja TCX do GPX
Stworzenie pliku GPX z dwóch różnych formatów postanowiłem przeprowadzić dwuetapowo:
1. Konwersja TCX do GPX
2. Scalenie wszystkich plików GPX
Innym rozwiązaniem byłoby tworzenie wynikowego pliku GPX bez dodatkowego kroku konwersji, jednak wybrane rozwiązanie pozwoliło mi rozwiązywać napotkane problemy etapami, również kod stał się bardziej czytelny.
Konwersja polegała na wyciągnięciu punktów z pliku TCX i przekonwertowanie ich do formatu GPX. Punkty w obu formatach zawierają te same dane, dlatego konwersja okazała prostym przetłumaczeniem danych punktu z formatu jednej biblioteki do formatu drugiej.
Scalenie plików GPX w jeden plik wynikowy
Ostatnim krokiem był główny cel projektu – scalenie wszystkich ścieżek do jednego pliku GPX.
Jako że na tym etapie miałem do dyspozycji już tylko pliki GPX, wystarczyło wczytać z nich ścieżki i bez żadnych zmian zapisać do wynikowego pliku.
Wynikowy plik powstały z około 470 plików gpx waży 49,1MB, po wyświetleniu go w programie gpxviewer otrzymałem mapę przedstawioną na początku artykułu.
Rozwój kodu
Kod który napisałem jest w zasadzie Proof of Concept, miał posłużyć do jednorazowego wykonania w celu osiągnięcia konkretnego efektu, niemniej widzę w nim możliwość stworzenia uniwersalnego narzędzia do scalania plików GPX/TCX, poszczególne etapy można zorganizować np. jako zadania wykonywane w kolejce, można się również pokusić o scalanie większej ilości informacji niż tylko koordynaty lat/lon.
Pełny kod udostępniłem w repozytorium: bike-tracks-merger.
Skomentuj