@@ -9,8 +9,23 @@ Nous allons utiliser un département de la [BDTopo](https://geoservices.ign.fr/b
9
9
10
10
## Configurer le projet
11
11
12
- * Commencer un nouveau projet et enregistrer le.
13
- * À côté du projet, ajouter le dossier provenant de la BDTopo, par exemple ` BDT_3-3_SHP_LAMB93_D0ZZ-EDYYYY-MM-DD ` .
12
+ * Commencer un nouveau projet et enregistrer le dans un dossier.
13
+ * À côté du projet ` qgs ` ou ` qgz ` , ajouter le dossier provenant de la BDTopo, le dossier ` BDT_3-3_SHP_LAMB93_D0ZZ-EDYYYY-MM-DD ` .
14
+
15
+ ``` bash
16
+ .
17
+ ├── BDT_3-3_SHP_LAMB93_D0ZZ-EDYYYY-MM-DD
18
+ │ ├── ADMINISTRATIF
19
+ │ ├── ADRESSES
20
+ │ ├── BATI
21
+ │ ├── HYDROGRAPHIE
22
+ │ ├── LIEUX_NOMMES
23
+ │ ├── OCCUPATION_DU_SOL
24
+ │ ├── SERVICES_ET_ACTIVITES
25
+ │ ├── TRANSPORT
26
+ │ └── ZONES_REGLEMENTEES
27
+ └── formation.qgs
28
+ ```
14
29
15
30
## Manipulation dans la console
16
31
@@ -67,7 +82,9 @@ class Personne{
67
82
}
68
83
```
69
84
70
- ### Pratique
85
+ ## Pratique
86
+
87
+ ### Documentation
71
88
72
89
* Dans QGIS, ` Plugins ` -> ` Console Python `
73
90
* QGIS nous donne accès au projet actuel via la classe ` QgsProject `
@@ -82,72 +99,99 @@ class Personne{
82
99
* Static Public Member Functions
83
100
* Nous verrons progressivement ces différentes sections.
84
101
* En haut de la documentation, il y a une explication sur le cas particulier de ` QgsProject.instance() ` .
85
- * Recherchons ` filename ` .
102
+ * Afin de trouver le chemin de notre projet, recherchons ` filepath ` , afin de trouver une méthode ` absoluteFilePath ` :
86
103
``` python
87
104
project = QgsProject.instance()
88
- project.fileName ()
105
+ project.absoluteFilePath ()
89
106
```
90
107
* Ajoutons un titre à notre projet. Dans l'interface graphique, cela se passe dans les propriétés de notre projet.
91
108
Il y a donc des chances que cela soit aussi dans la classe ** QgsProject**
92
109
* Recherchons donc ` title ` dans la page : ` setTitle ` dans la classe
93
- [ QgsProject] ( https ://qgis.org/api/classQgsProject .html) .
110
+ [ QgsProject] ( hhttps ://qgis.org/pyqgis/3.34/core/QgsProject .html) .
94
111
95
112
!!! warning
96
- Il est important de bien pouvoir lire la signature des ** méthodes** .
97
- La méthode ` title ` retourne une ** QString** et ** ne prend pas** de paramètre.
98
- La méthode ` setTitle ` retourne ** rien** , (** void** ) mais elle prend un paramètre, une ** QString** .
113
+ Il est important de bien pouvoir lire la signature des ** méthodes** :
114
+
115
+ * La méthode `title` retourne une **QString** (`str` en Python) et **ne prend pas** de paramètre.
116
+ * La méthode `setTitle` retourne **rien**, (`void`, en CPP et `None` en Python) mais elle prend un paramètre, une **str**.
99
117
100
118
* Nous souhaitons désormais changer la couleur de fond du projet.
101
119
* Recherchons ` background `
102
- * Nous allons devoir utiliser aussi la classe [ QColor] ( https://doc.qt.io/qt-5/qcolor.html )
120
+ * Nous allons devoir utiliser aussi la classe [ QColor CPP ] ( https://doc.qt.io/qt-5/qcolor.html ) , [ QColor PySide2 ] ( https://doc.qt.io/qtforpython-5/PySide2/QtGui/QColor.html ) .
103
121
104
122
??? "Afficher la solution"
105
123
```python
106
124
color = QColor("#00A2FF")
107
125
QgsProject.instance().setBackgroundColor(color)
108
126
```
109
127
128
+ ### Manipulation en console pour ajouter une couche Shapefile
129
+
110
130
* Objectif, ajouter une couche vecteur contenu dans un dossier fils :
111
- * Recherchons dans l'API le dossier racine du projet. * Indice* , en informatique, on appelle souvent cela le ` home ` .
112
- * Nous allons utiliser le module ` os.path ` pour manipuler les dossiers.
113
- * [ https://docs.python.org/3/library/os.path.html ] ( https://docs.python.org/3/library/os.path.html )
114
- * ` join ` , ` isfile ` , ` isdir `
131
+ * Exemple ` BDT_3-3_SHP_LAMB93_D0ZZ-EDYYYY-MM-DD/ADMINISTRATIF/COMMUNE.shp ` :
132
+ * Recherchons dans l'API de ` QgsProject ` le fichier actuel du projet, à l'aide ` filepath ` .
133
+ * L'utilisation de ` home ` est un peu différente, dans QGIS on peut définir un répertoire différent pour la racine des données.
134
+ * Nous allons utiliser l'objet ` Path ` pour manipuler les fichiers/dossiers.
135
+ * [ Objet Path] ( https://docs.python.org/3/library/pathlib.html )
115
136
137
+ !!! note
138
+ L'utilisation de l'objet ` Path ` est très habituelle, mais on rencontre aussi l'utilisation des fonctions du module
139
+ ` os.path ` comme ` os.path.join ` ... On rencontre son utilisation dans plusieurs tutoriels/solutions/forums.
140
+
141
+ #### Solution étape par étape
142
+
143
+ Pour récupérer le projet en cours
116
144
``` python
117
- from os.path import join, isfile, isdir
118
- racine = QgsProject.instance().homePath()
119
- join(racine, ' nexiste_pas ' )
120
- ' /home/etienne/Documents/3liz/formation/nexiste_pas '
121
- isfile(join(racine, ' nexiste_pas ' ))
122
- False
123
- isdir(join(racine, ' nexiste_pas ' ))
124
- False
125
- chemin = join(racine, ' BDT_3-3_SHP_LAMB93_D0ZZ-EDYYYY-MM-DD ' , ' ADMINISTRATIF ' )
126
- fichier_shape = join(chemin, ' COMMUNE.shp ' )
127
- isfile(fichier_shape )
128
- True
145
+ project = QgsProject.instance()
146
+ ```
147
+
148
+ Pour passer du chemin ` str ` de QGIS à un objet ` Path ` et directement appeler la propriété ` parent ` pour obtenir le dossier :
149
+ ``` python
150
+ racine = Path(project.absoluteFilePath()).parent
151
+ ```
152
+
153
+ On peut joindre notre BDTopo, en donnant plusieurs paramètres à ` joinpath ` :
154
+ ``` python
155
+ chemin = racine.joinpath( ' BDT_3-3_SHP_LAMB93_D0ZZ-EDYYYY-MM-DD ' , ' ADMINISTRATIF ' )
156
+ fichier_shape = chemin.joinpath( ' COMMUNE.shp ' )
129
157
```
130
158
131
- * Charger la couche vecteur à l'aide de ` iface ` [ QgisInterface] ( https://qgis.org/api/classQgisInterface.html )
132
- (et non pas ** Qgs** Interface !)
159
+ Il ne faut pas hésiter à vérifier au fur et à mesure avec des ` print ` :
133
160
134
161
``` python
135
- communes = iface.addVectorLayer(fichier_shape, ' communes' , ' ogr' )
136
- print (communes)
162
+ print (racine)
163
+ print (racine.is_dir())
164
+ print (racine.is_file())
165
+ print (fichier_shape.exists())
166
+ print (fichier_shape.is_file())
137
167
```
138
168
139
- * Charger la couche autrement (conseillé)
169
+ !!! tip
170
+ Tant que l'on est en console, on n'a pas besoin de faire ` print ` , la console le fait pour nous automatiquement.
171
+ On peut se contenter de ` fichier_shape.exists() ` .
172
+
173
+ Si tout est bon pour le chemin, charger la couche vecteur à l'aide de ` iface `
174
+ [ QgisInterface] ( https://qgis.org/api/classQgisInterface.html ) (et non pas ** Qgs** Interface), en utilisant la méthode ` addVectorLayer ` :
175
+
176
+ Attention, QGIS, étant écrit en C++, ne connait pas l'usage de ` Path ` , il faut repasser par une chaîne de caractère avec l'aide de ` str ` :
177
+
140
178
``` python
141
- communes = QgsVectorLayer(fichier_shape, ' communes' , ' ogr' )
142
- communes.isValid()
143
- QgsProject.instance().addMapLayer(communes)
179
+ communes = iface.addVectorLayer(str (fichier_shape), ' communes' , ' ogr' )
180
+ print (communes)
144
181
```
145
182
183
+ !!! tip "Charger la couche autrement à l'aide du constructeur ` QgsVectorLayer ` (conseillé)"
184
+ ```python
185
+ communes = QgsVectorLayer(str(fichier_shape), 'communes', 'ogr')
186
+ # communes.isValid()
187
+ QgsProject.instance().addMapLayer(communes)
188
+ ```
189
+
146
190
??? "Afficher la solution complète avec ` pathlib ` "
147
191
```python
148
192
from pathlib import Path
149
193
project = QgsProject.instance()
150
- racine = Path(project.homePath ())
194
+ racine = Path(project.absoluteFilePath ()).parent
151
195
chemin = racine.joinpath('BDT_3-3_SHP_LAMB93_D0ZZ-EDYYYY-MM-DD', 'ADMINISTRATIF')
152
196
fichier_shape = chemin.joinpath('COMMUNE.shp')
153
197
# fichier_shape.is_file()
@@ -156,7 +200,7 @@ QgsProject.instance().addMapLayer(communes)
156
200
QgsProject.instance().addMapLayer(communes)
157
201
```
158
202
159
- ??? "Afficher la solution complète avec ` os.path ` "
203
+ ??? "Afficher "l'ancienne" solution complète avec ` os.path ` "
160
204
```python
161
205
from os.path import join, isfile, isdir
162
206
@@ -170,38 +214,67 @@ QgsProject.instance().addMapLayer(communes)
170
214
QgsProject.instance().addMapLayer(communes)
171
215
```
172
216
173
- * Explorer l'objet ` communes ` qui est un ` QgsVectorLayer ` à l'aide de la documentation pour chercher sa
174
- géométrie, le nombre d'entités.
175
- [ API QgsVectorLayer C++] ( https://qgis.org/api/classQgsVectorLayer.html ) , [ API QgsVectorLayer Python] ( https://qgis.org/pyqgis/3.34/core/QgsVectorLayer.html )
176
- * Pour la géométrie, toujours utiliser l'énumération et non pas le chiffre
217
+ !!! success
218
+ Bien joué si vous avez votre couche des communes !
177
219
178
- ``` python
179
- communes.geometryType() == QgsWkbTypes.PolygonGeometry
180
- communes.geometryType() == QgsWkbTypes.PointGeometry
181
- ```
220
+ ### Découverte des méthodes sur notre objet ` communes `
221
+
222
+ Notre ** variable** ` communes ` est une instance de ` QgsVectorLayer ` .
223
+
224
+ [ API QgsVectorLayer C++] ( https://qgis.org/api/classQgsVectorLayer.html ) , [ API QgsVectorLayer Python] ( https://qgis.org/pyqgis/3.34/core/QgsVectorLayer.html )
225
+
226
+ À l'aide de la documentation, recherchons :
227
+
228
+ * le nombre d'entités, (indice : ` count ` , ` feature ` , ` featureCount ` )
229
+ * comment ouvrir et fermer une session d'édition (indice : ` editing ` , ` start ` et ne pas hésiter à lire la docstring)
230
+ * le type de géométrie, mot clé ` geometry ` , ` type ` , ` geometryType `
231
+
232
+ !!! info
233
+ L'API est en train de changer depuis QGIS 3.30 environ, concernant l'usage et l'affichage des énumérations.
234
+ Par exemple pour ` geometryType ` .
235
+
236
+ ```python
237
+ communes.geometryType() == QgsWkbTypes.PolygonGeometry
238
+ communes.geometryType() == QgsWkbTypes.PointGeometry
239
+ ```
240
+
241
+ Pour la géométrie, toujours utiliser l'énumération et non pas le chiffre, ce n'est pas compréhensible (QGIS < 3.30)
242
+
243
+ * Essayons désormais de chercher :
244
+ * son nom : ` name `
245
+ * les seuils de visibilité de la couche min et max (` scale ` , ` minimum ` , ` maximum ` )
182
246
183
- * Essayer d'ouvrir et de clore une session d'édition
184
- * Essayer désormais de chercher son nom, la projection ou encore les seuils de visibilité de la couche.
185
247
On ne les trouve pas dans la page ` QgsVectorLayer ` !
186
248
Pour cela, il faut faire référence à la notion d'héritage en Programmation Orientée Objet.
187
249
250
+ ### Héritage
251
+
252
+ Il faut bien regarder les diagrammes en haut de la documentation :
253
+
254
+ [ API QgsVectorLayer C++] ( https://qgis.org/api/classQgsVectorLayer.html ) , [ API QgsVectorLayer Python] ( https://qgis.org/pyqgis/3.34/core/QgsVectorLayer.html )
255
+
188
256
``` mermaid
189
257
classDiagram
190
258
class QgsMapLayer{
191
259
+name() str
260
+ +id() str
192
261
+crs() QgsCoordinateReferenceSystem
193
- +autreFonctions()
262
+ +maximumScale() double
263
+ +minimumScale() double
264
+ +autreFonctionsPourToutesLesCouches()
194
265
}
195
266
196
267
class QgsVectorLayer{
268
+ +featureCount() int
197
269
+startEditing() bool
198
270
+commitChanges() bool
199
271
+autreFonctionsPourUneCoucheVecteur()
200
272
}
201
273
202
274
class QgsRasterLayer{
203
- +int largeur
204
- +int hauteur
275
+ +bandCount() int
276
+ +largeur int
277
+ +hauteur int
205
278
+autreFonctionsPourUneCoucheRaster()
206
279
}
207
280
@@ -226,12 +299,20 @@ True
226
299
227
300
* Objectif, ne pas afficher la couche commune pour une échelle plus petite que le ` 1:2 000 000 ` .
228
301
302
+ !!! important
303
+ Un raccourci à savoir, dans la console :
304
+ ```python
305
+ iface.activeLayer()
306
+ ```
307
+
308
+ Cela retourne la couche `QgsMapLayer` active dans la légende !
309
+
229
310
## Code
230
311
231
312
Petit récapitulatif à tester pour voir si cela fonctionne correctement !
232
313
233
314
``` python
234
- from os.path import join
315
+ from pathlib import Path
235
316
dossier = ' BDT_3-3_SHP_LAMB93_D0ZZ-EDYYYY-MM-DD'
236
317
thematique = ' ADMINISTRATIF'
237
318
couche = ' COMMUNE'
@@ -251,15 +332,9 @@ layer.setMinimumScale(2000000)
251
332
layer.triggerRepaint()
252
333
```
253
334
254
- * Ajouter également la couche ` ARRONDISSEMENT ` et sélectionner là.
335
+ ## Transition vers le script, avec le parcourir des entités
255
336
256
- ## Parcourir les entités
257
-
258
- Un raccourci a savoir, dans la console :
259
- ``` python
260
- iface.activeLayer()
261
- ```
262
- Cela retourne la couche ` QgsMapLayer ` active dans la légende !
337
+ Ajouter également la couche ` ARRONDISSEMENT ` et sélectionner là.
263
338
264
339
On souhaite désormais itérer sur les polygones et les faire clignoter depuis la console.
265
340
Nous allons donc avoir besoin de la méthode ` getFeatures() ` qui fait partie de ` QgsVectorLayer ` .
0 commit comments