Vous êtes sur la page 1sur 59

Programmation- SIG

Python

Tarek SBOUI

Etapes de la programmation
• Écrire un algorithme
• Écrire un programme dans un langage (e.g. Java,
C++, python)
• Compiler le programme
– Traduire le programme dans un langage de bas
niveau (machine)
– [éventuellement optimisation]
– Produire un programme (code) exécutable
• Exécuter le programme
– Charger le programme en mémoire
– Exécuter le programme pour avoir le résultat

1
Termes
• Syntaxe d’un langage
– Comment formuler une instruction correcte
(grammaire)
• Sémantique
– Ce que l’instruction réalise
• Erreur
– de compilation: typiquement reliée à la syntaxe
– d’exécution: sémantique (souvent plus difficile à
détecter et corriger)

Python
• Open-source : son utilisation est gratuite et les fichiers
sources sont disponibles et modifiables;
• Facile à apprendre, à lire et à écrire ;
• Portable (fonctionne sous de plusieurs systèmes
d'exploitation) ;
• Doté d’une communauté active (plusieurs bibliothèques
disponibles);
• Orienté objet ;
• Typage dynamique

2
Python : Compilation et Executuon

La compilation et l’exécution sont effectuées par l'environnement de


développement de Python.

Il suffit d'entrer des commandes, de taper <Enter>,


et Python se charge de les compiler et de les exécuter.

Premiers pas : Calculer avec Python

>>> 5+3
>>> 2 - 9 # les espaces sont optionnels
>>> 7 + 3 * 4 # la hiérarchie des opérations
mathématiques
# est-elle respectée ?
>>> (7+3)*4
>>> 20 / 3

3
Noms de variables et mots réservés
Les noms de variables sont des noms qu’on choisit assez librement.

Quelques règles pour les noms de variables sous Python :

1. Un nom de variable est une séquence de lettres (a à z , A à Z) et de chiffres (0 à 9), qui


doit toujours commencer par une lettre.

2. Seules les lettres ordinaires sont autorisées. Les lettres accentuées, les cédilles, les
espaces, les caractères spéciaux tels que $, #, @, etc. sont interdits, à l'exception du
caractère _ (souligné).

3. La casse est significative (les caractères majuscules et minuscules sont distingués).

En plus de ces règles, il faut encore ajouter que vous ne pouvez pas utiliser
comme noms de variables les 29 « mots réservés » au langage ci-dessous :

and assert break class continue def


del elif else except exec finally
for from global if import in
is lambda not or pass print
raise return try while yield

4
Affectation
Nous savons désormais comment choisir judicieusement un nom de variable.
Voyons à présent comment nous pouvons en définir et affecter une valeur.

En Python comme dans de nombreux autres langages, l'opération d'affectation


est représentée par le signe égal :

>>> n = 7 # donner à n la valeur 7


Print (n)

>>> msg = "Quoi de neuf ?" # affecter la valeur "Quoi de neuf ?" à msg

>>> pi = 3.14159 # assigner sa valeur à la variable pi


Mémoire
@
n 7 en binaire
@
msg « quoi de neuf »
en binaire…
@
Pi 3,14159
en binaire
.
.
.

Afficher la valeur d’une variable


Pour afficher la valeur à l'écran, il existe deux possibilités. :

1. La première consiste à entrer au clavier le nom de la variable, puis


<Enter>.

>>> n
7
>>> msg
"Quoi de neuf ? "
>>> pi
3.14159

2. A l'intérieur d'un programme, vous utiliserez toujours l'instruction print :

>>> print (msg)


Quoi de neuf ?

5
Affectations multiples
Sous Python, on peut assigner une valeur à plusieurs variables simultanément.
Exemple :
>>> x = y = 7
>>> x
7
>>> y
7

On peut aussi effectuer des affectations parallèles à l'aide d'un seul opérateur :
>>> a, b = 4, 8.33
>>> a
4
>>> b
8.33

Dans cet exemple, les variables a et b prennent simultanément les nouvelles


valeurs 4 et 8,33.

Exercice
1. Décrivez le plus clairement possible ce qui se passe à chacune des trois
lignes de l'exemple ci-dessous :

>>> largeur = 20
>>> hauteur = 5 * 9.3
>>> largeur * hauteur
(?)

2. Assignez les valeurs respectives 3, 5, 7 à trois variables a, b, c.


Effectuez l'opération a - b/c.

6
Opérateurs et expressions
On manipule les valeurs et les variables qui les référencent, en les
combinant avec des opérateurs pour former des expressions.
Exemple :
a, b = 7.3, 12
y = 3*a + b/5

Exercice
Décrivez ce qui se passe à l’exécution des lignes suivantes :

>>> r , pi = 12, 3.14159


>>> s = pi * r**2
>>> s
>>> type(r), type(pi), type(s)
>>>

Quelle est, à votre avis, l'utilité de la fonction type() ?

Structures de contrôle

7
Structures de contrôle
Les structures de contrôle sont les groupes d'instructions
qui déterminent l'ordre dans lequel les actions sont
effectuées dans le programme.

En programmation moderne, il en existe seulement trois : la


séquence, la sélection que nous allons décrire dans ce
qui suit, et la répétition.

Séquence d’instructions :
Sauf mention explicite, les instructions d'un programme s'exécutent les unes
après les autres, dans l'ordre où elles ont été écrites à l'intérieur du programme.
Le « chemin » d’exécution est appelé un flux d'instructions, et les constructions
qui le modifient sont appelées des instructions de contrôle de flux.
Python exécute normalement les instructions de la première à la dernière, sauf
lorsqu'il rencontre une instruction conditionnelle comme l'instruction «if». Une
telle instruction va permettre au programme de suivre différents chemins
suivant les circonstances.

début d’exécution

Instruction de contrôle du flux

if
circonstance1 circonstance2

fin d’exécution

8
Sélection ou exécution conditionnelle
• C’est une technique permettant d'aiguiller le déroulement du programme dans
différentes directions, en fonction des circonstances rencontrées.
• Disposer d'instructions capables de tester une certaine condition et de modifier le
comportement du programme en conséquence.

L'instruction if.
>>> a = 150
>>> if (a > 100):
... "a dépasse la centaine"
...
Indentation obligatoire

En interactif :
Frappez encore une fois <Enter>. Le programme s'exécute, et vous obtenez :
a dépasse la centaine.
Recommencez le même exercice, mais avec a = 20 en guise de première ligne : cette fois Python
n'affiche plus rien du tout.

>>> a = 20
>>> if (a > 100):
"a dépasse la centaine"
else:
"a ne dépasse pas cent"

En interactif :
Frappez <Enter> encore une fois. Le programme s'exécute, et affiche cette fois :
a ne dépasse pas cent.

9
On peut faire mieux encore en utilisant aussi l'instruction elif (contraction
de « else if ») :

