Maps, viticulture, beers, cheeses
from France
Twitter
Ce tuto a été délivré pour la nuit de la géographie 2019, certaines choses ont pu changer suite aux mises à jour de QGIS
On propose ici de réaliser un équivalent d’une carte topographique de l’IGN avec QGIS et des données ouvertes (ou presque) et gratuites.
Petit aperçu final afin de vous donner envie de continuer la lecture:
Ce tuto comporte beaucoup trop de GIF (fallait bien que je m’amuse à l’écrire aussi).
Allez ! On se lance sur QGIS !
(Mais non, mais non, ça va aller)
Ouvrir QGIS 3 puis créer un nouveau projet.
On télécharge le Modèle Numérique de Terrain (DEM) sur le site de Copernicus (inscription gratuite nécessaire). Si on travaille sur la France métropolitaine, il y a une bonne probabilité que ce soit la tuile E30N20.
C’est assez lourd, mais cela vaut la peine. Une fois extrait cela donne ceci :
Comme c’est la première couche ajoutée au projet, le système de projection s’y réfère et passe en système européen ETRS89 (EPSG:3035). Afin de produire une carte à grande échelle, il faut prêter attention au niveau de détail. On va donc s’intéresser à une zone particulière pas trop grande et le tuto produira ici des cartographies se situant sur des zones du Vaucluse ou à proximité.
C’est bien gentil, mais comment on se repère dans tout ça ?
On double-clique sur la couche OpenStreetMap dans l’explorateur. Le fond OSM se rajoute par dessus notre couche de relief (par défaut, une couche se rajoute toujours par-dessus la couche active). On double-clique sur la couche, pour accéder aux propriétés, dans le panneau Transparence, on règle l’opacité à 50% afin de voir à travers.
Note : le fond OSM n’apparaît pas net car il est déformé par notre système de projection. Si vous voulez des fonds cartographiques issus du web nets, il faut vous mettre en WGS84 / Pseudo-Mercator (EPSG:3857).
Une fois la zone repérée, on va faire une extraction du raster afin de travailler avec une zone et des fichiers plus petits : Raster > Extraction > Découper un raster selon une emprise…
On sélectionne notre raster et dans l’étendue de découpage, on clique sur les … et on choisit “Sélectionner l’emprise depuis le canvas”.
De là on trace un rectangle un peu large autour de notre zone d’intérêt et on clique sur exécuter :
On ne garde que la couche découpée (clic-droit > supprimer pour enlever une couche).
Pour voir ce que cela donne, on peut rapidement visualiser un effet 3d avec les paramètres suivants :
Si de loin, l’effet est tout à fait satisfaisant, de près je trouve qu’une résolution de 25m est limite pour une cartographie à cette échelle. Par exemple, ici, au 1:10000, on a clairement un effet pixelisé et désagréable.
Pour remédier à cela, on va rééchantilloner notre raster à une résolution de 5 m (taille de la cellule de la région GRASS) avec la fonction resamp.bspline de GRASS :
Je vous conseille d’enregistrer directement les résultats dans un fichier plutôt que de les laisser dans la mémoire (selon le département 1-2 Go)
Ça prend un bon moment là encore, mais le résultat est quand même sympa.
On ne va garder que la couche Resampled BSpline (ou bien nommée comme vous l’avez choisi) qui sera appelée relief dans la suite du tuto.
Prenons un moment pour observer le rendu de la topographie. Deux éléments principaux participent à la bonne perception du relief.
On commence par générer les contours, les courbes de niveau, car l’ombrage se réglé en fonction. On va utiliser des intervalles de 5m.
Raster > Extraction > Contours
Si la couche de contours produite ne vous satisfait pas, il est toujours possible de la lisser : Traitements > Lissage (avec les valeurs par défaut).
Une fois la couche de contours à la hauteur (arf) de vos attentes, on peut aller modifier leurs règles d’apparence en allant dans Symbologie de la couche contours > Ensemble de règles
Première règle :
expression (Filtre) : "ELEV" % 50 = 0
Deuxième règle :
Rendu de couche : Mode de fusion = Multiplier
Maintenant les étiquettes > Etiquettes basées sur des règles :
expression (Filtre) : "ELEV" % 50 = 0
Si tout va bien, on obtient quelque chose dans ce goût-là.
On voit déjà bien le relief, mais l’ombrage va aider à mieux appréhender les angles.
En fait les ombrages : un ombrage multidirectionnel et un ombrage normal. On duplique donc la couche raster de relief (clic-droit dupliquer).
Il faut adapter le rendu de façon à suffisament rendre compte du relief sans que la carte ne devienne trop sombre et que certaines zones soient totalement masquées par l’ombrage. C’est un jeu d’équilibriste entre plusieurs paramètres:
le facteur z : l’altitude doit-elle être exagérée (multipliée en l’occurence) afin de rendre compte des petits reliefs? comment se distribuent les altitudes sur mon espace à cartographier ? est-ce très plat ? est-ce très accidenté?
la transparence
le contraste
la teinte : pour coloriser le raster avec plus ou moins d’intensité
Pour régler ‘à la volée’ les différents paramètres, on va sélectionner notre couche de relief et cliquer sur le bouton style. Cela permet une visualisation en direct des actions appliquées et quand on change de couche, le menu reste ouvert.
Un premier ombrage (celui du dessous):
Avec le deuxième par-dessus :
Nos opérations rasters terminées, on va changer de système de projection afin de bénéficier d’une déformation cartographique plus propice à la visualisation du territoire français : RGF93 / Lambert-93 (EPSG:2154). Pour ça, on clique sur le bouton de projection :
On recherche 2154 dans la barre de filtre et on choisit RGF93 / Lambert-93 (EPSG:2154).
Les couches vont se déformer.
Aux différentes échelles, nos couches se comportent relativement bien, on considère donc que c’est suffisant.
On ajoute plus bas la suite les bornes kilométriques et géodésiques pour les points cotés.
Pour l’hydrographie, une seule source de données ne donnant pas satisfaction, j’en utilise trois :
Pour plus de praticité, je vous conseille de créer un sous-ensemble de chaque couche spécifique à votre zone d’intérêt, ce sera plus facile à travailler et styliser.
Traitement > Gdal > Découper des vecteurs selon une emprise
et dans étendue de découpage vous cliquez sur les … pour définir ce que vous voulez garder.
On commence par charger la couche SURFACE_EAU. Ce qu’on remarque vite, c’est que les surfaces ne sont pas continues. Par exemple, différents polygones coexistent pour cette même rivière:
On a en fait deux catégorie principales liées à l’attribut “RÉGIME” : les surfaces permanentes et les surfaces intermittentes. On va donc choisir une symbologie et le type “Catégorisé”, avec la colonne “REGIME”. On clique sur classer et nos deux catégories apparaissent en deux couleurs différentes.
On va commencer par régler le plus simple : le permanent.
On double-clic sur la ligne Permanent pour régler sa symbologie.
Symbologie > Remplissage > Remplissage simple
Si on laisse tel quel avec cette bordure noire, on s’aperçoit d’entrée d’un problème lié à la construction des polygones, la surface n’est toujours pas continue !
Pour résoudre ce problème, on peut fusionner les entités, mais une astuce de paramétrage de la symbologie de QGIS va nous permettre de contourner ce fastidieux traitement.
Ensuite, dans la symbologie de la couche SURFACE_EAU, on clique sur Avancé et on ouvre le menu des Niveaux de symboles, que l’on active. Il faut mettre votre élément surfacique “par-dessus” votre élément linéaire, on met donc 1 en face de l’élément surfacique et on laisse zéro en face de l’élément linéaire (pas de symbole affiché, c’est que la visualisation des symboles en “mètres” a encore du mal à s’afficher correctement dans les icones)
On applique et bingo, les limites entre deux surfaces d’eaux permanentes ont disparu !
Les surfaces en eaux de façon intermittentes sont représentées en gros de la façon suivante : un hachurage horizontal bleu + un ensemble de petits points bleus aléatoirement distribués.
On clic sur la symbologie de la catégorie Intermittent :
On arrive donc à quelque chose dans ce goût-là :
(à noter que si vous dézoomer assez, QGIS généralise vos lignes et la classe intermittente apparait alors en bleu uni un peu plus clair)
On a en fait besoin d’une troisième typologie, pour les bassins et autres réservoirs (attribut “NATURE” = ‘Bassin’) qui sinon apparaissent en Intermittents. On a donc besoin de passer la typologie générale de la couche à “Ensemble de règles”.
OUF Bingo ! les deux première règles sont conservées. On a juste à en ajouter une troisième avec l’expression “NATURE” = ‘Bassin’. En fait, comme la symbologie doit être la même que les surfaces continues, on fait juste un clic droit sur la règle “Permanent” pour copier le style, et on colle cela sur notre nouvelle règle.
Il manque maintenant les autres cours d’eau que l’on a dans la couche TRONCON_COURS_EAU.
Si l’on veut coller plus exclusivement aux cours d’eau des cartes topo IGN, on peut utiliser le filtre suivant :
"FICTIF"='Non' AND ("PREC_PLANI" != '5' AND "PREC_ALTI" != '1')
Là encore, on refait une symbologie par catégorie sur le régime avec :
Et on place cette couche en dessous de la couche surface, de façon à ce que les tronçons déjà représentés dans les surfaces soient masqués.
Il reste maintenant à ajouter les étiquettes des principaux cours d’eau. Le plus difficile. Pour cela on se sert de la couche CoursEau_FXX de la BD Sandre. Si cette couche est la meilleure, elle n’est néanmoins pas parfaite. Les
regexp_replace( "NomEntiteH", 'L''','l''')
regexp_replace( "NomEntiteH", 'La ','la ')
regexp_replace( "NomEntiteH", 'Le ','le ')
Une fois la bonne typo des étiquettes trouvée (peut-être plus précise, là c’est juste l’essentiel) :
Symbologie : Aucun symbole (on ne veut que les étiquettes)
Étiquettes : Étiquettes basées sur des règles
Règle 1 :
Règle 2 :
“Classe” NOT IN (‘1’,’6’)
Étiqueter avec “NomEntiteH”
Formata Condensed Italic
Taille = 40m
Couleur = #1b8dfc
Espacement lettre = 25
Tampon : 5m, blanc, opaque
Position : Incurvé, à gauche ou à droite de la ligne, orientation suivant la position
Répéter tous les 15000 mètres
C’est tout pour l’hydro à ce stade, ça pourrait être étoffer (noms des lacs, étiquetter les réservoirs, stations d’épurations, etc.), mais l’idée ici est d’avoir la base (pour obtenir des couches de données supplémentaires, voir le modèle des requêtes overpass plus bas).
Un peu de couleur ne ferait pas de mal à ce fond de carte. On s’occupe maintenant de l’occupation du sol.
Première couche à ajouter, les bâtiments !
Une fois que vous avez récupéré le json départemental ou communal sur https://cadastre.data.gouv.fr/, décompressez-le et ajoutez-le dans QGIS.
La symbologie est des plus sommaires :
Seconde couche d’occupation du sol bien pratique : le travail effectué par l’équipe du CESBIO avec des couches vectorielles départementales : http://osr-cesbio.ups-tlse.fr/echangeswww/TheiaOSO/vecteurs_2017/liste_vecteurs.html
Bon alors évidemment comme ça, on fait…
Mais en fait si. Il faut juste une bonne symbologie :
Symbologie > Catégorisé > par “Classe”
on ne va cocher que les cases : 31, 32, 34, 36, 46, 211, 221 et 222
Classe 31 = Forêt de feuillus
Classe 32 = Forêt de conifères
Classe 34 = pelouses
Classe 36 = landes ligneuses
Classe 46 = plages et dunes (notamment ici les berges de rivières)
Classe 211 = prairies
Classes 221 = vergers
Classe 222 = vignes
idem que 221 sauf que Symbole = line |
En option générale de la couche, on met Rendu = Multiplier afin que les ombrages apparaissent.
Et là, votre carte est déjà bien belle, il n’y a pratiquement plus que les routes, les noms de lieux et des petites données par-ci par-là à rajouter. CESBIO bravo.
Là on va faire un petit tour par https://overpass-turbo.eu/ qui va être votre ami (si, si) pour une bonne partie des données annexes que vous souhaitez rajouter.
La requête pour extraire les routes et voies de chemin de fer va être la suivante :
[out:json];
// gather results
(
// seulement les routes
way["highway"]["highway"!="cycleway"]["highway"!="proposed"]["highway"!="footway"]();
// seulement les rails
way["railway"]["railway"="rail"]();
);
// print results
out body;
> ;
out skel qt;
Une fois que la requête est finie, on clique sur exporter en geojson
Lors de l’ajout de la couche obtenue à QGIS, il est probable qu’on vous propose plusieurs options : il faut choisir LineString.
On met ensuite en place une symbologie par Ensemble de règles
On met ici deux lignes avec une épaisseur juste supérieure à l’autre afin d’obtenir des “bordures de lignes”.
On passe de la route au rail pour finir :
On ajoute également des niveaux de symbole comme suit :
On applique…
Les cartes IGN ont tendance à mettre la couche des bâtiments “sous” la couche des routes. Personnellement, je préfère accentuer les bâtiments donc je les mets au-dessus.
Au-dessus :
En dessous :
Deuxième argument : les batiments sont représentés ici avec davantage de précision (pas de tampon ni rien déformant la géométrie), il est donc juste que ce soient eux qui rognent sur les symboles de routes plutôt que l’inverse. Du coup, pour moi, au-dessus. Mordicus.
facultatif -> Les étiquettes : étiquettes basées sur des règles
Règle :
Dernière pierre de l’édifice principal, les noms de lieux.
Pour cela on utilise trois sources de données : le GEOFLA + export OSM pour les communes et OSM pour le reste (lieux-dits / hameaux).
NB : on ne s’occupe ici que des limites communales étant donné l’échelle envisagée.
Aucune des deux couches communales ne nous satisfaisant entièrement, on va joindre des attributs du GEOFLA sur la couche OSM. Pour cela on double-clique sur la couche OSM puis sur jointure et sur le + vert.
On joint les champs :
On choisit un préfixe vierge. Et on applique.
On exporte cette nouvelle couche vers un autre fichier qui s’ajoute automatiquement. On supprime les deux anciens.
Symbologie : Bordure : Ligne de symboles
Étiquettes. Là ça se complique un peu.
On opte pour un ensemble de règles.
On va faire 3 règles : une pour les petites communes de moins de 5000 hab, une pour les préfectures de département ou région / sous-préfectures / capitale, et une où on met tout le reste.
L’étiquette utilisée va être sur l’attribut ‘nom’ issu d’OSM qui a les accents, tirets et tout comme il faut (vérifier l’encodage lors du chargement de la couche si ce n’est pas le cas).
Comme les noms de commune à rallonge sont fréquents on va opter pour la 1ere et la 3e règle d’une modification appropriée de l’étiquette. Au lieu d’indiquer le nom on va opérer une expression efficace permettant le passage à la ligne :
regexp_replace( nom, '(.{7}[^-.]*)-', '\\1-\n-')
Traduction : à partir du 7e caractère, s’il y a un tiret, on le remplace par un tiret, suivi d’un passage à la ligne puis à nouveau un tiret.
Du coup :
Règle n°1 : Petites communes
"POPULATION" < 5000
regexp_replace( nom, '(.{7}[^-.]*)-', '\\1-\n-')
Règle n°2 : préfecture & cie
"STATUT" IN ( 'Capitale d''État' , 'Préfecture de département' , 'Préfecture de région' , 'Sous-préfecture' )
"STATUT" IN ( 'Capitale d''�tat' , 'Pr�fecture de d�partement' , 'Pr�fecture de r�gion' , 'Sous-pr�fecture' )
Règle n°3 : Autres
Expression : ELSE
Étiqueter avec : nom
Police Formata condensed Bold
Taille 150m
Type de casse : Majuscules
Tampon blanc 3m
Position : Donnée définie X => type de champ = X_CHF_LIEU & Y => type de champ = Y_CHF_LIEU
Arrière plan : afficher un fond
length("nom")*85
Les étiquettes sont ici fixées géographiquement pour travailler dessus plus facilement (voir les bonus). Néanmoins on peut adoper une stratégie de placement plus libre autour du centroïde. L’inconvénient de ce dernier système réside dans le placement parfois assez éloigné dû à la distance importante entre le centroïde et le centre de l’unité morphologique de la commune. Sinon, les placer à la main.
On va maintenant essayer de trouver ce qui fait aussi le charme des cartes topo, tous les petits noms de lieux qui assurent une certaine continuité dans la lecture de la carte et meublent un peu les espaces “vides”.
Pour cela, on a recours encore une fois à l’api d’overpass, avec maintenant la requête suivante :
Requête lieux-dits :
[out:json][timeout:50];
// gather results
(
// query part for: “hamlet”
node["place"="hamlet"]();
node["place"="isolated_dwelling"]();
);
// print results
out body;
> ;
out skel qt;
Je ne prends ici que les lieux-dits/hameaux “habités”, pas les lieux-dits cadastraux qui d’une part sont des polygones et d’autre part et aussi par conséquent représentent souvent assez mal le territoire concerné par le nom que la DGFiP leur a attribué. Un certain nombre de ces lieux existent dans OSM, mais je suis forcé d’avouer que j’ai dû en créer un certain nombre pour que cela donne quelque chose de suffisant.
Donc s’il vous manque également des lieux-dits par rapport à la carte topo IGN, n’hésitez pas à les rajouter dans OSM : Ajouter un point > le placer à côté du groupe de bâtiments concernés par le nom du lieu > Choisir Lieu-dit ou hameau
Ces changements seront répercutés rapidement sur un certain nombre de tiles OSM pour le web, aussi soyez suffisamment rigoureux quand vous effectuez ces ajouts.
On charge le json obtenu dans QGIS et on applique la symbologie suivante :
Symbole : Aucun symbole
Étiquettes :
On en a fini pour les éléments principaux !
Le reste c’est du bonus.
Bonus de bonus : pour mettre le nombre d’habitants au dessus du nom de la commune (à adapter selon la taille des caractères en m) :
round( POPULATION/1000,1)
"X_CHF_LIEU"+(length(label)*50)/2
"Y_CHF_LIEU"+125
Comme je n’ai rien trouvé de probant, j’ai fait ma petite salade perso à partir de traces GPX et numérisations diverses et variées.
Vous pouvez télécharger ce fichier absolument dégueulasse topologiquement ici : https://github.com/rxlacroix/CarteTopoGeoNight/raw/master/data/Randonnee.gpkg
Pour la symbologie : Ligne simple, couleur #ff00ff, 10m d’épaisseur, cap rond
Étiqueter avec name, taille 45m, condensed italic, #ff00ff, tampon blanc 4m, Position incurvée au dessus de la ligne, répéter tous les 5000m.
Pour tous les autres éléments, je passe par des requêtes d’éléments OSM
On peut rajouter tous les éléments de détail que l’on veut, on adapte juste la requête à l’aide des clés OSM (https://wiki.openstreetmap.org/wiki/FR:%C3%89l%C3%A9ments_cartographiques).
(Cartographe faisant ses requêtes OSM)
Requête :
[out:json];
// gather results
(
way["highway"]["highway"="cycleway"]();
);
// print results
out body;
> ;
out skel qt;
Symbologie : Ligne simple, couleur #ff00ff, 10m d’épaisseur, cap rond
Étiqueter avec : ‘voie cyclable’, taille 30m, condensed italic, #ff00ff, tampon blanc 4m, Position incurvée au dessus de la ligne, répéter tous les 7500m. Fusionner les lignes connectées pour éviter la duplication d’étiquettes.
Requête :
[out:json];
// gather results
(
node["natural"='spring']();
);
// print results
out body;
> ;
out skel qt;
Symbole : symbole simple (rond)
Étiqueter avec : name
Requête :
[out:json];
// gather results
(
way["natural"='ridge']();
way["natural"='cliff']();
);
// print results
out body;
> ;
out skel qt;
Symbologie : Ligne noire+ Lignes de symboles de ^^^ noirs ou bruns, d’espacement ou de longueur aléatoires
Requête
[out:json];
// gather results
(
way["landuse"='cemetery']();
);
// print results
out body;
> ;
out skel qt;
Symbologie : ligne noire, fond transparent, motif de croix
Requête
[out:json];
// gather results
(
node["hiking"='yes']["information" = 'guidepost']["name"~""]();
);
// print results
out body;
>;
out skel qt;
Symbologie : point rose, 10m, sans bordure
Etiquette : name, regular, 35m, rose, tampon 3m, position cartographique
(Pour l’altitude)
[out:json];
// gather results
(
node["highway"='milestone']();
);
// print results
out body;
> ;
out skel qt;
Symbologie :
Etiquette :
CASE WHEN "ele" != '0.0' THEN round( to_real( "ele"),0) END
On peut mettre le même genre de symbole pour les bornes géodésiques
(filtrer sur une valeur de ref : A, B, C… par ex : “ref” LIKE ‘%- A’)
[out:json];
// gather results
(
node["man_made"='survey_point']();
);
// print results
out body;
> ;
out skel qt;
Requête
[out:json];
// gather results
(
node["tower:type"='communication']();
node["man_made"='antenna']();
);
// print results
out body;
> ;
out skel qt;
Point noir, 10m sans bordure
Etiqueter avec ‘Ant.’, en italique, noir, 30m, tampon 3m blanc
Requête sommets-cols-pts de vue
[out:json];
// gather results
(
node["natural"='peak']["name"~""]();
node["natural"='saddle']["name"~""]();
node["tourism"='viewpoint']();
);
// print results
out body;
> ;
out skel qt;
Symbologie : point noir et altitude pour les cols et sommets, on duplique pour avoir à la fois le label de nom et le label d’altitude
Pour les points de vue, une deux croix roses superposées dont l’une a une petite rotation
Si vous avez survécu jusqu’ici, ou que vous êtes un petit malin qui n’aime pas les tutos ou qui vient directement ici, voici le lien pour le projet QGIS avec les paramètres, il faut juste adapter les couches selon vos chemins d’accès, ou abandonner celles que vous ne voulez pas !