Univers Libre

Carte des pistes de ski des Laurentides

Written on 23 April 2019, 21:22 CEST
Tags: ski, tech.

Après 4 hiver à skier et cartographier les pistes de ski nordique des Laurentides, je me devais de produire une carte de tout ça. C'est maintenant chose faite avec ces 2 cartes des Laurentides :

Ce sont les premières cartes à couvrir tout le secteur des Laurentides, et à être plus complètes que les cartes locales des différents organismes, qui ne montrent pas certaines des pistes historiques.

Pour générer ces cartes, j'ai utilisé QGIS, puissant outil libre de SIG mais qui reste assez complexe à maitriser pour quelqu'un comme moi qui manque clairement de connaissance dans ce domaine.

Voici les sources du projet QGIS.

J'explique ci-après les étapes en gros que j'ai suivi pour construire la carte dans QGIS.

Fond de carte

Pour les données topographiques, j'adore le rendu de OpenTopoMap pour leur précision et leur qualité graphique. J'ai donc connecté leur serveur WMS dans QGIS pour avoir leurs tuiles en fond de carte.

Récupération des données relatives aux pistes de ski nordique

Le but ici est de récupérer les données brutes de OpenStreetMap relatives aux pistes de ski nordique afin d'avoir des données vectorielles sur lesquelles travailler.

QGIS, via le plugin QuickOSM, peut interroger directement l'API Overpass pour récupérer ce qui nous intéresse. On va donc récupérer plusieurs choses à l'aide de requêtes Overpass API :