a=0
if a > 0 :
" a est positif "
elif a < 0 :
"a est négatif"
else:
"a est nul"

Exercice

Ecrire une fonction qui demande a l’utilisateur de saisir un


entier («Introduire un entier») jusqu’à ce que cet entier
soit entre 10 et 30.
Afficher l’entier.

10
>>> a = input('Entrez la première valeur : ')
>>> b = input('Entrez la deuxième valeur : ')
>>> if (a<b):
print (a)
else:
print (b)

>>> nom = input(« Introduire votre nom : ")

nom :

>>> note = int(input("Quelle est votre note ? : "))

>>> if note >= 10:


print("Vous avez la moyenne")
else:
print("Vous n'avez pas la moyenne")

11
Opérateurs de comparaison
La condition évaluée après l'instruction «if» peut contenir les opérateurs de
comparaison suivants :
x == y # x est égal à y (deux signes « égale » et non d'un seul)
x != y # x est différent de y
x>y # x est plus grand que y
x<y # x est plus petit que y
x >= y # x est plus grand que, ou égal à y
x <= y # x est plus petit que, ou égal à y

Exemple :
>>> a = 7
>>> if (a % 2 == 0):
"a est pair"
"parce que le reste de sa division par 2 est nul"
else:
"a est impair"

Répétitions en boucle
L'instruction while

L'une des tâches que les machines font le mieux est la répétition sans
erreur de tâches identiques !

Une des méthodes pour programmer ces tâches


répétitives est construite autour de l'instruction while.

1. Entrer les commandes ci-dessous

>>> a = 0
>>> while (a < 7): # (n'oubliez pas le double point !)
a = a + 1 # (n'oubliez pas l'indentation /alignement!)
a

2. Frappez sur <Enter>

3. Que se passe-t-il ?

12
>>> a = 0
>>> while (a < 7): # (n'oubliez pas le double point !)
... a = a + 1 # (n'oubliez pas l'indentation !)
...a

Commentaires
1. Dans notre exemple, si la condition a < 7 est encore vraie, le corps de la boucle est exécuté une
nouvelle fois et le bouclage se poursuit.
2. La variable évaluée dans la condition doit exister au préalable (Il faut qu'on lui ait déjà affecté au
moins une valeur)
3. Si la condition est fausse au départ, le corps de la boucle n'est jamais exécuté
4. Si la condition reste toujours vraie, alors le corps de la boucle est répété indéfiniment.

>>> n = 3
>>> while n < 5:
"hello !"

Répétitions en boucle
L'instruction for

entête
for <variable> in range(<nombre de repetitions>):
<instruction1>
< instruction2>
… corps
< instructionn>

>>> for x in range(3):


print('Hello!')
Compter n print('goodbye')
fois
Hello!
goodbye
Hello!
Instructions goodbye
Hello!
goodbye

13
>>> for x in range(0,3):
print('Hello!')
print (x)

x=0
While (x<3):
print('Hello!')
print (x)
x=x+1

>>> for i in range(0,10):


print (i)

>>> liste = [1,5,10,15,20,25]


>>> for i in liste:
if i > 15:
print ("On stoppe la boucle")
break
print (i)

>>> v = "Bonjour toi"

>>> for lettre in v:


print (lettre)

14
Exercice
Écrire un programme qui affiche les 3 premiers termes de la table
de multiplication par 7.

Les fonctions en
Python

15
Les fonctions en Python
Il arrivera souvent qu'une même séquence d'instructions doive être utilisée à
plusieurs reprises dans un programme, et on souhaitera bien évidemment ne
pas avoir à la reproduire systématiquement.

La syntaxe Python pour la définition d'une fonction est la suivante:

def nomDeLaFonction(liste de paramètres):


...
bloc d'instructions
...

Fonctions sans paramètre


>>> def table7():
n=1
while n <11 :
print (n * 7),
n = n+1

Pour utiliser la fonction que nous venons de définir, il suffit de l'appeler par
son nom. Ainsi :

>>> table7()

Provoque l'affichage de :

7 14 21 28 35 42 49 56 63 70

16
Fonctions avec paramètres
La fonction table() telle que définie ci-dessous utilise le paramètre base
pour calculer les dix premiers termes de la table de multiplication de base.

>>> def table(base):


n=1
while n <11 :
print (n, 'x', base, '=', n * base),
n = n +1

Pour tester cette nouvelle fonction, il nous suffit de l'appeler avec un


argument.
>>> table(13)
13 26 39 52 65 78 91 104 117 130
>>> table(9)
9 18 27 36 45 54 63 72 81 90

Exercice
Écrivez un programme qui contient une fonction carre qui calcule
le carré d’un nombre envoyé comme paramètre.

17
Une fonction peut avoir plusieurs paramètres.
Exemple : Ajouter des paramètres supplémentaires, dans une nouvelle version que nous
appellerons cette fois tableMulti() :

>>> def tableMulti(base, debut, fin):


print ('Fragment de la table de multiplication par', base, ':')
n = debut
while n <= fin :
print (n, 'x', base, '=', n * base)
n = n +1
Cette nouvelle fonction utilise donc trois paramètres : la base de la table comme dans
l'exemple précédent, l'indice du premier terme à afficher, et l'indice du dernier terme à
afficher.

Essayons cette fonction en entrant par exemple :


>>> tableMulti(8, 13, 17)
Fragment de la table de multiplication par 8 :
13 x 8 = 104
14 x 8 = 112
15 x 8 = 120
16 x 8 = 128
17 x 8 = 136

Exercice
Écrivez un programme qui contient une fonction addition qui
calcule la somme de deux nombres envoyés comme paramètre.

18
Appel/utilisation d’une fonction à
partir d’une autre
Les fonctions peuvent aussi s'utiliser dans d’autres fonctions.
Exemple : Ecrire une programme qui calcule le volume d'une sphère à
l'aide de la formule :

Ecrire le programme en quatre parties :


- Fonction cube() : calcule le cube du rayon r.
- Fonction volumeSphere(). Calcule le vlume de la sphere. A l'intérieur
de la fonction volumeSphere(), il y a un appel de la fonction cube().
- Une invitation a l’utilisateur pour introduire une valeur dans r
- Un appel de la fonction volumeSphere() (avec la valeur introduite par
l’utilisateur), et un affichage du résultat avec la commande print ().

>>> def cube(n):


return n**3
>>> def volumeSphere(r):
return 4 * 3.1416 * cube(r) / 3

>>> r = input('Entrez la valeur du rayon : ')


>>> intr = int(r)

>>> print ('Le volume de cette sphère vaut',


volumeSphere(intr))

19
Listes et dictionnaires

Listes
Une liste : une collection d'éléments séparés par des virgules, l'ensemble étant
enfermé dans des crochets.

Exemple :
>>> jour = ['lundi', 'mardi', 'mercredi', 100, 20.3]
>>> print (jour)
['lundi', 'mardi', 'mercredi', 100, 20.3]

On peut accéder à chacun d'entre eux individuellement si l'on connaît son


index dans la liste

Exemple :
>>> jour = ['lundi', 'mardi', 'mercredi', 100, 20.3]
>>> print (jour[2])
mercredi
>>> print (jour[4])
20.3

20
Remplacer certains éléments d'une liste par d'autres, comme ci-dessous :
>>> jour[3] = ‘jeudi'
>>> print (jour)

La fonction prédéfinie len(liste) renvoie le nombre d'éléments présents dans la


liste :
>>> len(jour)
5

La fonction prédéfinie del(elements de liste) permet de supprimer d'une liste


un élément quelconque (à partir de son index).
>>> del(jour[4])

La fonction prédéfinie append(element) permet d'ajouter un élément à une liste.


>>> jour.append(‘Jeudi')

Exercice
Analyser le script ci-dessous et commenter son fonctionnement :

>>>jour =
['dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi']

>>> a = 0
while a<7:
print (a , jour[a])
a=a+1

21
Listes imbriquées
Le premier élément dans une liste peut être n'importe quelle
expression, y compris une autre liste.

Voyez l'exemple suivant d'une matrice de 3 par 4, implémentée


sous la forme de 3 listes de 4 éléments :

>>> matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]

>>> [[row[i] for row in matrix] for i in range(4)]


[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

Exercice
Définissez une fonction listeMax(liste) qui renvoie
l'élément ayant la valeur la plus élevée dans la liste
transmise en argument.

Exemple d'utilisation :
serie = [5, 8, 2, 1, 9, 3, 6, 7]

listeMax(serie )
renvoie
9

22
Exercice
Définissez une fonction remplirListe(liste, n) qui
reçoit une liste vide et un entier n, et renvoie cette
liste remplie avec n entiers introduits par l’utilisateur.

Exemple d'utilisation :
>>> serie = []
>>> remplirListe(serie, 3)
renvoie
[3, 5, 7]

>>> def remplirlister(liste, n):


for i in range(0, n):
x = int(input('introduire une valeur : '))
liste.append(x)
return liste
>>> serie4 = []
>>> remplirlister(serie4, 4)
introduire une valeur : 3
introduire une valeur : 3
introduire une valeur : 9
[3, 3, 9]
>>>

23
Exercice
Définissez une fonction indiceMax(liste) qui
renvoie l’indice de l'élément ayant la valeur la plus
élevée dans la liste remplie par l’utilisateur.

Exemple d'utilisation :
serie = [5, 8, 2, 1, 9, 3, 6, 7]

indexMax(serie )
renvoie
4

Dictionnaire
• Un dictionnaire permet de stocker des
paires appelées éléments.
{ 'Cle1' : 'valeur1', 'Cle2' : 'valeur2'}
• Chaque paire d'entrées contient : une clé
et une valeur
• La clé doit être unique dans le
dictionnaire.

24
my_dict = {'nom':'Mariem', 'age': 26}
my_dict ['nom'] est 'Mariem' . my_dict
['age'] est 26
• voiture= {
“marque": "Ford",
"modele": "Mustang",
“annee": 1964
}

# mise a jour d'une valeur


my_dict['age'] = 27

# Ajout d'un element


my_dict['address'] = 'Tunis‘

# supprimer un element
del my_dict ['address']

25
my_dict.items() # renvoyer les elements
my_dict.keys() # renvoyer les cles
my_dict.values() # renvoyer les valeur

my_dict['name'] = my_dict.pop('nom') # mise a


jour d'une cle // dict[new_key] = dict.pop(old_key)

Exercise
• Créez trois dictionnaires contenant chacun
deux clés nom, annee. Puis créez un
dictionnaire qui contient les trois autres
dictionnaires.

26
Solution

• child1 = {"nom":"Sarra","annee":2004 }
child2 = {"nom":"Ali","annee":2002 }
child3 = {"nom":"Fatma","annee":2000 }
myfamily = {
"ch1" : child1,
"ch2" : child2,
"ch3" : child3
}

La programmation
Orientée Objet dans
Python

27
La programmation Orientée
Objet (POO) dans Python
• Il y plusieurs types de base en Python (int, float, str,
etc.).
• La notion de classe permet d’entendre la notion de «
type » en créant de nouvelles structures/types de
données (les classes).
• Une classe contient des attributs et des méthodes.
– Exemple, une classe voiture peut être caractérisée par
un attribut couleur, un attribut vitesse, etc. La classe
Voiture pourra également définir une méthode rouler().

POO - Définition d’une classe


Définition d’une classe en Python
• class Point:

• Création d’un objet (ou instance) de type Point


Point ()
• Mettons la référence à cet objet dans la variable p :
p = Point ()

28
POO - Définition des attributs
>>> class Point:
"c’est une classe"

>>> p = Point()
>>> p.x = 1
>>> p.y = 2
>>> print("p : x =", p.x, "y =", p.y)

• la variable p contient la reference


indiquant l’emplacement
memoire du nouvel objet (objet X 1
Point), qui contient lui-meme les p
deux attributs x et y. Ceux-ci Y 2
contiennent les references des
valeurs 1 et 2, memorisees
ailleurs.

29
POO - Définition des methodes
class Point:
def deplace(self, dx, dy):
self.x = self.x + dx
self.y = self.y + dy

>>> class Point:


def deplace(self, dx, dy):
self.x = self.x + dx
self.y = self.y + dy
>>> a = Point()
>>> a.x = 1
>>> a.y = 2
>>> print("a : x =", a.x, "y =", a.y)
>>> a.deplace(3, 5)
>>> print("a : x =", a.x, "y =", a.y)

30
POO- La notion de constructeur
>>> class Point:
def __init__(self):
self.x = 0
self.y = 0
>>> a = Point()
>>> print("a : x =", a.x, "y =", a.y)
>>> a.x = 1
>>> a.y = 2
>>> print("a : x =", a.x, "y =", a.y)

class Point:
def __init__(self, abs, ord):
self.x = abs
self.y = ord

a = Point(1, 2)
print("a : x =", a.x, "y =", a.y)

31
class Point:
def __init__(self, x, y):
self.x = x
self.y = y

a = Point(1, 2)
print("a : x =", a.x, "y =", a.y)

POO - exemple
>>> class Point:
def __init__(self, abs, ord):
self.x = abs
self.y = ord
def deplace(self, dx, dy):
self.x = self.x + dx
self.y = self.y + dy

32
>>> a = Point(1, 2)
>>> b = Point(3, 4)
>>> print("a : x =", a.x, "y =", a.y)
>>> print("b : x =", b.x, "y =", b.y)
>>> a.deplace(3, 5)
>>> b.deplace(-1, -2)
>>> print("a : x =", a.x, "y =", a.y)
>>> print("b : x =", b.x, "y =", b.y)

Methode statique
Une méthode statique peut être appelée sans créer d’objet/instance.
class Music:
@staticmethod
def play():
print("*playing music*")

def stop(self):
print("stop playing")

m= Music()
m. play()
Music.play()
Music.stop() # Erreur. On doit creer un objet
# -------------------------- solution :
obj = Music()
obj.stop()

33
Python et SIG

Python et SIG – pourquoi ?


• Etendre un SIG avec un programme
Python
• Effectuer des traitements répétitifs
• Exemples : Python et QGIS, Python et
ArcGIS

34
Bibliothèques Python-QGIS
• QGIS intègre des bibliothèques dans l’environnement
Python. Ce sont principalement des bibliothèques
géographiques (QT et QGIS).
• Les bibliothèques QT et QGIS sont deux bibliothèques bien
documentées qui peuvent être utilisées pour développer des
codes Python dans QGIS.
• Vous n'avez pas besoin de savoir le contenu de la
bibliothèque, mais plutôt de pouvoir l’utiliser dans votre code.
On utilise plutôt l’interface de la bibliothèque (API -
Application programming interface).
• Il s’agit de trouver l’API et parcourir ses modules.

• Qt
• QGIS étant construit à l'aide de Qt , un grand nombre de
classes QGIS héritent de la classe Qt de base (QObject).
Les classes de l'API PyQt sont disponibles à l'adresse
suivante : https://doc.qt.io/qt-5/classes.html. Vous trouvez
une liste de toutes les classes Qt.

35
• QGIS
• L’API QGI est décrite d’une façon similaire à celle de l’API
QT.
• La documentation de base de l’API QGIS est disponible à
l'adresse suivante: https://qgis.org/api .
• Vous pouvez obtenir la liste des classes de l'API QGIS à
l’adresse suivante: https://qgis.org/api/annotated.html

Interaction avec les objets QGIS


• Nous allons faire quelques exemples simples pour montrer
comment on peut utiliser les objets des API présentées ci-
dessus à partir de la console Python.
• Ouvrir ce fichier countries.shp dans QGIS avec la rubrique
‘Add Vector Layer’.
• Vous avez accès à l'interface QGIS à l'aide de l'objet iface.
– C'est un objet de la classe qgis.gui.QgisInterface (Ecrire la
commande : print (type(iface)).
– Parmi les méthodes de cette classe, on trouve activeLayer ( ) qui
retourne la couche sélectionnée dans QGIS.

36
layer = iface.activeLayer ()
print(type (layer))
• Résultat :
– < classe ' qgis ._ core.QgsVectorLayer ' >

• QgsVectorLayer. Voir la documentation de cette classe pour


vérifier les méthodes disponibles. Parmi ces méthodes, on
trouve featureCount () qui retourne le nombre d'entités
géographiques de la couche.

layer.featureCount ()
• Résultat :
– 177

• Nous pouvons explorer les données contenues dans la


couche vectorielle avec plus de détails. Par exemple, on peut
affiche les nom des payes.

layer = iface.activeLayer()
features = layer.getFeatures() # collection d’entites (objets de type
QgsFeature)
for feat in features: # nous itérons sur les entités des
couches
print (feat["name"] )

37
• Voici un exemple qui détermine la population totale du
monde en calculons les valeurs dans le champ pop_est (la
population de chaque pays).

layer = iface.activeLayer()
features = layer.getFeatures() # collection d’entites (objets de type
QgsFeature)
totalPopulation = 0
for feat in features: # nous itérons sur les entités des couches
pop = feat["pop_est"] # retrouver la valeur de la population en
utilisant l’entite sous forme de dictionnaire et le nom du
champ comme clé.
if pop > 0:
totalPopulation += pop
print (totalPopulation)

