Vous êtes sur la page 1sur 80

5 - SQL - Bases de

donnes

QGIS Perfectionnement

version 2.1 A

6 fvrier 2015

Table des
matires

Objectifs

I - Notions SQL

A. Introduction.................................................................................................7
B. La slection..................................................................................................9
C. Les oprateurs de comparaison et les oprateurs logiques................................10
D. Les types de donnes et les fonctions............................................................12
E. Tri et agrgation..........................................................................................15
F. Extensions spatiales.....................................................................................17
G. Prsentation de DBManager.........................................................................20
H. Exercice 6 : slections SQL avec DBManager..................................................26
I. Les jointures attributaires.............................................................................28
J. Les jointures spatiales..................................................................................31
K. Exercice 7 : Requtes et fonctions spatiales....................................................32

II - Spatialite

35

A. Grer les bases et les tables.........................................................................35


B. L'assistant de requte SQL de QspatiaLite......................................................38
C. Raliser des jointures avec Qspatialite...........................................................44
D. Indexation et optimisation............................................................................45
E. Exercice 8 : requtes SQL avec QspatiaLite....................................................49

III - PostGIS

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

53

Notions SQL
Notions SQL

A. PostGIS : Importer des donnes...................................................................53


B. Utiliser PostGIS depuis QGIS........................................................................65
C. Utilisation de DBManager avec PostGIS..........................................................68
D. Indexation spatiale sous PostGIS..................................................................72
E. Exercice 9 : PostGIS....................................................................................73

Solution des exercices

75

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

Objectifs

Ce module va vous permettre de :


Connatre les rudiments du SQL
Savoir utiliser et grer des tables dans une base Spatialite
Savoir utiliser et grer des tables dans une base Postgis
Savoir ouvrir une table avec une liaison ODBC

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

I -

Notions SQL

Introduction

La slection

Les oprateurs de comparaison et les oprateurs logiques

10

Les types de donnes et les fonctions

12

Tri et agrgation

15

Extensions spatiales

17

Prsentation de DBManager

20

Exercice 6 : slections SQL avec DBManager

26

Les jointures attributaires

28

Les jointures spatiales

31

Exercice 7 : Requtes et fonctions spatiales

32

Objectifs
Dcouvrir le langage de requte SQL pour rpondre des
besoins d'analyse spatiale dans QGIS.

A. Introduction
Introduction aux SGBDR
Un Systme de Gestion de Base de Donnes (SGBD) est un logiciel permettant de
stocker de la donne dans une base de donnes en garantissant la qualit, la
prennit et la confidentialit des informations. La complexit des oprations de
traitement des donnes ne ncessite pas d'tre totalement connue par les
utilisateurs. Ce module ne vise donc pas former des spcialistes des SGBD. Les
SGBD1 que nous utiliserons sont bass sur un modle de donnes relationnel
(SGBDR). Dans ce modle, la base de donnes est compose d'un ensemble de
tables et chaque ligne d'une table est un enregistrement.

1 - http://fr.wikipedia.org/wiki/Syst%C3%A8me_de_gestion_de_base_de_donn%C3%A9es#Typologie

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

Notions SQL
Notions SQL

Extrait du modle relationnel du standard COVADIS de l'olien terrestre (formalisme


UML)
Au sein du Ministre de l'Ecologie la COVADIS2 (Commission de Validation des
Donnes pour l'Information Spatialise) a pour mission de produire des modles de
donnes (gostandards) partags par tous.
La conception et la gestion d'une base de donnes relationnelle sont un domaine en
soi qui est hors du primtre de cette formation. Les personnes dsireuses d'en
savoir plus sont invites suivre le stage 'Concevoir et structurer des bases de
donnes gographiques3' (Ministre).
Dans cette formation nous n'exploiterons que des modles trs simples. Nous
considrerons le SGBD Spatialite qui est install avec QGIS et qui est un SGBD trs
lger. Il peut tre qualifi de 'bureautique' dans le sens o il est plutt orient vers
un usage personnel sur son poste de travail. Nous traiterons galement du SGBD
PostGIS qui est beaucoup plus complet et avanc, mais qui doit plutt tre
envisag, pour ce qui est du partage de donnes, comme un composant du systme
d'information d'un service avec un administrateur ddi. Une utilisation personnelle
de ce SGBD est cependant envisageable pour certains besoins d'analyse ou de
production de donnes, c'est dans ce cas galement un trs bon outil.
Pour suivre le module sur PostGIS il est ncessaire d'avoir accs une base installe.
L'organisateur de la formation pourra le cas chant fournir les paramtres de
connexion une base.

2 - http://www.developpement-durable.gouv.fr/La-standardisation-des-donnees-par.html
3 - http://geoinfo.metier.i2/presentation-de-la-formation-a349.html

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

Notions SQL

SQL
SQL (Structured Query Language qui signifie langage de requtes structur) est un
langage destin la manipulation des bases de donnes au sein d'un SGBD.
SQL est compos de trois sous-ensembles :
Le Langage de Dfinition de Donnes (LDD) qui permet de crer et supprimer
des objets dans la base de donnes et que nous n'aborderons pas
explicitement dans le cadre de cette formation.
Le Langage de Contrle de Donnes (LCD) pour grer les droits sur les objets
et que nous n'aborderons pas non plus.
Le Langage de Manipulation de Donnes (LMD) pour la recherche, l'insertion,
la mise jour et la suppression de donnes et qui sera le seul abord
partiellement.
A noter que le SQL est utilis galement dans QGIS dans les requtes de filtrages sur
les tables.

B. La slection
Syntaxe gnrale
La requte de slection est la base de la recherche de donnes en SQL.
Une requte SQL respecte une syntaxe de type :
SELECT (liste des attributs) FROM (liste des tables) WHERE (Conditions)
La partie SELECT indique le sous-ensemble des attributs (les colonnes) qui doivent
apparatre dans la rponse.
La partie FROM dcrit les relations (les tables) qui sont utilises dans la requte. Les
attributs de la clause SELECT doivent appartenir aux tables listes dans la clause
FROM.
La partie WHERE exprime les conditions, elle est optionnelle.
Nous verrons d'autres options plus tard...
ex 1: SELECT * FROM commune WHERE population > 1000
slectionne les enregistrements de la table COMMUNE dont la population est
suprieure 1000 avec tous les attributs (c'est le sens de *) de la table COMMUNE
ex 2 : SELECT nom_comm, insee_comm, population FROM commune
slectionne tous les enregistrements de la table COMMUNE (cf pas de conditions) et
renvoi une table avec les attributs NOM_COM, INSEE_COMM et POPULATION.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

Notions SQL
Notions SQL

rsultats de la slection sur la table COMMUNE


Il est possible de donner un nom d'alias aux attributs en sortie avec le mot clef AS.
Ex 3 : SELECT nom_comm AS COMMUNE , insee_comm AS INSEE, population FROM
commune
on peut galement crire directement (on omet le AS) :
SELECT nom_comm COMMUNE , insee_comm INSEE, population FROM commune

Utilisation des alias de nom de colonne

C. Les oprateurs de comparaison et les oprateurs


logiques
Les oprateurs de comparaison
La clause WHERE est dfinie par une condition qui s'exprime l'aide d'oprateurs de
comparaison et d'oprateurs logiques.
Les oprateurs de comparaison sont :
A=B
A <> B (diffrent)
A<B
A>B
A <= B (infrieur ou gal)
A >= B (suprieur ou gal)
A BETWEEN B AND C (compris entre B et C)

10

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

10

Notions SQL

A IN (B1, B2,...) liste de valeurs :


ex : SELECT nom_comm, insee_comm, population FROM commune WHERE statut
IN('Commune simple', 'Chef-lieu de canton')
A LIKE 'chane'
permet d'insrer des caractres jokers dans l'opration de comparaison, % dsignant
0 plusieurs caractres quelconques , _ dsignant un seul caractre.
Ex : SELECT * FROM commune WHERE nom_comm LIKE 'A%' slectionne toutes les
communes dont le nom commence par A
SELECT * FROM commune WHERE nom_comm LIKE '%SAINT%' slectionne toutes les
communes dont le nom contient la chane 'SAINT'

Attention

: Sensibilit la casse

SQL est sensible la casse (majuscule / minuscule) pour les constantes, ainsi
NOM_COMM LIKE '%A' est diffrent de NOM_COMM LIKE '%a'.
Les mots clefs et les noms de colonnes sont insensibles la casse. On peut ainsi
crire SeLecT * fRom ma_TabLE. Une convention couramment utilise est d'crire les
mots clefs en majuscule et les noms en minuscules exemple : SELECT * FROM
ma_table.
Dans PostgreSQL mettre les noms de colonnes entre guillemets double permet de les
rendre sensibles la casse, "ma_table" est diffrent de "MA_TABLE". Il est conseill
de donner des noms de champs en minuscules dans PostgreSQL.
Les chanes de caractres des constantes sont en gnral entoures de guillemets
simples (ex : 'SAINT %') qui est le caractre chr(39), cependant si la chane
constante contient elle-mme une apostrophe il faut la doubler (ex : SELECT * FROM
commune WHERE nom_com LIKE 'l'' %' slectionne toutes les communes dont le
nom commence par l'

Remarque : Nombre ou chane de caractres


Les oprandes (A ou B) peuvent tre des nombres ou des chanes de caractres.
Ainsi NOM_COMMUNE <> 'PARIS' est correct et slectionne toutes les communes
dont le nom n'est pas Paris

Fondamental: NULL
Une valeur par dfaut peut-tre attribue une colonne lors de la dfinition d'une
table. Si aucune valeur par dfaut n'est attribue la valeur par dfaut de la colonne
est positionne NULL (0 ou espace n'est pas quivalent NULL...c'est une
diffrence importante par rapport MapInfo).
Il est possible d'utiliser l'oprateur logique IS pour tester si un champ est ou non nul.
Exemple : SELECT * FROM commune WHERE nom_comm IS NULL rcupre les
enregistrement qui n'ont pas de nom de commune.
SELECT * FROM commune WHERE nom_comm IS NOT NULL rcupre ceux qui ont
effectivement un nom (non positionn NULL).

Les oprateurs logiques


OR : pour sparer deux conditions dont au moins une doit tre vrifie.
Ex : SELECT * FROM commune WHERE statut = 'Commune simple' OR STATUT =
'Chef-lieu de canton'
Cette requte slectionne les communes pour lesquelles le statut est commune

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

11

Notions SQL
Notions SQL

simple ou chef-lieu de canton.


Bien penser dans l'exemple ci-dessus que le OR lie deux conditions. Une
condition contient ncessairement un des oprateurs de comparaison. Ainsi
on ne peut crire
SELECT * FROM commune WHERE statut = 'Commune simple' OR 'Chef-lieu de
canton'
AND : pour sparer deux conditions qui doivent tre vrifies simultanment.
Ex : S E L E C T * FROM commune WHERE statut = 'Sous-prfecture'
population > 10000

AND

seules les sous-prfectures de plus de 10 000 habitants sont slectionnes.


NOT : permet d'inverser une condition.
Ex : SELECT * from commune WHERE NOT (statut = 'Commune simple' OR
statut = 'Chef-lieu de canton')
slectionne les communes qui ne sont ni commune simple, ni chef lieu de canton.

D. Les types de donnes et les fonctions


Les types de donnes
Les principaux types de donnes en SQL sont :
CHARACTER (ou CHAR) : valeur alpha de longueur fixe.
CHARACTER VARYING (ou VARCHAR) : valeur alpha de longueur maximale fixe.
TEXT : suite longue de caractres (sans limite de taille).
NUMERIC (ou DECIMAL ou DEC) : dcimal
INTEGER (ou INT) : entier long
REAL : rel virgule flottante dont la reprsentation est binaire.
BOOLEAN (ou LOGICAL) : vrai/faux
DATE : date du calendrier grgorien.

Remarque : Le typage des donnes


SQLite propose une gestion spcifique et simplifie4 des types de donnes.
PostgreSQL propose une gestion beaucoup plus complte 5. Certains de ses types sont
spcifiques (non normaliss).
Les extensions spatiales de ces SGBDR ajoutent des types gomtriques (points,
lignes,...) que nous verrons plus tard

Les fonctions
SQL propose des fonctions dont on trouvera une description par exemple ici6
Examinons en quelques unes...
Fonctions de transtypage:
cast (expr as type) : Est la fonction standard SQL qui permet de convertir un type en
un autre.
4 - http://fr.wikipedia.org/wiki/SQLite#Types_de_donn.C3.A9es
5 - http://docs.postgresql.fr/9.3/datatype.html
6 - http://sqlpro.developpez.com/cours/sqlaz/fonctions/

12

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

12

Notions SQL

Exemple :
Si x_commune est un champ de type INTEGER dans la table commune
SELECT x_commune FROM commune LIMIT 1
renvoi 478935
(noter l'utilisation de la clause LIMIT qui permet d'indiquer le nombre maximum
d'enregistrements en retour. Il est galement possible d'utiliser la clause OFFSET
pour dcaler le nombre de lignes obtenir
ex : SELECT * FROM commune LIMIT 10 OFFSET 5 (pour renvoyer les
enregistrements de 6 15)
SELECT cast(x_commune as real) FROM commune LIMIT 1 renvoie 478935.0
SELECT cast(x_commune as text) FROM commune LIMIT 1 renvoie '478935' c'est
dire une chane de caractre, puisque entre ''.
PotsgreSQL propose une notation compacte sous la forme expr::type
exemple : SELECT x_commune :: real FROM commune
Une opration de transtypage est parfois ncessaire pour obtenir le rsultat souhait,
en particulier avec SpatiaLite. Prenons l'exemple de calcul d'un indicateur (ratio de
deux entiers) avec SpatiaLite.
Exemple : SELECT (population/superficie) AS densite FROM commune LIMIT
10
renvoie :

non utilisation du cast avec spatialite


Ce rsultat est inattendu !
Il est d au fait que dans SpatiaLite, le rsultat de la division de deux entiers est un
entier.
Pour obtenir un rsultat satisfaisant il faut au minimum convertir le numrateur ou le
dnominateur en flottant:
SELECT cast(population as float)/superficie AS densite FROM commune
LIMIT 10
On remarquera nouveau l'utilisation de LIMIT qui permet d'indiquer le nombre
maximum d'enregistrements retourns... c'est une clause trs utile pour la mise au
point de requtes sur des grosses tables ou pour rcuprer juste le premier
enregistrement aprs un tri.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

13

Notions SQL
Notions SQL

Le rsultat devient bien celui attendu :

Utilisation de la fonction cast


Fonctions de chanes de caractres :
LENGTH : renvoie la longueur d'une chane
exemple : SELECT length(nom_comm) FROM commune
CHR : renvoie le caractre correspondant au code ASCII (exemple CHR(184) renvoi
)
|| : concatne deux chanes (on obtient ce symbole en tapant ALTGr 6)
exemple : SELECT nom_comm|| ' '||insee_comm FROM commune LIMIT 1
renvoie 'SAINT-JEAN-DE-LA-MOTTE 72291'
SUBSTR : extraction d'une sous-chane de caractres substr(chane, position ,
longueur)
Exemple : SELECT * FROM troncon_hydrographique WHERE substr(ID_BDCARTO,
1, 3) = '239'
slectionne tout les tronons dont l'identifiant commence par '239'
UPPER : convertit en majuscule
LOWER : convertit en minuscule
exemple : SELECT lower(nom_comm) FROM commune renvoie les noms de communes
en minuscules.
Fonctions mathmatiques et numriques :
SQL dispose des fonctions mathmatiques classiques... notons en particulier :
POW : pour lever une puissance quelconque ex : POW(champ, 2) pour lever au
carr.
SQRT : pour obtenir la racine carre.
ROUND : qui permet d'arrondir un rsultat
exemple : SELECT round(cast(population AS float)/superfice,2) AS densite
FROM commune

14

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

14

Notions SQL

renvoie :

fonction round

Remarque
sous PostGIS on crira SELECT (round (population/superficie) :: numeric, 2)
AS densite FROM commune
le :: tant une forme compacte sous PostGIS pour raliser le cast. Le format
numerique (numeric) tant obligatoire pour la fonction round sous PostGIS.

Complment : Sites de rfrences pour les fonctions SQL dans


spatialite et PostGIS
Les principales fonctions disponibles sous SpatiaLite sont dcrites ici7
Les fonctions de PostgreSQL 9.2 sont dcrites ici8
Nous vous conseillons vivement de parcourir une premire fois ces sites et d'y
revenir rgulirement par la suite...

E. Tri et agrgation
Tri
Il est possible de classer le rsultat d'une requte en ajoutant le mot clef ORDER BY
suivi d'une liste de champs.
Exemple : SELECT * FROM commune ORDER BY nom_comm
pour classer le rsultat par nom de commune.
Un tri dcroissant peut-tre obtenu en ajoutant DESC.
Exemple : SELECT * FROM commune ORDER BY nom_comm DESC
SELECT nom_comm, round(cast(population as float)/superficie,2)
densite FROM commune ORDER BY densite

AS

retourne la densit de population par ordre croissant de densit.

7 - http://www.sqlite.org/lang_corefunc.html
8 - http://docs.postgresql.fr/9.2/functions.html

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

15

Notions SQL
Notions SQL

Densite de population trie

Remarque
Sous PostGIS on crira
SELECT nom_comm, round(population/superficie :: numeric,2) AS densite
FROM commune ORDER BY densite)

Agrgations
Une agrgation est une opration qui permet de regrouper les enregistrements de la
table en sortie selon des critres et d'obtenir des informations statistiques sur ces
regroupements. Il faut utiliser l'expression GROUP BY suivi du critre de
regroupement.
Prenons un exemple partir de la table COMMUNE. Nous souhaitons obtenir la
population totale par dpartement.
SELECT Nom_comm, nom_dept, population FROM commune

16

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

16

Notions SQL

nous donne :

Population des communes


la requte :
SELECT nom_dept, sum(population) AS population_dept FROM commune GROUP
BY nom_dept
renvoie :

Agrgation par dpartement


La clause GROUP BY fonctionne de concert avec les fonctions d'agrgation (ici
sum()). Les principales fonctions d'agrgation sont :
count() : renvoie le nombre d'enregistrements
sum() : renvoie la somme

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

