Cet exercice a pour objectif de montrer l’intérêt de la console Python pour automatiser des actions répétitives.
malta-latest.shp.zip
: Données OpenStreetMap (transformées en Shapefile par GeoFabrik) pour Malte [1] ➜ TéléchargementLors 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.
.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 !
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.
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 dossierStyles
),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)
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')
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.
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
)
Footnotes