QuickOSM stocke le résultat de chaque requête dans des calques séparés. On voit déjà que des mêmes données se retrouvent dans plusieurs calques (la 3ème requête inclue forcement les données de la 4ème et beaucoup de chemins avec piste:type=nordic ont aussi le tag highway=path. Idéalement j'aurai rajouté des exclusions dans les requêtes, mais je suis allé au plus simple, pourquoi s'embêter avec des requêtes Overpass quand il suffit de changer l'ordre d'affichage des calques.

J'ai donc dans l'ordre (du plus bas au plus haut) :

Maintenant il s'agit d'ajouter des styles à tout ça

Pour reprendre ce qui se fait de plus commun au Québec, les pistes de ski de fond tracées seront en trait plein et avec le code de couleur représentant leur niveau de difficulté (vert/bleu/noir). Les pistes de ski nordique (communément appelé « hors-piste ») seront en rouge et en tirets. Les autres sentiers seront noir en tirets avec une épaisseur légèrement moindre que les autres (ils sont moins importants). Les relations quant a elles ont une couleur rouge pale. Ça ne se verra pas dans la plupart des cas car par dessus il y a la couleur de la piste de ski (appliquée sur les calques des chemins, sauf dans le cas où la piste que représente la relation traverse un lac ou suit une route : dans ce cas il n'y a pas de chemin avec piste:type=nordic. Ça permet de bien différencier là où il y a une vraie piste des parties qui ne sont pas forcement skiables (routes) ou qu'il n'y a pas de tracé définit (lacs).

Pour les 2 premiers calques (de l'ordre évoqué précédemment), c'est simple on joue avec les options de style de QGIS. Pour le 3ème, on ne veut pas les afficher donc on les mets en transparence totale ou largeur de 0 px (c'est toujours à cause de la fameuse astuce, j'y reviens, j'y reviens !).

Et enfin pour le 4ème calque, pour définir le style en fonction du type de piste et du niveau de difficulté (pour les pistes tracées), on va dire à QGIS de gérer le style suivant 5 règles, que voici :

"piste:grooming" =  'backcountry'
("piste:grooming" like '%classic%' or "piste:grooming" like '%skating%') and "piste:difficulty" = 'easy'
("piste:grooming" like '%classic%' or "piste:grooming" like '%skating%') and "piste:difficulty" = 'intermediate'
("piste:grooming" like '%classic%' or "piste:grooming" like '%skating%') and ("piste:difficulty" = 'advanced' or "piste:difficulty" = 'expert')
"piste:grooming" = 'scooter'

Puisqu'on a accès à tous les attributs OSM dans les données vectorielles importées, c'est relativement simple.

Nom et référence des pistes

Ensuite vient la partie où il faut placer le nom et/ou la référence (en fonction de qu'est ce qui est présent dans les attributs OpenStreetMap) sur les pistes. C'est là que j'ai bloqué pendant longtemps car, au niveau de OpenStreetMap, c'est un peu le bordel : une piste peut être créée par une relation qui assemble plusieurs chemins. Dans ce cas le nom et la référence (numéro ou lettre identifiant la piste en pratique) de la piste sont portés par les attributs name et ref de la relation. Une piste peut aussi ne pas avoir de relation, et être constituée d'un ou plusieurs chemin indépendants. Dans ce cas le nom et la référence peuvent être portés par les attributs name et ref des chemins où, si ces attributs existent déjà et qu'ils ne reflètent pas les bonnes valeurs, par les attributs piste:name et piste:ref (c'est le cas par exemple si la piste de ski emprunte un sentier de vélo ou de marche qui est nommé différemment).

Mon problème sur lequel j'ai luté pendant un moment était pour savoir si un chemin faisait parti d'une relation ou nom via le langage de requête de QGIS. En effet, une fois les données OSM importées, on perd leur structuration. La solution qu'on m'avait proposée sur StackOverflow consistait à utiliser des fonctions géométriques pour voir si le chemin donné se superposait à la relation donnée, mais je ne pouvais pas faire ça simplement pour chacune des relations à tester. D'où l'idée que j'ai eu de récupérer ce fameux calque supplémentaire : les chemins qui ne font partie d'aucune relation. Ainsi au niveau de QGIS c'est bien plus simple : j'affiche les noms pour le calque des relations ainsi que pour le calque des chemins n'ayant pas de relations. Le calque qui contient tous les chemins, lui, je ne lui fait afficher aucun nom.

Pour chacun des 2 calques, Il reste quand même à savoir quels attributs afficher parmi name, ref, piste:name et piste:ref mais ça se fait simplement avec le langage de QGIS.

Pour les relations :

case
    when name <> '' and ref <> '' then
        name || ' (' || ref || ')' 

    when ref <> '' then
        ref

    when name <> '' then
        name

end

Pour les chemins :

case
    when ("name" <> '' or "piste:name" <> '') and ("ref" <> '' or "piste:ref" <> '') then
        if("piste:name" <> '', "piste:name", "name") || ' (' || if("piste:ref" <> '', "piste:ref", "ref") || ')' 

    when "ref" <> '' or "piste:ref" <> ''then
        if("piste:ref" <> '', "piste:ref", "ref")

    when "name" <> '' or "piste:name" <> '' then
        if("piste:name" <> '', "piste:name","name")

end

On a maintenant les noms et/ou les référence des pistes qui s'affichent, et sans conflit. J'ai du jouer beaucoup sur les options d'affichage de QGIS car par défaut si la ligne est trop courbe dans tous les sens ou qu'il y a déjà trop d'information à un endroit, le moteur de QGIS n'affiche pas le nom. Pour plus de lisibilité, mais du coup je me retrouvais avec beaucoup de piste qui n'étaient pas identifiées.

Composition des cartes

Enfin c'est le moment de générer l'aperçu de la carte, via le module de composition de QGIS. Je définis la zone géographique que je veux imprimer, fixe une échelle, y ajoute des objets de texte pour le titre, les sources de données utilisées, une barre d'échelle, etc… QGIS permet de générer automatiquement une légende en fonction des règles de style qu'on a définit précédemment, ce qui est très pratique !

J'ai décidé de générer 2 cartes (secteur nord et secteur sud) pour économiser de la place sur le papier, car il n'y a pas beaucoup de pistes entre les 2.

J'aurai aimé pouvoir imprimer cette carte sur du grand papier pour pouvoir la donner à des collègues de ski. Pour avoir une échelle de 1:50 000, ça m'aurait pris environ une surface de papier de 1 m × 1 m. Mais après quelques devis, les prix sont vraiment chers et je ne suis pas non plus 100 % satisfait du rendu graphique (ni certain du résultat une fois imprimé !) donc j'ai plutôt décidé de découper ça en feuille A4 avec posterazor.

Améliorations

Il y en a beaucoup !

Déjà construire cette carte a permis de détecter pas mal de petites erreurs dans OpenStreetMap sur les données utilisées, je n'ai clairement pas tout corrigé, au delà du fait qu'il y a toujours des pistes incomplètes à aller explorer.

Je ne suis pas non plus très satisfait du placement automatique des noms des pistes par QGIS, bien que j'ai pas mal bidouillé ses réglages. La solution serait probablement de placer le nom des pistes à la main pour chacune d'elles, pour ainsi les mettre à l'endroit qui me semble le plus naturel.

Mais surtout je ne peux malheureusement pas considérer mes cartes générées comme de réelles cartes topographiques car j'ai du faire plusieurs approximations :

Mis à part ces problématiques, j'espère que cette carte pourra servir aux autres skieurs pour découvrir des nouvelles pistes dans les Laurentides !