17

Notions SQL
Notions SQL

max() : maximum
min() : minimum
avg() : moyenne

Complment : La clause HAVING


Il se peut que l'on souhaite mettre un critre de slection sur une colonne calcule
par l'opration d'agrgation. Dans l'exemple a serait le cas si on souhaite n'afficher
que les dpartements de plus de 20000 habitants.
On pourrait tre tent d'crire une requte de la forme :
SELECT nom_dept, sum(population) AS population_dept FROM commune WHERE
population_dept > 20000 GROUP BY nom_dept
a ne marche pas car la clause where est excute avant l'agrgation.
La clause HAVING permet d'indiquer au SQL d'effectuer une nouvelle slection la
fin du calcul sur les rsultats du regroupement.
On crira donc:
SELECT nom_dept, sum(population) AS population_dept FROM commune GROUP
BY nom_dept HAVING population_dept > 20000
Sous PostgreSQL il faut rpter la fonction d'agrgation dans la clause having
SELECT nom_dept, sum(population) AS population_dept FROM commune GROUP
BY nom_dept HAVING sum(population) > 20000
nb : On n'utilisera la clause HAVING que dans le cas ou la slection porte sur une
colonne d'agrgation calcule, pour une slection sur une colonne existante dans la
table de dpart on utilisera une condition dans la clause WHERE.

F. Extensions spatiales
Sqlite et PostgreSQL proposent des extensions spatiales (respectivement Spatialite et
PostGIS) permettant d'ajouter le stockage et la manipulation d'objets spatiaux en
ajoutant des types de donnes gomtriques et des fonctions spatiales.

Complment : Les spcifications


La spcification SFSQL (Simple Features for SQL9) dfinit les types et les fonctions
qui doivent tre disponibles dans une base de donnes spatiale selon l'OGC. La
spcification SQL/MM10 tend le modle. On pourra galement se rfrer au
document Matrices de Clementini et prdicats spatiaux de l'OGC disponible sur
le site du Ministre de l'Ecologie sur l'information gographique (ici11)

Les types de donnes gomtriques


Dans cette formation nous ne considrerons que les objets en dimension 2 et plus
prcisment : les points, les lignes, et les polygones.
La gomtrie est stocke dans un format binaire 'WKB' (ou ventuellement texte
'WKT', exemple : POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10)) dans une colonne
de table qui est souvent nomme geometry ou the_geom). Le systme utilise au
9 - http://www.opengeospatial.org/standards/sfs
10 - http://www.fer.unizg.hr/_download/repository/SQLMM_Spatial_The_Standard_to_Manage_Spatial_Data_in_Relational_Database_Systems.pdf
11 - http://www.geoinformations.developpement-durable.gouv.fr/qgis-documents-et-fiches-a1853.html

18

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

18

Notions SQL

moins deux autres tables internes supplmentaires qu'il maintient jour :


geometry_columns et spatial_ref_sys (PostGIS 1.5)

Tables internes OGC


SRID est l'identifiant du systme de projection. Par exemple 2154 pour le
RGF93/Lambert93

Conse il: Quelques informations utiles pour les


Administrateurs de Donnes Localises (ADL)...
En cas de problme la fonction Populate_Geometry_columns() dtecte les colonnes
qui contiennent de la gomtrie et met jour la table interne geometry_columns.
A partir de PostGIS 2.0 la table Geometry_columns devient une vue12
On pourra consulter le document QGIS et les bases de donnes spatiales cette
adresse13 (sur internet).
Pour les ADL des Ministres, ces informations sont galement disponibles ici14
(intranet).

Les fonctions spatiales


Il existe plusieurs catgories de fonctions spatiales, comme par exemple celles qui
permettent de passer du format WKT au WKB ou inversement. Voici quelques
fonctions de dpart :
ST_SRID() : retourne le code du systme de projection de l'objet
ST_IsValid() : vrifie la gomtrie des objets (pas d'erreur topologique)... Ceci
concerne essentiellement les polygones voir par exemple15

Remarque
Vrification de gomtrie sous PostGIS
PostGIS ajoute d'autres fonctions de vrification de la gomtrie
ST_IsValidReason() : retourne un texte indiquant les raisons d'une ventuelle
invalidit.
12
13
14
15

http://postgis.net/docs/manual-2.0/using_postgis_dbmanagement.html#geometry_columns
http://www.geoinformations.developpement-durable.gouv.fr/qgis-et-les-bases-de-donnees-a2257.html
http://geoinfo.metier.i2/qgis-et-les-bases-de-donnees-a2257.html
http://www.postgis.fr/chrome/site/docs/workshop-foss4g/doc/validity.html

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

19

Notions SQL
Notions SQL

ST_IsValidDetail() : retourne en plus un pointeur vers la partie non valide ( partir


de PostGIS 2.0).
ST_MakeValid() : Tente de corriger les gomtries invalides (PostGIS 2.0)
ST_X() : retourne la coordonne X d'un point (et uniquement d'un point).
ST_Y() : coordonne Y d'un point
ST_Centroid() : retourne le centroide d'un polygone
Exemple : ST_X(ST_Centroid(Geometry)) retourne la coordonne X du centroide
d'un polygone.
SELECT nom_comm, ST_X(ST_centroid(Geometry)) AS X,
ST_Y(ST_centroid(Geometry)) AS Y FROM commune

Utilisation St_Centroid
ST_Area() retourne la surface d'un objet
ST_Buffer() retourne un nouvel objet tampon construit autour d'un objet
ST_Length() : retourne la longueur d'un objet de type ligne ou multi-ligne
(attention ne pas utiliser length() qui retourne la longueur du champ, spatialite
autorise aussi Glength()).
ST_Perimeter() : retourne le primtre d'un objet polygone ou multi-polygone

Attention

: Prefixe ST_

Il est recommand de prfixer les commande par ST_ (Spatial Temporal) pour tre
conforme au standard SQL/MM. PostGIS a entam une migration vers ce standard et
mme si certaines fonctions anciennes sont toujours disponibles sans ce prfixe, elles
deviendront prochainement obsoltes. Donc autant prendre les bonnes habitudes !

20

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

20

Notions SQL

G. Prsentation de DBManager
Mise en oeuvre
Nous allons mettre en pratique SQL dans les SGBD SpatiaLite, puis PostGIS.
Pour chacun de ces SGBD il existe de nombreux 'clients' permettant d'crire et
d'excuter les requtes SQL. Depuis QGIS nous allons utiliser le plugin DBManager
qui s'interface aussi bien avec SpatiaLite que PostGIS. C'est le plugin qui est le plus
port par la communaut QGIS.
Nous utiliserons galement QspatiaLite qui est un plugin spcifique pour SpatiaLite
qui propose un diteur SQL avanc (ergonomie proche de celle de MapInfo). Pour
ceux qui en dispose, il est possible d'utiliser PgAdmin III16 qui est le client le plus
populaire de PostGIS et qui dispose de fonctionnalits intressantes comme un
assistant l'criture de requtes SQL.
Pour mettre en uvre le plugin DB Manager...
Vrifiez qu'il est bien install ou sinon installez le.

Gestionnaire d'extension de QGIS


Le plugin est alors disponible dans le menu 'bases de donnes' de QGIS.

Menu Base de donnes


Il est possible de crer une nouvelle base de donnes spatialite partir de QGIS en
exportant une premire couche (clic droit, enregistrer sous) puis de choisir le format
spatialite (et pas sqlite).
Pour se connecter la premire fois une base de donnes existante (spatialite ou
postgis) dans DBManager, il est ncessaire de le faire par l'intermdiaire de QGIS.
16 - http://www.pgadmin.org/?lang=fr_FR

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

21

Notions SQL
Notions SQL

tablir la connexion avec la base de donnes QGIS_perf_sandbox_V2.sqlite


(QGIS_perf_sandbox pour les versions de QGIS antrieure la V2.0) en utilisant le
bouton 'ajouter une couche spatialite'

et dsigner le fichier

QGIS_perf_sandbox_V2.sqlite fourni dans le jeux de donnes (rpertoire Divers).


Puis connecter... vous devez voir apparatre cette bote de dialogue :