• Sachant qu'il existe un champ contenant le continent


auquel chaque pays appartient, nous pouvons calculer la
population de chaque continent.
layer = iface.activeLayer()
features = layer.getFeatures()
totalPopulation = {}
for feat in features:
pop = feat["pop_est"]
continent = feat["continent"]
if pop > 0:
if continent in totalPopulation:
totalPopulation[continent] += pop
else:
totalPopulation[continent] = pop
print (totalPopulation)

38
Visualiser et filtrer une couche
vectorielle
• Ouvrir une couche vectorielle
• Pour ouvrir une couche vectorielle dans QGIS, vous pouvez
utiliser la méthode addVectorLayer () de la classe
QgisInterface (qgis.gui.QgisInterface). Cette méthode permet
d’ajouter la couche dans le canevas.

• iface.addVectorLayer (path_to_layer, "Ports layer",


"ogr")

• Voici un exemple :

ch = os.path.join(QgsProject.instance().homePath(),
"data", "populated_places.shp")
# ou chemin absolu : Ch =“C:/document/…/ populated_places.shp ”

vlayer = iface.addVectorLayer(ch, "", "ogr")


if not vlayer:
print("Layer failed to load!")

• QGIS utilise l’API OGR pour lire et écrire les de données


vectorielles, y compris les fichiers .shp.

