Dans cette série d’articles nous allons voir comment accéder aux données de type vecteur avec Python et QGis. Tout d’abord nous verrons comment charger les différents formats de données vecteur (shapefile, postgis et spatialite), puis comment accéder aux propriétés géométriques et attributaires, et enfin, quelques exemples de traitement spatial de ce type de données.Parmi le grand nombre de formats possibles pour les données vecteur, nous allons voir les deux principaux: shapefile et postgis.
Pour les exemples nous allons utiliser le plugin Script Runner de QGis, mais vous pouvez taper directement les lignes de code dans la console Python de QGis.
Charger un shapefile avec Python
Nous allons utiliser un fichier shapefile disponible sur Github pour cet exemple. Vous pouvez le télécharger ici:
Nous supposons dans la suite de l’article que vous décompressez ce fichier dans un répertoire c:/data.
Démarrez QGis et ouvrez Script Runner (ceci suppose que vous l’avez déjà installé et activé).
Cliquez sur l’outil Nouveau Script
et nommez votre script charger_vecteur.py
Dans l’onglet Source vous aurez le contenu du fichier créé.
Ouvrez le menu contextuel du script en cliquant droit sur le nom du script et sélectionnez Edit script in external editor
# to the run_script function. See the Help for
# complete information on how to create a script
# and use Script Runner.
« » » Your Description of the script goes here « » »
# Some commonly used imports
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
def run_script(iface):
layer = QgsVectorLayer(« /data/NYC_MUSEUMS_GEO.shp », « Musees de la ville de New York », « ogr »)
if not layer.isValid():
print « erreur de chargement de la couche %s » % layer.name()
QgsMapLayerRegistry.instance().addMapLayers([layer])
Vous pouvez faire du copier-coller de ce texte, mais ATTENTION!! : vous devrez corriger l’indentation des lignes pour que le script fonctionne. L’affichage html ignore les espaces en début de ligne, mais Python…NON!
Votre script doit apparaître dans Scriptrunner comme suit:
Je sais que Musées prend un accent, mais si vous voulez que le script marche il faut l’enlever. Sur la gestion des caractères accentués dans Python, cet article ne suffirait pas pour aborder ce casse-tête.
Si vous avez un message comme celui-ci:
c’est qu’il y a une erreur de syntaxe (ou un caractère accentué) dans votre script et que ScriptRunner n’arrive pas à interpréter votre code source.
Si vous exécutez le script à partir de scriptrunner vous aurez alors:
votre shapefile chargé dans QGis.
Voyons maintenant en détail ce que nous avons fait dans ce script:
layer = QgsVectorLayer(« /data/NYC_MUSEUMS_GEO.shp », « Musees de la ville de New York », « ogr »)
Cette ligne de code crée la couche (layer). QgsVectorLayer nécessite trois arguments:
- un chemin de fichier vers les données à charger : « /data/NYC_MUSEUMS_GEO.shp«
- le nom que nous souhaitons donner à cette couche dans la fenêtre de QGis: « Musees de la ville de New York«
- et le fournisseur de données (data provider) à utiliser : ici « ogr » de la librairie GDAL. OGR détermine le format des données à partir de l’extension du fichier et adapte le driver à utiliser en fonction. Voici la liste des formats gérés par ogr:
Ensuite, nous avons introduit les deux lignes de code:
if not layer.isValid():
print « erreur de chargement de la couche %s » % layer.name()
Si pour une raison ou pour une autre QgsVectorLayer échoue dans la création de la couche (erreur dans le nom de fichier, données corrompues, etc…) il ne renvoie pas de message d’erreur. Votre script continuera à s’exécuter et il plantera plus loin. Le message d’erreur que vous aurez a de fortes chances de ne rien avoir avec le véritable problème. Il convient donc de tester la validité de chaque couche créée et d’afficher l’erreur immédiatement.
En fin, dans la dernière ligne, nous ajoutons la couche vectorielle à l’QgsMapLayerRegistry, ce qui la rend disponible et visible sur la carte.
QgsMapLayerRegistry.instance().addMapLayers([layer])
Le registre conserve la trace de toutes les couches du projet. La raison pour laquelle QGIS fonctionne de cette façon est pour vous permettre de charger plusieurs couches, leur affecter un style , les filtrer, ainsi que plusieurs autres opérations, avant de les afficher sur la carte.
Coder le choix du fichier à charger
Dans notre code, le fichier à charger est écrit en dur, ce qui est rarement le cas dans la réalité des développements. Nous allons voir comment coder la recherche du fichier avec la fenêtre »ouvrir un fichier » .
Dans scriptrunner créez un nouvel script dialogue_fichier.py.
Rentrez le code suivant
# to the run_script function. See the Help for
# complete information on how to create a script
# and use Script Runner.
« » » Your Description of the script goes here « » »
# Some commonly used imports
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
def run_script(iface):
qfd = QFileDialog()
title = ‘Ouvrir un fichier’
path = « C:/ »
f = QFileDialog.getOpenFileName(qfd, title, path)
print f
Votre script doit ressembler à ça:
Quand vous l’exécutez, il affiche la fenêtre de recherche de fichiers. Quand vous cliquez sur « Ouvrir », le script vous affiche le nom complet de votre fichier.
La ligne from PyQt4.QtGui import * est indispensable pour pouvoir appeler le dialogue.
QFileDialog utilise trois paramètres:
- l’objet QFileDialog : qfd
- le titre de la fenêtre du dialogue: title
- le chemin de départ de la fenêtre : dans cet exemple C:/ (mais vous pouvez indiquer n’importe quel répertoire)
Le résultat (f) contient une chaîne de caractères avec le chemin et nom du fichier sélectionné. Si l’utilisateur ne clique pas sur Ouvrir mais sur Annuler, la chaîne est vide.
Nous pouvons maintenant modifier le premier script (chargement d’un shape) pour utiliser le dialogue à la place du codage en dur:
A l’exécution du script, la fenêtre de dialogue s’ouvre, vous choisissez le fichier à charger, puis le script le charge dans QGis.
Dans le prochain article nous verrons comment faire la même chose mais à partir d’une table Postgis ou d’une base de données Spatialite.
Comment importer des fichier shp vers une base de donnee creer en paython (les donnees ce sont de map)
Quel type de base de données?
Bonjour,
Je ne parviens pas utiliser QFileDialog: « NameError: name ‘QFileDialog’ is not defined ». Je suis sous QGIS3.8, ScritRunnerV3.0.5, MacOSX10.13.6. J’ai modifié les imports en :
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from qgis.core import *
from qgis.gui import *
.. mais QFileDialog ne fonctionne toujours pas.
Avez-vous une idée ?
Merci !
from PyQt5.QtWidgets import QFileDialog
Merci !
La variable f retourne un type ‘tuple’ désormais : TypeError: QgsVectorLayer(): argument 1 has unexpected type ‘tuple’. C’est vraiment dommage toutes ces modifications de comportement entre les versions d’objet. Votre tutoriel n’est pourtant pas si vieux !
J’ai donc modifié QgsVectorLayer(f, »Mon fichier », »ogr ») par QgsVectorLayer(f[0], »Mon fichier », »ogr ») et ça marche.