Cartographie

Bouquet final de cette activité autour des fichiers GPX : la visualisation d'informations géolocalisées sur une carte interactive. Il existe justement un module Python qui facilite cette opération.

Le module folium

Ce module doit être installé avant d'être utilisé. La commande sous Windows est la suivante :

pip.exe install folium

Et sous macOS ou Linux

pip3 install folium

Attention !

Cette commande doit être exécutée en mode administrateur. Sous Windows, dans le menu Démarrer, clic droit sur l'application "invite de commandes" et choisir "exécuter en tant qu'administrateur".

Si vous ne disposez pas des droits administrateur, vous pouvez ajouter l'option --user à la fin de la commande pour installer le module dans votre compte utilisateur.

Le module folium permet de créer une carte interactive et d'y dessiner des marqueurs, des lignes brisées, des polygones, etc.

import folium

# Création d'une carte
fmap = folium.Map(location=[55.7353606, 10.822693], tiles='OpenStreetMap', zoom_start=8)

# Ajout d'un marqueur
folium.Marker([55.8716693, 9.8839912],
              popup='VIA University College',
              icon=folium.Icon(color='green')).add_to(fmap)


# Ajout d'une ligne brisée définie à partir de 5 points
points = [
  (55.6713808, 12.4533972),
  (55.4013094, 11.2062387),
  (55.3311408, 10.6322608),
  (55.7148992, 9.3734841),
  (55.8716693, 9.8839912)
]

folium.PolyLine(points, color='blue', weight=2.5, opacity=0.8).add_to(fmap)

# Génération du fichier HTML contenant la carte
fmap.save('via.html')

La méthode folium.Map(location=[latitude, longitude], tiles='OpenStreetMap', zoom_start=zoom) crée une carte centrée sur le point de coordonnées (latitude, longitude) avec un grossissement égal à zoom_start (compris entre 1 et 18). Il est possible d'utiliser plusieurs fonds de carte en initialisant le paramètre tiles avec OpenStreetMap, Stamen Terrain ou Stamen Toner.

La méthode Marker() place un marqueur sur la carte au point de cordonnées (latitude,longitude) avec une couleur (paramètre color) choisie dans la palette suivante :

Nom Couleur
black
gray
lightgray
white
darkred
red
lightred
orange
beige
lightgreen
green
darkgreen
darkblue
blue
cadetblue
lightblue
pink
purple
darkpurple

Enfin, le paramètre popup permet de renseigner le contenu d'une fenêtre qui s'ouvre lors du clic sur le marqueur.

La méthode PolyLine() dessine une ligne brisée à partir d'une liste de couples de coordonnées.

Enfin, la méthode save() génère un fichier HTML qui embarque la carte, ainsi que tous les éléments ajoutés par le script (marqueurs, lignes, polygones, etc).

Exercice

Modifiez (une dernière fois) le script GPXplorer.py afin de générer une carte centrée sur le point de départ du parcours. Vous représenterez le parcours sous la forme d'une ligne brisée bleue d'épaisseur 3. Vous placerez aussi quatre marqueurs : un sur le départ, un sur l'arrivée et deux autres correspondant respectivement aux points de plus faible et plus grande altitude.

Correction
from bs4 import BeautifulSoup as bs
import pandas as pd
import folium as fl

df = pd.DataFrame([], columns = [ 'datetime', 'latitude', 'longitude', 'elevation' ])

# Chargement du fichier GPX
content = open('RATJ2012-21km-herve.schely.gpx')

# Construction de l'arborescnce
root = bs(content, features='xml')

k = 0
for point in root.find_all('trkpt'):
    df.loc[k, 'datetime'] = point.find('time').string
    df.loc[k, 'latitude'] = float(point['lat'])
    df.loc[k, 'longitude'] = float(point['lon'])
    df.loc[k, 'elevation'] = float(point.find('ele').string)
    k = k + 1


fmap = fl.Map(location=[df['latitude'][0], df['longitude'][0]], tiles='OpenStreetMap', zoom_start=13)

fl.Marker([df['latitude'][0], df['longitude'][0]],
              popup='Départ',
              icon=fl.Icon(color='green')).add_to(fmap)

fl.Marker([df['latitude'].iloc[-1], df['longitude'].iloc[-1]],
              popup='Arrivée',
              icon=fl.Icon(color='red')).add_to(fmap)

idmin = df['elevation'].idxmin()
fl.Marker([df['latitude'][idmin], df['longitude'][idmin]],
              popup=str(df['elevation'][idmin]) + ' m',
              icon=fl.Icon(color='blue')).add_to(fmap)

idmax = df['elevation'].idxmax()
fl.Marker([ldf['atitude'][idmax], df['longitude'][idmax]],
              popup=str(df['elevation'][idmax]) + ' m',
              icon=fl.Icon(color='lightblue')).add_to(fmap)

# Draw polyline
points = zip(df['latitude'], df['longitude'])
fl.PolyLine(points, color="blue", weight=3, opacity=0.6).add_to(fmap)

fmap.save('RATJ2012-21km-herve.schely.html')

Vous pouvez tester votre script sur d'autres fichiers GPX.

Je suggère que nous nous dégourdissions les jambes avant d'aborder le chapitre suivant qui traite des interfaces graphiques ou comment créer des applications Python dans une fenêtre avec des boutons, des cases à cocher, des listes déroulantes, des images, etc.