39
• Vous pouvez ouvrir plusieurs fichiers se trouvant dans le
même répertoire.

ch = os.path.join(QgsProject.instance().homePath(),
"data", "") # permet d’ouvrir tous les fichiers de ce
repertoire
vlayer = iface.addVectorLayer(ch, "", "ogr")
if not vlayer:
print("Layer failed to load!")

• On peut accéder aux données d'une couche sans pour autant


l’afficher dans le canevas. Pour cela, on peut utiliser la classe
QgsVectorLayer.
• L’exemple suivant afficher le nombre d’entités géographiques
de la couche.

ch = “c:/ …../countries.shp”
vlayer = QgsVectorLayer (ch, "", "ogr")
Nbre = vlayer.featureCount ()

40
• Afficher les attributs d’une couche
vectorielle

print (vlayer.fields().size ())


for field in vlayer.fields():
print(field.name ())

• Filtrer une couche vectorielle


• Le filtre consiste à définir une ou plusieurs contraintes sur une
couche pour qu'elle ne contienne que les entités qui
respectent ces contraintes.
• Par exemple, filtrer la couche vectoriel countries pour afficher
uniquement les entités dont la valeur de l’attribut NAME
commence par un A:
vlayer = QgsVectorLayer (ch, "", "ogr")
print ("Nombre total : ",vlayer.featureCount())
vlayer.setSubsetString("NAME LIKE 'A%'")
print ("Nombre filtre : ",vlayer.featureCount())
for feature in vlayer.getFeatures():
print(feature["NAME"])

