Zoeken

Blog Je fietsroutes eenvoudig in kaart brengen

Marcel-Jan doet het eenvoudig met behulp van Python.

Geschreven door Marcel-Jan Krijgsman

Twee jaar geleden kocht ik een Sony FDR-X3000 actioncam om video’s te filmen vanaf mijn racefiets. Het is geweldig om mijn ritjes te herleven in 4K. Kilometers lang naar beneden racen vanaf een berg die ik even ervoor heb beklommen. Ook maak ik graag compilaties voor andere fietsers.

Het maken van deze video’s is een geweldige manier om de vakantie te herbeleven. Maar: het bewerken van de video’s (één voor elke dag) duurt weken. Vorig jaar kwamen er andere prioriteiten tussendoor, en toen kon ik ze pas maanden later afmaken. 

Bij de filmpjes zet ik ook details als langs welk dorp ik ben gereden, welke berg ik heb beklommen etc. De uitdaging: na meer dan een half jaar nog onthouden welke video, waar gemaakt is. Gelukkig zit er bij elke video op mijn actioncam ook een XML-bestand met onder andere GPS-data. 

Over Sony's XML

Het XML-bestand, gegenereerd door Sony, lijkt op dit (of bekijk het voorbeeld op Github)

Blog Je fietsroutes eenvoudig in kaart brengen... 2

We hebben nu de GPS-coördinaten in graden, minuten en seconden inclusief de hoogte en snelheid. In eerste instantie verwerkte ik deze data handmatig. Om de data in Google Maps te vinden, moest ik deze eerst naar GPS-coördinaten in decimalen omzetten. Een typisch klusje dat vraagt om automatisering.

 

Sommige XML’s hebben geen GPS data. Het is onduidelijk waarom. Mogelijk heeft de actioncam niet het GPS signaal kunnen opvangen omdat ik te dicht bij een bergwand reed? Daar moet dus rekening mee gehouden worden bij het verwerken van de XML bestanden.

XML lezen in Python

In het afgelopen jaar heb ik veel gewerkt met XML, maar niet zozeer in Python. Ik dacht dat je door de boomstructuur van het XML bestand zou moeten lopen. Maar in de voorbeelden die ik op Google vond, zag ik dat er meestal op de naam van een entiteit gezocht wordt. Omdat het een hobby-project is, hoeft het niet helemaal fancy te worden. 

 

Het werd ook niet helemaal fancy. Ik zou het liefst bijvoorbeeld de CreationDate uit de data pikken, maar nu gaat dat via een for loop die slechts 1 waarde leest. Iets voor latere verbetering.

Hier is een simpele Python-snippet waar ik de CreationDate mee uitlees. Je kunt de complete code vinden op Github. (Als je de code wilt kopiëren, vergeet dan niet de directory te veranderen.) 

 

from xml.dom import minidom
import os


path_of_the_directory= 'D:\Video\Vercors en Drome 2021'
ext = ".XML"
 
for filename in os.listdir(path_of_the_directory):
    sonyfile = os.path.join(path_of_the_directory, filename)
    sonyxml = minidom.parse(sonyfile)
    CreationDate = sonyxml.getElementsByTagName('CreationDate')
    for createdate in CreationDate:
        print(createdate.attributes['value'].value)
        creationdate = createdate.attributes['value'].value

GPS: graden naar decimalen

De meeste programma’s werken met GPS coördinaten in decimalen. Zoals bijvoorbeeld Google Maps. Dus dat moeten we converteren. Op zich is het converteren van graden naar decimalen niet zo moeilijk. Je moet de lengte- en breedtegraad splitsen bij de dubbele punt, minuten met 60 vermenigvuldigen en seconden met 60*60. 

 

def geoconv_degr_dec(geodegree):
    degree, minute, second = re.split(':', geodegree)
    geodecim = float(degree) + float(minute) / 60 + float(second) / (60 * 60)
    return geodecim


Om het leven makkelijker te maken, heb ik al deze data in een Pandas dataframe gezet. 

 

geodf = pd.DataFrame(columns=['xmlfilename', 'creationdate', 'latitude', 'longitude', 'altitude'])

 

Het resultaat van alle XML-bestanden zijn in een rij van het frame geplaatst, waarbij ik de naam van het bestand als index heb gebruikt. 

 
geodf.loc[filename, :] = [filename, pd.to_datetime(creationdate), latdecimal, longdecimal, altitude]

Video locaties op de kaart zetten

In eerste instantie ging ik te werk met de matplotlib library. Deze aanpak vergt dat je voor iedere nieuwe kaart, een afbeelding van de kaart download van Openstreetmaps.org. En als die kaart te groot is, loop je daar vaak tegen Gateway errors aan.

Een Twitteraar, Bob Haffner, wees me er op dat er een makkelijkere bibliotheek hiervoor is: Folium. Folium laadt kaartgegevens zelf en maakt ze ook nog eens zoom-baar, waardoor jouw toepassing er net zo uitziet als Google Maps.

We beginnen met het importeren van de Folium library:

import folium

 

Dan bepalen we van het middelpunt van de kaart. Pandas maakt het ons makkelijk die te vinden met de means functie over de breedte- en lengtegraad.

latitude_mean = geodf['latitude'].mean()
longitude_mean = geodf['longitude'].mean()

 

En daarmee kunnen we de kaart aanmaken:

my_map = folium.Map(location=[latitude_mean, longitude_mean], zoom_start=12)

 

Nu willen we alle video coördinaten op de kaart zetten. Folium heeft daarvoor parachute-achtige markeringen die bekend zijn van Google Maps. Als je klikt op die markeringen, kun je ook nog eens popup informatie krijgen in HTML formaat. Ik koos om hier de naam van het bestand en de CreationDate in te vullen.

for index, georow in geodf.iterrows():
    folium.Marker([georow['latitude'], georow['longitude']], popup=f"filename: {georow['xmlfilename']}</br>creationdate: {georow['creationdate']}").add_to(my_map)

De kaart tonen

Toen ik de code runde in PyCharm kreeg ik niets te zien. Het bleek dat Folium meer gericht is op notebook achtige toepassingen, zoals Jupyter. Geen probleem: we kunnen de resulterende kaart ook opslaan als HTML bestand en die openen in een browser.

             my_map.save('videogps_folium.html')

En als je dit bestand opent, dan krijgen we deze mooie kaart waarop we kunnen inzoomen en markeringen bekijken.

Blog Je fietsroutes eenvoudig in kaart brengen... 1

Het blijkt dat die zoom functionaliteit eigenlijk voor mij heel handig is. In de oorspronkelijke versie met matplotlib was ik van plan voor elke fietstocht een andere kaart te maken. Maar nu hoef ik slechts in te zoomen op die rit.

De hele code is terug te vinden op Github.

Volgende stappen?

Eigenlijk voldoet deze oplossing al volledig aan mijn wensen. Dit gaat het bewerken van de video’s van mijn volgende vakantie zoveel makkelijker maken.


Maar zoals dat gaat is de ene klus nog niet geklaard of je bedenkt al weer hoe het mooier kan. Ik heb al de tip gekregen dat Folium ook routes zou kunnen uittekenen. Misschien kan ik mijn routes uit Strava halen en dat in de kaart intekenen. Of wat te bedenken van thumbnails van de video’s die op de kaart geplaatst worden. We zullen zien…