Cartographie et SIG interactifs en ligne

publicité
Atelier Cartographie octobre 2004
Département de Géographie / UTM
Laurent Jégou
[email protected]
DESS Sigma : Module 233
Cartographie et SIG interactifs en ligne
Séance 3 : Introduction à PostgreSQL, PostGIS et AsSVG.
1°) Présentation du système
Un des moyens les plus utilisés pour stocker les données SIG utilisées par MapServer est le duo
PostgreSQL+PostGIS. Le principe est de faire gérer toutes les données, même géométriques, par un
Système de Gestion de Bases de Données (relationnel), pour apporter une plus grande intégration avec les
données attributaires, les tables, et une meilleure gestion de l'information.
PostgreSQL (http://www.postgresql.org/) se revendique comme le SGBD OpenSource le plus
« sophistiqué » du monde. C'est en effet un système très puissant et très ouvert, en constante évolution. Au
départ réservé au monde Unix, PostgreSQL a été porté depuis sous Windows, ce qui permet une intégration
plus simple à MS4W.
PostGIS (http://postgis.refractions.net/) est une extension de PostgreSQL qui ajoute des fonctions de
stockage et de requêtes spatiales au SGBD. On peut ainsi stocker sous forme de tables des couches SIG
complètes, munies de leurs données attributaires, et composées d'éléments géométriques variés.
Concrètement une telle couche SIG devient une table PGSQL munie d'un champ supplémentaire,
comprenant les données géométriques décrites dans une syntaxe propre. Il existe des convertisseurs simples
pour intégrer des couches SIG aux formats courants : shapesfiles, mapinfo.
AsSVG (http://svg.cc/pg/assvg/) est une extension de PostGIS qui permet de convertir les données
géométriques PostGIS en syntaxe SVG, directement dans le SGBD. Les résultat d'une requête PGSQL
pourra ainsi être retourné sous la forme de commandes de dessin SVG, facilement intégrables dans un
document.
2°) Installation
Étant des projets OpenSource destinés en priorité au monde Unix, le mode d'installation normal de
ces logiciels se base sur une configuration/compilation/installation des sources. Donc jusqu'à il y a peu, pour
pouvoir utiliser PostgreSQL sous windows, il fallait l'installer avec CygWin, système qui émule une machine
linux sous windows. Depuis la version 8.0 de PostgreSQL est disponible une version native win32, installable
sur tout système compatible (de NT 4.0 à XP pro). Mais le problème réside dans la nécessité de devoir
compiler PostGIS en même temps que PostgreSQL... et idem pour AsSVG.
La solution mise au point par de sympathiques développeurs à été de compiler des exécutables win32
directement depuis les sources de ces trois applications, on peut donc aujourd'hui installer ce système assez
facilement, en utilisant leur productions :
http://www.webbased.co.uk/mca/
http://www.01map.com/download/ (Jean-David Techer, auteur de nombreux tutoriaux sur PostGIS)
L'installation est détaillée sur cette page : http://www.01map.com/david/doc/postgis090/
Dans le cas de notre installation, il faut créer un utilisateur classique « sigma » sur le poste Windows XP, doté
du mot de passe « sigma » (pour faire simple).
Le lancement de PostGreSQL en tâche de fond se fait dans une fenêtre de commande de l'utilisateur
sigma (si vous êtes en session administrateur, lancez une fenêtre de commandes au nom de l'utilisateur
sigma par la commande : runas /noprofile /user:sigma cmd), puis dans la fenêtre de comande exécuter
postmaster (lancement de PostgreSQL).
Pour initialiser la base de donénes de l'utilisateur sigma, il faut, toujours dans une fenêtre de commandes à
son nom, se rendre dans le répertoire C:\PostgreSQLWin32, charger les variables globales en lançant
set_env.bat, puis lancer la commande : initdb.
3°) Découverte de PostgreSQL+PostGIS
a) Ajout d'une interface graphique utilisateur.
Le premier frein à l'utilisation de PostgreSQL est l'absence d'interface. En effet, le logiciel « tourne »
sous la forme de services systèmes, et les opérations de gestion s'effectuent à la ligne de commande.
Heureusement, il existe des logiciels qui proposent de faciliter ces opérations par le biais d'une interface
graphique, c'est ce que l'on appelle des « front-ends » ou devantures, par exemple :
pgAdmin3 : http://www.pgadmin.org/
pgAccess : http://www.pgaccess.org/index.php?page=Users
DbVisualizer : http://www.dbvis.com
phpPGAdmin : http://phppgadmin.sourceforge.net/
Ce dernier utilitaire est intéressant car totalement en php il ne demande pas d'installation et s'utilise dans une
fenêtre de navigateur Internet classique.
Installation de phpPGAdmin :
–
–
–
télécharger le fichier .zip
le décompresser dans le répertoire C:\ms4w\Apache\htdocs\test
éditer le fichier de configuration /conf.config.config.inc.php :
– ajouter « localhost » pour obtenir : $conf['servers'][0]['host'] = 'localhost';
Pour vérifier le bon fonctionnement de l'installation, vérifiez bien que postmaster est lancé sur la
machine, et allez avec votre navigateur sur l'adresse : http://localhost/test/phppgadmin, choisissez l'utilisateur
sigma, le mot de passe sigma, sur le serveur par défaut « postgreSQL », et la langue française. En modifiant
la configuration, vous pouvez aussi utiliser phppgadmin pour contrôler un serveur postgreSQL distant.
b) Intégration d'une couche SIG.
Pour nos tests PostGIS, nous allons travailler avec une couche des communes de Midi-Pyrénées,
fournie au format shapefile (répertoire /test/regcom73). L'intégration dans une base PgSQL peut s'effectuer à
la ligne de commande ou en utilisant un script php réalisé par J.D. Techer. Mais, avant tout, il faut créer une
nouvelle base et lui apporter les extensions PostGIS :
A la ligne de commande, il faut ouvrir une fenêtre de commandes sous le nom de l'utilisateur PostgreSQL :
–
exécuter : runas /noprofile /user:sigma cmd
–
dans la fenêtre de comande faire :
cd C:\PostgreSQLWin32
createdb testgis
createlang plpgsql testgis
psql -d testgis -c "\i share/postgresql/postgis.sql"
psql -d testgis -c "\i share/postgresql/spatial_ref_sys.sql"
Pour convertir un shapefile en table PGSQL, il faut utiliser le programme en ligne de commande
« shp2pgsql » qui est fourni avec PostGIS : http://www.01map.com/david/doc/postgis090/ch02s05.html
L'utilisation ce fait selon cette syntaxe :
shp2pgsql -D shapefile nom_de_la_table nom_de_la_base | psql nom_de_la_base
(notez le caractère « pipe » utilisé, obtenu avec la combinaison alt gr + 6)
Ce programme va générer un fichier de script .sql qui contient en fait les commandes en langage
SQL nécessaires pour créer et remplir notre nouvelle table. Dans phpPgAdmin, il suffit ensuite de se rendre
sur la base « testgis », de choisir l'onglet « sql » et d'importer le script SQL qui vient d'être généré.
Exercice : intégrer la couche shape regcom73 (fournie) dans une table pgsql nommée identiquement dans la
base testgis de l'utilisateur sigma
Attention, pour pouvoir utiliser des couches SIG de grande taille, et possédant de nombreux champs
attributaires, il est préférable de construire un index. Comme dans toute base de données, l'index servira à
accélérer la recherche des informations. Dans le cas de l'indexation de données SIG, il faut construire l'index
sur la colonne des géométries (par défaut elle se nomme « the_geom »), en utilisant un type particulier :
GiST. Les « Generalized Search Tree » sont bien adaptés à des données de contenu irrégulier, ne possédant
pas de structure répétitive. Comme nos géométries peuvent êtres diverses, selon le type d'objet mais surtout
selon sa complexité en éléments géométriques simples, le type GiST sera approprié.
Dans PhpPGAdmin, il faut sélectionner la table, cliquer sur le menu « index », puis choisir la colonne des
géométries, et dans « index type » choisir « GiST ». Les index facilitent, améliorent, accélèrent les requêtes
sur les champs qu'ils recouvrent. On peut donc créer des index simples sur le champ des géocodes et des
noms des communes, pour compléter le premier index consacré aux informations topologiques de la couche
vectorielle.
Pour réaliser cette indexation sans utiliser phpPgAdmin, il faut lancer la console de PostgreSQL (toujours
sous utilisateur sigma), par la commande : psql testgis. L'indexation de la table se fait par la commande SQL
suivante : CREATE INDEX regcom73ndx on regcom73 USING GIST. Pour avoir des informations sur la
table, on peut utiliser \d recom73. \q permet de quitter la console.
c) Requête simple : affichage d'une couche.
Pour commencer, nous allons demander à PostGIS de simplement fournir les données géométriques
à MapServer pour un affichage sous forme d'image bitmap. Pour ce faire, il faut écrire un mapfile contenant
une couche dont les données sont issues d'une liaison PostGIS :
MAP
EXTENT 3852699.9709013 -260100.031703873 4159699.98477761 15299.9461098508
IMAGECOLOR 255 255 255
IMAGETYPE PNG
SIZE 500 700
STATUS ON
UNITS METERS
NAME "Communes"
LAYER
NAME "Communes"
CONNECTION "user=sigma password=sigma dbname=testgis host=localhost"
CONNECTIONTYPE POSTGIS
DATA "the_geom from regcom73 as foo using unique geometry_columns.srid using
SRID=-1"
STATUS DEFAULT
TYPE POLYGON
UNITS METERS
CLASS
OUTLINECOLOR 128 0 0
END
END
END
Les paramètres importants sont la connexion et la source de données, qui est ici de la forme : « DATA
<colonne géom> from <table ou requête> », en langage SQL. PostGIS apporte une aide intéressante pour
trouver l'extent d'une couche directement, sans avoir à la mesurer dans un SIG. Il suffit d'utiliser la fonction du
même nom dans une fenêtre de commande SQL :
select extent(the_geom) from regcom73;
(Sous phpPgAdmin il faut se connecter, cliquer sur la base postgis, la liste des tables, puis la table
« communes », et cliquer sur le menu « SQL ». Apparaît la fenêtre de commande SQL, dans laquelle on peut
saisir la fonction, toujours suivie d'un point-virgule, et cliquer sur le bouton « GO »).
Cette fonction retourne une valeur de type Box3D (3D possible) :
BOX3D(3852699.9709013 -260100.031703873 0,4159699.98477761 15299.9461098508 0)
Une box3D est définie par un couple de triplets, pour les valeurs minimum et maximum. Ici, la 3° dimension
n'est pas renseignée, la fonction retourne donc une valeur nulle.
Pour en faire un EXTENT, il suffit de supprimer les valeurs nulles d'altitude et la virgule qui sépare les
triplets.
d) Requête simple : sélection sur critères
Le paramètre DATA peut contenir une requête comme source de données, du moment que les objets
retournés sont des géométries. On peut donc faire des sélections paramétrées directement dans le mapfile
(ou dans une page PHPMapScript).
Exemple, la sélection des communes de l'arrondissement de Foix :
DATA "the_geom from (select the_geom from regcom73 where (lib_arr = 'FOIX')) as
foo using unique geometry_columns.srid using
SRID=-1"
Exercice :
Réaliser une requête qui sélectionne les communes du bassin de
vie quotidienne de Cadours.
e) Requêtes spatiales.
La puissance de PostGIS se mesure réellement à sa capacité de répondre à des requêtes de type
SIG, sur des paramètres spatiaux. La liste des fonctions comprises dans l'extension PostGIS est longue
(http://postgis.refractions.net/docs/ch05.html#id3228815), on y retrouve les requêtes géométriques de base
(distance, surface, géométrie booléenne, géométrie relative des objets), mais aussi des outils plus avancés
comme la génération de zones tampons, le calcul de coques convexes, et les manipulations de projections.
* Aire de la commune de Toulouse (attention à utiliser des apostrophes plutôt que des guillemets) :
select Area2d(the_geom) from regcom73 where (nom = 'TOULOUSE');
* Liste des communes dont un des points composant le polygone est à moins de 5Kms d'un point du
polygone de Toulouse (unités en mètres) :
select nom from regcom73 where Distance((select the_geom from
regcom73 where nom = 'TOULOUSE'), regcom73.the_geom)<5000;
* Liste des communes jointives à Toulouse :
select nom from regcom73 where Touches((select the_geom from regcom73 where nom =
'TOULOUSE'), regcom73.the_geom);
Pour utiliser ces fonctions dans une génération de carte par MapServer, il faut les utiliser directement
dans comme paramètre DATA, en tenant compte du fait que ce paramètre demande obligatoirement des
objets géométriques uniques, donc la requête distance ci-dessus devient, par exemple :
DATA "the_geom from (select the_geom from regcom73 where Distance((select
the_geom from regcom73 where nom = 'TOULOUSE'), regcom73.the_geom)<5000) as foo
using unique geometry_columns.srid using SRID=-1"
Exercice : Afficher la carte des communes jointives de la commune de Cadours.
4°) La génération de sorties vectorielles avec AsSVG.
AsSVG est une fonction supplémentaire à PostGIS qui apporte la possibilité de générer du format
SVG directement en sortie de PgSQL. Ainsi, au lieu de ne retourner que la colonne géométrique
« the_geom », on retournera AsSVG(the_geom).
a) usage de la fonction AsSVG dans PostGIS
Pour observer ce type de réponse à la source, essayons dans le module de commande SQL de phpPgAdmin,
en demandant la liste des noms des communes et les coordonnées du centroïde exprimées en syntaxe
SVG :
select nom, AsSVG(PointOnSurface(the_geom)) from regcom73;
La réponse est ce de type :
nom
assvg
AIGUES-JUNTES
cx="3999572.58999018"
cy="206149.969047248"
AIGUES-VIVES
cx="4033064.59347419"
cy="212899.971311721"
AIGUILLON (L')
cx="4034934.03265133"
cy="222600.038219596"
ALBIES
cx="4018292.91372494"
cy="239699.986667888"
ALEU
cx="3982977.30552718"
cy="223550.051269048"
Lorsqu'on demande la conversion des géométries en format SVG, en utilisant AsSVG(the_geom),le retour est
présenté selon le type de géométrie. Ici nos communes de Midi-Pyrénées sont des multipolygones, le retour
SVG sera de type path. Par exemple, pour le polygone de la commune de Toulouse :
select AsSVG(the_geom) from regcom73 where (nom = 'TOULOUSE')
Le retour est :
M 3995699.99341306 137400.028733048 3997299.94302683 138400.054530024
3997499.99401692 137800.01613649 3998299.96882381 137699.990641444 ...
Cette syntaxe SVG signifie qu'un chemin (path) commence par un déplacement du crayon (commande M)
aux coordonnées fournies, puis les commandes L (ligne, segment) sont omises mais le chemin passe par les
coordonnées (couples de valeurs) qui suivent.
Exercice :
Afficher sous phpPgAdmin la géométrie des communes du bassin
de vie quotidienne de Grenade au format SVG.
b) utilisation de PHP pour générer un fichier SVG à partir d'une couche SIG PostGIS.
L'utilité première du format SVG est d'être un format vectoriel lisible avec un simple navigateur doté
du plugin éponyme. Ainsi, l'application cliente peut recevoir des données vectorielles, sous la forme de code
SVG, qui est en fait du XML, donc un format texte. Cela permet une très bonne optimisation de la connexion
entre serveur et client, les données textuelles se compressant bien.
L'affichage d'un fichier SVG passe par l'inclusion en tant qu'objet (balise <embed>) dans un fichier HTML,
d'un lien vers un fichier SVG localisé sur le serveur. Pour générer un tel fichier SVG à partir d'une couche
SIG stockée dans une base PostGIS, nous allons utiliser un script PHP (source Jean-David Techer). Le script
va réaliser les opérations suivantes :
–
–
–
récupération des données SIG retournées au format SVG par AsSVG
formatage et écriture du fichier SVG
génération de la page HTML qui va intégrer ce fichier.
Cf. listing commenté ci-joint. Pour activer la gestion des sources de donénes postGreSQL dans php, il faut
modifier le fichier c:\ms4w\Apache\cgi-bin\php.ini pour enlever le point virgule devant la ligne
extension=php_pgsql.dll (à peu près au milieu du fichier).
Exercice :
Afficher les polygones et les noms des communes de la région
Midi-Pyrénées dont la superficie est supérieure à 80Km² dans
un document SVG généré par un script PHP.
Téléchargement