41
• Maintenant, en utilisant iface.addVectorLayer au lieu de
QgsVectorLayer, affichez dans le canevas uniquement les
entités géographiques qui respectent la contrainte
précédente.

vlayer = iface.addVectorLayer(ch,
"","ogr").setSubsetString("NAME LIKE 'A%'")
# ou avec activeLayer().
vlayer = iface.activeLayer().setSubsetString("NAME LIKE
'A%'")

• Pour supprimer le filtre, nous définissons


une chaîne de sous-ensemble vide :

vlayer = iface.activeLayer().setSubsetString("")

42
Edition d’une couche vectorielle
• Créer un nouvel objet de la classe QgsVectorLayer. La
nouvelle couche se caractérise par "Point" comme géométrie,
"temp" comme nom de la couche, et "memory" comme
fournisseur de données (data provider).

vl = QgsVectorLayer("Point", "temp", "memory")


QgsProject.instance().addMapLayer(vl)

• Ajouter et supprimer des attributs

pr = vl.dataProvider()
chp1 = QgsField("name",QVariant.String)
chp2 = QgsField("age",QVariant.Int)
chp3 = QgsField("size",QVariant.Int)
pr.addAttributes([chp1, chp2, chp3])
vl.updateFields()

43
• Pour valider l’ajout de l’attribut à la couche, nous devons
appeler la méthode updateFields().
• Nous pouvons ajouter un attribut en utilisant la méthode
addAttribute () de la classe QgsVectorLayers.

vl.startEditing()
my_field_name = 'new field'
vl.addAttribute(QgsField(my_field_name, QVariant.String))
vl.updateFields()
for field in vl.fields():
print (field.name ())

• Nous pouvons maintenant affecter une valeur à l’attribut créé.


my_field_value = 'Hello world!'
for f in vl.getFeatures():
f[my_field_name] = my_field_value
vl.updateFeature(f)

# Affichage de donnees
for f in vl.getFeatures():
print("Feature:", f.id(), f.attributes(),
f.geometry().asPoint())

44
• Pour supprimer un attribut, on utilise la méthode
deleteAttributes.
vl.dataProvider().deleteAttributes([3])
vl.updateFields()

Enfin, pour terminer la session d’édition, on utilise la méthode


stopEditing.
iface.vectorLayerTools().stopEditing(vl)

• Enfin, pour terminer la session d’édition, on utilise la méthode


stopEditing.
iface.vectorLayerTools().stopEditing(vl)

• Ajouter et supprimer des entités géographiques


• Ajouter et supprimer des entités à l’aide des méthodes
addFeature et deleteFeatures.

f = QgsFeature()
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10,10)))
f.setAttributes(["Point 1.", 2, 0.3])
pr.addFeature(f)
vl.updateExtents()

