Gestion du temps

Un fichier GPX contient, en plus de relevés GPS, des temps sous la forme d'une date et d'une heure nous permettant, par exemple, d'effectuer des calculs de vitesse. Dans ce nouveau chapitre, nous allons étudier quelques fonctions Python afin de manipuler des dates et des durées.

Le format ISO 8601

Le format GPX utilise le format ISO 8601 pour représenter une date. Une date est codée de la façon suivante :

YYYY-MM-DDThh:mm:ssZ

Code Signification
Y année sur 4 chiffres
M mois sur 2 chiffres
D jour sur 2 chiffres
h heure sur 2 chiffres
m minutes sur 2 chiffres
s secondes sur 2 chiffres (parfois complétées par 3 décimales pour une précision de l'ordre de la milliseconde)

La lettre Z correspond à la zone horaire selon l'échelle de temps UTC (Coordinated Universal Time). Elle peut-être suivie d'un décalage horaire.

Le module datetime

Comme le module math, ce module est préinstallé avec Python, donc pas besoin d'opération particulière pour l'utiliser. Je vous encourage à ajouter les lignes de code suivantes à votre script GPSutils.py afin d'enrichir notre petite bibliothèque de fonctions dédiées aux fichiers GPX.

from datetime import *

def duration(t1, t2):
  start = datetime.strptime(t1[0:19],'%Y-%m-%dT%H:%M:%S')
  end   = datetime.strptime(t2[0:19],'%Y-%m-%dT%H:%M:%S') 
  duration = end-start 

  return duration.total_seconds()

t1 et t2 sont des chaînes de caractères représentant des dates au format ISO 8601. La fonction duration() les convertit en objets datetime à l'aide de la méthode strptime().

Après soustraction, on obtient un résultat de type deltatime qui correspond à la durée entre les deux dates fournies en paramètres. Grâce à la méthode total_seconds(), on peut récupérer cette durée en secondes.

Exercice

Complétez le script GPXplorer.py en ajoutant une liste time contenant le temps écoulé (en secondes) de chaque relevé GPS depuit le départ en utilisant la fonction duration(). Le script affichera, en plus de la distance parcourue, la date et l'heure du départ, la durée du parcours et enfin la vitesse moyenne.

Heure de départ : 2012-10-21T07:01:39
Durée : 8178.0 s
Distance parcourue : 21564.27 m
Vitesse moyenne : 9.49 km/h
Correction
from lxml import etree
from GPSutils import *

# Liste des latitudes exprimées en degrés
latitude  = []

# Liste des longitudes exprimées en degrés
longitude = []

# Liste des altitudes exprimées en mètres
elevation = []

# Liste des distances cumulées
distance  = []

# Liste des temps en secondes,
# le premier étant égal à 0
time      = []

root = etree.parse("RATJ2012-21km-herve.schely.gpx")
ns = "http://www.topografix.com/GPX/1/1"

#
# Heure de départ
#
datetimelist = root.xpath("/ns:gpx/ns:trk/ns:trkseg/ns:trkpt/ns:time",
                          namespaces={"ns": ns}) 
startTime = datetimelist[0].text

trackpointlist = root.xpath("/ns:gpx/ns:trk/ns:trkseg/ns:trkpt",
                            namespaces={"ns": ns}) 
for point in trackpointlist:
    latitude.append(float(point.get("lat")))
    longitude.append(float(point.get("lon")))
    for param in point.getchildren():
        if param.tag == "{" + ns + "}ele":
            elevation.append(float(param.text))

        if param.tag == "{" + ns + "}time":
            time.append(duration(startTime, param.text))

distance.append(0)
for i in range(1,len(latitude)):
    d = greatCircleDistance(latitude[i-1], longitude[i-1], latitude[i], longitude[i])
    distance.append(distance[i-1]+d)

print("Heure de départ : " + startTime[0:19])
print("Durée : " + str(round(time[-1], 2)) + " s")
print("Distance parcourue : " + str(round(distance[-1], 2)) + " m")
print("Vitesse moyenne : " + str(round(distance[-1]/time[-1]*3.6, 2)) + " km/h")

Maintenant que nous avons extrait toutes les informations contenues dans un fichier GPX, nous pouvons les enregistrer dans un autre format (CSV par exemple) pour les traiter avec un autre logiciel ou les représenter sur une carte interactive : c'est justement ce qui va nous occuper dans les deux chapitres suivants.