Exercice 6 : Automatisation d'actions répétitives ================================================= .. figure:: img/ex4_osm.png :width: 40% :align: center :figwidth: 98% Objectif -------- Cet exercice a pour objectif de montrer l'intérêt de la console Python pour automatiser des actions répétitives. Données ------- | • ``malta-latest.shp.zip`` : Données **OpenStreetMap** (transformées en Shapefile par GeoFabrik) pour Malte [#f1]_ ➜ `Téléchargement `_ | • ``StylesQgisOsm.zip`` : Une collection de styles QGIS pour données OSM [#f2]_ ➜ `Téléchargement `_ Problème -------- Lors de la décompression de l'archive ``malta-latest.shp.zip`` on peut constater que de nombreux fichiers sont extraits (16 couches). Seules 11 d'entres elles vont nous être utile. Pour appliquer les styles téléchargés, en l'absence de projet ``.qgs`` nous devrons effectuer les étapes suivantes. - charger les différentes couches nécessaires, - appliquer le style téléchargé (par exemple : double-click sur la couche ``gis_osm_water_a_free_1.shp`` pour ouvrir les propriétés de style, puis click sur ``Style .. > Charger style ..`` et sélection du style ayant le nom ``gis_osm_water_a_free_1.qml``), - ... en faisant attention à l'ordre des couches ! - ... et en répétant l'opération pour chacune des couches ! .. figure:: img/ex4_consignes_GH.png :align: center :figwidth: 98% :class: m12 *Exemple d'instructions trouvées sur internet (1)* .. figure:: img/ex4_consignes_GH2.png :align: center :figwidth: 98% :class: m12, w100 *Exemple d'instructions trouvées sur internet (2)* N'étant pas satisfait par les propriétés de transparence, nous verrons comment la changer sur toutes les couches qui contiennent des polygones. On va tout effectuer en Python pour voir le gain de temps que ça peut représenter. Procédure --------- - **Décompresser l'archive 'StylesQgisOsm.zip' dans un dossier de votre choix ('exercice4' par exemple)**. L'archive contenant les couches de données sera à décompresser en Python. - **Ouvrir QGIS**. - **Ouvrir la console Python (les fichiers seront extraits de l'archive et ajoutés à la carte en Python)**. - **Lire les rappels et les nouveaux éléments qui suivent :**. * Rappel concernant les dossiers en Python : :: # On accède à la majorité des fonctions relatives à la navigation # dans l'arborescence du système de fichier à part du module 'os' import os # Connaitre le dossier actuel de travail os.getcwd() # getcwd -> get current working directory # Se rendre dans le dossier approprié (attention à le modifier) os.chdir('exercice4') # Lister le contenu d'un dossier (ici le dossier 'Styles') os.listdir('Styles') # On utilise '.' pour le dossier actuel * On peut ainsi effectuer des opérations de filtrage lors du listage du dossier :: # Lister les fichiers d'un type particulier au sein d'un dossier # en utilisant une liste de compréhension names_svg = \ [name for name in os.listdir('/home/mthh/Images') if '.svg' in name] * Rappel sur les chaines de caractères :: # Remplacer/supprimer une sous-chaine de caractères : name = 'filename.svg' name.replace('.svg', '') # 'filename' name.replace('.svg', '.png') # 'filename.png' * Extraire une archive ``.zip`` dans le dossier courant depuis l'interpréteur Python : :: import zipfile zip_ref = zipfile.ZipFile('malta-latest-free.shp.zip', 'r') zip_ref.extractall('.') zip_ref.close() * Nouvelles notions en PyQgis concernant l'interface (``QgisInterface``) ou le projet (``QgsProject``) en cours : :: # Obtenir une référence au projet en cours : project = QgsProject.instance() # Enlever les couches existantes dans le projet actuel : project.clear() # Zoomer la carte sur une couche (ici sur la couche active) : layer = iface.activeLayer() canvas = iface.mapCanvas() canvas.setExtent(layer.extent()) canvas.refresh() # Changer l'étendue du canvas en utilisant # des coordonnées xmin, ymin, xmax, ymax : rect = QgsRectangle(QgsRectangle(1599940, 4284653, 1617650, 4284653)) iface.mapCanvas().setExtent(rect) iface.mapCanvas().refresh() # Régler la projection du projet sur "Web-Mercator" : project.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) iface.mapCanvas().refresh() * Nouvelles notions en PyQgis concernant les couches vecteurs (``QgsVectorLayer``) :: # Ajouter une couche : layer = iface.addVectorLayer('path/to/layer.shp', name, 'ogr') # Charger un style et le lui appliquer : layer.loadNamedStyle('path/to/style.qml') layer.triggerRepaint() # Si on ajoute plusieurs couches à la suite et que la mise en cache # n'est pas active on évitera d'appeler la méthode 'triggerRepaint' # sur chaque couche et on préférera rafraichir # l'ensemble du canvas une fois l'opération terminée : if iface.mapCanvas().isCachingEnabled(): layer.triggerRepaint() else: iface.mapCanvas().refresh() - **À vous de jouer !** En utilisant les éléments vu au-dessus, écrivez un script permettant de : * se rendre dans le dossier dans lequel vous avez décompresser la première archive, * y dézipper la seconde (``malta-latest.shp.zip``) dans le même dossier, * lister les styles disponibles (fichiers ``.qml`` dans le dossier ``Styles``), * utiliser leurs noms pour charger les fichiers *Shapefile* correspondants, * appliquer le style approprié à chacune des couches. - Et l'ordre des couches ? Voici l'ordre optimal pour ce projet *(la première couche de la liste est celle qui doit apparaître au-dessus de toutes les autres à l'affichage, c'est le même ordre que dans le panneau de gestion des couches de QGIS)*. Utiliser cette variable pour obtenir l'ordre souhaité dans votre projet ! **À vous de jouer !** *(La cheatsheet de ce TP, un moteur de recherche et/ou la documentation PyQgis seront utiles)* :: ordre = [ 'gis_osm_traffic_a_free_1', 'gis_osm_pofw_a_free_1', 'gis_osm_places_free_1', 'gis_osm_natural_free_1', 'gis_osm_roads_free_1', 'gis_osm_buildings_a_free_1', 'gis_osm_pois_a_free_1', 'gis_osm_water_a_free_1', 'gis_osm_waterways_free_1', 'gis_osm_landuse_a_free_1', 'gis_osm_natural_a_free_1', ] - Nous devons maintenant régler l'opacité de chacune des couches de type ``Polygon`` à 90%. **À vous de jouer !** *(La cheatsheet de ce TP, un moteur de recherche et/ou la documentation PyQgis seront utiles)* Sauvegarder votre projet ------------------------ - Il est nécessaire de récupérer une référence au projet actuel : :: project = QgsProject.instance() # Attention au chemin du fichier que vous sauvegardez ! project.write('osm_malta.qgs') Autres exemples d'utilisation du Python dans QGIS ------------------------------------------------- Qu'en est-il des actions qu'il pourrait être nécessaire d'effectuer à chaque ouverture d'un projet spécifique ? Il est possible de définir des fonctions Python qui seront appelées à l'ouverture, à l'enregistrement ou à la fermeture d'un projet. .. figure:: img/ex4_macros.png :width: 100% :align: center :figwidth: 98% - Nous souhaitons par exemple afficher un message d'avertissement à l'ouverture d'un projet : :: def openProject(): msg_bar = iface.messageBar() msg_bar.pushMessage( 'WARNING', # Le titre du message 'Le projet contient des données sensibles.', # Son contenu Qgis.WARNING, # Le type de message 15, # Le délai d'affichage ) .. raw:: html
.. rubric:: Footnotes .. [#f1] `© les contributeurs d’OpenStreetMap `_. Source : http://download.geofabrik.de/europe/malta.html. Données téléchargées le 01/03/2020. .. [#f2] Adaptés depuis les styles de `MrXsquared `_, maintenant maintenus `ici `_. Données téléchargées le 01/03/2020.