45
• Affichons maintenant quelques informations sur la couche:

print("Nombre d'attributs :", len(pr.fields()))


print("Nombre d'entites :", pr.featureCount())
e = vl.extent()
print("Extent:", e.xMinimum(), e.yMinimum(), e.xMaximum(),
e.yMaximum())

for f in vl.getFeatures():
print("Feature:", f.id(), f.attributes(), f.geometry())
# attributes() : cherche les valeurs se basant sur les noms des
attributs

• Pour supprimer des entités, on utilise la méthodes


deleteFeatures .

pr.deleteFeatures([2]) # feature id
vl.updateExtents()

46
Manipulation de données
raster
• Afficher une couche raster
• Utiliser la méthode addRasterLayer () de la classe
QgisInterface : permet d’ajouter la couche raster dans le
canevas.

ch = os.path.join(QgsProject.instance().homePath(),
"data/ndvi", "farm-field2.tif")
rlayer = iface.addRasterLayer(ch, 'layer name')

• Nous avons ouvert la couche raster dans l’interface QGIS.


Simultanément, nous avons affecté cette couche à la variable
rlayer.

• Affichons le nombre de bandes de la


couche raster en utilisant la méthode
bandCount.
print (rlayer.bandCount())

47
Symbologie d’un raster
• Créer une palette de couleurs, et l’utiliser pour définir une
symbologie de la couche raster. Pour cela, nous
commençons par déterminer les valeurs minimum et
maximum d’une bande de cette couche (exemple : bande
numéro 1).
stats = rlayer.dataProvider().bandStatistics(1,
QgsRasterBandStats.All)
# Ensuite, nous aurons les valeurs minimum et maximum.
min = stats.minimumValue
max = stats.maximumValue

• Ensuite :

• 1 Créer une palette de couleurs


• a) Créer une palette de couleurs vide
• Pour créer une palette de couleurs vide, nous devons définir
le type de palette de couleurs à utiliser :
Interpolated, Discrete, ou Exact.
• Interpolated : étend les couleurs sur un intervalle de valeurs
• Discrete : donne la même couleur à toutes les valeurs dans
un intervalle donné
• Exact : donne à chaque valeur de pixel unique une couleur
unique

48
• Les données qu’on utilise représentent
des altitudes, qui sont des données
continues, donc on utilise une palette
interpolée.
palette = QgsColorRampShader()
palette.setColorRampType(QgsColorRampShader.Interpolat
ed)

• b) Définir les couleurs pour l’objet QgsColorRampShader