Connexion sandbox
En lanant DB Manager vous devez maintenant pouvoir vous connecter cette base.
Nb : Une base de donnes de type PostGIS peut tre protge par mot de passe,
dans ce cas il faut le saisir dans la fentre qui apparat pour cela.

22

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

22

Notions SQL

DbManager
L'onglet info fournit les informations sur les tables

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

23

Notions SQL
Notions SQL

DBManager Informations
On peut par exemple lire que la table COMMUNE contient 19 enregistrements (rows),
qu'il y a une colonne de gomtrie contenant des objets 'MULTIPOLYGONS', que la
projection est Lambert 93 et qu'il n'y a pas d'index spatial ('No spatial index
defined...nous verrons ce que cela signifie concrtement plus tard).
L'onglet 'table' fournit une vision des donnes de la table et l'onglet preview une
visualisation de la gomtrie.
Le bouton 'SQL window' ouvre une nouvelle bote de dialogue dans laquelle nous
allons pouvoir excuter des ordres SQL.

24

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

24

Notions SQL

Exemple : slectionner tous les objets de la table commune :

Slection avec DBManager

Complment : Glisser / lcher


DBmanager autorise le glisser/lacher (drag'n'drop), partir du navigateur de QGIS et
inversement, ou entre bases l'intrieur de DBManager, ou mme partir de toute
source valide depuis le navigateur de fichier de windows, c'est une autre faon que
celles que nous verrons plus loin d'importer des donnes dans SpatiaLite ou PostGIS.
Le rsultat d'une requte SQL peut-tre charg comme une nouvelle couche dans
QGIS en cochant la case 'Charger en tant que nouvelle couche'.
Il faut prciser la colonne avec des valeurs entires et uniques. Ce doit tre un
champ de type INTEGER, on choisira si on ne dispose de rien d'autres le champ
PKUID, mais par exemple pour la table COMMUNE se pourrait tre ID_BDCARTO. La
colonne gomtrique est en gnrale la colonne de nom Geometry.

Attention
Problmes connus avec Spatialite
QGis utilise gdal/ogr pour lire et crire dans les bases spatialite.
Avec gdal 1.10.1 (voir le menu a propos de QGIS pour vrifier la version) il y a des
lenteurs en cration des bases spatialite17. C'est corrig partir de gdal 1.10.2 (QGIS
2.6).

17 - http://trac.osgeo.org/gdal/ticket/5270

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

25

Notions SQL
Notions SQL

H. Exercice 6 : slections SQL avec DBManager


Raliser ses premires requtes SQL avec DBManager sous QGIS
en utilisant les tables de 'QGIS_perf_sandbox.sqlite' avec DBManager raliser les
requtes suivantes :
Question 1
[Solution n1 p 73]

Q1 : slectionner tous les IRIS (table IRIS_extrait72) de la commune de LA FLECHE


(colonne Nom_Com).
nb : On fera attention l'criture FLECHE (LA) dans la table COMMUNE, avec deux
espaces entre FLECHE et (LA).
Indice :
Utiliser la table iris_extrait72 et mettre une condition aprs la clause WHERE
permettant d'indiquer qu'on se limite la commune de la Flche.
Question 2
[Solution n2 p 73]

Q2 : slectionner les communes du dpartement de la Sarthe de plus de 1500


habitants en affichant un tableau avec les noms de communes et leur population.
Indice :
Utiliser la table commune, slectionner les champs demands (nom des
communes et population) dans la clause SELECT. Mettre deux conditions
'dpartement de la Sarthe' ET 'population de plus de 1500 habitants' dans la
clause WHERE.
Question 3
[Solution n3 p 73]

Q3 : slectionner les communes de la table COMMUNE dont le statut n'est pas cheflieu de canton et afficher les colonnes NOM_COMM en lui donnant comme alias NOM
et les colonnes, STATUT, POPULATION et SUPERFICIE
Indice :
On peut traduire le "n 'est pas" par l'utilisation de NOT
Question 4
[Solution n4 p 73]
Q4 : slectionner les diffrents noms des tronons comportant le nom 'ruisseau' dans
la colonne TOPONYME de la table TRONCON_HYDROGRAPHIQUE

Indice :
Utiliser la table troncon_hydrographique. On pourra utiliser LIKE pour indiquer que
le nom de tronon doit contenir la chane 'ruisseau'.

26

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

26

Notions SQL

Question 5
[Solution n5 p 74]

Q5 : partir de la table COMMUNE, calculer pour chaque dpartement ; la population


totale, la densit moyenne de population des communes = moyenne(population
commune /superficie commune) arrondie deux dcimales, la population de la
commune la plus peuple et celle de la moins peuple, la superficie moyenne des
communes.
Indice :
Le rsultat doit tre :

exo6 - question 4
on cherche des sommes, moyennes,...par dpartement il faut donc utiliser un
GROUP BY (agrgation) avec comme critre le nom de dpartement
(NOM_DEPT).
Qui dit agrgation implique automatiquement l'utilisation de fonctions
d'agrgation...On utilisera les fonctions d'agrgation donnant la somme, la
moyenne, le maximum et le minimum.
Question 6
[Solution n6 p 74]

Q6 : quels sont les surfaces (en km2) et primtres (en km), arrondis deux chiffres
aprs la virgule, des communes du dpartement de la Sarthe ?
Indice :
trouver la fonction gomtrique qui renvoie une aire, et celle qui renvoie un
primtre. Ces fonctions ne prennent pas de paramtres d'units, il faut donc faire
la conversion soit mme par une division.
nb : pour spatialite on fera attention ne pas utiliser length() qui renvoi la
longueur d'une chane de caractres. Dans les dernires versions on utilisera la
mme fonction que sous PostGIS pour renvoyer le primtre.
Question 7
[Solution n7 p 74]

Q7 : slectionner le nombre de tronons de la 'rivire le loir', par classe de largeur


(colonne LARGEUR)
Indice :
Il faut 'compter' le nombre de tronons, donc utiliser une agrgation avec la
fonction d'agrgation qui permet de compter.
il y a 3 tronons dans la classe 0 15 mtres et 29 dans la classe plus de 50
mtres.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

27

Notions SQL
Notions SQL

Question 8
[Solution n8 p 74]

Q8 : quelle est la longueur de la 'rivire le loir' par type de largeur sur ce jeu de
donnes ?
Indice :
Il faut partir de la requte prcdente et ajouter une colonne qui va calculer la
somme de la longueur des tronons... on utilisera la fonction st_length qui donne
la longueur d'un objet linaire.

I. Les jointures attributaires


Une jointure permet de mettre en relation deux (ou plus) tables afin de combiner
leurs colonnes. Il existe plusieurs natures de jointure, mais la plupart des jointures
attributaires se font en imposant l'galit d'une valeur d'une colonne d'une table
une colonne d'une autre table.
Exemple : Table IRIS (extrait) et table des COMMUNES

Exemple de jointure attributaire


On recherche pour chaque IRIS le nom de la commune d'appartenance. Ce nom n'est
pas dans la table IRIS_extrait72, mais il existe dans la table COMMUNE.

28

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

28

Notions SQL

La solution est donc d'tablir un lien (une jointure) entre les deux tables afin que
pour chaque enregistrement de la table IRIS_extrait72 on retrouve le nom de la
commune dans la table COMMUNE.
Une analyse des tables IRIS_extrait72 et COMMUNE permet de voir que DepCom
reprsente le N INSEE de la commune d'appartenance dans la table IRIS_extrait72.
On retrouve ce NINSEE dans le champ INSEE_COMM de la table COMMUNE. Le lien
peut donc s'tablir par galit des ces colonnes ce que l'on crira :
IRIS_extrait72.DepCom = COMMUNE.INSEE_COMM
C'est ce que l'on appelle la condition de jointure.

Remarque
Lorsqu'on utilise plusieurs tables, il devient ncessaire s'il y a risque d'ambigut de
prciser le nom de la table devant le nom des colonnes sous la forme
NomTable.NomColonne d'o par exemple COMMUNE.INSEE_COMM.
Lorsqu'on ralise une jointure attributaire entre deux tables (deux noms de tables
aprs le from) il faut retenir qu'en gnral il faut une condition de jointure qui sera
une galit de champ.
La requte pourrait tre la suivante (on ne retient que certains champs) :
SELECT DepCom, Nom_Iris, insee_comm, nom_comm FROM iris_extrait72,
commune WHERE DepCom = insee_comm
Ici il n'y a pas d'ambigut sur les noms de colonnes et on peut ne pas utiliser la
notation NomTable.NomColonne

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

29

Notions SQL
Notions SQL

Principe de jointure attributaire


La table rsultat est une table qui a le mme nombre d'enregistrements que la table
IRIS_extrait72 dans laquelle on rcupre le nom des communes de la table
COMMUNE.

Complment
On peut galement utiliser une syntaxe normalise qui est dans ce cas strictement
quivalente :
SELECT <colonnes> FROM <table1> JOIN <table2> ON <condition de jointure>
dans notre exemple cela donne :
SELECT DepCom, Nom_Iris, insee_comm, nom_comm FROM iris_extrait72 JOIN
commune ON iris_extrait72.DepCom = INSEE_COMM
SQL autorise beaucoup de subtilit dans les types de jointures, on pourra par
exemple consulter Le SQL de A Z sur les jointures18.

18 - http://sqlpro.developpez.com/cours/sqlaz/jointures/

30

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

30

Notions SQL

J. Les jointures spatiales


Il n'est pas toujours possible de raliser une jointure attributaire s'il n'y a pas de
colonne commune entre deux tables. Dans le cas de tables ayant chacune un champ
gomtrique il est possible de raliser des jointures spatiales.
La jointure spatiale utilisera une fonction spatiale (voir ci-dessous) dans la clause
WHERE d'une requte SQL :
exemple :
SELECT * FROM tableA, tableB WHERE ST_Intersects(tableA.geometry,
tableB.geometry)

Les relations spatiales


Les prdicats spatiaux de l'OGC sont reprsents dans le tableau suivant :

Prdicats de l'OGC
Ils sont disponibles sous formes de fonctions spatiales qui renvoient VRAI (1) ou
FAUX (0) :
ST_Equals(geometry A, geometry B) retourne vrai si les gomtries sont de
mme type et ont les mmes coordonnes.
ST_Intersects(geometry A, geometry B) retourne vrai s'il y a au moins un point
commun.
ST_Disjoint(geometry A, geometry B) retourne vrai s'il n'y a aucun point
commun (quivalent n'intersecte pas ou NOT ST_Intersect, qu'il est prfrable

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

31

Notions SQL
Notions SQL

d'utiliser pour des questions de performance lie aux possibilits d'indexation


spatiale)
ST_Crosses(geometry A, geometry B) retourne vrai si le rsultat de l'intersection
des gomtries est de dimension immdiatement infrieure la plus grande des
dimensions des objets (ex : si A est un polygone et B une ligne, la dimension de
l'intersection doit tre une ligne) ET que le rsultat de l'intersection est l'intrieur
des deux gomtries.
ST_Overlaps(geometry A, geometry B) retourne vrai si les deux gomtries sont
de mme dimension et que l'intersection est de mme dimension mais de gomtrie
diffrente (renvoi faux si les deux gomtries sont identiques).
ST_Touches(geometry A, geometry B) retourne vrai si les contours s'intersectent
ou si un seul des intrieurs intersecte le contour de l'autre.
ST_Within(geometry A, geometry B) retourne vrai si le premier objet est
compltement dans le deuxime.
ST_Contains(geometry A, geometry B) retourne vrai si le deuxime objet est
compltement dans le premier.
Les fonctions suivantes sont galement intressantes :
ST_Dwithin(geometry A, geometry B, distance) qui retourne vrai si la distance
la plus courte entre A et B est infrieure ou gale distance.
ST_Distance(geometry A, geometry B) qui calcule la distance la plus courte entre
deux gomtries.

Attention

: Comportement diffrent avec MapInfo

Les relations spatiales normalises n'ont pas le mme comportement que sous
MapInfo puisque les oprateurs Contains et Within utilisent la gomtrie exacte des
objets et non leurs centrodes.
Pour plus de dtails voir Matrices de Clementini et prdicats spatiaux de l'OGC
disponible sur le site GoInformations du Ministre de l'Ecologie (ici19)

K. Exercice 7 : Requtes et fonctions spatiales


Raliser des requtes et fonctions spatiales
Objectif : En utilisant les tables de 'QGIS_perf_sandbox.sqlite' raliser les 4 requtes
suivantes
Question 1
[Solution n9 p 75]
Q1 : quels sont les ponctuels hydrographiques de la commune de La Flche ?

Indice :
On utilisera les tables PONCTUEL_HYDROGRAPHIQUE et COMMUNE... trouver la
relation gomtrique entre PONCTUEL_HYDROGRAPHIQUE.Geometry et
COMMUNE.Geometry.

19 - http://www.geoinformations.developpement-durable.gouv.fr/qgis-documents-et-fiches-a1853.html

32

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

32

Notions SQL

Question 2
[Solution n10 p 75]

Q2 : quelle est la longueur de la 'rivire le loir' dans chacune des communes


intersectes par le cours d'eau ?
rsultat obtenir :

rsultat exo7 question 2


Indice :
Chaque commune peut contenir plusieurs tronons, il faut donc calculer la somme
des longueurs des tronons pour chaque commune... donc utiliser un GROUP BY
et une fonction sum(). On utilisera la fonction ST_Length() pour obtenir la
longueur de chaque tronon. Il faut galement tenir compte que certains tronons
sont cheval sur plusieurs communes, et donc ne prendre en compte que la
longueur des tronons qui sont l'intrieur de chaque commune pour ce faire on
utilisera st_intersection(a.geom, b.geom) qui permet de rcuprer la gomtrie de
l'objet a qui intersecte celle de l'objet b.
Question 3
[Solution n11 p 76]

Q3 : slectionner les 'ponctuels hydrographiques' qui sont moins de 5 km d'un


tablissement d'enseignement (couche ETABLISSEMENT)
Indice :
On pourra utiliser une fonction st_distance() ou une fonction st_buffer()
associe un oprateur de type st_contains() ou st_intersects().
Question 4
[Solution n12 p 76]

Q4 : Quel est l'tablissement le plus proche du centroide de la commune de la


Flche?
On utilisera les coordonnes X_COMMUNE et Y_COMMUNE et la fonction
st_makepoint() ou Makepoint() sous spatialite ou encore st_point() qui est un
alias de Makepoint(). Le SRID (Identifiant du Systme de Rfrence Spatial) est
2154, mais on pourra le cas chant gnraliser la requte tout SRID en utilisant la
fonction srid() qui rcupre le srid d'une gomtrie.
Indice :
utiliser la fonction distance(), ORDER BY pour trier et LIMIT 1 pour prendre le
1er objet renvoy.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

33

Notions SQL
Notions SQL

Une requte de type


SELECT nom_comm, srid(Geometry)
Y_COMMUNE, srid(Geometry)) AS
commune.nom_comm = 'LA FLECHE'

