Intersection
Maintenant vous savez :
- Exporter des cartes en série
- Intersecter des couches géographiques
Et bien ajoutez donc dans le sous-titre de vos cartes la commune où se trouve le sommet sélectionné.
À vous de jouer !
Vous allez devoir utiliser la couche des IRIS (disponible en pièce jointe de cet article) et l'intersecter avec vos sommets :
... import os import shutil ... monCheminDeBase = r'C:\\Users\\georg\\Downloads\\' ... project = QgsProject.instance() ... peaks = QgsVectorLayer(monCheminDeBase + 'peaks_selection/peaks_selection.shp', 'Sommets', 'ogr') iris = QgsVectorLayer(monCheminDeBase + 'iris/iris.shp', 'IRIS', 'ogr') ... QgsProject.instance().addMapLayer(peaks) QgsProject.instance().addMapLayer(iris) ... #Intersect peaks and IRIS peaks_iris_path = _peaks_iris + r'\\peaks_iris.shp' processing.run('qgis:intersection', { \ "INPUT": peaks, \ "OVERLAY": iris, \ "INPUT_FIELDS": ["OSM_ID", "NAME", "OTHER_TAGS"], \ "OVERLAY_FIELDS": ["CODE_IRIS", "NOM_COM"], \ "OVERLAY_FIELDS_PREFIX": "", \ "OUTPUT": peaks_iris_path}) # Remove layers project.removeMapLayer(peaks) project.removeMapLayer(iris) # Open the new intersected layer peaks_iris = QgsVectorLayer(peaks_iris_path, "Sommets", "ogr") project.addMapLayer(peaks_iris) # Register layer mes_sommets = project.mapLayersByName("Sommets")[0]
Puis appeler le nouveau champ disponible (NOM_COM) et modifier la chaîne formatée qui remplit le sous-titre :
...
commune = feat['NOM_COM']
...
subtitle.setText("Identifiant OSM : {} - Commune : {}".format((str(id_peak)), (commune)))
...Notez qu'au lieu de l'ancien %, nous utilisons ici une méthode de formatage plus moderne (.format())
Attention
Puisque nous créons un shape, et que nous l'ouvrons dans QGIS, si vous souhaitez exécuter votre code plusieurs fois, il faudra retirer votre couche de votre projet après votre boucle.
Idéalement il faudrait aussi créer/recréer (et donc supprimer) le shape avant la boucle, allons au chapitre Processing: Intersection de cet article pour modifier notre géo-traitement Python.
Fusion
Bien, nous voici avec 2 codes qui fonctionnent. Le 1er génère des cartes, le 2nd fait un intersection pour ramener des champs externes.
Le 1er est basé sur une boucle, tout ce qui s'exécute dans la boucle est renouvelé.
Le 2nd est un géo-traitement disons figé, quand nous avons récupéré notre champ sur la couche principale, nul besoin de ré-exécuter ce géo-traitement.
Maintenant l'objectif est de remplacer notre couche principale du 1er code par notre notre nouvelle couche créée par le 2ème code. Il nous faut donc fusionner ces 2 morceaux de code.
Partez d'une copie du 1er code et ajoutez les librairies manquantes.
Ajoutez le myPath juste en dessous du repExport, enlevez le instance() de QgsProject.instance().addMapLayer(iris) et remplacer son QgsProject par project avant de le coller sous hydro = QgsVectorLayer (car project vaut déjà QgsProject.instance() en haut du 1er code).
Juste après, collez le bloc def myIntersection() mais avec 2 modifications :
Il s'agit de créer une nouvelle fonction def genererCartes(), de remplacer myIntersection = project.mapLayersByName('Peaks')[0] par l'exécution de cette nouvelle fonction (...), puis de déplacer l'exécution de la 1ère fonction en fin de script (car elle contiendra maintenant l'exécution de la nouvelle fonction).
Top ! Maintenant nous pouvons utiliser le nouveau champ dans le sous-titre de la carte :
...
id_peak = feat['OSM_ID']
peak_name = str(feat['NAME'])
commune = str(feat['NOM_COM'])
expr = u"OSM_ID = '{}'".format(id_peak)
...
# Sous-titre
subtitle = QgsLayoutItemLabel(layout)
subtitle.setText(commune)
subtitle.setFont(QFont("Verdana", 17))
...
Pour être propre, on peut dédoublonner les chemins en double restant et utiliser la librairie Path systématiquement.