Skip to content

Commit f2b427b

Browse files
committed
MAJ chapitre fonctions et scripts
1 parent 019803d commit f2b427b

File tree

2 files changed

+355
-278
lines changed

2 files changed

+355
-278
lines changed

docs/console.md

+133-58
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,23 @@ Nous allons utiliser un département de la [BDTopo](https://geoservices.ign.fr/b
99

1010
## Configurer le projet
1111

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+
```
1429

1530
## Manipulation dans la console
1631

@@ -67,7 +82,9 @@ class Personne{
6782
}
6883
```
6984

70-
### Pratique
85+
## Pratique
86+
87+
### Documentation
7188

7289
* Dans QGIS, `Plugins` -> `Console Python`
7390
* QGIS nous donne accès au projet actuel via la classe `QgsProject`
@@ -82,72 +99,99 @@ class Personne{
8299
* Static Public Member Functions
83100
* Nous verrons progressivement ces différentes sections.
84101
* 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`:
86103
```python
87104
project = QgsProject.instance()
88-
project.fileName()
105+
project.absoluteFilePath()
89106
```
90107
* Ajoutons un titre à notre projet. Dans l'interface graphique, cela se passe dans les propriétés de notre projet.
91108
Il y a donc des chances que cela soit aussi dans la classe **QgsProject**
92109
* 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).
94111

95112
!!! 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**.
99117

100118
* Nous souhaitons désormais changer la couleur de fond du projet.
101119
* 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).
103121

104122
??? "Afficher la solution"
105123
```python
106124
color = QColor("#00A2FF")
107125
QgsProject.instance().setBackgroundColor(color)
108126
```
109127

128+
### Manipulation en console pour ajouter une couche Shapefile
129+
110130
* 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)
115136

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
116144
```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')
129157
```
130158

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` :
133160

134161
```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())
137167
```
138168

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+
140178
```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)
144181
```
145182

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+
146190
??? "Afficher la solution complète avec `pathlib`"
147191
```python
148192
from pathlib import Path
149193
project = QgsProject.instance()
150-
racine = Path(project.homePath())
194+
racine = Path(project.absoluteFilePath()).parent
151195
chemin = racine.joinpath('BDT_3-3_SHP_LAMB93_D0ZZ-EDYYYY-MM-DD', 'ADMINISTRATIF')
152196
fichier_shape = chemin.joinpath('COMMUNE.shp')
153197
# fichier_shape.is_file()
@@ -156,7 +200,7 @@ QgsProject.instance().addMapLayer(communes)
156200
QgsProject.instance().addMapLayer(communes)
157201
```
158202

159-
??? "Afficher la solution complète avec `os.path`"
203+
??? "Afficher "l'ancienne" solution complète avec `os.path`"
160204
```python
161205
from os.path import join, isfile, isdir
162206

@@ -170,38 +214,67 @@ QgsProject.instance().addMapLayer(communes)
170214
QgsProject.instance().addMapLayer(communes)
171215
```
172216

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 !
177219

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`)
182246

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.
185247
On ne les trouve pas dans la page `QgsVectorLayer` !
186248
Pour cela, il faut faire référence à la notion d'héritage en Programmation Orientée Objet.
187249

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+
188256
```mermaid
189257
classDiagram
190258
class QgsMapLayer{
191259
+name() str
260+
+id() str
192261
+crs() QgsCoordinateReferenceSystem
193-
+autreFonctions()
262+
+maximumScale() double
263+
+minimumScale() double
264+
+autreFonctionsPourToutesLesCouches()
194265
}
195266
196267
class QgsVectorLayer{
268+
+featureCount() int
197269
+startEditing() bool
198270
+commitChanges() bool
199271
+autreFonctionsPourUneCoucheVecteur()
200272
}
201273
202274
class QgsRasterLayer{
203-
+int largeur
204-
+int hauteur
275+
+bandCount() int
276+
+largeur int
277+
+hauteur int
205278
+autreFonctionsPourUneCoucheRaster()
206279
}
207280
@@ -226,12 +299,20 @@ True
226299

227300
* Objectif, ne pas afficher la couche commune pour une échelle plus petite que le `1:2 000 000`.
228301

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+
229310
## Code
230311

231312
Petit récapitulatif à tester pour voir si cela fonctionne correctement !
232313

233314
```python
234-
from os.path import join
315+
from pathlib import Path
235316
dossier = 'BDT_3-3_SHP_LAMB93_D0ZZ-EDYYYY-MM-DD'
236317
thematique = 'ADMINISTRATIF'
237318
couche = 'COMMUNE'
@@ -251,15 +332,9 @@ layer.setMinimumScale(2000000)
251332
layer.triggerRepaint()
252333
```
253334

254-
* Ajouter également la couche `ARRONDISSEMENT` et sélectionner là.
335+
## Transition vers le script, avec le parcourir des entités
255336

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à.
263338

264339
On souhaite désormais itérer sur les polygones et les faire clignoter depuis la console.
265340
Nous allons donc avoir besoin de la méthode `getFeatures()` qui fait partie de `QgsVectorLayer`.

0 commit comments

Comments
 (0)