Cartographie et SIG interactifs en ligne
Transcription
Cartographie et SIG interactifs en ligne
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.