AS SRID, MakePoint(X_COMMUNE,
Geometry FROM commune WHERE

retourne des points au centroide calcul partir des coordonnes X_COMMUNE, Y


COMMUNE.

34

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

34

II -

II

Spatialite

Grer les bases et les tables

35

L'assistant de requte SQL de QspatiaLite

38

Raliser des jointures avec Qspatialite

44

Indexation et optimisation

45

Exercice 8 : requtes SQL avec QspatiaLite

49

Objectifs
Dcouvrir et mettre en pratique le SGBDR SpatiaLite avec
QGIS

A. Grer les bases et les tables


Utiliser Spatialite sous QGIS
SpatiaLite est l'extension spatiale de Sqlite. Il est conforme la norme OGC-SFS20
(Open Geospatial Consortium - Simple Feature SQL) et ouvre la porte la ralisation
d'analyses spatiales au-del des fonctions natives de QGIS.
SpatiaLite est utilis par QGIS pour stocker ses propres informations. Il est donc
disponible de faon sous-jacente lorsqu'on installe QGIS.

Remarque
Le plug-in 'dition hors connexion21' permet de grer la synchronisation avec une
base SpatiaLite (offline.sqliter) embarque.
Il est donc possible d'envisager des utilisations avec saisie terrain sous SpatiaLite
puis synchronisation au retour avec une base partage centrale (sous PostGIS par
exemple).
Nous allons utiliser spatialite sous QGIS avec le plugin QspatiaLite ralis par
Romain RIVIERE (mais ceux qui prfrent peuvent utiliser DBManager qui est plus
universel, mais qui ne dispose pas encore (QGIS 2.2) d'assistant SQL).
Vrifier que QspatiaLite est bien install :

20 - http://www.opengeospatial.org/standards/sfs
21 - http://docs.qgis.org/2.2/fr/docs/user_manual/plugins/plugins_offline_editing.html

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

35

Spatialite
Spatialite

Qspatialite installation
Le menu base de donnes de QGIS doit proposer un item 'SpatiaLite'
Son lancement doit afficher la bote de dialogue suivante :

Qspatialite interface principale


Choisir par exemple la base QGIS_perf_sandbox_v2.sqlite.
(QGIS_perf_sandbox.sqlite pour une version de QGIS < 2.0)
vaccum database : permet de nettoyer la base de donnes des
enregistrements vides (quivalent 'compacter table' sous MapInfo).

36

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

36

Spatialite

Open/Create new DataBase : permet de crer une nouvelle base SQLite, ou


de rcrer le lien vers une base existante. Le fichier d'extension . sqlite ainsi cr est
compltement autonome et peut-tre diffus un utilisateur distant (comme par
exemple le fichier qgis_perf_sandbox_V2.sqlite fourni dans le jeu de donnes de la
formation).
Remove : permet de supprimer la base de donnes en cours de la liste des
bases rfrences sous QspatiaLite. La base n'est pas supprime physiquement. Pour
re-rfrencer une base existante, il faut utiliser 'New DB' et slectionner la base
existante. Une fentre demandant si on veut remplacer la base apparat, mais la base
n'est pas crase et nouveau rfrence.

Pour chaque Table liste :


l'icne reprsente le type de table (point, ligne, polygones, donnes, vues,...) en
fonction du type de table un clic droit affiche un menu droulant qui donne accs aux
commandes suivantes :
REFRESH TREE: ractualise l'arbre dcrivant les tables.
NEW TABLE : permet de crer une nouvelle table directement sous QspatiaLite
NEW VIEW : affiche dans l'diteur SQL l'ordre ( complter) permettant de crer
une 'vue' (le concept de vue est un peu similaire aux tables requtes sous MapInfo.
Voir par exemple ici22). L'intrt est qu'elle est remise jour si les donnes des tables
sources de la requte qui a gnr la vue sont modifies. Une vue s'utilise comme
une table (avec quelques restrictions).
SHOW MEDATA : affiche les mtadonnes stockes dans 'geom_cols_ref_sys' de la
table en cours.
DROP TABLE : permet de supprimer la table
LOAD IN QGIS : permet de charger la table dans QGIS
SHOW SAMPLE : montre un chantillon des donnes de la table
SHOW ALL : montre les donnes de la table
SHOW COLUMNS : liste des colonnes de la table avec leurs caractristiques.
NEW INDEX : permet d'afficher dans la bote SQL la syntaxe de cration d'un index.
La notion d'index sous Sqlite est plus puissante que sous mapInfo car elle peut
reposer sur plusieurs colonnes voir par exemple23.
NEW COLUMN : permet d'afficher dans la bote SQL la syntaxe de cration d'une
nouvelle colonne
NEW TRIGGER : permet d'afficher dans la bote SQL la syntaxe de cration d'un
trigger. Nous ne verrons pas dans ce cours les triggers, voir par exemple ici24 pour en
savoir plus.
CREATE SPATIAL INDEX : permet de crer un index spatial (Rtree) sur le champ
geometry (pour acclrer les requtes sur les grosses tables). Nous en reparlerons...
Advance SQL Editor : donne accs une boite de dialogue permettant de
construire les requte SQL en mode interactif. Nous allons l'tudier un peu plus loin...
22 - http://sqlpro.developpez.com/cours/sqlaz/ddl/?page=partie2#L8
23 - http://sqlpro.developpez.com/cours/sqlaz/ddl/?page=partie2#L10
24 - http://fr.wikipedia.org/wiki/Dclencheur

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

37

Spatialite
Spatialite

ces boutons permettent de naviguer dans l'historique des commandes


SQL.
Import des couches QGIS. fixer le SRID est prudent. Si c'est du
RGF93/Lambert 93 on indiquera 2154 comme code EPSG25.
Import de fichiers OGR. permet d'importer directement dans spatialite des
fichiers dans les formats reconnus par OGR. Un onglet Multi Files selection permet
d'importer plusieurs fichiers en une seule fois.
Import de fichiers TXT ou CSV
Export de fichiers OGR. permet d'exporter les tables dans un format spatial
accept par ogr2ogr. L'option 'just load in QGIS' permet de charger le rsultat dans
QGIS au lieu de l'crire sur le disque.
Export txt, csv, sqlite, ou DBF. l'option 'just load in QGIS' permet de charger
le rsultat dans QGIS au lieu de l'crire sur le disque.
excution requte SQL

B. L'assistant de requte SQL de QspatiaLite


L'assistant de requte est une aide pour raliser des requtes SQL. Son utilisation
n'est pas obligatoire, mais utile pour les dbutants en SQL et pour les utilisateurs
connaissant MapInfo qui ne seront pas trop dpayss.

25 - http://georezo.net/wiki/main/dico/epsg

38

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

38

Spatialite

Advance SQL
Cette bote de dialogue permet de construire la requte SQL. La dmarche est
d'abord de slectionner la ou les tables sur lesquelles on souhaite travailler (ex :
''AERODROME'', puis les colonnes de ces tables que l'on souhaite en sortie ou mettre
* dans la case Columns pour choisir toutes colonnes.
Ex :
"AERODROME".'NATURE',
"AERODROME".'DESSERTE',
"AERODROME".'TOPONYME'
et ventuellement d'ajouter une condition (clause where) pour laquelle on peut
utiliser les listes droulantes droite.
exemple :
NATURE = 'Normal'

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

39

Spatialite
Spatialite

Exemple SQL avec le requteur avanc

Remarque
Il n'y a pas * par dfaut (comme sous MapInfo) dans le champ 'Columns' dans la
bote de dialogue pour slectionner tous les champs,
on peut crire = ou == comme oprateur d'galit.
on ne dispose pas de = ANY (utiliser IN)
|| est l'oprateur de concatnation (ne pas utiliser + comme sous MapInfo)

Complment
GLOB : est similaire l'oprateur LIKE (%= 0 n caractres, _= 1 caractre) mais
utilise les jokers unix (* = 0 n caractres, ?= 1 caractre ) et est sensible la
casse.
BETWEEN n'est pas disponible dans les menus droulants, mais est utilisable.
MATCH : permet de comparer un ensemble de valeurs de ligne un ensemble de
lignes retourn par une sous-requte (usage rare). Voir ici26 pour en savoir plus.
REGEXP : permet d'utiliser les expressions rgulires ou rationnelles (voir ici27). Le
documentation prcise toutefois qu'il faut se dfinir sa propre fonction regexp() car il
n'y en pas par dfaut. L'utilisation de cet oprateur sans dfinir de fonction gnre un
message d'erreur. Trs peu utile pour les besoins des services.

Attention
SQLite est laxiste sur le contrle de type des champs, plus prcisment SQLite utilise
u n typage dynamique28. L o MapInfo affichera un message du type 'Non26 - http://sqlpro.developpez.com/cours/sqlaz/sousrequetes/#L1.3
27 - http://fr.wikipedia.org/wiki/Expression_rationnelle
28 - http://fr.wikipedia.org/wiki/SQLite#Types_de_donn.C3.A9es

40

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

40

Spatialite

concordance de type de donnes dans l'expression' QspatiaLite n'affichera rien mais


le rsultat sera 'Empty rsultat' (rsultat vide). Rappelons la fonction cast pour faire
des comparaisons avec changement de type.

Affichage de toutes les communes avec calcul d'un champ


supplmentaire de densit

Qspatialite, editeur SQL avanc, gestion des champs en sortie


Le choix d'une colonne dans la liste droulante 'columns' ajoute le nom du champ
prcd d'une virgule. Ce n'est pas toujours souhaitable comme dans le cas o l'on
fait une division de deux champs. Il faut alors supprimer la virgule. Par dfaut le nom
de la table est ajout devant le nom de la colonne.
L'appel aux fonctions comme round pour arrondir que l'on peut choisir dans la liste
droulante 'math' n'affiche pas la syntaxe de la fonction. Pour une aide sur les
fonctions spatiale, il est conseill d'utiliser une description en ligne29. (il est possible
d'obtenir la version SpatiaLite dans le menu 'a propos' de QGIS). Pour QGIS 2.2 la
version de spatialite est la 4.1.1
Pour une aide sur les fonctions de sqlite on pourra consulter ce site30.
La validation par OK affiche alors la syntaxe en SQL. Dans notre cas :
SELECT *,
Round(cast("COMMUNE".'POPULATION' as float) /
"COMMUNE".'SUPERFICIE',2) as densite
FROM "COMMUNE"

29 - http://www.gaia-gis.it/gaia-sins/spatialite-sql-4.2.0.html
30 - https://www.sqlite.org/lang_corefunc.html

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

41

Spatialite
Spatialite

onglet option

onglet option
Il permet de fixer la destination du rsultat :
par dfaut dans une nouvelle table provisoire 'sqlResult'.
On peut :
Load in QGIS as Spatial layer : charger dans QGIS comme table spatiale
(contenant une gomtrie). Dans ce cas on peut dsigner la colonne contenant la
gomtrie.
Create Table & Load in QGIS : crer une table (uniquement attributaire) du nom
indiqu dans Table Name dans Spatialite et charger cette table dans QGIS.
Create Spatial Table & Load in QGIS : crer une table spatiale (avec la
gomtrie) et la charger dans QGIS.
Create View & Load in QGIS : crer une Vue et la charger dans QGIS.
Create spatial View & Load in QGIS : crer une Vue spatiale et la charger dans
QGIS.
U n e vue est une table virtuelle. Seule la requte est mmorise et nouveau
excute chaque fois que l'on utilise la vue comme une table. Le concept est tout
fait similaire aux tables requtes de MapInfo.

Conse il: Gestion de la gomtrie dans les agrgations


Il est possible de faire des agrgations et des tris en utilisant les champs goup By
Columns et Order by columns.
Lorsqu'on fait une agrgation sur une table gomtrique par un 'group by', il est
important de comprendre que cela ne traite pas automatiquement la fusion des
gomtries. Ainsi si on se contente de reprendre le champ geometry dans le rsultat,
il ne faut pas l'utiliser.
Exemple :
si on fait un group by sur le statut des communes :
select geometry, asText(geometry) as WKT, statut, sum(superficie) as
superficie, sum(population) as population from commune group by
commune.statut
le rsultat

42

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

42

Spatialite

Group by avec gomtrie


contient la colonne Geometry (la transformation en texte de la gomtrie au format
WKT est demande titre illustratif)
Cependant un affichage sous QGIS montre que la gomtrie est uniquement celle de
Clermont-Crans (premire commune dans la table rpondant au critre 'commune
simple' et non la fusion des gomtries de toutes les communes de Statut 'commune
simple'.
D'une faon gnrale si on utilise un GROUP BY, toutes les colonnes en sortie sauf
celle du critre de regroupement doivent faire l'objet d'une fonction d'agrgation, ce
doit tre galement le cas pour la gomtrie.
Pour obtenir la fusion des gomtries il faut donc le demander explicitement avec une
commande ST_UNION
dans notre exemple cela donne :
CREATE TABLE EXEMPLE AS
SELECT STATUT, ST_Union(Geometry) as geometry, sum(superficie) as
superficie, sum(population) as population
FROM "COMMUNE"
GROUP BY "COMMUNE".'STATUT'
ORDER BY "COMMUNE".'STATUT'
(Pour crer la table EXEMPLE dans spatialite sans l'exporter dans QGIS on utilise un
create table en amont du select).
La table est affiche comme tant uniquement attributaire.
Il faut utiliser la fonction RecoverGeometryColumn() pour mettre jour les tables
internes de mtadonnes de spatialite :
SELECT RecoverGeometryColumn('EXEMPLE', 'Geometry', 2154,
'MULTIPOLYGON', 'XY')
o u SELECT RecoverGeometryColumn('EXEMPLE', 'Geometry', 2154, 'POLYGON',
'XY') si les objets sont des polygones simples.
nb : s o u s Po s t G I S ( v e r s i o n a n t r i e u r e l a 2 . 0 ) o n p o u r r a u t i l i s e r
Populate_Geometry_Columns() ou Probe_Geometry_Columns()
La table devient graphique et peut-tre charge sous QGIS pour vrification.
A partir de la version 2.0 de PostGIS il n'est plus ncessaire d'utiliser les fonctions de
mise jour des tables internes. Le type geometry tant un type part entire on
peut crire :
CREATE TABLE EXEMPLE AS
SELECT statut, st_multi(ST_Union(Geom)) :: Geometry(MULTIPOLYGON, 2154)
as geom, sum(superficie) as superficie, sum(population) as population
FROM commune
GROUP BY commune.statut
ORDER BY commune.statut

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

43

Spatialite
Spatialite

La conversion en type 'multipolygon' avec le modificateur de type Geometry() met


jour automatiquement la vue 'geometry_columns'.
(Le rsultat de ST_union tant soit un 'polygon', soit un 'multipolygon' on utilise la
fonction st_multi() pour convertir tous les rsultats en 'multipolygon').
nb : Pour les lignes il est possible de supprimer les discontinuits et viter la
constructions de multilignes avec la fonction st_linemerge()
ex :
SELECT toponyme, row_number() over() as id,
st_linemerge(st_union(Geom)) as geom from troncon_hydrographique where
toponyme <> '' group by toponyme
DBManager demandant un identifiant de type entier unique pour charger les couches
sous QGIS, il est cr avec row_number() over().
Ceci permet de rcuprer le numro de ligne qui est alors utilis comme identifiant.
Pour ceux qui sont intresss, cette syntaxe utilise les possibilits avancs de SQL
sur le fentrage31.

C. Raliser des jointures avec Qspatialite


Les jointures attributaires peuvent tre ralises avec l'assistant de requte en
choisissant (au moins) deux tables.

Jointures avec Qspatialite


Dans l'exemple ci-dessus, le paramtrage ralise la commande SQL :
SELECT "IRIS_extrait72".'DepCom',

31 - http://sqlpro.developpez.com/article/olap-clause-window/

44

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

44

Spatialite

"IRIS_extrait72".'Nom_Iris',
"IRIS_extrait72".'Nom_Com'
FROM "IRIS_extrait72", "COMMUNE"
WHERE "IRIS_extrait72".'DepCom' =="COMMUNE".'INSEE_COMM'
De mme on peut raliser des jointures spatiales

Qspatialite jointures spatiales


Noter que cette requte s'excute en 202 ms (indiqu en bas droite dans l'onglet
'result').

Remarque
Les oprateurs spatiaux sont des fonctions, la syntaxe est donc diffrente de celle de
MapInfo.
Si on souhaite utiliser le rsultat comme une table spatiale, il est ncessaire de
choisir une des colonnes de gomtrie en sortie, si on indique *, il y a aura deux
colonnes de gomtrie dans la table rsultante. Il faudra donc prciser laquelle on
considre comme la source de gomtrie (champs 'geometry field) lors de l'export de
QsptiaLite vers QGIS.

D. Indexation et optimisation
Dans le cas d'une grosse base de donnes, les requtes Sql peuvent tre coteuses
en temps de calcul, a fortiori les requtes spatiales qui utilisent la gomtrie des
objets.
Crer des index (spatiaux ou non) peut permettre d'amliorer les temps de
traitement. Ce n'est cependant pas une recette miracle. Dans SpatiaLite, un index

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

45

Spatialite
Spatialite

spatial ne peut acclrer les calculs que dans le cas o le rsultat appartient une
petite portion du jeu de donnes. Quand les rsultats incluent une grande partie du
jeu de donnes, l'index spatial ne permet pas de gains de performance.
Dans un SGBD labor comme PostGIS le planificateur de requte choisit de faon
adapte d'utiliser ou non les index et l'index spatial (de type Gist que nous verrons
plus tard) est primordial. La seule restriction d'utilisation est celle des tables avec
de trs gros objets en petit nombre (ex : tache urbaine dpartementale rpartie en
10 priodes soit 10 enregistrements).
On trouvera quelques explications sur le principe de l'algorithme R-Tree utilis par
spatialite ici32 et sur les index Gist ici33

Remarque : Clef primaire


Pour des raisons expliques ici34 il est indispensable sous spatialite que la
table dispose d'une clef primaire avant de crer un index spatial. Une clef primaire
est une colonne qui reprsente un identifiant unique pour chaque enregistrement.
Dans QspatiaLite elle est reprsente par une clef !
Malheureusement SqLite n'autorise pas (encore?) la cration d'une clef primaire
aprs coup, (pour les anglicistes voir les limites de ALTER TABLE 35) il faut re-crer
une autre table. Contacter l'assistance interne si vous tes confront ce type de
problmes

Index spatial
Construisons un index spatial sur la table TRONCON_HYDROGRAPHIQUE, ainsi que
sur la table PONCTUEL_HYDROGRAPHIQUE.

32
33
34
35

http://www.gaia-gis.it/gaia-sins/spatialite-cookbook-fr/html/rtree.html
http://docs.postgresqlfr.org/8.3/gist.html
https://sites.google.com/site/sgbdspatialite/bon-usage-de-l-index-spatial-r-tree
http://sqlite.org/lang_altertable.html

46

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

46

Spatialite

Cration index spatial


Dans les anciennes versions de spatialite, on pouvait utiliser des fonctions Rtree
(RtreeIntersects, RTreeWithin, RtreeContain).
Ce sont ces fonctions qui sont implmentes dans l'assistant SQL de Qspatialite
(version 7.0.2 - Aot 2014) :

Index spatial
En appuyant sur 'use Spatial Index' Qspatiale rajoute automatiquement une
syntaxe dans la clause where.
AND"PONCTUEL_HYDROGRAPHIQUE".ROWID IN (
SELECT pkid FROM "idx_PONCTUEL_HYDROGRAPHIQUE_Geometry" WHERE pkid MATCH
RTreeIntersects(
MBRminX("TRONCON_HYDROGRAPHIQUE".'Geometry'),MBRminY("TRONCON_HYDROGRAPH
IQUE".'Geometry'),MBRmaxX("TRONCON_HYDROGRAPHIQUE".'Geometry'),MBRmaxY("
TRONCON_HYDROGRAPHIQUE".'Geometry')))
Cette syntaxe n'est plus recommande dans les dernires versions de spatialite
(> 4.0.1) pour laquelle, il y a eu des travaux d'optimisation36.

36 - https://www.gaia-gis.it/fossil/libspatialite/wiki?name=speed-optimization

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

47

Spatialite
Spatialite

Elle peut conduire au message d'erreur suivant si le module geocallback n'est pas
prsent :
'no such function : RtreeIntersects' (module geocallbacks non prsent)
Dsormais, pour utiliser explicitement les index spatiaux on peut construire une
requte copiant la syntaxe indique ici 37:
SELECT p.'Geometry' AS Geometry,
p.'TYPE',
p.'NATURE',
p.'TOPONYME',
p.'COTE',
t.'TOPONYME' as COUR_D_EAU
FROM 'PONCTUEL_HYDROGRAPHIQUE' p, 'TRONCON_HYDROGRAPHIQUE' t
WHERE st_intersects(p.'Geometry',t.'Geometry') and p.'ROWID' in ( select
rowid from spatialIndex where f_table_name = 'PONCTUEL_HYDROGRAPHIQUE'
AND search_frame = t.'Geometry')
nb : O n u t i l i s e p o u r p l u s d e c o n c i s i o n l e s a l i a s d e t a b l e ; p p o u r
'PONCTUEL_HYDROGRAPHIQUE' et t pour 'TRONCON_HYDROGRAPHIQUE'
Sans rentrer trop dans les dtails une sous-requte est ici utilise (ordre select
dans la clause Where de la requte de base relanant une sous-requte). Cette sousrequte utilise les colonnes f_table_name et search_frame de la table systme
SpatialIndex (cette table n'est pas interrogeable).
Cela donne :

Requte complte
Ici le traitement s'excute en 26 ms...(au lieu de 45 ms sans l'utilisation explicite des
index spatiaux) le gain de temps n'est semble-t-il pas en rapport avec l'effort
intellectuel consenti ! Mais dans d'autres cas cette petite gymnastique qui aprs
quelques essais n'est pas si difficile mettre en uvre peut faire gagner beaucoup
de temps.
37 - https://www.gaia-gis.it/fossil/libspatialite/wiki?name=SpatialIndex

48

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

48

Spatialite

Quelques exemples de gains sont donnes ici38

Complment
Les possibilits de manipulation spatiale sont trs grandes... voici quelques
rfrences supplmentaires :
Quelques exercices et astuces classiques39
le livre de cuisine !40
Ne pas hsitez consulter partir de cette page 41le 'Spatial SQL functions reference
guide' qui est la liste de rfrence des fonctions disponibles dans la dernire version
de spatialite (attention ce n'est pas forcement celle de votre version de QGIS). Pour
aller plus loin, on pourra en particulier regarder avec intrt les fonctions 'GEOS
Advanced', ainsi que les fonctions 'LWGEOM'
(Sur SQL d'une faon gnrale on pourra consulter un cours en ligne42 ou ce site43 de
rfrence en franais

E. Exercice 8 : requtes SQL avec QspatiaLite


Raliser des requtes SQL avec QspatiaLite
Objectif : crer une nouvelle base avec QspatiaLite et raliser des requtes SQL
Question 1
[Solution n13 p 77]

Q1 : Charger les couches suivantes dans QGIS :


BD_TOPO/I_ZONE_ACTIVITE/PAI_SANTE.SHP
/BD_TOPO/H_ADMINISTRATIF/COMMUNE.SHP
/BD_TOPO/E_BATI/BATI_INDUSTRIEL.SHP
/BD_TOPO/F_VEGETATION/ZONE_VEGETATION.SHP
avec QspatiaLite crer une nouvelle base de nom BDTOPO72
Importer toutes les couches charges sous QGIS en EPSG 2154 (Lambert 93).
Crer une nouvelle couche BATI_INDUSTRIEL10 et la charger dans QGIS en
slectionnant dans la table BATI_INDUSTRIEL les 'Btiment industriel' (attention la
majuscule!) dont la hauteur est d'au moins 10 m
Indice :
La table rsultat doit contenir 8 enregistrements.
Question 2
[Solution n14 p 77]

Q2 : Afficher dans la fentre 'Result' de QspatiaLite les 'Fort ferme de conifres' de


la commune de La Flche. Ne pas oubliez de mettre une condition de jointure entre
les deux couches... qui devra tre ici spatiale.

38
39
40
41
42
43

https://www.gaia-gis.it/fossil/libspatialite/wiki?name=speed-optimization
https://sites.google.com/site/sgbdspatialite/exercices-astuces
http://www.gaia-gis.it/spatialite-2.4.0-4/spatialite-cookbook-fr/index.html
https://www.gaia-gis.it/fossil/libspatialite/index
http://www.1keydata.com/fr/sql/
http://sqlpro.developpez.com/

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

49

Spatialite
Spatialite

La table rsultat doit contenir 55 enregistrements.


Question 3
[Solution n15 p 77]

Q3 : Plus difficile...
Calculer la somme des surfaces des 'Fort ferme de feuillus' de la commune de la
Flche en ha (1ha = 10 000 m2), en faisant attention ne prendre en compte que
les parties de surfaces des polygones rellement situes l'intrieur de la commune.

attention aux limites des polygones


Ainsi dans l'exemple ci-dessus il ne faut prendre en compte que la partie du polygone
jaune qui est l'intrieur de la commune de la Flche... on pourra penser la
fonction st_Intersection() qui retourne un objet gomtrique intersection de deux
objets...le rsultat est 565 ha
Question 4
[Solution n16 p 77]

Q4 : Construire une nouvelle couche dans QGIS (non graphique) de nom


ETABLIS_PLUS_PROCHE qui pour chaque tablissement hospitalier de la couche
PAI_SANTE donne l'identifiant (ID) de l'tablissement industriel de la couche
BATI_INDUSTRIEL le plus proche, ainsi que la distance
ATTENTION : Cet exercice fait appel pour sa solution l'utilisation d'une sousrequte44, il peut tre jug complexe, dans ce cas essayez de comprendre la solution.
Son objectif est de montrer la puissance du SQL pour la rsolution de problmes
parfois complexes...

44 - http://sqlpro.developpez.com/cours/sqlaz/sousrequetes/

50

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

50

Spatialite

Le rsultat est :

exo8 Q4 rsultat
Indices :
Il est conseill de dcomposer un problme complexe en problmes plus simples
pour arriver la solution...
On pourra dans un premier temps construire une table qui donne les distances de
tous les tablissements industriels de la couche BATI_INDUSTRIEL pour chaque
tablissement hospitalier. Il faut pour cela utiliser les deux tables PAI_SANTE et
BATI_INDUSTRIEL. On notera qu'on ne peut donner une condition de jointure, ni
attributaire (pas de champ commun), ni gographique (les objets ne se
superposent pas). Dans ce cas on peut construire le produit des deux tables
(produit cartsien) sans condition (ce que n'autorise pas MapInfo).
SELECT * FROM "Pai_SANTE","BATI_INDUSTRIEL"
Il reste ajouter la colonne donnant les distances.
ATTENTION : Faire un produit cartsien sur deux tables sans condition de
jointure doit tre rserv des tables de petite dimension.
nb : Pour viter de faire le produit cartsien complet, on pourrait penser utiliser
sous PostGIS la fonction ST_DWithin() avec un rayon de recherche maximum,
fonction qui est disponible que dans spatialite 4.0 sous le nom de PtDistWithin().
La table prcdent peut nous donner accs pour chaque PAI_SANTE la distance
minimum de l'tablissement le plus proche avec un GROUP BY
SELECT PAI_SANTE.ID, min(st_distance(PAI_SANTE.Geometry,
BATI_INDUSTRIEL.Geometry)) AS distance_min from
PAI_SANTE,BATI_INDUSTRIEL GROUP BY PAI_SANTE.ID
On pourrait penser demander dans le tableau BATI_INDUSTRIEL.ID... mais le
rsultat serait faux, car il ne faut pas oublier lorsqu'on utilise un GROUP BY que
chaque colonne en sortie (dans la clause SELECT) doit tre, soit le critre de
rupture (celui du GROUP BY), soit tre le rsultat d'une fonction d'agrgation...
(sous PostGIS vous aurez d'ailleurs un message du type
ERREUR : la colonne "bati_industriel.id" doit apparatre dans la
clause GROUP BY ou tre utilise dans une fonction d'agrgation
Spatialite est plus tolrant, mais il vaut mieux prendre les bonnes habitudes !
Nous voila donc avec le tableau suivant :

rsultat sous-selection
Il faut maintenant trouver les couples (PAI_SANTE.ID BATI_INDUSTRIEL.ID) pour
lesquels la distance est l'une ou l'autre des distances de la table prcdente...
autrement dit excuter une requte du type

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

51

Spatialite
Spatialite

SELECT...st_distance(...) as distance FROM PAI_SANTE, BATI_INDUSTRIEL


WHERE distance IN (... rsultat de la requte donnant les deux distances
minimum)

52

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

52

III -

III

PostGIS

PostGIS : Importer des donnes

53

Utiliser PostGIS depuis QGIS

65

Utilisation de DBManager avec PostGIS

68

Indexation spatiale sous PostGIS

72

Exercice 9 : PostGIS

73

Objectifs
Dcouvrir et mettre en pratique PostGIS avec QGIS

A. PostGIS : Importer des donnes


PostGIS est beaucoup plus complet que SpatiaLite. En comparaison il propose :
une plus grande richesse dans les fonctions spatiales (ex : fonction de
conversion de projection, 3D, routing,...) administration de base (gestion des
droits, outils d'administration et d'optimisation,...)
une meilleure gestion des transactions (ACID45).
l'utilisation automatique des index spatiaux grce l'optimiseur de
requtes.
Mais en contrepartie d'une plus grande complexit. L'utilisation de PostGIS n'est donc
recommande que s'il existe dj une base installe dans votre service, gre par
une quipe spcialise, ou si vous avez les comptences (et l'autorisation) pour le
faire installer sur votre poste de travail dans un but d'analyse spatiale plus que de
partage de donnes.
Pour utiliser ce module il faut avoir accs une base PostGIS. Le cas chant les
paramtres de connexion doivent tre fournis par l'organisateur de la formation.
Pour importer et exporter des donnes dans PostGIS, il existe plusieurs solutions
avec chacune leurs avantages et inconvnients.

Utilisation de l'extension SPIT (outil d'importation de shapefiles


dans PostGIS)
Pour importer des fichiers shape et .dbf dans PostgreSQL directement depuis QGIS, il
existe une extension baptise SPIT46.
45 - http://fr.wikipedia.org/wiki/Proprits_ACID
46 - http://docs.qgis.org/1.8/fr/docs/user_manual/plugins/plugins_spit.html

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

53

PostGIS
PostGIS

Cette extension doit tre active l'aide du gestionnaire d'extensions de QGIS.


Une fois l'activation effectue, il faut cliquer sur l'icne de l'extension SPIT dans la
barre d'outils de QGIS.

Importer des Shapes dans PostgreSQL


Cette extension est galement accessible depuis le menu Base de donnes.
La fentre suivante apparat.

importation de Shapefile
Il faut crer une nouvelle connexion ou utiliser une connexion dj cre.
Une fois que la connexion est tablie, cliquer sur Ajouter.
La fentre suivante apparat.

54

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

54

PostGIS

Choix du fichier SHP


Choisir le ou les fichiers shape importer dans PostGis (les choisir les uns aprs les
autres).
Cliquer sur Open.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

55

PostGIS
PostGIS

La fentre suivante apparat :

connexion PostgreSQL
Le ou les fichiers shape imports dans PostGis apparaissent dans la liste.
Dans le champ Nom de la colonne de gomtrie, laisser vide, ou saisir le nom de la
colonne de gomtrie du fichier shape ou cocher la case Utiliser le nom de colonne
gomtrique par dfaut (the_geom).
Dans le champ SRID, saisir la valeur 2154 qui correspond au systme de
coordonnes de rfrence (SCR) RGF93/Lambert 93.
Cliquer sur OK.
Les donnes sont importes dans PostGIS.

Conse il: Utilisation des schmas


Il est recommand de ne pas utiliser le schma public, mais plutt d'utiliser des
schmas personnaliss. Ceci permet de sparer le cur de PostGIS (tables systmes
PostGIS, fonctions...) des donnes elle-mme.
On peut crer des schmas par thmatique ou selon d'autres organisations
(rfrentiel / donnes mtiers / donnes produites ou donnes tabulaires / donnes
vectorielles par exemple). L'organisation en schmas multiples permet de simplifier la
gestion des droits d'utilisation, mais le principal avantage reste de faciliter la mise
jour de PostGIS ainsi que la restauration ou l'change plus efficaces de donnes.
La dfinition d'une structure d'exploitation de la base partage par tous est du
ressort de l'administrateur de la base47.
47 - https://fr.wikipedia.org/wiki/Administrateur_de_bases_de_donn%C3%A9es

56

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

56

PostGIS

Complment : Avantages / Inconvnients de SPIT


Avantages :
Multiplateforme (Windows, Linux, Unix, Mac OS X)
Possibilit d'importer plusieurs fichiers en une seule fois
Bref rsum de chaque fichier avant import, tel que le dcompte de la
gomtrie et le type
Inconvnients :
prend en compte uniquement les fichiers SHP
N'affiche pas le systme de projection natif des tables
Surtout il entoure tous les noms de champs de "" dans PostGIS pour prserver
la casse (majuscule/minuscule). Cette option n'est pas dsactivable. Le
principal inconvnient tant que dans d'autres outils que QGIS il faut alors
systmatiquement utiliser les champs entre "" dans les requtes SQL
Ne semble plus maintenu
lent sur pour des grosses tables.

L'outil 'PostGIS 2.0 Shapefile and DBF Loader Exporter'


Si vous avez install une distribution PostGIS sur votre poste de travail, vous
disposez de l'outil pgShapeloader aussi connu sous le nom de 'PostgIS shapefile
and DBF Loader.'
Dans ce cas, Il est possible de le dmarrer depuis le poste de travail :
Dmarrer/Programmes/PostGIS 2.0 for PostgreSQL 9.0/PostGIS 2.0 Shapefile and
DBF Loader Exporter
La fentre suivante apparat.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

57

PostGIS
PostGIS

PostGIS ShapeFile Import/Export Manager


Cliquer sur View connection details...
Saisir les informations demandes pour :
User Name : (ici postgres)
Password : ( choisir lors de l'installation de PostGIS)
Server Host : localhost Port : (ici 5432)
Database : (ici postgis)

58

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

58

PostGIS

dtails connexion
Cliquer sur OK.
La fentre suivante apparat.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

59

PostGIS
PostGIS

Connecting
Dans la fentre de connexion (Log Window), un message indique si la connexion est
tablie et rappelle les informations la concernant.
Pour ajouter des fichiers importer, cliquer sur Add File
On peut choisir entre importer des fichiers .shp ou dbf

60

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

60

PostGIS

import SHP

Attention
Il faut veiller ce que les chemins et les noms des fichiers ne comportent ni espaces
blancs ni accents.
Lorsque le ou les fichiers importer dans PostGis ont t choisis, cliquer sur Options.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

61

PostGIS
PostGIS

La fentre suivante apparat :

Options import
Selon le type de donnes importer, il faut cocher les cases correspondantes.
Puis cliquer sur OK.
Pour le fichier shape et/ou dbf importer, modifier le SRID en double cliquant dans la
colonne SRID ( 2154 pour les donnes en RGF93/Lambert 93).
Les diffrents modes sont :
Create : Cr la table et la remplit.
Append : Ajoute les enregistrement la table (si elle existe dj).
Delete : Supprime la table et la recre avec les enregistrements.
Prepare : Cr la table mais ne la remplit pas avec les enregistrements.
Pour afficher la fentre des options de l'importation, cliquer sur Options...
Les options les plus importantes retenir sont les suivantes :
Preserve case of column names : conserve la casse (majuscule/minuscule)
des colonnes du fichier import (Les noms de colonnes sont entours de ""
dans PostGIS).
Create spatial index automatically after load : cre automatiquement un
index spatial aprs le chargement du fichier import. Conseill si vous ne
chargez pas d'autres donnes dans cette table.
Load only attribute (dbf) data : permet de ne charger que les donnes
attributaires dans une table au format .dbf
Load into GEOGRAPHY column : charge la gomtrie des donnes dans
une colonne de type GEOGRAPHY (plutt que GEOMETRY). Ceci permet des
mesures sur le sphrode, plutt que cartsiennes. Pour plus de dtails48.
Generate simple geometries instead of MULTI geometries : cre des
gomtries simples au lieu de gomtries multiples
Il est propos dans l'exemple de ne cocher que Load only attribute (dbf) data et de
renseigner le type d'encodage des caractres du fichier .dbf source : LATIN1 dans la
case prvue cet effet (DBF file character encoding).
48 - http://www.postgis.fr/chrome/site/docs/workshop-foss4g/doc/geography.html

62

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

62

PostGIS

nb : au sujet de l'encodage des fichiers SHP voir ici49, ainsi que quelques informations
complmentaires ici50.
Cliquer sur OK.
La fentre se ferme et la prcdente est nouveau affiche.
Cliquer sur Import.
La fentre de connexion (Log window) fait apparatre un ou des messages sur la
procdure d'importation des fichiers choisis.
Si l'importation se droule correctement, le message suivant apparat dans la fentre
de connexion.

log window
La connexion et l'importation de donnes dans PostGIS tant faite, on peut passer
dans QGIS pour afficher des donnes provenant de PostGIS.

Utilisation de DBmanager
DBManager permet de charger des fichiers dans une base PostGIS connecte sous
QGIS, par glisser / lch de fichiers partir du navigateur QGIS, ou par le menu
'Table > Importer une couche ou un fichier' pour les couches dj charge dans
QGIS. Ce dernier menu est galement accessible par le bouton
nb : DBManager permet galement de faire des changes de donnes avec les bases
de donnes spatialite par gliss / lch.

49 - http://www.geoinformations.developpement-durable.gouv.fr/qgis-2-2-encodage-des-fichiers-shp-a2908.html
50 - http://chinook.memoris.fr/

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

63

PostGIS
PostGIS

La fentre d'import permet de saisir les paramtres ncessaires :

DbManager paramtres d'import

Complment : Ogr2ogr
Les spcialistes prfrent parfois utiliser ogr2ogr51 pour contrler l'import des
donnes dans PostGIS. Nous ne dtaillerons pas ici cet outil qui est plutt rserver
l'administrateur de la base.
Avantages :
Prend en charge une multitude de format52.
Possibilit de changement de projection
Possibilit de slection SQL des donnes en import.
Inconvnient :
Syntaxe complexe cause des nombreuses options.
nb : Pour les spcialistes l'option "- config PG_USE_COPY YES" permet dacclrer de
51 - http://www.portailsig.org/content/comment-importerexporter-des-donnees-vers-une-base-de-donneespostgresqlpostgis
52 - http://www.gdal.org/ogr/ogr_formats.html

64

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

64

PostGIS

faon drastique le chargement de gros fichiers avec ogr2ogr.


Dans la version QGIS 2.8 devrait apparatre un algorithme d'import dans le menu
traitement (Processing) 'Import vector into PostGIS database' qui utilisera de faon
transparente ogr2ogr.

B. Utiliser PostGIS depuis QGIS


Il existe deux modalits diffrentes pour lancer PostGIS depuis QGIS.

Ajouter une couche PostGIS


Cliquer sur l'icne Ajouter une couche PostGIS dans la barre d'outils de QGIS.
ou partir du menu Couche puis Ajouter une couche PostGIS (Ctrl+Shift+D).
La fentre suivante apparat.

Ajouter couches PostGIS


Cliquer sur Nouveau pour tablir une nouvelle connexion avec une base PostGIS.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

65

PostGIS
PostGIS

La fentre suivante apparat.

Information de connexion
Une fois les paramtres corrects renseigns et les cases coches, tester ma
connexion, puis cliquer sur OK.

Conse il
Le recours la table de mtadonnes estimes permet d'optimiser la rapidit
d'ouverture du fichier.
L'utilisation du bouton connecter en ayant choisi la connexion donne accs la liste
des schmas et tables de la base.

66

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

66

PostGIS

Liste des tables et schmas

Conse il
Dans le cas de tables volumineuses (comme par exemple la BDParcellaire), il est
conseill d'utiliser le constructeur de requtes (bouton 'Filtrer') pour filtrer les
donnes afficher (par exemple sur une seule commune).
Choisir la table qu'on souhaite afficher dans QGis et cliquer sur Ajouter.
La couche des donnes de PostGIS apparat dans la liste des couches de QGIS et
s'affiche dans la fentre cartographique si on coche son affichage.
L'info-bulle dans le contrle des couches affiche les informations sur l'origine de la
couche (base Sandbox,...)

visualisation dans QGIS

Ajouter des donnes par Gliss / Lch depuis DBManager


Une possibilit trs simple pour ajouter une couche d'une base PostGIS dans QGIS
est de la slectionner depuis DBManager et de faire un gliss / Lch dans QGIS.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

67

PostGIS
PostGIS

C. Utilisation de DBManager avec PostGIS


Comme nous l'avons vu dans le cours sur SpatiaLite, il est possible d'utiliser le plugin
DbManager.
Si la base de donnes PostgreSQL/PostGIS est protge par un mot de passe, il faut
le saisir dans la fentre qui apparat pour cela.
Nous rappelons ici les principales tapes...
La fentre suivante apparat indiquant que la connexion avec la base de donnes
PostgreSQL/PostGIS est effective.
nb : A noter que chaque utilisateur dispose de Privilges qui sont indiqus. C'est
l'administrateur de la base de donnes qui rgles les droits et rles.
Un utilisateur doit pourvoir au minimum 'accder aux objets', un producteur doit
pouvoir 'crer de nouveaux objets'.

DbManager
Cliquer sur le schma utilis ici public puis sur le nom du fichier souhait : ici
route_xy
La fentre suivante apparat indiquant tous les champs attributaires de cette table
PostgreSQL/PostGIS.

68

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

68

PostGIS

table
On peut cliquer sur l'onglet 'Table' pour faire apparatre la table avec ses champs et
ses valeurs, ou 'Aperu' pour avoir un aperu de la gomtrie.
On se propose de slectionner tous les tronons de route de la table route_xy dont le
champ numero comprend la valeur D104.
La requte est : SELECT * FROM route_xy where numero = 'D104'
Aprs avoir cliqu sur le bouton Excuter (F5), la liste des enregistrements de la
table correspondant la requte apparat dans la partie Rsultat de la fentre.
En cochant la case Charger en tant que nouvelle couche, on peut afficher dans QGIS
les donnes rsultant de la requte.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

69

PostGIS
PostGIS

rsultat
Il faut dsigner obligatoirement la colonne avec des valeurs entires et uniques
(identifiant) et la colonne gomtrique.
La colonne Gomtrique peut tre trouve dans l'onglet info de la table sous
DBManager ou l'on voit que le champ 37 est de type geometry(LineString, 2154). La
colonne avec des 'valeurs entires et uniques' est donne par la rubrique Constraint
dans le mme onglet, il s'agit de la colonne gid.
Si nous n'avions pas dispos d'un identifiant de type INTEGER on aurait pu le crer
en modifiant la requte SQL :
SELECT row_number() over() as ident, * FROM "ROUTE_XY" where "Numero" =
'D104'
L'info-bulle de la couche rsultante dans QGIS aprs chargement indique la source :
table ="(SELECT * FROM \"ROUTE_XY\" where \"Numero\" = 'D104'

infobulle dans QGIS

D. Indexation spatiale sous PostGIS


Comme indiqu prcdemment, l'utilisation d'index est une faon habituelle
d'amliorer les performances d'une base de donnes.
L'indexation acclre les recherches en organisant les donnes dans des arbres de
recherche qui peuvent tre parcourus efficacement pour retrouver une entit
particulire.

70

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

70

PostGIS

Mais les index ajoutent aussi une surcharge au systme de base de donnes dans
son ensemble, si bien qu'ils doivent tre utiliss avec discernement.
L'indexation spatiale sous PostGIS utilise l'index GiST (Generalized Search Tree).
Lorsque une table de PostGIS est charge avec l'extension pgShapeLoader, celui-ci
cre automatiquement un index spatial appel table_the_geom_gist.
Il est possible de supprimer cet index.
DROP INDEX table_the_geom_gist
Si l'index n'existe pas il est possible de le crer par la commande suivante :
CREATE INDEX table_the_geom_gist ON table USING GIST (the_geom)
Plus la table est grande, plus le temps d'excution d'une requte utilisant les index
diminue par rapport la mme requte excute sur une table sans index spatial.

L'optimiseur de requtes sous PostGIS


PostGIS possde un planificateur/optimiseur de requte qui utilise une fonction
d'estimation des cots des diffrentes stratgies afin de trouver le chemin le moins
coteux et tablir un plan d'excution optimal.
On trouvera des dtails sur Prsentation des mcanismes internes de PostgreSQL 53.
Il est recommand l'administrateur de la base de lancer une commande
d'analyse et de nettoyage rgulirement afin de maintenir les statistiques utiles la
fonction d'estimation des cots et de rcupration de l'espace libre, suite aux mises
jour. Ceci peut se faire manuellement par une commande VACUUM ANALYSE, et/ou
tre activ automatiquement par le processus autovacuum.
Plus gnralement il est ncessaire de mettre en place des procdures de
maintenance54, mais ceci est en dehors du primtre de cette formation.
En ce qui concerne les relations et fonctions spatiales, l'optimisation passe par
l'utilisation des index Gist et les oprateurs spatiaux utilisant les rectangles
d'encombrement (bounding box) des objets, afin de n'excuter les fonctions utilisant
la gomtrie exacte que sur un sous-ensemble d'objets des tables initiales.
Depuis la version 1.3.0 de PostGIS il n'est plus ncessaire d'utiliser explicitement les
oprateurs utilisant les rectangles d'encombrements (contrairement SpatiaLite)
l'exception notable des fonctions ST_Disjoint et ST_Relate.
Un ordre SQL de type EXPLAIN ANALYZE suivi de la requte permet de rcuprer la
stratgie retenue par l'optimiseur.
Ex : explain analyse select * from d84_commune
renvoi
QUERY PLAN
Seq Scan on d84_commune (cost=0.00..7.51 rows=151 width=4306) (actual
time=0.038..0.283 rows=151 loops=1)
QUERY PLAN
Total runtime: 0.421 ms
Ce qui indique un balayage squentiel de la table d84_commune qui sera excut en
0.421 ms
On trouvera ici55 quelques recommandations pour lesquelles on pourra retenir :
mettre les conditions (where) les plus "rapides" en premier: l'analyseur de
requtes se charge lui-mme d'adopter la stratgie d'excution de la requte
thoriquement la plus rapide. Il dtermine donc l'ordre d'excution des
conditions. Dans certains cas o l'analyseur n'a pas assez d'lments pour
53 - http://docs.postgresqlfr.org/8.3/overview.html
54 - http://www.dalibo.org/glmf109_operations_de_maintenance_sous_postgresql
55 - http://www.portailsig.org/content/postgresql-postgis-bonnes-pratiques-et-astuces

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

71

PostGIS
PostGIS

choisir, mettre en premier la condition la plus "rapide" ou la plus discriminante


permet d'optimiser les requtes.
penser utiliser les sous-requtes56 : dans certains cas, l'utilisation de sous
requtes est plus efficace que les multiples conditions et jointures. Il faut donc
penser tester l'utilisation de sous-requtes, d'autant plus qu'elles
permettent de dcomposer un problme complexe en plusieurs problmes
plus simples. L'utilisation de sous-requte peut cependant paratre complexe
lorsqu'on dbute en SQL... n'hsitez pas vous faire aider pour mettre au
point une requte devant traiter de grosses tables et faire des essais
pralables sur des extraits !
Ce site57 donne galement quelques explications sur le fonctionnement de
l'optimiseur (planner).

E. Exercice 9 : PostGIS
Utilisation de PostGIS
objectif :Importer des donnes dans PostGIS et visualiser une partie des donnes
dans QGIS en ralisant une requte de filtrage.
Question
[Solution n17 p 78]
Importer le fichier shape ROUTE_XY (rpertoire Divers) dans PostGIS en utilisant
l'extension SPIT,
puis,
Dans la table ROUTE_XY, slectionner les tronons de route appartenant la D323 en
utilisant le constructeur de requte de QGIS pour n'ouvrir que cette route dans QGIS.
nb : Choisir UTF-8 comme encodage des caractres.
Importer le fichier shape COMMUNE_DENSITE dans PostGIS partir d'un gliss-Lch
depuis le navigateur de QGIS.

56 - http://sqlpro.developpez.com/cours/sqlaz/sousrequetes/
57 - http://www.postgresql-sessions.org/_media/5/dalibo_optimiseur.pdf

72

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

72

Solution des
exercices

> Solution n1 (exercice p. 26)


SELECT * FROM iris_extrait72 WHERE Nom_com LIKE '%FLECHE%'
On peut aussi utiliser le code INSEE de la commune :
SELECT * FROM IRIS_extrait72 WHERE DepCom = '72154'
On doit obtenir un tableau de 7 lignes avec colonne Nom_Com toujours gale
FLECHE (LA).

> Solution n2 (exercice p. 26)


SELECT nom_comm, population FROM commune WHERE population > 1500 AND
nom_dept='SARTHE'
On doit obtenir un tableau de 2 lignes :
MALICORNE-SUR-SARTHE : 2000
LA FLECHE : 15400

> Solution n3 (exercice p. 26)


SELECT nom_comm AS nom,statut, population, superficie FROM commune WHERE
NOT(statut = 'Chef-lieu de canton')
autres syntaxes possible :
SELECT nom_comm AS nom,statut, population, superficie FROM commune WHERE
statut <> 'Chef-lieu de canton'
SELECT nom_comm AS nom,statut, population, superficie FROM commune WHERE
statut IS NOT 'Chef-lieu de canton'
On doit obtenir un tableau de 18 lignes pour lesquelles le statut est commune simple
ou Sous-prfecture.

> Solution n4 (exercice p. 26)


SELECT DISTINCT toponyme FROM troncon_hydrographique WHERE toponyme LIKE
'%ruisseau%'
la clause DISTINCT permet de supprimer les doublons dans la rponse (on ne
s'intresse ici qu'au tableau de rsultat et pas aux objets gographiques).
On obtient un tableau de 10 lignes. Le toponyme doit contenir 'ruisseau'.

> Solution n5 (exercice p. 27)

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

73

Solution des exercices


Solution des exercices

SELECT nom_dept, sum(population) AS population_dept,


round(avg(cast(population as float)/superficie),2) AS
densite_moy_communes,
max(population) AS pop_max_commune, min(population) AS pop_min_commune,
round(avg(superficie),2) AS surface_moy_commune FROM commune
GROUP BY nom_dept
nb : le cast n'est pas utile si on utilise PostGIS au lieu de spatialite.

> Solution n6 (exercice p. 27)


SELECT nom_comm, round(st_area(geometry)/1000000,2) AS SURFACE_km2,
round(ST_Perimeter(Geometry)/1000,2) AS PERIMETRE_km FROM commune WHERE
nom_dept = 'SARTHE'
La fonction de calcul retourne une valeur dans les units de la projection qui est ici le
mtre, d'o la ncessaire division pour convertir dans les units demandes.
nb : La fonction ST_perimeter() n'est pas disponible dans la version de spatialite
fournie avec QGIS 1.8, on utilise alors Glength(). Elle est disponible dans les
dernires versions (QGIS > 2.2).
sous postGIS on crira :
SELECT nom_comm, round((st_area(geom)/1000000) :: numeric,2) AS
SURFACE_km2, round((ST_perimeter(geom)/1000) :: numeric,2) AS
PERIMETRE_km FROM commune WHERE nom_dept = 'SARTHE'
On obtient un tableau de 16 lignes.
Pour ARTHEZE ont doit obtenir une surface de 8.7 km2 et un primtre de 15.59 km.

> Solution n7 (exercice p. 27)


SELECT toponyme, count(*) AS nbre_troncons, largeur FROM
troncon_hydrographique WHERE toponyme = 'rivire le loir' GROUP BY
largeur
on doit obtenir 3 tronons de 0 15 mtres et 29 tronons de plus de 50 mtres.

Complment
La fonction count() accepte des expressions comme paramtre... on peut par
exemple crire
SELECT count(DISTINCT toponyme) from TRONCON_HYDROGRAPHIQUE qui donne 13
toponymes diffrents dans la table TRONCON_HYDROGRAPHIQUE

> Solution n8 (exercice p. 28)


SELECT LARGEUR, TOPONYME,round(sum(ST_LENGTH(Geometry))/1000,4) AS
Longueur_km FROM TRONCON_HYDROGRAPHIQUE WHERE TOPONYME = 'rivire le
loir' GROUP BY LARGEUR
On doit obtenir :
de 0 15 mtres : 0.7981 km
plus de 50 mtres : 19.3578 km

74

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

74

Solution des exercices

> Solution n9 (exercice p. 32)


Solution : SELECT * FROM ponctuel_hydrographique, commune WHERE
st_within(ponctuel_hydrographique.Geometry, commune.Geometry) AND
commune.nom_comm = 'LA FLECHE'
On retient donc les ponctuels qui sont dans (st_within) les communes et on
slectionne uniquement la commune de la Flche avec AND commune.nom_comm =
'LA FLECHE'
Il doit y avoir 81 ponctuels dans le rsultat.

> Solution n10 (exercice p. 33)


SELECT
nom_comm,
toponyme,
round(sum(st_length(st_intersection(troncon_hydrographique.Geometry,
commune.Geometry))),2) as longueur FROM troncon_hydrographique, commune
WHERE toponyme= 'rivire le loir' AND st_intersects(commune.geometry,
troncon_hydrographique.geometry) GROUP BY nom_comm
et sous PostGIS
SELECT
nom_comm,
toponyme,
round(sum(st_length(st_intersection(troncon_hydrographique.Geometry,
commune.Geometry))) : :
numeric,2)
as
longueur
FROM
troncon_hydrographique, commune WHERE toponyme= 'rivire le loir' AND
st_intersects(commune.geometry, troncon_hydrographique.geometry) GROUP
BY nom_comm
Le rsultat est le suivant :

rsultat Exo7 Question 2

Complment
Lorsque les requtes sont un peu longues, il peut-tre utile d'utiliser des alias pour
pour les noms des tables. Ils s'obtiennent en plaant directement un alias aprs le
nom de table dans la clause FROM
Dans le cas prcdent cela donne :
SELECT
nom_comm,
toponyme,
round(sum(st_length(st_intersection(a.Geometry,b.Geometry))),2) as
longueur FROM troncon_hydrographique a, commune b WHERE toponyme=
'rivire le loir' AND st_intersects(a.geometry, b.geometry) GROUP BY
nom_comm

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

75

Solution des exercices


Solution des exercices

> Solution n11 (exercice p. 33)


SELECT * FROM ponctuel_hydrographique, etablissement WHERE
st_distance(ponctuel_hydrographique.Geometry, etablissement .Geometry) <
5000
ou
SELECT * FROM ponctuel_hydrographique, etablissement WHERE
st_contains(Buffer(etablissement.Geometry, 5000),
ponctuel_hydrographique.Geometry)
sous PostGIS on pourrait utiliser la fonction st_Dwithin()
SELECT * from ponctuel_hydrographique, etablissement WHERE
ST_DWithin(ponctuel_hydrographique.Geometry, etablissement .Geometry,
5000)
On remarquera cependant qu'avec ces requtes les ponctuels qui sont moins de
5000 m de plusieurs tablissements apparaissent plusieurs fois. On peut ajouter une
clause GROUP BY pkuid pour ne les obtenir qu'une seule fois (dans ce cas on n' a
pas tous les tablissements situs moins de 5000 m d'un ponctuel hydrographique,
mais ce n'est pas la question).
Il doit y avoir 86 ponctuels avec le group by et 150 rponses sans le group by
Une autre solution est d'utiliser une union des buffers individuels autour de chaque
tablissement avec la fonction st_union().
La syntaxe qui utilise une sous-requte directement dans la fonction st_contains() est
alors :
SELECT * FROM PONCTUEL_HYDROGRAPHIQUE WHERE ST_contains((SELECT
st_union(st_buffer(Geometry,5000)) FROM ETABLISSEMENT)
,PONCTUEL_HYDROGRAPHIQUE.Geometry)

> Solution n12 (exercice p. 33)


SELECT *, st_distance( MakePoint(X_COMMUNE, Y_COMMUNE,
srid(COMMUNE.Geometry)), etablissement .Geometry) AS distance FROM
etablissement , COMMUNE WHERE commune.nom_comm = 'LA FLECHE' ORDER BY
distance LIMIT 1
On aurait pu galement utiliser la fonction st_centroid() qui donne un centrode
calcul, mais qui est diffrent des coordonnes donnes dans X_COMMUNE et
Y_COMMUNE.
L'identifiant BdCARTO de l'tablissement rpondant la question est 123049.

> Solution n13 (exercice p. 49)

76

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

76

Solution des exercices

solution

> Solution n14 (exercice p. 49)


SELECT *
FROM "ZONE_VEGETATION", "COMMUNE"
WHERE "ZONE_VEGETATION".'NATURE' = 'Fort ferme de conifres' and
"COMMUNE".'NOM'
=
'La
Flche'
and
st_intersects("ZONE_VEGETATION".'Geometry', "COMMUNE".'Geometry')

> Solution n15 (exercice p. 50)


SELECT
round(sum(st_area(st_intersection("ZONE_VEGETATION".'Geometry',"COMMUNE"
.'Geometry'))) / 10000) as surface_ha
FROM "ZONE_VEGETATION", "COMMUNE"
WHERE st_intersects("ZONE_VEGETATION".'Geometry',"COMMUNE".'Geometry')
and "ZONE_VEGETATION".'NATURE' = 'Fort ferme de feuillus' and
"COMMUNE".'NOM' = 'La Flche'

> Solution n16 (exercice p. 50)


La solution est :
SELECT PAI_SANTE.ID, BATI_INDUSTRIEL.ID, st_distance(PAI_SANTE.Geometry,
BATI_INDUSTRIEL.Geometry) AS distance FROM PAI_SANTE,BATI_INDUSTRIEL
WHERE distance IN (SELECT min(st_distance(PAI_SANTE.Geometry,
BATI_INDUSTRIEL.Geometry))
AS
distance_min
FROM
PAI_SANTE,BATI_INDUSTRIEL GROUP BY PAI_SANTE.PKUID)
Pour charger la table dans QGIS on utilisera un 'Create Table & Load in QGIS'
(puisque ce n'est pas un table spatiale).

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

77

Solution des exercices


Solution des exercices

exo8 Q4 rsultat

Complment
Le but de l'exercice est de montrer l'intrt et la syntaxe d'une requte complexe.
Cependant pour rpondre la question pose nous aurions pu utiliser l'outil Vecteur
-> Outils d'analyse -> Matrice des distances.
Cet outil ne fonctionnant que sur des couches de points, il faut au pralable crer la
couche BATI_INDUSTRIEL_CENTROID avec la fonction Vecteur -> Outil de gomtrie
-> Centrodes de polygones.
On utilise ensuite l'outil 'matrice de distances' en choisissant 'Utiliser uniquement les
points cibles les plus proches' avec k=1, Ceci gnre un fichier csv qui donne le
rsultat cherch. Les distances sont un peu diffrentes qu'avec la fonction
st_distance qui utilise le contour des polygones au lieu du centrode.
On pourrait galement utiliser le plugin NNJoin58 qui permet de calculer pour chaque
objet de la couche (input layer), l'objet le plus proche de la couche 'Join vector
Layer', ainsi que sa distance.
Il est possible pour la couche 'input layer' d'utiliser les centroides si la couche n'est
pas une couche de points et pour calculer les objets les plus proches d'utiliser
'Approximate by index geometries' qui utilise les rectangles englobant plutt que la
gomtrie exacte ce qui permet un calcul beaucoup plus rapide.

> Solution n17 (exercice p. 72)


Importation des fichiers dans PostGIS
Lancer l'extension SPIT.

Image 1 Importer des Shapes dans PostgreSQL


Il faut crer une nouvelle connexion ou utiliser une connexion dj cre. Les
paramtres de connexion et la base utiliser sont ventuellement prciss par
l'organisateur de la formation.
Une fois que la connexion est tablie, cliquer sur Ajouter.
Choisir le fichier ROUTE_XY.SHP (rpertoire Divers). Prciser l'encodage UTF-8 (au
lieu la premire fois de 'system' par dfaut).

58 - http://arken.umb.no/~havatv/gis/qgisplugins/NNJoin/

78

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

78

Solution des exercices

Choisir l'encodage du SHP


Le ou les fichiers shape imports dans PostGIS apparaissent dans la liste.
Dans le champ Nom de la colonne de gomtrie, laisser vide, ou saisir le nom de la
colonne de gomtrie du fichier shape ou cocher la case Utiliser le nom de colonne
gomtrique par dfaut (the_geom).
Dans le champ SRID, saisir la valeur 2154 qui correspond au systme de
coordonnes de rfrence (SCR) RGF93/Lambert 93.
Si SPIT renvoi un message du type ERROR : zero-length delimited
identifier at or near """"""
LINE 1 : CREATE TABLE "public"."ROUTE_XY"("" SERIAL PRIMARY KEY, "Id"...
Alors tapez (ou retapez) explicitement un nom dans le champ 'Nom de la cl
primaire' (ce peut-tre 'gid' par exemple, mais ce ne peut-tre un des champs du
fichier SHP).
Cliquer sur OK.
Les donnes sont importes dans PostGIS.

Requte SQL sur une table dans PostGIS


Charger la table PostGIS dans QGIS
Dans la fentre de connexion la table ROUTE_XY dans PostGIS, double-cliquer sur
la table ROUTE_XY.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

79

Solution des exercices


Solution des exercices

constructeur de requte
Double-cliquer sur le champ numro. Ce champ doit apparatre entre "" dans la
fentre Clause SQL WHERE situe en bas de la fentre du constructeur de requtes.
Cliquer sur l'oprateur =. Celui-ci doit apparatre aprs le champ numero dans la
fentre Clause SQL WHERE.
Cliquer sur le bouton Tout. La liste des valeurs du champ numro doit apparatre
dans la partie droite de la fentre.
Choisir la valeur D323. Cette valeur doit apparatre entre '' dans la fentre Clause
SQL WHERE aprs l'oprateur =.
Cliquer sur OK.
Le rsultat doit apparatre dans la fentre cartographique de QGis sous cette forme.

80

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

80

Solution des exercices

QGIS
En cliquant sur la couche on peut afficher la table attributaire et vrifier que les
tronons affichs ont bien la valeur D323 dans le champ numero .

Remarque : Des messages d'erreur possible


si vous rencontrez le message d'erreur :

erreur postgis
Vous n'avez pas indiqu une clef primaire correcte.

Matrise d'ouvrage : MEDDE - METL - MAAF / Matrise d'uvre : ENTE Aix - ENSG /
Licence ouverte ETALAB

81

Solution des exercices


Solution des exercices

Si vous rencontrez le message suivant :

erreur PostGIS
Vous n'avez pas indiqu le bon encodage de caractres (UTF-8 en gnral).
Pour le gliss / lch depuis le navigateur :

Gliss / lch avec DBmanager

82

Matrise d'ouvrage : MEDDE - METL


Matrise
- MAAF
d'ouvrage
/ Matrise
: MEDDE
d'uvre
- METL
: ENTE
- MAAF
Aix - /
ENSG
Matrise
/
d'uvre :
Licence ouverte ETALAB
ENTE Aix - ENSG / Licence ouverte ETALAB

82