• Définir un modèle de couleurs. Pour notre exemple, on crée
une palette de couleur très simple qui interpole du vert (pour
la valeur min) au rouge (pour la valeur max).

lst = [QgsColorRampShader.ColorRampItem(min,
QColor(0,255,0)), QgsColorRampShader.ColorRampItem(max,
QColor(255,0,0))]
# Constructs a color with the RGB value r, g, b. here green for min and red for max
palette.setColorRampItemList(lst)

49
• c) Attribuer la palette de couleur à un QgsRasterShader
• Nous attribuons la palette de couleur à un objet de la classe
QgsRasterShader afin qu’il puisse être utilisé pour symboliser
une couche raster.

shader = QgsRasterShader()
shader.setRasterShaderFunction(palette)

• 2 Appliquer la symbologie au raster


• Enfin, nous devons appliquer la symbologie créée à la couche
raster. Tout d'abord, nous allons créer un rendu à l'aide de
l’objet ‘shader’ de la classe QgsRasterShader. Nous
assignerons ensuite le rendu à notre couche raster.

renderer =
QgsSingleBandPseudoColorRenderer(rlayer.dataProvider(),
1, shader)
rlayer.setRenderer(renderer)

50
Interroger une couche raster
• Déterminer les coordonnées d’un point qui se situe quelque
part dans la zone couverte par une couche raster.
• Les coordonnées devront être dans les mêmes unités que la
projection utilisée pour afficher la couche.
• Interroger la couche raster en utilisant deux méthodes
différentes sample () et identifier ().

• 1- Valeur de la requête avec sample ()


• La méthode sample () prend deux paramètres : un point (avec
des coordonnées x, y) et la bande raster à interroger. Nous
passons le point en tant qu’un objet de la classe QgsPointXY,
et interroger la valeur de la bande 1.

val, res = rlayer.dataProvider().sample(QgsPointXY(714093,


3803770), 1)
print(val, res)

51
• 2- Valeur de la requête avec identifier ()
• La méthode identifier () de layer.dataProvider () est similaire
au pointeur d’identification utilisé dans l'interface QGIS. La
méthode identifier () retourne un dictionnaire contenant le
numéro de bande et la valeur de toutes les bandes de la
couche raster. Nous spécifions un point de type QgsPointXY
et le format du résultat (IdentifyFormatValue)
ident = rlayer.dataProvider().identify(QgsPointXY(714093,
3803770), QgsRaster.IdentifyFormatValue)
print(ident.isValid())
print (ident.results())

Calcul sur les données raster


• On peut effectuer plusieurs calculs sur les données raster en
utilisant l’environnement Python. Dans cette section on va voir
quelques exemples.
• Calculer l’indice NDVI avec Python
• L’indice de végétation par différence normalisé (NDVI en
anglais) est un indice qui indique le stade de croissance
végétale à un moment donné.
• L’indice NDVI est calculé en se basant sur le contraste de
deux bandes d’une couche rasters, généralement le rouge et
le proche infrarouge.
• Le code python suivant permet de calculer l’indice NDVI.

52
rasterName4 = "bandd4"
rasterName5 = "bandd5"
chrep = QgsProject.instance().homePath()+ "data/raster/ndvi"
rband4 = QgsRasterLayer(chrep + "/TunB4.tif", rasterName4)
rband5 = QgsRasterLayer(chrep + "/TunB5.tif", rasterName5)

ir = QgsRasterCalculatorEntry() # QgsRasterCalculatorEntry représente


une entrée (bande) dans un calcul raster
r = QgsRasterCalculatorEntry()

r.raster = rband4
ir.raster = rband5 # Couche raster associée à cette entrée

ir.ref = "band4@1" # Nom de l'entrée, selon la nomination QGIS


r.ref = rasterName4 + "@1“

exp = "("+ir.ref+" - "+r.ref+") / ("+ir.ref+ " + "+r.ref+")"

references = (ir.ref, r.ref, ir.ref, r.ref)


exp = "(%s - %s) / (%s + %s)" % references

output = chrep + "/nddv.tif"


e = rband4.extent() # ou rband5, meme extent
w = rband4.width()
h = rband4.height()
entrees = [ir,r]

ndvi = QgsRasterCalculator(exp, output, "GTiff", e, w, h, entrees) #


QgsRasterCalculator effectue des calculs sur des couches raster.
Parametres : formulaString, outputFile, outputFormat, outputExtent,
nOutputColumns, nOutputRows, rasterEntries.
ndvi.processCalculation() # Effectue le calcul et crée un nouveau raster

# affecter la nouvelle couche a l’objet lyr, et l’ajouter à notre projet


QGIS
lyr = QgsRasterLayer(output, "NDVI")
QgsProject.instance().addMapLayer(lyr)

53
Manipulation de plusieurs
sources de données raster
• Un avantage important de la programmation Python
dans QGIS est de pouvoir traiter plusieurs couches
automatiquement, et en même temps.
• Le code suivant permet de convertir les valeurs
d’élévation du mètre en kilomètre, et ce, pour plusieurs
fichiers contenant des données raster.

import os
from os import listdir
from os.path import isfile, join
chrep = os.path.join(QgsProject.instance().homePath(),
"data/raster/elev/",)
myfiles = [f for f in listdir(chrep) if isfile(join(chrep, f))]
for myf in myfiles:
filename, file_extension = os.path.splitext(myf)
rasterName = filename
raster = QgsRasterLayer(chrep+myf, rasterName)
r = QgsRasterCalculatorEntry()
r.raster = raster
r.bandNumber = 1
r.ref = rasterName + "@1"
print ("ref : ",r.ref)
print ("raster", r.raster.name())
references = (r.ref)

54
exp = "%s / 1000" % references
output = chrep+"mil"+myf
print ("output : ", output)
e = raster.extent()
w = raster.width()
h = raster.height()
entrees = [r]

elev = QgsRasterCalculator(exp, output, "GTiff", e, w, h, entrees)


elev.processCalculation()
lyr = QgsRasterLayer(output, ("mil"+filename))
QgsProject.instance().addMapLayer(lyr)

Plugins
• Les plugins sont un excellent moyen d’étendre les
fonctionnalités de QGIS. On peut écrire des plugins en
utilisant Python.
• On peut utiliser un modèle existant : ex. le Minimal QGIS
plugin template. Ce modèle contient le minimum nécessaire
pour créer un plugin dans QGIS.
• Il se compose de deux fichiers: un fichier texte contenant des
métadonnées, et un fichier contenant un code Python.

55
• Comment l'utiliser?
• Créer un nouveau répertoire "minimal" : Settings -> User profiles
-> Open Active Profile Folder. Vous trouverez python/plugins.
• Copiez metadata.txt et __init__.py dans ce répertoire.
• Démarrer QGIS et activer le plugin (menu Plugins> Manager
and Install Plugins ...)
• Maintenant, vous devriez voir un "Bonjour" bouton dans la barre
d’outils "Plugins" (assurez-vous qu’il est activé dans le menu
View> Toolbars > Plugins Toolbar).

• Contenu des fichiers du plugin :

metadata.txt :
• Ce fichier est utilisé pour décrire le plugin. QGIS l'utilisera pour
gérer les versions des plugins et afficher les informations dans le
gestionnaire de plugins.
• Le fichier contient les lignes suivantes:

[general]
name=minplugin
description= Plugin minim
version=1.0
qgisMinimumVersion=3.0
author=Tarek Sbouiemail=enseignant.tarek@gmail.com

56
__init__.py :
• Ce fichier ne contient une seule méthode qui sert à informer QGIS de la
classe de plugins qu'il doit charger pour instancier le plugin. Ce fichier
contient :
classFactory ( )
• C’est une méthode obligatoire dans le fichier __init__.py. Il devrait retourner
un objet de la classe qui représente le plugin (MinPlugin dans notre cas).
def classFactory(iface):
return MinPlugin (iface)

plugin.py :
• Ce fichier contient la classe du plugin MinPlugin. Toutes les classes de
plugins doivent contenir les quatre méthodes suivantes.
__ init __ (self, iface )
• Cette méthode devrait contenir tout le code nécessaire pour initialiser le
plugin, à l'exception des éléments de l'interface graphique. Les éléments de
l'interface graphique sont initialisés dans la méthode initGui ( ).
• Dans notre exemple, l’objet QgisInterface (iface) est passé aux plugins lors
de son instanciation (à noter que pouvons utiliser cet objet dans d'autres
méthodes de la classe).

def __init__(self, iface):


self.iface = iface

57
initGui(self)
• C'est ici que le contenu de l'interface graphique doit être initialisé. Dans
notre exemple, nous ajoutons le menu du plugin à la barre de menus de
QGIS.

def initGui(self):
self.action = QAction(u'Bonjour', self.iface.mainWindow())
self.action.triggered.connect(self.run)
self.iface.addToolBarIcon(self.action)

unload (self)
• Les opérations de nettoyage doivent être effectuées ici. Ils seront exécutés
lorsque le plugin est désactivé à l'aide du gestionnaire de plugins ou à la
fermeture de QGIS). Dans notre cas, nous supprimons le menu du plugin
qui a été ajouté dans la méthode initGui() et l'action associée.
def unload(self):
self.iface.removeToolBarIcon(self.action)
del self.action

• Cette méthode contient l’opération à exécuter suite à l’action de l’utilisateur.


Dans notre cas, on affiche un message.

def run(self): QMessageBox.information(None, u'Minimal


plugin', u'A creer une operation plus complexe')

58
Installer un plugin
• Une fois que vous avez écrit le code de votre plugin, vous
devez l'installer dans votre application QGIS. Dans QGIS 3,
les plugins se trouvent dans le répertoire python/plugins.
Vous pouvez trouver ce répertoire en choisissant le menu :
Settings -> User profiles -> Open Active Profile Folder.
• Vous pouvez copier l'exemple de plugin. Après le démarrage
de QGIS, le plugin devrait être disponible pour être
exécuté. Si ce n'est pas le cas, vous devrez l'activer dans
QGIS Plugin Manager.

Références

• G. Swinnen. Apprendre à programmer avec Python. O’Reilly, 2005.


• Github, qgis python course [En ligne]. https://github.com/volaya/qgis-python-course
(consulté le 15 mai 2019)
• Github, minimal plugin [En ligne]. https://github.com/wonder-sk/qgis-minimal-plugin
(consulté le 15 mai 2019)
• Opensource options [En ligne]. https://opensourceoptions.com/python (consulté le 20
mai 2019)
• Documentation QGIS [En ligne]. https://qgis-
docs.readthedocs.io/en/latest/docs/index.html (consulté le 10 juin)

59

Vous aimerez peut-être aussi