: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.
: Function eregi_replace() is deprecated in /home/www/drupal_old/postgis.fr/modules/smileys.module on line 90.

 Table des matières

Charte des documentations collaboratives de PostGIS.fr
Devenir rédacteur pour PostGIS.fr
Syntaxe
Insérer du code dans une documentation
Listes de fonctions
Type de donnée
Vous manquez d'inspiration ou vous avez du mal à traduire un terme particulier ?
Guide d'installation des outils dédiés au serveur cartographique internet sous Debian Sarge Minimal
Les divers outils à installer
Avant d'installer
Création de l'utilisateur postgres
Installaton des paquets debian requis
Installation de PROJ et de GEOS
Installation de PostgreSQL et de PostGIS
Initialisation de PostgreSQL et test de création d'une base avec PostGIS
À retenir pour Démarrer/Arrêter le serveur PostgreSQL
Installation de GD
Installation de PDFLIB
Installation de PHP
Configuration en tant que CGI
Chargement du module Actions avec Apache
Installation de CURL
Installation de GDAL
Installation de MapServer
Librairie PHPMapScript
Test 1: PhpInfo
Test 2: Affichage de la carte d'Europe
Chargement des données et visualisation
Librairie PgRouting (version 1.0.0a)
Prérequis
Installation
Guide de l'utilisateur
Création de données pour l'application de routage
Plus court chemin avec l'algorithme Dijkstra (sans heuristique)
Fonction A*
Fonction Shooting*
Fonction Driving Distance
Fonction TSP
Fonctions géométriques
Tutoriels pgRouting
Comment utiliser des routes à sens unique
Utiliser l'exemple mis à disposition sur le site de postlbs.
Afficher directement le résultat dans MapServer.
Manuel PostGIS 1.4.0
Chapitre 1. Introduction
1.1. Remerciements
1.2. Pour plus d'informations
1.3 Traducteurs
Chapitre 2. Installation
2.1 Version courte
2.2. Prérequis
2.3. Obtenir le code source
2.4. Installation
2.4.1. Configuration
2.4.2. Compilation
2.4.3. Tests
2.4.4. Installation
2.5. Créer une base de données spatiales
2.6. Créer des bases de données spatiales à partir d'un modèle
2.7. Mise à jour
2.7.1. Mise à jour 'légère'
2.7.2. Mise à jour 'complète'
2.8. Problèmes fréquents
2.9. JDBC
2.10. Importeur/Exporteur
Chapitre 3. Foire aux questions
3.1. Quel type d'objets géométriques puis-je stoquer ?
3.2. Comment insérer un objet SIG dans la base de données ?
3.3. Comment construire une requête spatiale ?
3.4. Comment rendre plus rapide des requêtes spatiale sur de grandes tables ?
3.5. Pourquoi les arbres R de PostgreSQL ne sont-ils pas supportés ?
3.6. Pourquoi dois-je utiliser la fonction AddGeometryColumn() et toutes les autres fonctions de l'OpenGIS ?
3.7. Quelle est la meilleure façon de trouver tous les objets autour d'un autre ?
3.8. Comment puis-je appliquer une reprojection de coordonnées dans une requête ?
Chapitre 4. Utiliser PostGIS
4.1. Objets SIG
4.1.1. Les formats WKB et WKT de l'OpenGIS
4.1.2. PostGIS EWKB, EWKT et formes canoniques
4.1.3. SQL-MM Partie 3
4.2. Utilisation des standards de l'OpenGIS
4.2.1. La table SPATIAL_REF_SYS
4.2.2. La table GEOMETRY_COLUMNS
4.2.3. Créer une table spatiale
4.2.4. Assurer la conformité OpenGIS des géométries
4.3. Chargement de données SIG
4.3.1. Utilisation de code SQL
4.3.2. Utiliser l'importeur
4.4. Accéder aux données SIG
4.4.1. Utilisation du SQL
4.4.2. Utilisation de l'exporteur
4.5. Création d'index
4.5.1. Les index GiST
4.5.2. Utilisation des index
4.6. Requêtes complexes
4.6.1. Tirer avantage des indexes.
4.6.2. Exemple de SQL spatial
4.6.2.1. Quelle est la longueur totale en kilomètres de toutes les routes ?
4.6.2.2. Quelle est l'aire en hectare de la ville Prince George ?
4.6.2.3. Quelle est la plus grande municipalité (aire) de la province ?
4.6.2.4. Quelle est la longueur des routes totalement contenues dans chaque municipalités ?
4.6.2.5. Créer une nouvelle table contenant toutes les routes de la ville de Prince George.
4.6.2.6. Quelle est la longueur en kilomètre de "Douglas St" à Victoria ?
4.7. Utilisation de Mapserver
4.7.1. Utilisation de base
4.7.2. Questions fréquemment posées
4.7.2.1. Lorsque j'utilise une EXPRESSION dans ma map, la condition ne retourne jamais vrai, même si elle devrait.
4.7.2.2. Le FILTER que j'utilise pour mon fichier vecteur ne fonctionne pas pour ma table PostGIS contenant les mêmes données.
4.7.2.3. Ma couche PostGIS se dessine plus doucement que mon fichier vecteur, est-ce normal?
4.7.2.4. Mes couches PostGIS s'affichent correctement, mais les requêtes sont vraiment lentes. Que se passe-t-il ?
4.7.3. Utilisation avancée
4.7.4. Exemples
4.8. Clients Java (JDBC)
4.9. Clients C (libpq)
4.9.1. Curseurs Text
4.9.2. Curseurs Binaires
Chapitre 5. Performance, trucs et astuces
5.1. Petites tables comportant de vastes objets géométriques
5.1.1. Description du problème
5.1.2. Solutions de contournement
5.2. Faire des CLUSTER sur des index géométriques
5.3. Eviter la conversion de dimensions des données
Chapitre 6. Référence des fonctions PostGIS
6.1. Fonctions OpenGIS
6.1.1. Fonctions de gestion
6.1.2. Fonctions "relationelles"
6.1.3. Fonctions de traitement géométrique
6.1.4. Accès aux caractéristiques géométriques
6.1.5. Constructeurs géométriques
6.2. Extensions PostGIS
6.2.1. Fonctions de gestion
6.2.2. Opérateurs
6.2.3. Fonctions de mesure
6.2.4. Extraction d'informations géométriques
6.2.5. Constructeurs géométriques
6.2.6. Éditeur géométriques
6.2.7. Mise en référence linéaire
6.2.8. Fonctions diverses
6.2.9. Support des transactions longues
6.3. Fonctions SQL-MM
6.4 Fonctions ArcSDE
Chapitre 7. Signaler des bogues
Appendix A. Release Notes
A.1. Release 1.1.1
A.1.1. Upgrading
A.1.2. Bug fixes
A.1.3. New functionalities
A.2. Release 1.1.0
A.2.1. Credits
A.2.2. Upgrading
A.2.3. New functions
A.2.4. Bug fixes
A.2.5. Function semantic changes
A.2.6. Performance improvements
A.2.7. JDBC2 works
A.2.8. Other new things
A.2.9. Other changes
A.3. Release 1.0.6
A.3.1. Upgrading
A.3.2. Bug fixes
A.3.3. Improvements
A.4. Release 1.0.5
A.4.1. Upgrading
A.4.2. Library changes
A.4.3. Loader changes
A.4.4. Other changes
A.5. Release 1.0.4
A.5.1. Upgrading
A.5.2. Bug fixes
A.5.3. Improvements
A.6. Release 1.0.3
A.6.1. Upgrading
A.6.2. Bug fixes
A.6.3. Improvements
A.7. Release 1.0.2
A.7.1. Upgrading
A.7.2. Bug fixes
A.7.3. Improvements
A.8. Release 1.0.1
A.8.1. Upgrading
A.8.2. Library changes
A.8.3. Other changes/additions
A.9. Release 1.0.0
A.9.1. Upgrading
A.9.2. Library changes
A.9.3. Other changes/additions
A.10. Release 1.0.0RC6
A.10.1. Upgrading
A.10.2. Library changes
A.10.3. Scripts changes
A.10.4. Other changes
A.11. Release 1.0.0RC5
A.11.1. Upgrading
A.11.2. Library changes
A.11.3. Other changes
A.12. Release 1.0.0RC4
A.12.2. Library changes
A.12.3. Scripts changes
A.12.4. Other changes
A.13. Release 1.0.0RC3
A.13.1. Upgrading
A.13.2. Library changes
A.13.3. Scripts changes
A.13.4. JDBC changes
A.13.5. Other changes
A.14. Release 1.0.0RC2
A.14.1. Upgrading
A.14.2. Library changes
A.14.3. Scripts changes
A.14.4. Other changes
A.15. Release 1.0.0RC1
A.15.1. Upgrading
A.15.2. Changes
Manuel PostGIS avec JTS
Prérequis
Compilation des sources de JTS et création de l'archive JAR
Création des librairies dynamiques et des fichiers d'entêtes
Tester la liaison à la librairie libjts.so à l'aide des exemples fournis
Installation de JTS et création de l'utilitaire jts-config
Compilation de PostGIS et liaison avec JTS
Manuels Mapserver
Génération d'une imagemap à partir d'une couche PostGIS
1. Génération d'une imagemap simple
2. Problème avec les géométries de type MULTIPOLYGON
PostGIS.fr au Colloque SIG Libres : Logiciels et données, Services géographiques de Toulouse.
Accueil, ambiance générale et organisation
Le monde du libre _ Jean-Christophe BECQUET (APITUX)
PostgreSQL et Stunnel
Sécurisation simple en utilisant un tunnel ssh
Prérequis
Démarrage du serveur PostgreSQL
Création du tunnel ssh

Charte des documentations collaboratives de PostGIS.fr

Ce document vous explique comment contribuer à la rédaction de documentations pour le site PostGIS.fr.

haut de la page | table des matières

Devenir rédacteur pour PostGIS.fr

Avant de pouvoir contribuer à la rédaction de documentations pour PostGIS.fr, vous devrez nous informer de votre volonter de participer à ce projet. Pour ce faire il vous suffit de contacter l'un des administrateurs de ce site (dont voici les membres : djay david jad bernd01map jasmine lsouk).

Une fois cette étape passée, vous serez informé par mail de la validation ou non de votre compte rédacteur. Ne vous inquiétez pas vous n'aurez pas à recréer un compte utilisateur ou effectuer la moindre maipulation, ce travail incombe aux administrateurs du site et ne nécessite aucune intervention de votre part ormis l'émission du mail.

Lorsque vous avez reçu le mail de confirmation de la création de votre compte rédacteur, vous êtes alors fin prêt à participer aux diverses documentations proposées sur le site PostGIS.fr. Vous trouverez plus d'informations sur la marche à suivre pour traduire ou participer correctement à la rédaction de documentations dans le chapitre suivant (qui reste à rédiger Eye-wink ).

haut de la page | table des matières

Syntaxe

Dans cette section nous expliciterons les diverses syntaxes utilisées pour rédiger des documentations sur le site postgis.fr.

haut de la page | table des matières

Insérer du code dans une documentation

Afin d'inserer du code dans une documentation, il existe deu xsyntaxe différentes, suivant les cas. Si votre code doit être inclus dans une ligne, vous utiliserez la syntaxe suivante :

<code>mon code</code>
. Si votre code doit être considéré comme un bloc à part entière, vous utiliserea alors la syntaxe suivante :
<div class="code"> le code en question </div>
haut de la page | table des matières

Listes de fonctions

Lorsque vous souhaitez lister un ensemble de fonctions dans une documentation vous devez utiliser la syntaxe suivante :

<dl>
<dt><span class="term"> nom de la fonction : </span></dt>
<dd>

description
</dd>
<dt><span class="term"> nom d'une autre fonction : </span></dt>
<dd>

une autre description
</dd>
[...]
</dl>

haut de la page | table des matières

Type de donnée

Lorsque vous parlez d'un type de données cartographiques dans une documentation sur le site postgis.fr, ce dernier doit être contenu dans le balisage utilisé pour insérer du code dans une documentation, comme décrit ici.

Par exemple pour parler d'un objet de type POINT, vous utiliserez la syntaxe suivante :

<code>POINT</code>
haut de la page | table des matières

Vous manquez d'inspiration ou vous avez du mal à traduire un terme particulier ?

Dans le cas où vous ne sauriez trop quel terme utiliser lors de votre traduction, vous pouvez vous rendre sur cette page afin de trouver l'inspiration :

haut de la page | table des matières

Guide d'installation des outils dédiés au serveur cartographique internet sous Debian Sarge Minimal

Le présent document fournit les diverses commandes à effectuer pour la mise en place d'un serveur cartographique à partir d'outils open-source sur un système GNU/ Linux .
Les points abordés concernent :

haut de la page | table des matières

Les divers outils à installer

Le tableau suivant liste l'ensemble des outils à installer:

Tableau 1. Les outils à installer

PROJ 4.4.9 ftp://ftp.remotesensing.org/proj/proj-4.4.9.tar.gz
GEOS 2.1.3 http://geos.refractions.net/geos-2.1.3.tar.bz2
POSTGRESQL 8.0.3 ftp://ftp3.fr.postgresql.org/pub/postgresql/source/v8.0.3/postgresql-8.0.3.tar.bz2
POSTGIS 1.0.3 http://postgis.refractions.net/download/postgis-1.0.3.tar.gz
GD 2.0.33 - par apt-get -
PDFLIB 5.0.3
PHP 4.3.11
CURL 7.10.5
GDAL 1.2.0
MAPSERVER 4.4.2

Les adresses données ici ont été testées et validées pour la journée du mercredi 4 mai 2005. On pourra obtenir les sources à partir de wget et d'un simple shell. Par exemple:

wget ftp://ftp.remotesensing.org/proj/proj-4.4.9.tar.gz
wget http://geos.refractions.net/geos-2.1.3.tar.bz2

haut de la page | table des matières

Avant d'installer

Pour procéder aux installations, il faudra avoir le compte root de la machine.

haut de la page | table des matières

Création de l'utilisateur postgres

Nous aurons aussi recours à un utilisateur normal. Dans ce document, la session de l'utilisateur normal sera postgres. C'est avec ce compte postgres que nous utiliserons PostgreSQL. Toutes les sources des outils du tableau précédent seront mis dans /home/postgres/src. Tout en étant root sur la machine, créons notre utilisateur et notre répertoire :

adduser postgres
mkdir /home/postgres/src

Comme mot de passe, nous choisirons ici postgres. Pour cette dernière commande c'est le mot de passe à saisir en deux fois.

haut de la page | table des matières

Installaton des paquets debian requis

Afin de garantir une installation conforme du serveur, la distribution GNU/Linux Debian Sarge Minimal doit être complétée par des paquets Debian. Nous allons les installer grâce à l'utilitaire de gestionnaire de paquets apt-get:

Nous aurons besoin d'installer

À l'aide des commandes suivantes :

apt-get install bzip2
apt-get install zip
apt-get install unzip
apt-get install zlib1g
apt-get install zlib1g-dev
apt-get install mysql-server-4.1
apt-get install apache
apt-get install apache-ssl
haut de la page | table des matières

Installation de PROJ et de GEOS

Il s'agit d'une installation standard du monde GNU/Linux. PROJ est un paquetage permettant de tirer profit des systèmes de projection spatial, notamment des reprojections entre divers systèmes (Lambert II étendu, Lambert III etc...)

cd /home/postgres/src
wget ftp://ftp.remotesensing.org/proj/proj-4.4.9.tar.gz
tar xvzf proj-4.4.9.tar.gz
cd proj-4.4.9
./configure && make && make install

Occupons-nous maintenant de GEOS. Ce paquetage contient notamment une librairie qui permet d'ajouter des fonctionnalités supplémentaires à PostGIS notamment Within(), Intersects()...Pour son installation , nous ferons

cd /home/postgres/src
wget http://geos.refractions.net/geos-2.1.3.tar.bz2
tar xvjf geos-2.1.3.tar.bz2
cd geos-2.1.3
./configure && make && make install

Les librairies concernant GEOS et PROJ (libgeos.so, libproj.so ...) sont dans le répertoire /usr/local/lib. Il faut inclure ce chemin dans le fichier /etc/ld.so.conf en fin de fichier
echo /usr/local/lib >> /etc/ld.so.conf

Pour que le système charge dans son cache les librairies qui viennent juste d'être créées, nous saisirons la commande : ldconfig .

Pour vérifier que PROJ et GEOS ont respectivement bien été installés, la commande
proj devrait nous renvoyer :

Rel. 4.4.9, 29 Oct 2004
usage: proj [ -beEfiIlormsStTvVwW [args] ] [ +opts[=arg] ] [ files ]
et pour GEOS, la commande geos-config --version, devrait nous renvoyer 2.1.1.

haut de la page | table des matières

Installation de PostgreSQL et de PostGIS

On va commencer par PostgreSQL. Nous nous occuperons de PostGIS plus tard.

cd /home/postgres/src
wget ftp://ftp3.fr.postgresql.org/pub/postgresql/source/v8.0.3/postgresql-8.0.3.tar.bz2
tar xvjf postgresql-8.0.3.tar.bz2
cd postgresql-8.0.3
./configure --prefix=/usr/local --without-readline --enable-multibyte --with-CXX --enable-nls
make
make install

On s'occupe maintenant de PostGIS

cd /home/postgres/src
wget http://www.01map.net/download/sources/postgis-1.0.3.tar.gz
tar xvzf postgis-1.0.0.tar.gz
cd postgis-1.0.3
autoconf
./configure --with-geos=/usr/local/bin/geos-config --enable-autoconf --with-proj=/usr/local
--with-pgsql-src=/home/postgres/src/postgresql-8.0.3
make
make install

Pour s'assurer que PostgreSQL a été installé, nous utiliserons les commandes suivantes which pg_config; for i in 'version' 'bindir' ; do pg_config --$i;done qui devraient nous renvoyer :

/usr/local/bin/pg_config
PostgreSQL 8.0.3
/usr/local/bin

indiquant que PostgreSQL a bien été installé dans le répertoire /usr/local et que la version en cours est la 8.0.2.

haut de la page | table des matières

Initialisation de PostgreSQL et test de création d'une base avec PostGIS

ATTENTION : contrairement aux autres sections, cette section doit avoir lieu sous la session de l'utilisateur postgres dans un terminal. L'initialisation va avoir lieu avec la commande initb ....La création de la base - testgis - sera rendue possible par la saisie des 4 dernières commandes ci-dessous(createb ..., createlang, psql ...).

su postgres
initdb -A trust -E SQL_ASCII -D /home/postgres/pgdata
pg_ctl -o -i -D /home/postgres/pgdata start
createdb testgis
createlang plpgsql testgis
psql -d testgis -f /usr/local/share/postgresql/contrib/lwpostgis.sql
psql -d testgis -f /usr/local/share/postgresql/contrib/spatial_ref_sys.sql

haut de la page | table des matières

À retenir pour Démarrer/Arrêter le serveur PostgreSQL

Tout démarrage/arrêt doit être effectuer sous la session (terminal) de l'utilisateur postgres. On utilisera pour ce faire la commande :

haut de la page | table des matières

Installation de GD

Pour GD, nous utiliserons directement l'installation par apt-get. Avant de procéder à l'installation, il nous faut vérifier que la version utilisée est la 2.0.33-1.1 ou au moins une version supérieure ou égale à la 2.0.15 . Pour celà, la commande suivante apt-cache show libgd2 | grep Version devrait renvoyer Version: 2.0.33-1.1.

Si la version est bonne, alors installons GD en faisant

apt-get install libgd2
apt-get install libgd2-dev
haut de la page | table des matières

Installation de PDFLIB

C'est une installation usuelle comme pour Geos et Proj:

cd /home/postgres/src
wget http://www.01map.net/download/sources/PDFlib-Lite-5.0.3-Unix-src.tar.gz
tar xvzf PDFlib-Lite-5.0.3-Unix-src.tar.gz
cd PDFlib-Lite-5.0.3-Unix-src
./configure && make && make install
haut de la page | table des matières

Installation de PHP

ici, nous allons procéder à l'installation de PHP, puis sa configuration avec Apache en tant que CGI (Common Gateway Interface).

cd /home/postgres/src
wget http://www.01map.net/download/sources/php-4.3.11.tar.bz2
tar xvjf php-4.3.11.tar.bz2
cd php-4.3.11
./configure --enable-fastcgi --with-config-file=/var/www/php.ini --with-gd=/usr
--with-pdflib=/usr/local --with-png-dir=/usr --with-freetype-dir=/usr --with-zlib=/usr --with-pgsql
--with-regex=system --enable-dbase --enable-dbx --with-jpeg-dir=/usr --enable-versioning
make
make install

Si on souhaite vérifier que PHP a été installé, on effectuera le test suivant php-config --version qui nous renverra 4.3.11.

haut de la page | table des matières

Configuration en tant que CGI

Il nous maintenant copier l'executable PHP (CGI) résultant dans le répertoire d'Apache fournit à cet effet /usr/lib/cgi-bin/.
cp /usr/local/bin/php /usr/lib/cgi-bin/

Pour que PHP soit configuré en tant que CGI, nous allons ajouter quelques lignes au fichier de configuration d'Apache à savoir /etc/apache/httpd.conf

echo ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ >> /etc/apache/httpd.conf
echo AddType application/x-httpd-php .php .php3 .php4 >> /etc/apache/httpd.conf
echo Action application/x-httpd-php \"/cgi-bin/php\" >> /etc/apache/httpd.conf

haut de la page | table des matières

Chargement du module Actions avec Apache

La dernière ligne de la sous-section précédente -celle contenant le mot-clé Action - nécessite un module qu'Apache a besoin de charger. Or il se peut que cette dernière ne soit pas chargée par défaut. Pour le vérifier, nous allons charger le module en faisant:
apache-modconf apache enable mod_actions
Il se peut qu'une interface graphique se charge alors à l'écran. Le cas échéant il se peut que l'écran apparaisse avec un fond bleu. Le seul impératif est de répondre par oui en ce qui concerne la question de garder la configuration actuelle du serveur - concernant ici le fichier de configuration /etc/apache/httpd.conf.

haut de la page | table des matières

Installation de CURL

C'est ici une installation standard

cd /home/postgres/src
wget http://www.01map.net/download/sources/curl-7.10.5.tar.gz
tar xvzf curl-7.10.5.tar.gz
cd curl-7.10.5
./configure && make && make install

Pour vérifier que CURL a été installé, le test suivant
for i in 'version' 'prefix'; do curl-config --$i;done
devrait renvoyé comme résultat

libcurl 7.10.5
/usr/local
haut de la page | table des matières

Installation de GDAL

C'est l'avant-dernier outil à installer

cd /home/postgres/src
wget http://www.01map.net/download/sources/gdal-1.2.0.tar.gz
tar xvzf gdal-1.2.0.tar.gz
cd gdal-1.2.0
/configure -- with-libz=/usr --with-png=/usr --with-libtiff=internal --with-geotiff=internal
--with-jpeg=/usr
make
make install

La commande suivante for i in 'version' 'prefix'; do gdal-config --$i;done, doit renvoyer comme résultat :
1.2.0
/usr/local

haut de la page | table des matières

Installation de MapServer

C'est ler dernier outil à installer. Avant tout, vous devez télécharger les sources de mapserver à partir cette page. Il n'y a pas de 'make install' avec MapServer

cd /home/postgres/src
tar xvzf mapserver-version.tar.gz
cd mapserver-version
./configure --without-tiff --with-jpeg=/usr --with-png=/usr \
--with-threads --with-proj --with-postgis --with-pdf \
--with-mapscript --with-gdal=/usr/local/bin/gdal-config \
--with-gd=/usr --with-freetype=/usr --with-ogr --with-wmsclient\
--with-wfs --with-wfsclient \
--with-php=/home/postgres/src/php-4.3.11
make

haut de la page | table des matières

Librairie PHPMapScript

La librairie PHPMapScript - fichier php_mapscript.so -doit être mis dans le répertoire des extensions de PHP. Or il se peut que ce répertoire spécifique à PHP n'existe pas encore. Pour connaître le chemin d'accès à ce répertoire, il suffit de taper : php-config --extension-dir qui devrait renvoyer quelque chose semblable à : /usr/local/lib/php/extensions/no-debug-non-zts-20020429

Il se peut que les deux répertoires extensions et no-debug-non-zts-20020429 n'existent pas. Il faudra alors les créer. On pourra alors par exemple les créer en essayant les commandes suivantes -à adapter -

mkdir /usr/local/lib/php/extensions
mkdir `php-config --extension-dir`

Il nous faut maintenant copier la librairie php_mapscript.so dans ce répertoire: cp /home/postgres/src/mapserver-4.4.2/mapscript/php3/php_mapscript.so `php-config --extension-dir`

haut de la page | table des matières

Test 1: PhpInfo

En faisant un phpinfo() - fonction interne de PHP -, il va nous être possible de savoir si PHP a bien été configuré en tant que CGI et que PHPMapScript a été chargé-. Le mieux est de copier le contenu suivant dans un fichier /var/www/phpinfo.php : <? dl("php_mapscript.so");phpinfo();> sinon pour créer ce fichier à partir d'un terminal, on pourra essayer echo "<? dl("php_mapscript.so");phpinfo();>" >> /var/www/phpinfo.php.

On démarre ensuite le serveur Apache en faisant apachectl start.

On ouvre ensuite un navigateur (Mozilla...) en pointant vers l'URL suivante : http://localhost/phpinfo.php.

Vous devriez vous retrouver avec un des tabeaux apparaissant dans la page dont le contenu est

Tableau 2. MapScript

MapServer Version MapServer version 4.4.2 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG
OUTPUT=WBMP OUTPUT=PDF SUPPORTS=PROJ SUPPORTS=FREETYPE
SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT
SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT INPUT=EPPL7
INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE
PHP MapScript Version ($Revision: 1.220.2.3 $ $Date: 2005/02/28 14:27:19 $)

La présene de ce tableau confirme bien que le chargement de PHPMapScript a réussi.

haut de la page | table des matières

Test 2: Affichage de la carte d'Europe

Ici, nous allons afficher les données concernant une petite carte d'Europe. Les données seront importées dans la base de données testgis que nous avons créées - voir section "Initialisation de PostgreSQL et test de création d'une base avec PostGIS"-....

haut de la page | table des matières

Chargement des données et visualisation

L'ensemble des données ainsi que les scripts php nécessaires se trouve dans un fichier compressé au format zip sur le site de 01map...;Commençons par le télécharger et le décompresser dans le répertoire /var/www. Les dernières lignes de commandes -chmod ....- nous permettront d'accorder les divers droits d'exécution (lecture et exécution) dans ce répertoire

cd /var/www
wget http://www.postgis.fr/download/phpmapscript.zip
unzip phpmapscript.zip
chmod 777 /var/www/phpmapscript/
chmod 777 /var/www/phpmapscript/*.*

On s'assurera d'abord que le serveur PostgreSQL est bien démarré en faisant

su postgres
pg_ctl -D /home/postgres/pgdata status
qui devrait renvoyer pg_ctl: postmaster is running [....] .

Sinon démarrez-le et tapez la ligne de commande suivante qui va permettre d'importer les données du fichier europesvg.shp dans la base de données testgis. L'utilitaire de conversion shp2pgsql permet de convertir les données d'un fichier .shp en données PostGIS. Il s'agit ici pour nous d'importer les données dans une table que nous appelerons europe.

su postgres
shp2pgsql -D /var/www/phpmapscript/europesvg.shp europe | psql testgis

Vérifiez que Apache est lancé..;Sinon faites apachectl start.

Ouvrez ensuite un navigateur Web et rendez-vous à l'URL suivante http://localhost/phpmapscript/.

Saisissez comme nom d'utilisateur postgres. En cliquant sur 'Envoyer', la carte suivante devrait apparaître:

Figure 1. Carte de l'Europe
Carte de l'Europe

haut de la page | table des matières

Librairie PgRouting (version 1.0.0a)

Cette librairie contient l'implémentation des algortihmes suivants :

La documentation originale peut être trouvée ici.

haut de la page | table des matières

Prérequis

haut de la page | table des matières

Installation

Étape 1 : intallation des libraries
Compiler et installer PostgreSQL, PostGIS, Proj, GEOS, BGL et GAUL. Il est habituellement suffisant d'utiliser : ./configure; make; make install dans les répertoires correspondants.

Si vous avez installé BGL mais que la version est inférieure à la 1.33.0, téléchargez simplement le fichier astar.hpp depuis http://www.boost.org/boost/graph/astar_search.hpp et copiez le dans le répertoire BOOST_PATH/graph.

La librairie GAUL doit être compilée avec l'option --no-slang. Sinon assurez-vous d'avoir le fichier slang.h installé dans le répertoire /usr/include. Pour plus de détails merci de vous référer au fichier README ou INSTALL.

Pour CGAL, les options de compilation suivantes peuvent être utilisés pour créer la librairie :

./install_cgal --prefix=/usr/local/cgal --with-boost=n --without-autofind -ni /usr/bin/g++

Étape 2 : compilation de la librairie pgRouting

Dans le cas où il y aurait 2 versions dePostgreSQL installés sur l'ordinateur (par exemple une 7.4 et une 8.1), assurez-vous que le pg_config de la version que vous souhaitez utiliser est dans la variable d'environnement PATH.

Pour compiler pgRouting, lancer la commande "configure" devrait suffir. Si les librairies BOOST, GAUL ou CGAL ne sont pas dans les chemins par défaut, il sera alors necéssaire de spécifier à configure où elles peuvent être trouvées. Taper ./configure --help listera l'ensemble des options de configuration.

Tapez ./configure --with-cgal=/usr/local/cgal --with-gaul=/usr/local

Taper make install

Étape 3: installation de la base de données

Pour créer une base de données de routage exemple utilisez les commandes suivantes :

PGSQL_PATH/bin/createdb -E UTF-8 routing
PGSQL_PATH/bin/createlang plpgsql routing
PGSQL_PATH/bin/psql -f PGSQL_PATH/share/contrib/lwpostgis.sql routing
PGSQL_PATH/bin/psql -f PGSQL_PATH/share/contrib/spatial_ref_sys.sql routing
PGSQL_PATH/bin/shp2pgsql -D kanagawa.shp kanagawa > kanagawa.sql
PGSQL_PATH/bin/psql -f dourol.sql DB_NAME

Pour augmenter la rapiditer d'exécution, créez des index pour la table kanagawa.

create index gid_idx on kanagawa(gid);
create index source_idx on kanagawa(source);
create index target_idx on kanagawa(target);
create index geom_idx on kanagawa using GIST (the_geom GIST_GEOMETRY_OPS);

Chargez le fichier sql routing.sql pour installer les fonctions dans votre base de données

PGSQL_PATH/bin/psql -f routing.sql DB_NAME

Charger le fichier routing_postgis.sql qui créera les fonctions PostGIS d'import et de manipulation des données.

PGSQL_PATH/bin/psql -f routing_postgis.sql DB_NAME

haut de la page | table des matières

Guide de l'utilisateur

Le fonctionnalités essentielles sont définies dans le fichier routing.sql. Ces fonctions attendent en entrée des données dans un format spécifique.

Pour renvoyer des données elles utilisent le type suivant :

CREATE TYPE path_result AS (vertex_id integer, edge_id integer, cost float8);

Cela renvoit un type qui peut être utilisé pour générer des résultats géographiques qui seront décrits plus tard.

haut de la page | table des matières

Création de données pour l'application de routage

Les logiciels de routage requièrent toujours un noeud source et destination pour chaque arc afin de créer une recherche du plus court chemin. La création de ces données sur des réseaux de lignes implique la création de la topologie de ce réseau. Bien que pgDijkstra donne la possibilité de créer les noeuds sources et destinations dans PostgreSQL, les performances ne sont pas bonne, parfois cette opération peut prendre un jour ou plus pour un grand nombre de données (le paramétrage de la base de donnée peux réduire le temps necéssaire).

Il y a d'autre logiciel qui peuvent être utilisés pour créer une topologie plus rapidement.

Certains d'entre eux sont :

PostGIS

Lors de la rédaction de cette documentation, la dernière version de PostGIS (1.1.2), a commencé à ajouter des fonctionnalités topologiques. Mais cela reste dans un état de développement très primaire et il y a encore très peu de documentation sur la création de topologies. Cette page sera mise à jour lorsque les fonctionnalités topologiques de PostGIS seront dans un état suffisament stable pour être utilisées.

ArcInfo

Pour ceux qui possède un licence ArcInfo, la création de topologie est faite simplement en utilisant la commend build: build line {Coverage Name} et en exportant ensuite la couverture dans un fichier vecteur, qui peut être ensuite importé dans PostGIS. La commande build va créer les colonnes fnode_,tnode_,length qui peuvent être renommées dans PotgreSQL comme source,target, et la colonne length peut être utilisé comme le coût intial.

GRASS

GRASS peut aussi être utilisé pour créer une topologie, mais l'extraction de l'information topologique et l'insertion dans PostgreSQL n'est pas aussi simple que dans ArcInfo puisque l'information topologique n'est pas inclue dans l'ensemble des donnée lors de l'export dans un fichier vecteur.

La commande de création de topologie, v.build, a un option dump qui permet d'afficher l'information dans un flux qui peut être redirigé dans un fichier. Par exemple :

v.build map=dourol option=build,dump > dourokukan.txt

La sortie devrait ressembler à cela :

---------- TOPOLOGY DUMP ----------
N,S,E,W,T,B: 35.897887, 24.281578, 153.985841, 138.943042, 0.000000, 0.000000
Nodes (148304 nodes, alive + dead ):
node = 1, n_lines = 3, xy = 139.756532, 35.67451
line = 1, type = 2, angle = -2.265356
line = -20, type = 2, angle = -0.055499
line = 8, type = 2, angle = 1.281166
node = 2, n_lines = 3, xy = 139.756261, 35.674216
line = -9, type = 2, angle = -2.827622
line = 2, type = 2, angle = -1.878154
...
...
...
Lines (220672 lines, alive + dead ):
line = 1, type = 2, offset = 14 n1 = 1, n2 = 2, left/area = 0, right = 0
N,S,E,W,T,B: 35.674510, 35.674216, 139.756532, 139.756261, 0.000000, 0.000000
line = 2, type = 2, offset = 79 n1 = 2, n2 = 3, left/area = 0, right = 0
N,S,E,W,T,B: 35.674216, 35.672010, 139.756261, 139.755285, 0.000000, 0.000000
line = 3, type = 2, offset = 160 n1 = 3, n2 = 4, left/area = 0, right = 0
N,S,E,W,T,B: 35.672010, 35.671649, 139.755285, 139.755014, 0.000000, 0.000000

Un programme perl comme celui-ci (table_topo.pl) peut être utilisé pour convertir la sortie de GRASS dans un fichier SQL qui créera les table de noeuds et d'arcs contenant l'imformation topologique. Ces tables peuvent ensuite être liés dans la table réseau de PostGIS pour créer les information source-destination.

haut de la page | table des matières

Plus court chemin avec l'algorithme Dijkstra (sans heuristique)

La fonction shortest_path est définie de la manière suivante :

CREATE OR REPLACE FUNCTION shortest_path(sql text, source_id integer, 
       target_id integer, directed boolean, has_reverse_cost boolean) 
    RETURNS SETOF path_result
Les arguments sont les suivants :
sql
une requête SQL qui doit renvoyer les champs suivants :
SELECT id, source, target, cost FROM edge_table;
  • id: l'identifiant entier (int4) de l'arc
  • source: un identifiant entier (int4) du noeud de départ
  • target: un identifiant entier (int4) du noeud d'arrivée
  • cost: le coût de la traversée d'un arc (float8, un coût négatif permet de s'assurer qu'on ne passera jamais par cette arc)
  • reverse_cost : (optionel) le coût de la traversée de l'arc en sens invers. Cela n'estutilisé que lorsque la fonction est appelé avec l'argument has_reverse_cost à vrai.
source_id
identifiant du noeud de départ.
target_id
identifiant du noeud d'arrivée.
directed
vrai si le graphe est orienté.
has_reverse_cost
vrai si la colonne reverse_cost doit être considérée lors de la recherche du plus court chemin, dans le cas où lma traversée de l'arc se fait en sens invers.
Cette fonction renvoit un ensemble de tuples. Il y a un tuple par arc traversé et un tuple supplémentaire à la fin contenant le noeud d'arrivée. Les colonnes de chaque lignes sont les suivants : Exemple :
SELECT * FROM shortest_path('SELECT gid AS id, source::int4, 
          target::int4, length::double precision AS cost,
    FROM dourol',3, 7, false, false);
 vertex_id | edge_id | cost 
-----------+---------+------------------------
         3 |       2 |    0.000763954363701041
         4 |      21 |    0.00150254971056274
         6 |       5 |    0.000417442425988342
         7 |      -1 |    0
(4 rows)
SELECT * FROM shortest_path('SELECT gid AS id, source::int4, 
         target::int4, length::double precision AS cost,length::double precision 
    AS reverse_cost FROM dourol', 3, 7, true, true);
haut de la page | table des matières

Fonction A*

La fonction shortest_path_astar est définie de la façon suivante :

CREATE OR REPLACE FUNCTION shortest_path_astar(sql text, source_id integer, target_id integer, directed boolean, has_reverse_cost boolean)
RETURNS SETOF path_result

Les arguments sont :

Fonction Shooting*

La fonction shortest_path_shooting_star est définie de la façon suivante :

CREATE OR REPLACE FUNCTION shortest_path_shooting_star(sql text, source_id integer, target_id integer,directed boolean, has_reverse_cost boolean)
RETURNS SETOF path_result

Les arguments sont :

sql
une requête SQL, qui doit renvoyer un ensemble de lignes ayant les mêmes colonnes que celles nécessaires à A* plus :

  • rule: une chaîne de caractère contenant une liste d'identifiants d'arcs, séparés par une virgule, qui décrit le sens giratoir (si je suis sur tel tronçon je peux aller sur tel tronçon avec le coût décrit dans la colonne to_cost)
  • to_cost : le coût d'un passage restrain (peut être très élevé dans le cas où le fait de tourner vers tel arc entraine le passage par un feu)

source_id
int4 identifiant de l'arc de départ
target_id
int4 identifiant de l'arc d'arrivé
directed
vrai si le graphe est orienté
has_reverse_cost
si sa valeur est vrai, la colonne reverse_cost du résultat SQL généré sera utilisé pour le coût de la traversé d'un arc dans la direction oposée.

La fonction renvoie un ensemble de lignes équivalent à celui renvoyé par A* mis à part que le dernier coût retourné n'est pas -1.

Exemple:

SELECT * from shortest_path_shooting_star('SELECT id, source, target, cost,
x1, y1, x2, y2, rule, to_cost FROM edges', 17, 9, true, false);
vertex_id | edge_id | cost
----------+---------+------------------------
       16 |      17 | 1
       15 |      16 | 1
        2 |       5 | 1
        3 |       4 | 1
       20 |      12 | 2
       10 |       9 | 2
(6 rows)


haut de la page | table des matières

Fonction Driving Distance

La fonction driving_distance est définie comme suit :

CREATE OR REPLACE FUNCTION driving_distance(sql text, source_id integer,distance float8)
RETURNS SETOF path_result

Les arguments sont :

sql
une requête SQL, qui devrait renvoyer un ensemble de lignes ayant les colonnes suivantes :

  • id: un identifiant (int4) de l'arc
  • source: un identifiant (int4) du noeud origine
  • target: un identifiant (int4) du noeud destination
  • cost: une valeur float8 représentant le coût de traversé d'un arc. (un coût négatif entrainera la non insertion de l'arc dans le graphe).

source_id
un identifiant (int4) du point de départ id of the start point
distance
une valeur float8 de la distance en degrés

La focntion renvoie un ensemble de lignes. Il y a une ligne pour chaque arc tranversés et un ligne supplémentaire contenant le noeud terminal. Les colonnes de chaque lignes sont :

Fonction TSP

La fonction tsp est définie comme suit :

CREATE OR REPLACE FUNCTION tsp(sql text, ids varchar, source_id integer)
RETURNS SETOF path_result

Les arguments sont :

sql
un requête SQL qui devrait retourner un ensemble de lignes ayant les colonnes suivantes :

  • source_id: un int4 identifiant du noeud
  • x: la coordonée x du noeud
  • y: la coordonée y du noeud

ids
une chaîne de charactères contenant les idetifiants (int4) des noeuds séparés par une virgule.
source_id
identifiant (int4) du point de départ

La fonction renvoie un ensemble de lignes. Il y a une ligne pour chaque arc travsersé et une en plus contenant le noeud final. Les colonnes de chaques lignes sont les suivantes :

Exemple:

SELECT * from tsp('select distinct source as source_id,
x1::double precision as x,
y1::double precision as y from dourol
where source in (83593,66059,10549,18842,13)',
'83593,66059,10549,18842,13', 10549);
vertex_id | edge_id | cost
----------+---------+------
    10549 |       0 |     0
    83593 |       0 |     0
    66059 |       0 |     0
    18842 |       0 |     0
       13 |       0 |     0
(5 rows)

Ensuite la colonne vertex_id peut être utilisée pour le calcul du plus court chemin.

haut de la page | table des matières

Fonctions géométriques

Il y a de nombreuses fonctions dans le fichier routing_postgis.sql qui renvoient le résultat sous la forme d'une geometrie (objet de type geometry). Vous pouvez trouver leur noms facilement - elles contiennent "as_geometry".

haut de la page | table des matières

Tutoriels pgRouting

Vous trouverez ici de courts articles et des tutoriels.
(Pour commencer il n'y a pas de structuration spéciale du contenue, simplement une listes de liens)

haut de la page | table des matières

Comment utiliser des routes à sens unique

Les deux algorithmes Dijkstra et A* permettent de calculer le coût pour chaque orientation de l'arc d'un graphe, ce qui peut être très utile lors de la recherche de chemins avec un réseau routier qui a des rues en sens uniques.

Ce petit exemple illustrera comment cela est fait. Les données utilisées dans cet exemple ont été créées en utilisant OpenJump et ont ensuite été charger dans une base de données PostGIS pour laquelle pgRouting à aussi été installlé.

Le graphe ressemble à ceci; remarquez que l'arc #2 à été arienté de droite à gauche, contrairement à la plupart des arcs qui ont été orienté de gauche à droite. Cela a été fait comme cela pour simuler une route à sens unique.

Lors du calcul pour le coût de chaque coté d'un arc, un champ représentant le coût inverse (rcoast) doit être passer en argument à l'olgorithme de routage.

Intiallement, les deux coût (coast,rcoast) ont la même valeur qui est la longueur de l'arc.

routing=# update rtest set
          cost=length(the_geom),rcost=length(the_geom);
UPDATE 5

Ensuite, pour agmenter le coût inverse de l'arc n°2 , une valeur de 1000000 sera ajouter à la valeur de la colonne rcoast.

routing=# update rtest set rcost = rcost + 1000000
          where gid = 2;

routing=# select gid,cost,rcost,source,target
          from rtest
          order by gid;

gid |        cost      |         rcost       | source | target
----+------------------+---------------------+--------+--------
 1  | 90.4777391240398 | 90.4777391240398    |      1 |      2
 2  | 266.663211021467 | 000266.663211021467 |      3 |      2
 3  | 74.7975644284963 | 74.7975644284963    |      2 |      4
 4  | 264.887335603738 | 264.887335603738    |      4 |      5
 5  | 49.0618009646755 | 49.0618009646755    |      3 |      5
(5 rows)

Le dernier argument passé aux algoithmes Dijkstra et A* détermine si le coût inverse doit aussi être calculé lors de la recherche d'un chemin à travers le graphe.

Lorsque vous lui attribué la valeur faux, les deux algorithmes effectueront la recherche en utilisant uniquement le paramètre coût, qui est simplement dans ce cas la longueur de chaque arc. Avec notre exemple, nous trouverons un chemin partant du noeud n°1 jusqu'au noeud n°3.

routing=# select * 
          from shortest_path_astar(
            'select gid as id,
                    source::int4,
                    target::int4,
                    cost::double precision,
                    rcost::double precision as reverse_cost,
                    x1,y1,x2,y2 
             from rtest',
             1,3,false,false);

 vertex_id | edge_id |      cost
-----------+---------+------------------
       1   |     1   | 90.4777391240398
       2   |     2   | 266.663211021467 
       3   |    -1   |  0
(3 rows)

Maintenant, si nous attribuons la valeur vrai au paramètre inverse, les algorithmes utilseront alors le coût inverse, ils constateront que le noeud 2 de l'arc n°2 a un coup très élevé et chercheront donc un autre chemin.

routing=# select * 
          from shortest_path_astar(
            'select gid as id,
                    source::int4,
                    target::int4,
                    cost::double precision,
                    rcost::double precision as reverse_cost,
                    x1,y1,x2,y2 
             from rtest',
             1,3,false,true);

vertex_id | edge_id |       cost
----------+---------+------------------
       1  |      1  |  90.4777391240398           
       2  |      3  |  74.7975644284963           
       4  |      4  |  264.887335603738
       5  |      5  |  49.0618009646755
       3  |     -1  |   0
(5 rows)

Bien que nous ayons la possibilité de calculer le coût de chaque sens de l'arc, c'est très astucieux, cela reste néanmoins très couteux puisqu'il influera fortement sur les performances et devrait donc être utilisé seulement lorsque c'est vraiment nécessaire.

routing=# explain analyze 
          from shortest_path_astar(
            'select gid as id,
                    source::int4,
                    target::int4,
                    cost::double precision,
                    rcost::double precision as reverse_cost,
                    x1,y1,x2,y2 
             from rtest',
             1,3,false,false);

                               QUERY PLAN 
--------------------------------------------------------------------------------
Function Scan on shortest_path_astar  (cost=0.00..12.50 rows=1000 width=16) 
(actual time=0.954..0.958 rows=3 loops=1)  Total runtime: 1.020 ms
(2 rows)

routing=# explain analyze 
          from shortest_path_astar(
            'select gid as id,
                    source::int4,
                    target::int4,
                    cost::double precision,
                    rcost::double precision as reverse_cost,
                    x1,y1,x2,y2 
             from rtest',
             1,3,false,false);

                               QUERY PLAN 
--------------------------------------------------------------------------------
Function Scan on shortest_path_astar  (cost=0.00..12.50 rows=1000 width=16) 
(actual time=11.088..11.093 rows=5 loops=1)  Total runtime: 11.155 ms
(2 rows)

"

haut de la page | table des matières

Utiliser l'exemple mis à disposition sur le site de postlbs.

Dans cette section nous allons vous expliquer comment utiliser l'exemple mis à notre disposition sur le site de postlbs (cf. ce lien).

Prérequis :

Afin de mettre en pratique ce petit tutoriel, il est nécessaire que vous ayez installé les logiciels listés ci-dessous :

Création initiale de la base de données de test :

La première étape consiste à créer une base de données nommée routing et d'y importé les fonctionnalités de PostGIS et de pgRouting. Pour ce faire je vous conseil de vous référer à la section "Installation" du présent manuel (l'étape 3).

Afin de pas avoir à faire trop de modifications dans la mapfile dont nous parlerons plus loin, je vous conseil aussi de créer cette base de données en tant qu'utilisateur postgres sans quoi vous devrez éditer la mapfile routing.map se trouvant dans routingj/maps/ afin d'y modifier le nom d'utilisateur utilisé dans la chaîne de connection des deux couches PostGIS.

Décompression du projet de démonstration de postlbs :

Avant d'aller plus loin, nous allons télécharger l'archive de démonstration du projet postlbs puis la décompresser dans le répertoire racine de votre aborescence apache, j'utiliserais dans la suite de ce tutoriel /var/www/localhost/htdocs comme répertoire racine.

Télécharger l'archive au format bzip2, puis rendez-vous dans le repertoire /var/www/localhost/htdocs afin d'y décompressez le fichier fraîchement téléchargé à l'aide de la commande suivante : tar -xvf pgRouting-sampleapp.tar.bz.
Une fois ceci fait vous êtes fin prêt pour intrégrer les données contenues dans le répertoire : /var/www/localhost/htdocs/routingj/data.

Cette partie peut donc être résumé par les lignes de commande suivantes :

cd
wget http://www.postlbs.org/postlbs-cms/files/downloads/pgRouting-sampleapp.tar.bz
cd /var/www/localhost/htdocs/routingj/
tar -xvf ~/pgRouting-sampleapp.tar.bz

 

Convertion d'un réseau routier en une couche PostGIS et créationd es indexes :

Maintenant que nous avons une base avec PostGIS et pgRouting d'activé et que nous avons décompresser l'archive contenant la démonstration de postlbs, nous pouvons charger nos données de tests. Pour ce faire, il suffit de se rendre dans le répertoire routingj/data à la racine de votre serveur web afin de créer le fichier sql correspondant au fichier vecteur kanagawa.shp. Pour ce faire nous utilisons l'outils shp2pgsql comme nous en avons l'habitude, nous chargeons ensuite ce fichier dans notre base de données routing et nous finissons par créer les indexes nécessaires :

shp2pgsql -D -c kanagawa kanagawa > kanagawa.sql
psql routing
create index k1 on kanagawa using gist (the_geom GIST_GEOMETRY_OPS);
create index k2 on kanagawa( source );
create index k3 on kanagawa( target );
vacuum full;

Voilà nous venons d'intégrer les données de démonstration de postlbs dans notre base de données nommée routing, nous pouvons maintenant passé à la configuration de notre application de démonstration.

Modifications nécessaires au bon fonctionnement de l'application :

Pour ma part je paramettre toujours mon php.ini pour qu'il charge php_mapscript, c'est ce qui explique que je doive supprimer les chargement dynamique contenus dans les diverses pages du projet de démonstration, cette manipulation n'est donc à faire que dans le cas où vous avez php_mapscript d'activé dans votre php.ini. Pour réaliser cette modification, il suffit de lancer la commande suivante :

for i in $(find /var/www/localhost/htdocs/routingj/phtmls/);do
  sed "s:dl:\#dl:g" -i $i
done

De même les références à la mapfile dont nous avons parlé plus tôt ne fonctionnaient pas avec un chemin relatif, c'est pourquoi j'ai pour ma part modifier ces références de la manière suivantes :

for i in $(find routingj/phtmls/); do
  sed "s:../maps:/var/www/localhost/htdocs/routingj/maps:g" -i $i
done

J'ai aussi due modifier le fichier maps/routing.map afin d'y modifier les valeurs pour le répertoire où seront stoquées les images générées dans la section WEB.
J'ai donc la section WEB suivante :

  WEB
    IMAGEPATH "/var/www/localhost/htdocs/routingj/tmp/"
    IMAGEURL "/routingj/tmp/"
  END

 

Consultation de l'application de démonstration :
Une fois que vous avez réalisé toutes les étpaes précédantes, vous devriez pouvoir tester l'application en vous rendant sur la page de votre serveur web, en supposant que ce soit sur localhost, rendez-vous sur la page : http://localhost/routingj/ et utilisez les liens présents sur cette pages afin de tester les diverses fonctionnalités.

Si vous voulez un exemple en "live", j'ai installé l'application de démonstration de postlbs sur un portable sous gentoo, librement accessible ici.

haut de la page | table des matières

Afficher directement le résultat dans MapServer.

(Author: Camptocamp/ pgDijkstra)

La fonction shortest_path_as_geometry() peut être utilisée dans la définition d'une couche MapServer pour afficher directement le plus court chemin :

LAYER
    NAME "europe"
    TYPE LINE

    STATUS DEFAULT
    CONNECTIONTYPE postgis
    CONNECTION "user=postgres host=localhost dbname=geo"
    DATA "the_geom from (SELECT the_geom, gid from
        shortest_path_as_geometry('bahnlinien_europa_polyline', 2629, 10171)) AS
        foo using unique gid using srid=-1"
    TEMPLATE "t"
    CLASS
        NAME "0"
        STYLE
            SYMBOL "circle"
            SIZE 10
            COLOR 50 50 100
        END
    END
END

Notez cependant que cette fonction est appelée à chaque affichage de la carte, calculant le plus court chemin à chaque fois.

Une meilleur approche serait de générée le plus court chemin et de le stoquer dans une table temporaire.

haut de la page | table des matières

Manuel PostGIS 1.4.0

Résumé

PostGIS est une extension du système de gestion de bases de données relationnel à objets PostgreSQL qui permet de stocker des objets SIG dans une base. PostGIS contient la gestion des index spatiaux de type "arbres de recherches généralisés" (GiST) sur arbre R, et des fonctions de calcul et d'analyse des objets géographiques.

(Ce manuel correspond à la version 1.4.0)

haut de la page | table des matières

Chapitre 1. Introduction

PostGIS est développé par la companie Refractions Research Inc dans le cadre d'un projet de recherche sur les bases de données spatiales. Refractions est une société de conseil dans le domaine du SIG et des bases de données, basée au Canada, à Victoria, Colombie Britanique, elles est spécialisée dans l'intégration de données et le développement de logiciels spécifiques. Ils ont prévu d'aider et de développer PostGIS afin de supporter un nombre important de fonctionnalités SIG, incluant un support complet de l'OpenGIS, la construction topologique avancée (couvertures, surfaces, réseaux), des interfaces utilisateurs permettant de visualiser et d'éditer des données SIG, et des applications accessibles via le web.

haut de la page | table des matières

1.1. Remerciements

Sandro Santilli :
coordination de toutes les corrections de bogues et des efforts de maintenance, intégration des nouvelles fonctionnalités de GEOS, et amélioration des nouvelles fonctions.
Mark Leslie
Maintenances et développements continus des fonctions 'coeurs'.
Chris Hodgson :
maintient les nouvelles fonctions et la liaison avec l'index 7.2.
Paul Ramsey :
maintient les objets JDBC et conserve une trace de la documentation et du packaging.
Jeff Lounsbury :
développement initial du chargeur/extracteur de fichier vecteur.
Dave Blasby :
le développeur à l'origine de PostGIS. Dave a écrit les objets côté serveur, liaison avec les indexs, et certaines des fonctions analytiques côté serveur.
Autres contributeurs :
Par ordre alphabétique : Alex Bodnaru, Alex Mayrhofer, Bernhard Reiter, Bruno Wolff III, Carl Anderson, Charlie Savage, David Skea, David Techer, IIDA Tetsushi, Geographic Data BC, Gérald Fenoy, Gino Lucrezi, Klaus Foerster, Kris Jurka, Mark Cave-Ayland, Mark Sondheim, Markus Schaber, Michael Fuhr, Nikita Shulga, Norman Vine, Olivier Courtin, Ralph Mason, Steffen Macke.
Un grand merci à :
la bibliothèque d'opérations géométriques GEOS, et la partie algorithmique qui est le travail de Martin Davis <mbdavis@vividsolutions.com> de Vivid Solutions qui fait que tout fonctionne.
la bibliothèque de projection cartographique Proj4, et au travail de Gerald Evenden et Frank Warmerdam pour sa création et son maintien.

haut de la page | table des matières

1.2. Pour plus d'informations

haut de la page | table des matières

1.3 Traducteurs

Voici la liste des traducteurs du manuel PostGIS :

haut de la page | table des matières

Chapitre 2. Installation


haut de la page | table des matières

2.1 Version courte

tar xvfz postgis-1.4.0.tar.gz
cd postgis-1.4.0
./configure
make
make install
createdb yourdatabase
createlang plpgsql yourdatabase
psql -d yourdatabase -f lwpostgis.sql
psql -d yourdatabase -f spatial_ref_sys.sql

Le reste de ce chapitre va vous présenter chacune de ces étapes d'installation de manière détaillée.

haut de la page | table des matières

2.2. Prérequis

Pour être compilé et utilisé, PostGIS nécessite l'ensemble des outils suivants.
Nécessaires :

Optionnels :

haut de la page | table des matières

2.3. Obtenir le code source

Téléchargez l'archive du code source de PostGIS depuis la site de téléchargement : http://postgis.refractions.net/download/postgis-1.4.0.tar.gz.

wget http://postgis.refractions.net/download/postgis-1.4.0.tar.gz
tar -xvzf postgis-1.4.0.tar.gz

Cela va créer un répertoire intitulé postgis-1.4.0 dans le répertoire courant où vous avez lancé les commandes précédentes.

Vous pouvez aussi récupérer le code source de PostGIS à partir du serveur svn de l'OSGeo http://svn.osgeo.org/postgis/trunk/.

svn checkout http://svn.osgeo.org/postgis/trunk/ postgis-1.4.0

Rendez-vous dans le nouveau répertoire postgis-1.4.0 pour continuer l'installation.

haut de la page | table des matières

2.4. Installation

De nombreux système d'exploitation possèdent maintenant des paquets pré-compilés pour PostgreSQL/PostGIS. La plupart du temps, la compilation est uniquement nécessaire si vous souhaitez utiliser la toute derinère version ou si vous êtes responsable du paquet.

Le module PostGIS est une extension du serveur principal PostreSQL. En temps que tel, PostGIS 1.4.0 nécessite une accès à l'ensemble des fichiers d'entêtes (.h) du serveur PostgreSQL pour être compilé. Il peut être compilé en utilisant une version 8.2.0 ou supérieure de PostgreSQL. Les version plus ancienne de PostgreSQL ne sont pas supportées.

Référez vous aux guides d'installation de PostgreSQL si vous ne l'avez pas déjà installé http://www.postgresql.org.

Si vous envisagez d'utiliser les fonctionnalités de GEOS, vous pourriez devoir explicitement lier PostgreSQL à la bibliothèque standard C++ :

LDFLAGS=-lstdc++ ./configure [VOS OPTIONS ICI]
C'est la bonne manière de procéder afin d'éviter les exceptions C++ inter-agissant avec les anciens outils de développement. Si vous constatez des erreurs étranges (le serveur principal se ferme de façon inattendue ou ce genre de chose) essayez cette astuce. Cela nécessite évidemment de recompiler PostgreSQL à partir des sources.
Les étapes suivantes présentent la configuration et la compilation des sources de PostGIS. Ils ont été écrit pour les utilisateurs de Linux et ne fonctionneront pas sur Windows et Mac. haut de la page | table des matières

2.4.1. Configuration

Comme pour la plupart des installation Linux, la première étape consiste à générer le fichier Makefile qui sera utilisé pour compiler le code source. Cela est réalisé en lançant le script shell :

./configure

Sans paramètres supplémentaires, cette commande va tenter de localiser automatiquement les composants requis et les librairies nécessaires pour compiler le code source de PostGIS sur votre système. Bien que cela soit la manière standard d'utiliser le script configure, ce script supporte de nombreux paramètres pour ceux qui auraient installé les librairies nécessaires et les programmes dans des répertoires non standard.

La liste suivante présentent seulement les paramètres les plus couramment utilisés. Pour obtenir une liste complète des paramètres existant, utilisez le paramètre --help our --help=short.

--prefix=PREFIX
C'est le répertoire où seront installé les librairies et les scripts SQL de PostGIS. Par défaut, ce répertoire est le même que celui détecté de votre installation de PostgreSQL.
Attention : ce paramètre n'est actuellement pas opérationel, étant donné que le paquet va être installer dans le répertoire de votre installation de PostgreSQL. Consultez cette page : http://trac.osgeo.org/postgis/ticket/160 pour suivre l'état d'avancement de la résolution de ce problème.
--with-pgconfig=FICHIER
PostgreSQL fournit un utilitaire appelé pg_config pour permettre aux extensions comme PostGIS de récupérer le répertoire d'installation de PostgreSQL. Utilisez ce paramètre (--with-pg_config=/chemin/vers/pg_config) pour spécifier manuellement un répertoire d'installation de PostgreSQL spécifique à utiliser pour compiler PostGIS.
--with-geosconfig=FICHIER
GEOS, une librairie géométrique requise, fournit un utilitaire appelé geos-config qui permet au logiciels de récupérer le répertoire d'installation de GEOS. Utilisez ce paramètre (--with-geosconfig=/chemin/vers/geos-config) pour spécifier manuellement le répertoire d'installation de la version spécifique de GEOS avec laquelle vous souhaitez compilet PostGIS.
--with-projdir=RÉPERTOIRE
Proj4 est la librairie de reprojection requise par PostGIS. Utilisez ce paramètre (--with-projdir=/chemin/vers/le_repertoire_de_proj) pour spécifier manuellement le répertoire d'installation de la version de Proj4 spécifique avec laquelle vous souhaitez compiler PostGIS.
description
--with-gui
Compiler l'interface graphique d'inportation de données (nécessite GTK+ 2.0). Cela créera l'interface graphique pour shp2pgsql intitulée : shp2pgsql-gui

Si vous utilisez le code source issue du serveur SVN, la première étape sera de lancer le script

./autogen.sh

Ce script produira le script configure qui sera ensuite utiliser pour paramétrer votre installation de PostGIS.

Au contraire, si vous avez obtenu le code source depuis l'archive, l'exécution du script ./autogen.sh ne sera pas nécessaire étant donné qu'il a déjà été généré.

haut de la page | table des matières

2.4.2. Compilation

Une fois que le fichier Makefile a été produit, compiler PostGIS est aussi simple que de lancer la commande suivante :
make
La dernière ligne affichée devrait être "PostGIS was built successfully. Ready to install".
Depuis la version 1.4.0 de PostGIS, toutes les fonctions ont des commentaires générés à partir de la documentation. Si vous souhaitez installer ces commentaires dans votre base de données plus tard, utilsez la commande suivante :
make comments

haut de la page | table des matières

2.4.3. Tests

Si vous souhaitez tester votre compilation de PostGIS, lancez la commande suivante

make check

La commande ci-dessus va exécuter de nombreuses vérification et des tests de régressions en utilisant la librairie compilée avec la base PostgreSQL actuelle.

Si vous avez compilé PostGIS en utilisant des répertoires non standard pour PostgreSQL, GEOS ou Proj4, vous pourriez avoir besoin de définir la variable d'environnement LD_LIBRARY_PATH.
Actuellement, la commande make check utilise les variables d'environnement PATH et PGPORT pour réaliser ses vérification - il n'utilise pas la version de PostgreSQL qui aurait pût être spécifiée comme option (--with-pgconfig) au script configure. Donc assurez-vous que votre variable PATH coïncide bien avec l'installation de PostgreSQL utilisée lors de la configuration ou préparez-vous a avoir des mots de têtes. Consultez cette page http://trac.osgeo.org/postgis/ticket/186 pour suivre l'évolution de la résolution de ce problème.

Si tout s'est bien passé, la sortie des vérifications devrait ressembler à ceci :

        CUnit - A Unit testing framework for C - Version 2.1-0
        http://cunit.sourceforge.net/



Suite: PostGIS Computational Geometry Suite
    Test: test_lw_segment_side() ... passed
    Test: test_lw_segment_intersects() ... passed
    Test: test_lwline_crossing_short_lines() ... passed
    Test: test_lwline_crossing_long_lines() ... passed
    Test: test_lwpoint_set_ordinate() ... passed
    Test: test_lwpoint_get_ordinate() ... passed
    Test: test_lwpoint_interpolate() ... passed
    Test: test_lwline_clip() ... passed
    Test: test_lwline_clip_big() ... passed
    Test: test_lwmline_clip() ... passed
    Test: test_geohash_point() ... passed
    Test: test_geohash_precision() ... passed
    Test: test_geohash() ... passed
Suite: PostGIS Measures Suite
    Test: test_mindistance2d_recursive_tolerance() ... passed

--Run Summary: Type Total Ran Passed Failed
               suites   2   2    n/a      0
               tests   14  14     14      0
               asserts 84  84     84      0


Creating spatial db postgis_reg
TMPDIR is /tmp/pgis_reg_15328


  PostgreSQL 8.3.7 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
  Postgis 1.4.0SVN - 2009-05-25 20:21:55
    GEOS: 3.1.0-CAPI-1.5.0
    PROJ: Rel. 4.6.1, 21 August 2008

Running tests

   loader/Point.............. ok
   loader/PointM.............. ok
   loader/PointZ.............. ok
   loader/MultiPoint.............. ok
   loader/MultiPointM.............. ok
   loader/MultiPointZ.............. ok
   loader/Arc.............. ok
   loader/ArcM.............. ok
   loader/ArcZ.......... ok
   loader/Polygon.............. ok
   loader/PolygonM.............. ok
   loader/PolygonZ.............. ok
   regress. ok
   regress_index. ok
   regress_index_nulls. ok
   lwgeom_regress. ok
   regress_lrs. ok
   removepoint. ok
   setpoint. ok
   simplify. ok
   snaptogrid. ok
   affine. ok
   wkt. ok
   measures. ok
   long_xact. ok
   ctors. ok
   sql-mm-serialize. ok
   sql-mm-circularstring. ok
   sql-mm-compoundcurve. ok
   sql-mm-curvepoly. ok
   sql-mm-general. ok
   sql-mm-multicurve. ok
   sql-mm-multisurface. ok
   geojson. ok
   gml. ok
   svg. ok
   kml. ok
   regress_ogc. ok
   regress_bdpoly. ok
   regress_proj. ok
   regress_ogc_cover. ok
   regress_ogc_prep. ok

Run tests: 42
Failed: 0

haut de la page | table des matières

2.4.4. Installation

Pour installer PostGIS, lancez la commande suivante :

make install

Cela va copier les fichiers d'installation de PostGIS dans leur répertoires respectifs par rapport au paramètre --prefix spécifié lors de la configuration. En particulier :

Si vous aviez précédemment lancer la commande make comments pour générer le fichier postgis_comments.sql, installez le fichier en lançant la commande :

make comments-install
Le fichier postgis_comments.sql a été séparé du processus de compilation et d'installation par défaut car il implique une dépendance supplémentaire : xsltproc.

haut de la page | table des matières

2.5. Créer une base de données spatiales

La première étape pour créer une base de données PostGIS est de créer une simple base de données PostgreSQL.

createdb [votre_base_de_données]

Bon nombre de fonctions de PostGIS sont écritent dans le language procédural PL/pgSQL. Ainsi, la prochaine étape pour créer une base données PostGIS consiste a charger le support du langage PL/pgSQL dans votre nouvelle base de données. Ceci se fait en utilisant la commande ci-dessous.

createlang plpgsql [votre_base_de_données]

Maintenant chargez les objets et les définitions de fonctions PostGIS dans votre base de données en utilisant le fichier de définition postgis.sql (installé dans le répertoire [prefix]/share/contrib spécifié lors de l'étape de configuration).

psql -d [votre_base_de_données] -f postgis.sql

Pour obtenir un ensemble complet des identifiants de système de références spatiales, vous pouvez aussi charger le fichier de définition spatial_ref_sys.sql et remplir ainsi la table spatial_ref_sys. Cela vous permettra d'utiliser la fonction ST_Transform() sur vos objets géographiques.

psql -d [votre_base_de_données] -f spatial_ref_sys.sql

Si vous souhaitez ajouter les commentaires des fonctions PostGIS, l'étape finale consiste à charger le fichier de définitions postgis_comments.sql dans votre base de données. Les commentaires peuvent être vu simplement en utilisant la méta-commande \dd [nom_de_la_fonction] depuis le terminal interactif psql.

psql -d [votre_base_de_données] -f postgis_comments.sql
haut de la page | table des matières

2.6. Créer des bases de données spatiales à partir d'un modèle

Certaines distributions de PostGIS (en particulier l'installeur de PostGIS pour Win32 >= 1.1.5) charge les fonctionalités de PostGIS dans une base de données modèle appelé template_postgis. Si la base template_postgis existe dans votre installation de PostgreSQL, l'installation rend alors possible pour les utilisateurs ou les applications la création de bases de données spatiales en utilisant une seule commande. Notez que dans les deux cas, l'utilisateur de la base de données doit posséder les droits nécessaires à la création de bases de données.

Depuis un shell :

# createdb -T template_postgis ma_base_spatiale

Pour le code SQL :

postgres=# CREATE DATABASE ma_base_spatiale
TEMPLATE=template_postgis;

ndrpf : bien entendu si vous utilisiez directement template1 à la place de tamplate_postgis vous pourriez simplement utiliser la commande suivante : createdb ma_base_spatiale pour créer une base de données spatiale PostGIS. Cependant il semble pertinent de considérer que toutes les bases de données de votre serveur PostgreSQL n'auront pas besoin des fonctionnalités spatiales de PostGIS. C'est pourquoi template_postgis est présenté ici.

haut de la page | table des matières

2.7. Mise à jour

La mise à jour d'une base de données spatiale existante peut être compliquée étant donné qu'elle implique le remplacement ou l'introduction de nouvelles définitions d'objets PostGIS.
Hélas toutes les définitions ne peuvent pas être facilement remplacées dans une base de données en production, donc parfois le meilleur moyen est encore de sauvegarder puis de recharger les données.
PostGIS fournit une procédure de mise à jour 'légère' (SOFT UPGRADE) pour les versions mineures ou réparant simplement des bugs, et une procédure 'complète' (HARD UPGRADE) pour les versions majeures.
Avant de tenter de mettre à jour postgis, il est toujours plus sûr de sauvegarder vos données. Si vous utilisez l'option -Fc de pg_dump, vous serez toujours capable de restaurer la sauvegarde avec une mise à jour 'complète'.

haut de la page | table des matières

2.7.1. Mise à jour 'légère'

La mise à jour 'légère' consiste à charger le script lwpostgis_upgrade.sql dans votre base de données

$ psql -f lwpostgis_upgrade.sql -d votre_base_de_données_spatiale

Si une mise à jour 'légère' n'est pas possible, le script abandonnera et vous serez informé qu'une mise à jour 'complète' doit être effectuée, donc n'hésitez pas à essayer une mise à jour 'légère' en premier.

Note
Si vous ne trouvez pas le fichier lwpostgis_upgrade.sql, vous utilisez probablement une version antérieure à 1.1 et vous devrez générer ce fichier vous même. Cela se fait avec la commande suivante :

$ utils/postgis_proc_upgrade.pl lwpostgis.sql > lwpostgis_upgrade.sql
haut de la page | table des matières

2.7.2. Mise à jour 'complète'

Par mise à jour 'complète' nous entendons une sauvegarde/rechargement complet des base de données ayant PostGIS d'activé. Vous avez besoin d'une mise à jour 'complète' lorsque le stockage des objets internes de PostGIS change ou lorsqu'une mise à jour 'légère' n'est pas possible.

L'annexe des notes de sorties de versions PostGIS signale pour chaque version si vous devez désinstaller/réinstaller (mise à jour complète) lors du changement de version.

PostGIS fournit un utilitaire pour restaurer une sauvegarde créée avec la commande pg_dump -Fc. Il est expérimental, donc rediriger sa sortie standard dans un fichier sera utile en cas de problèmes. La procédure est la suivante :

Créez une sauvegarde au "format-particulier" de la base que vous souhaitez mettre à jour (appelons là "ancienne_base")

$ pg_dump -Fc ancienne_base > ancienne_base.dump

Restaurez la sauvegarde pour mettre à jour postgis dans une nouvelle base de données. La nouvelle base n'a pas à exister. postgis_restore prend en charge les paramètres passés à createdb après le nom du fichier de sauvegarde et cela peut être utilisé, par exemple, si vous souhaitez utiliser un encodage de caractères différent de celui utilisé par défaut par votre serveur PostgreSQL. Appelons là "nouvelle_base" et utilisons l'encodage de caractères UNICODE :

$ sh utils/postgis_restore.pl lwpostgis.sql nouvelle_base ancienne_base.dump > restauration.log

Vérifiez que tous les objets de la sauvegarde ont réellement besoin d'être restaurés à partir de la sauvegarde et n'entre pas en conflit avec ceux définis dans lwpostgis.sql

$ grep ^KEEPING restauration.log | less

Si vous mettez à jour PostgreSQL d'une version < 8.0 à une version >= 8.0 vous devrez sans doute supprimer les colones attrelid, carattnum et stats de la table geometry_columns, qui ne sont plus nécessaires. Les conserver ne pose pas de problèmes. LES SUPPRIMER ALORS QU'ON EN A BESOIN POSERA UN PROBLÈME !!!

$ psql nouvelle_base -c "ALTER TABLE geometry_columns DROP attrelid"
$ psql nouvelle_base -c "ALTER TABLE geometry_columns DROP varattnum"
$ psql nouvelle_base -c "ALTER TABLE geometry_columns DROP stats"

La table spatial_ref_sys est restaurée à partir de la sauvegarde, pour être sur que vos ajouts particuliers seront conservés, mais ceux fournis pourraient contenir des modifications et donc vous devriez sauvegarder vos modifications, supprimer la table et insérer la nouvelle. Si vous aviez fait des ajouts, nous supposons que vous savez comment les sauvegarder avant la mise à jour de la table. La remplacer par la nouvelle se fait de la manière suivante :

$ psql nouvelle_base
nouvelle_base=> delete from spatial_ref_sys;
DROP
nouvelle_base=> \i spatial_ref_sys.sql

haut de la page | table des matières

2.8. Problèmes fréquents

Il y a plusieurs choses à vérifier lorsque votre installation ou votre mise à jour ne se déroule pas comme prévu.

  1. Vérifiez que vous avez installé la version de PostgreSQL 8.1 ou plus récente, et que vous avez compilé PostGIS avec la même version des sources de PostgreSQL que la version de PostgreSQL que vous utilisez sur votre serveur en production. Des problèmes de références peuvent arriver lorsque votre distribution (Linux) a déjà installé une version de PostgreSQL, ou que vous aviez déjà installé précédemment une version de PostgreSQL que vous avez oublié. PostGIS fonctionne uniquement avec les version 8.1 et supérieures de PostgreSQL, et bizarrement, des messages d'erreurs innattendus peuvent apparaître si vous utilisez une version plus ancienne. Pour vérifier la version de PostgreSQL que vous utilisez, connectez vous à la base de données en utilisant psql et exécutez la requête : SELECT version();. Si vous utilisez une distribution basé sur RPM, vous pouvez vérifier la présence des paquets installés en utilisant la commande rpm de la façon suivante : rpm -qa | grep postgresql.

Vérifiez aussi que le script configure a correctement détecté les répertoire d'installation et les versions de PostgreSQL et des librairies Proj4 et GEOS.

  1. Le script configure est utilisé pour produire un fichier postgis_config.h. Vérifiez que les vairables POSTGIS_PGSQL_VERSION, POSTGIS_PROJ_VERSION et POSTGIS_GEOS_VERSION ont la bonne valeur.
haut de la page | table des matières

2.9. JDBC

L'extension JDBC fournit des objets Java correspondant aux types internes de PostGIS. Ces objets peuvent être utilisés pour écrire des clients java qui interrogent la base de données PostGIS et dessinent ou effectuent des calculs sur les données SIG dans PostGIS.

  1. Entrez dans le sous-répertoire java/jdbc des sources de PostGIS.
  2. Lancez la commande ant. Copiez le fichier postgis.jar là où vous avez l'habitude de stocker vos bibliothèques java.

Les extensions JDBC nécessitent qu'un pilote JDBC pour PostgreSQL soit déjà installé dans votre CLASSPATH actuel durant la compilation. Si le pilote JDBC PostgreSQL est situé dans un répertoire non standard, vous pouvez spécifier le chemin d'installation du JAR du pilote JDBC en utilisant le paramètre -D de la manière suivante :

# ant -Dclasspath=/chemin/vers/postgresql-jdbc.jar

Les pilote JDBC PostgreSQL peuvent être télécharger depuis la page suivante : http://jdbc.postgresql.org.

haut de la page | table des matières

2.10. Importeur/Exporteur

L'exporteur et l'importeur de données sont compilés et installés automatiquement lors de la compilation de PostGIS. Pour les compiler et les installer manuellement :

# cd postgis-1.1.1/loader
# make
# make install

L'importeur est appelé shp2pgsql, il permet de convertir des fichiers vecteurs (Shape) ESRI en SQL capables d'être chargés dans PostGIS/PostgreSQL. L'exporteur est appelé pgsql2shp et il permet de convertir des tables PostGIS (ou des requêtes) en fichiers vecteurs (Shape) ESRI.

haut de la page | table des matières

Chapitre 3. Foire aux questions


haut de la page | table des matières

3.1. Quel type d'objets géométriques puis-je stoquer ?

Vous pouvez stocker des points, des lignes, des polygones, des multipoints, des multilignes, des multipolygones et des geometrycollections. Ceci est spécifié dans le format Textuel Bien Connu (Well Known Text) de l'OpenGIS Consortium (avec les extensions XYZ, XYM, XYZM).

haut de la page | table des matières

3.2. Comment insérer un objet SIG dans la base de données ?

Avant tout, vous devez créer une table avec une colonne de type "géométrique" pour stocker vos données SIG. Connectez-vous à la base de données avec psql et essayez le code SQL suivant :

CREATE TABLE gtest ( ID int4, NAME varchar(20) );
SELECT AddGeometryColumn('', 'gtest','geom',-1,'LINESTRING',2);

Si l'ajout de la colonne gémétrique échoue, c'est sans doute que vous n'avez pas chargé les fonctions et objets PostGIS dans la base de données. Consultez les instructions d'installation.

Ensuite, vous pouvez insèrer un objet géométrique dans la table en utilisant la commande SQL INSERT. L'objet SIG est fomaté en utilisant le format Textuel Bien Connu (Well Known Text) de l'OpenGIS Consortium :

INSERT INTO gtest (ID, NAME, GEOM) VALUES (1, 'First Geometry', GeomFromText('LINESTRING(2 3,4 5,6 5,7 8)', -1));

Pour plus d'information concernant les autres objets SIG, consultez la référence de l'objet.

Pour visualiser vos objets SIG de la table :

SELECT id, name, AsText(geom) AS geom FROM gtest;

Le résultat obtenu devrait ressembler à quelque chose comme ça :

 id |      name      |           geom
----+----------------+-----------------------------
  1 | First Geometry | LINESTRING(2 3,4 5,6 5,7 8 )
(1 row)

haut de la page | table des matières

3.3. Comment construire une requête spatiale ?

De la même manière que vous construisez n'importe quel autre type de requête pour vos bases de données, comme une combinaison SQL de valeurs de retour, fonctions et autre tests booléens.

Pour les requêtes spatiales, il y a deux choses importantes à garder à l'esprit lorsque vous construisez votre requête : y-a-t-il un index spatial que vous pouvez utiliser ; et, faites vous des calculs couteux sur un grand nombre de géométries.

En général, vous voudrez utiliser l'opérateur d'intersection (&&) qui test si les cadres limites des objets s'intersectent. La raison pour laquelle l'opérateur && est utile vient du fait que si un index spatial est disponible pour accélérer le test, l'opérateur && l'utilisera. Ceci peut rendre les requête beaucoup plus rapides.

Vous pourrez aussi utiliser des fonctions spatiales, comme par exemple Distance(), Intersects(), Contains() et Within(), parmi tant d'autres, pour limiter les résultats de vos recherches. La plupart des requêtes spatiales contiennent à la fois un test indexé et un test utilisant une fonction spatiale. Le test indexé sert à limiter le nombre de tuples résultants, uniquement ceux qui respectent la condition. La fonction spatiale est ensuite utilisée afin de tester réellement la condition.

SELECT id, the_geom FROM thetable
WHERE
the_geom && 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'
AND
Contains(the_geom,'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))';

haut de la page | table des matières

3.4. Comment rendre plus rapide des requêtes spatiale sur de grandes tables ?

Les requêtes rapides sur de grandes tables sont la raison d'être des bases de données spatiales (transactionnelles) donc avoir un bon index est primordial.

Pour construire vos index spatiaux sur les tables qui ont un colonne géométrique, utilisez la fonction CREATE INDEX de la manière suivante :

CREATE INDEX [nom_de_index] ON [nom_de_la_table]
USING GIST ( [colonne_géométrique] );

L'option USING GIST signifie que le serveur doit utiliser un index GiST (Generalized Search Tree, en d'autres termes : un arbre de recherche généralisé).

Les index GiST sont supposés à perte. Les index à perte utilisent un objet par procuration (dans le cas spatial, le cadre limite) pour construire l'index.

Vous devriez aussi vous assurer que le planificateur de requête de PostgreSQL a suffisamment d'informations concernant votre index pour prendre une décision rationnelle quant à son utilisation. Pour ce faire, vous devez rassembler les statistiques de vos tables géométriques.

Pour PostgreSQL 8.0.x et supérieur, lancez simplement la commande VACUUM ANALYZE

Pour PostgreSQL 7.4.x et précédant, lancez la commande : SELECT UPDATE_GEOMETRY_STATS().

haut de la page | table des matières

3.5. Pourquoi les arbres R de PostgreSQL ne sont-ils pas supportés ?

Les précédentes versions de PostGIS utilisaient les arbres R de PostgreSQL. Cependant, les arbres R de PostgreSQL ont été totalement supprimé depuis la version 0.6, et l'indexation spatiale est disponible avec un schéma arbre R sur arbre de recherches généralisés (GiST).

Nos tests ont montrés que la rapidité d'exécution pour les arbres R natifs et les GiST sont comparables. Les arbres R natifs de PostgreSQL ont deux limitations qui les rendent inutilisable pour une utilisation dans le cadre SIG (notez que ces limitations sont dues à l'implémentation des arbres R natifs de PostgreSQL, et non au concept d'arbre R en lui-même) :

haut de la page | table des matières

3.6. Pourquoi dois-je utiliser la fonction AddGeometryColumn() et toutes les autres fonctions de l'OpenGIS ?

Si vous ne voulez pas utiliser les fonctionnalités spécifiées par l'OpenGIS, vous n'avez pas à les utiliser. Créez simplement vos tables comme vous le faisiez avec les versions précédentes, définissez vos colonnes géométriques lors de leurs créations. Toutes vos géométries auront alors -1 comme valeur pour SRID et les tables de méta-données de l'OpenGIS ne seront pas remplies correctement. Cependant, cela a pour conséquence que la plupart des applications basées sur PostGIS ne fonctionneront plus. C'est pourquoi il est généralement conseillé d'utiliser la fonction AddGeometryColumn() pour créer ses tables géométriques.
Par exemple Mapserver est une application qui utilise les méta-données de la table geometry_columns. Par exemple, Mapserver peut utiliser le SRID de la colonne géométrique afin de réaliser des reprojections.

haut de la page | table des matières

3.7. Quelle est la meilleure façon de trouver tous les objets autour d'un autre ?

Afin d'utiliser la base de données plus efficacement, il vaut mieux faire une requête de rayon qui combine le test de rayon et le test des cadres limites : le test de cadre limite utilise un index spatial, permettant un accès rapide à un sous-ensemble de données pour lesquels le test de rayon est ensuite effectué.

La fonction ST_DWithin(geometry, geometry, distance) permet de réaliser un calcul de distance utilisant les index. Elle fonctione en créant un espace rectangulaire de recherche suffisamment large pour contenir le rayon ayant la valeur du parmètre distance, ensuite elle réalise l'opération exacte de calcul de distance sur le sous-ensemble résultant.

Par exemple, pour trouver tout les objets dans un rayon de 100 mètres autour du point POINT(1000 1000), la requête suivante devrait bien fonctionner :


SELECT * FROM tablegeo
WHERE ST_DWithin(colonnegeo, 'POINT(1000 1000)', 100.0);

haut de la page | table des matières

3.8. Comment puis-je appliquer une reprojection de coordonnées dans une requête ?

Pour effectuer une reprojection, les systèmes de références spatiales source et destination doivent être tout deux définis dans la table SPATIAL_REF_SYS, et les géométries qui doivent être reprojetées doivent déjà avoir un SRID d'attribué. Une fois que cela est fait, une reprojection consiste simplement à stipuler le SRID du système de projection désiré pour la destination. L'exemple ci-dessous reprojette une géométrie dans le système NAD 83 long lat. Cet exemple ne fonctionnera que si la valeur du srid de la colonne the_geom est différente de -1 (qui correspond à un système de référence indéfini).

SELECT ST_Transform(the_geom,4269) FROM geotable;
haut de la page | table des matières

Chapitre 4. Utiliser PostGIS


haut de la page | table des matières

4.1. Objets SIG

Les objets SIG supportés par PostGIS sont un sur-ensemble des "Fonctionnalités Simples" définies par l'OpenGIS Consortium (OGC). Depuis la version 0.9, PostGIS gère tous les objets et fonctions définis dans les spécifications "Simple Features Specifications for SQL" de l'OGC.
PostGIS étend les standards en ajoutant le support pour les coordonnées 3DZ, 3DM et 4D.

haut de la page | table des matières

4.1.1. Les formats WKB et WKT de l'OpenGIS

Les spécifications de l'OpenGIS définissent deux méthodes standards pour décrire les objets spatiaux : la forme "textuelle bien connue" et la forme "binaire bien connue". Les deux formats contiennent des informations sur le type de l'objet ainsi que sur ses coordonnées.

Exemples de représentation en WKT d'objets spatiaux dont voici la description :

Les spécifications de l'OpenGIS imposent également que le format de stockage interne des objets géographiques inclue un identifiant du système de références spatiales ("spatial referencing system identifier", SRID). Le SRID est obligatoire lors de la création d'objets géographiques dans la base de données.

La gestion des entrées/sorties dans ces formats est rendue possible grâce aux fonctions suivantes :

bytea WKB = ST_asBinary(geometry);
text WKT = ST_asText(geometry);
geometry = ST_GeomFromWKB(bytea WKB, SRID);
geometry = ST_GeometryFromText(text WKT, SRID);

Par exemple, voici des commandes valides pour créer et insérer des objets géographiques OGC :

INSERT INTO SPATIALTABLE (
  THE_GEOM,
  THE_NAME
)
VALUES (
  ST_GeomFromText('POINT(-126.4 45.32)', 312),
  'A Place'
)

haut de la page | table des matières

4.1.2. PostGIS EWKB, EWKT et formes canoniques

Les formats proposés par l'OGC gèrent seulement la 2D et le SRID associé n'est jamais embarqué dans la représentation en entrée/sortie.

Les formats étendus de PostGIS sont actuellement un sur-ensemble de ceux de l'OGC (chaque WKB/WKT valide est un EWKB/EWKT valide) mais cela pourrait changer à l'avenir, particulièrement si l'OGC venait à sortir un nouveau format qui serait en conflit avec nos extensions. Donc vous NE DEVRIEZ PAS compter sur cette propriété.

Les format EWKB/EWKT de PostGIS ajoute les gestions de système de coordonnées 3dm, 3dz et 4d et contiennent l'information relative au SRID.

Des exemples de la représentation textuelle (EWKT) d'objets spatiaux étendus des propriétés sont les suivantes :

Les entrées/sorties dans ces formats sont disponibles via les interfaces suivantes :

Par exemple, une requête d'insertion valide pour créer et insérer un objet spatial PostGIS pourrait être :

INSERT INTO SPATIALTABLE (
  THE_GEOM,
  THE_NAME
)
VALUES (
  ST_GeomFromEWKT('SRID=312;POINTM(-126.4 45.32 15)'),
  'A Place'
)

Les "formes canoniques" d'un type PostgreSQL sont les représentations que vous obtenez avec de simples requêtes (sans appel de fonctions) et celle qui est sûr d'être accepté avec un simple insert, update ou copy. Pour le type geometry de PostGIS se sont les suivantes :

- Sortie -
binaire : EWKB
ascii : HEXEWKB (EWKB sous la forme hexadécimale)
- Entrée -
binaire : EWKB
ascii : HEXEWKB|EWKT

Par exemple cette requêtes lit du EWKT et renvoie du HEXEWKB dans le processus d'entrée/sortie canonique ascii :

=# SELECT 'SRID=4;POINT(0 0)'::geometry;
                     geometry
----------------------------------------------------
 01010000200400000000000000000000000000000000000000
 (1 row)

haut de la page | table des matières

4.1.3. SQL-MM Partie 3

Les spécifications des applications multimédia spatiales SQL étendent les propriétés simples des spécifications SQL en définissant un nombre de "courbes circulairement interpolées"
(original : "a number of circularly interpolated curves").
Les définitions de SQL-MM incluent les coordonées 3dm, 3dz et 4d, mais ne permettent pas d'embarquer l'information pour le SRID.
Les extensions "texte bien-connu" ne sont pas totalement supportées. Des exemples de quelque géométries courbées sont disponibles ci-dessous :

Les versions précédentes de la version 1.4 de PostGIS ne supportent pas les courbes composées dans les polygones courbes, mais les versions supérieures ou égales à la version 1.4 supporte l'utilisation de courbes composées dans les polygones courbes.
Note : tout les comparaisons à virgule flottante dans l'implémentation de SQL-MM sont effectuées avec une tolérance spécifiée, actuellement fixée à 1e-8.

haut de la page | table des matières

4.2. Utilisation des standards de l'OpenGIS

La spécification "Simple Features for SQL" de l'OpenGIS definie les types d'objets géographiques standards, les fonctions necessaires pour les manipuler et un ensemble de tables de méta-données. Pour s'assurer que les méta-données seront toujours complètes, les opérations telles que créer ou supprimer une colonne géométrique sont effectuées selon certaines procédures définies par l'OpenGIS.

Il y a deux tables de méta-données OpenGIS : SPATIAL_REF_SYS et GEOMETRY_COLUMNS. La table SPATIAL_REF_SYS contient les identifiants numériques et la description textuelle des systèmes de coordonnées utilisés dans la base de données.

haut de la page | table des matières

4.2.1. La table SPATIAL_REF_SYS

La table spatial_ref_sys est inclue dans PostGIS et est conforme aux spécifications de l'OGC, elle contient environ 3000 systèmes de références spatiales et les détails nécessaires à la transformation/reprojection entre eux.

Bien que la table spatial_ref_sys contienne environ 3000 des systèmes de références spatiales les plus communément utilisés qui sont gérés par la librairie Proj4, elle ne contient pas tout les systèmes de références spatiales connue et vous pouvez même définir vos propres systèmes si vous êtes familiers avec la syntaxe de Proj4. Gardez à l'esprit que la plupart des systèmes de références spatiales sont régionaux et n'ont pas de signification hors de leurs limites respectives.

Une ressource essentiel pour la recherche de systèmes de références spatiales qui ne seraient pas présent dans la table spatial_ref_sys est le site web http://spatialreference.org/.

Les systèmes de références spatiales les plus couramment utilisés sont : 4326 - WGS 84 Long Lat, 4269 - NAD 83 Long Lat, 3395 - WGS 84 World Mercator, 2163 - US National Atlas Equal Area, les systèmes de références spatiales pour les zones NAD 83, WGS 84 UTM zone - UTM sont idéaux pour mesurer, mais couvrent uniquement des régions de 6 degrés.

Pour des détails sur la détermination de la zone UTM à utiliser pour votre espace d'intérêts, utilisez la fonction plpgsql de PostGIS : utmzone.

Voici la définition de la table SPATIAL_REF_SYS :

CREATE TABLE SPATIAL_REF_SYS (
   SRID INTEGER NOT NULL PRIMARY KEY,
   AUTH_NAME VARCHAR(256),
   AUTH_SRID INTEGER,
   SRTEXT VARCHAR(2048),
   PROJ4TEXT VARCHAR(2048)
)

Et voici les colonnes de SPATIAL_REF_SYS :

Le fichier spatial_ref_sys.sql contient les définitions de SRTEXT et de PROJ4TEXT pour toutes les projections EPSG.

haut de la page | table des matières

4.2.2. La table GEOMETRY_COLUMNS

La définition de la table GEOMETRY_COLUMNS est la suivante :

CREATE TABLE GEOMETRY_COLUMNS (
  F_TABLE_CATALOG VARCHAR(256) NOT NULL,
  F_TABLE_SCHEMA VARCHAR(256) NOT NULL,
  F_TABLE_NAME VARCHAR(256) NOT NULL,
  F_GEOMETRY_COLUMN VARCHAR(256) NOT NULL,
  COORD_DIMENSION INTEGER NOT NULL,
  SRID INTEGER NOT NULL,
  TYPE VARCHAR(30) NOT NULL
)

Les colonnes sont les suivantes :

haut de la page | table des matières

4.2.3. Créer une table spatiale

Créer une table avec des données géographiques se déroule en deux étapes :

  1. Créer une table (non-spatialisée) normale. Par exemple : CREATE TABLE ROADS_GEOM ( ID int4, NAME varchar(25) )
  2. Ajouter à la table la colonne spatiale en utilisant la fonction "AddGeometryColumn" de l'OpenGIS.
    La syntaxe est la suivante :
    AddGeometryColumn(<nom_du_schema>, <nom_de_la_table>,
                      <nom_de_la_colonne>, <srid>, <type>,
                      <dimension>)
    Ou, en utilisant le schéma courant :
    AddGeometryColumn(<nom_de_la_table>,<nom_de_la_colonne>,
                      <srid>, <type>, <dimension>)

    Exemple 1:
    SELECT AddGeometryColumn('public', 'roads_geom', 'geom', 423, 'LINESTRING', 2)

    Exemple 2:
    SELECT AddGeometryColumn( 'roads_geom', 'geom', 423, 'LINESTRING', 2)

Voici un exemple de code SQL utilisé pour créer une table et ajouter une colonne spatiale (en supposant qu'un SRID de 128 existe déjà) :

CREATE TABLE parks ( PARK_ID int4, PARK_NAME varchar(128), PARK_DATE date, PARK_TYPE varchar(2) );
SELECT AddGeometryColumn('parks', 'park_geom', 128, 'MULTIPOLYGON', 2 );

Voici un autre exemple, utilisant le type générique "geometry" et un SRID indéfinie de valeur -1 :

CREATE TABLE roads ( ROAD_ID int4, ROAD_NAME varchar(128) );
SELECT AddGeometryColumn( 'roads', 'roads_geom', -1, 'GEOMETRY', 3 );

haut de la page | table des matières

4.2.4. Assurer la conformité OpenGIS des géométries

La plupart des fonctions implémentées par la librairie GEOS supposent que vos données géométrique soient valides du point de vue des spécifications "Simple Feature for SQL" de l'OpenGIS. Pour vérifier la validité de vos géométries, vous pouvez utiliser la fonction isValid() :

gisdb=# select isvalid('LINESTRING(0 0, 1 1)'), isvalid('LINESTRING(0 0,0 0)');
isvalid | isvalid
---------+---------
t | f

Par défaut, PostGIS n'exécute pas la vérification de la validité lors de l'insertion d'objets géométriques, du fait qu'un tel test requière beaucoup de temps processeur pour les géométries complexes, principalement les polygones. Si vous n'avez pas confiance en vos données, vous pouvez manuellement contraindre vos tables en ajoutant une contrainte de validité de la façon suivante :

ALTER TABLE mytable ADD CONSTRAINT geometry_valid_check CHECK (isvalid(the_geom));

Si vous rencontrez un quelconque message d'erreur étrange du style "GEOS Intersection() threw an error!" ou "JTS Intersection() threw an error!" lorsque vous faites appel aux fonctions PostGIS avec des géométries valides, vous avez sans doute trouvé une erreur soit dans PostGIS soit dans une des librairies qu'il utilise, et vous devriez contacter les développeurs de PostGIS pour les en informer. Ceci est aussi vrai si une fonction de PostGIS vous renvoi une géométrie invalid pour une entrée géométriques valide.

Note :

Les géométries strictement conformes à l'OGC ne peuvent pas avoir de valeurs Z ou M. La fonction isValid() ne considèrera pas les géométries de plus grandes dimensions comme invalide ! L'invocation de AddGeomtryColumn() ajoutera une contrainte vérifiant les dimensions de la géométrie, il est donc suffisant ici de spécifier 2.

haut de la page | table des matières

4.3. Chargement de données SIG

Une fois que vous avez créer une table spatiale, vous êtes prêt pour ajouter des données SIG à la base de données. Actuellement, il y a deux façons d'insérer les données dans une base PostgreSQL/PostGIS : en utilisant des requête SQL ou en utilisant l'importeur/exporteur de fichiers vecteurs (Shape).

haut de la page | table des matières

4.3.1. Utilisation de code SQL

Si vous pouvez convertir vos données en une représentation textuelle, alors utiliser du code SQL pourrait être la manière la plus simple d'insérer vos données dans PostGIS. Comme avec Oracle et d'autre bases de données SQL, les données peuvent être chargées par le moniteur interactif en utilisant un fichier texte contenant des requêtes de type "INSERT" :

Un fichier d'importation de données (par exemple roads.sql) pourrait ressembler à ceci :

BEGIN;
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (1,GeomFromText('LINESTRING(191232 243118,191108 243242)',-1),'Jeff Rd');
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (2,GeomFromText('LINESTRING(189141 244158,189265 244817)',-1),'Geordie Rd');
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (3,GeomFromText('LINESTRING(192783 228138,192612 229814)',-1),'Paul St');
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (4,GeomFromText('LINESTRING(189412 252431,189631 259122)',-1),'Graeme Ave');
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (5,GeomFromText('LINESTRING(190131 224148,190871 228134)',-1),'Phil Tce');
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (6,GeomFromText('LINESTRING(198231 263418,198213 268322)',-1),'Dave Cres');
COMMIT;

Le fichier de données peut être chargé dans PostgreSQL vraiment facilement en utiliant le moniteur interactif psql de la façon suivante :

psql -d [database] -f roads.sql

haut de la page | table des matières

4.3.2. Utiliser l'importeur

L'importeur de données shp2pgsql convertit des fichiers vecteurs (Shape) ESRI en requêtes SQL directement utilisables pour insérer des données dans des bases PostgreSQL/PostGIS. L'importeur possède différents modes opératoires qui se distinguent suivant les options qui lui sont passées en paramètre :

-d Supprime la table de la base données avant la création de la nouvelle table avec les données du fichier vecteur (Shape).
-a Ajoute les données du fichier vecteur dans la table de la base de données. Notez qu'il faut utiliser cette option pour charger plusieurs fichiers, qui doivent contenir les mêmes attributs et les mêmes types de données.
-c Crée une nouvelle table et la remplit avec le contenu du fichier vecteur (Shape). C'est le mode par défaut.
-p Produit uniquement le code de création des tables, sans ajouter les données. Cela peut être utile lorsque vous avez besoin de séparer complètement les étapes de création de table et celle de son remplissage.
-D Utilise le format d'export spécial de PostgreSQL pour extraire les données. Cette option peut être combinée avec -a, -c et -d. Ceci est plus rapide pour charger des données que d'utiliser des requêtes au format SQL de type "INSERT". Utilisez ceci pour l'insertion d'une grande quantité de données.
-s <SRID> Crée et remplit les tables géométriques avec le SRID spécifié.
-k Respecte la syntaxe (casse : majuscules/minuscules) des identifiants (colonne, schéma et attributs). Notez que les attributs dans des fichiers vecteurs sont en majuscules.
-i Coercition de tous les entiers en entiers 32 bits standards, ne crée pas de bigints 64 bits, même si la signature de l'en-tête DBF apparait pour le garantir.
-I Crée un index GiST sur la colonne géométrique.
-w Retour au format WKT, utilisé avec les anciennes versions (0.X) de PostGIS. Notez que cela introduira des dérives de coordonnées et supprimera les valeurs M des fichiers vecteurs.
-W <encoding> Spécifie l'encodage des données en entrée (du fichier dbf). Lorsque cette option est utilisée, tous les attributs du dbf sont convertis de l'encodage spécifié en UTF-8. La sortie SQL résultante contiendra une commande SET CLIENT_ENCODING to UTF8, donc le serveur principal sera capable de reconvertir de l'UTF-8 dans l'encodage choisi dans la configuration de la base de données.


Notez que les options -a, -c, -d et -p sont mutuellement exclusives.

Une session exemple utilisant l'importeur pour générer un fichier d'importation et le chargement de ce fichier est décrite ci-dessous :

# shp2pgsql shaperoads myschema.roadstable > roads.sql
# psql -d roadsdb -f roads.sql

Une conversion et une importation des données peuvent être faites en une seule étape en utilisant les tubes UNIX :

# shp2pgsql shaperoads myschema.roadstable | psql -d roadsdb

haut de la page | table des matières

4.4. Accéder aux données SIG

Pour accéder aux données de la base vous pouvez soit utiliser le langage SQL soit l'importeur/exporteur de fichiers vecteurs (Shape File). Dans la section traitant du SQL, nous présenterons certains opérateurs disponibles pour comparer les objets géographiques et interroger les tables spatiales.

haut de la page | table des matières

4.4.1. Utilisation du SQL

L'intérêt principal d'insérer des données dans une base de données est de pouvoir utiliser une requête SQL de type SELECT et de récupérer les champs retournés dans un fichier texte lisible :

db=# SELECT id, ST_AsText(geom) AS geom, name FROM ROADS_GEOM;
id | geom | name
---+-----------------------------------------+-----------
 1 | LINESTRING(191232 243118,191108 243242) | Jeff Rd
 2 | LINESTRING(189141 244158,189265 244817) | Geordie Rd
 3 | LINESTRING(192783 228138,192612 229814) | Paul St
 4 | LINESTRING(189412 252431,189631 259122) | Graeme Ave
 5 | LINESTRING(190131 224148,190871 228134) | Phil Tce
 6 | LINESTRING(198231 263418,198213 268322) | Dave Cres
 7 | LINESTRING(218421 284121,224123 241231) | Chris Way
(6 rows)

Parfois certain types de clauses sont nécessaires pour limiter le nombre de champs retournés. Dans le cas de clauses utilisant des attributs standards, utilisez simplement la même syntaxe SQL que celle utilisée pour des tables non spatiales. Dans le cas de clauses mettant en oeuvre des champs spatiaux, les opérateurs suivant sont à utiliser :

Maintenant, vous pouvez utiliser ces opérateurs dans vos requêtes. Remarquez que lorsque vous utilisez des géométries et des boites dans vos requêtes SQL en ligne de commande, vous devez explicitement spécifier que vous souhaitez créer une géométrie à partir d'une chaine de caractères en utilisant la fonction ST_GeomFromText().

Par exemple :

SELECT ID, NAME
  FROM ROADS_GEOM
  WHERE GEOM ~= ST_GeomFromText('LINESTRING(191232 243118,191108 243242)',-1);

La requête ci-dessus devrait renvoyer un enregistrement unique de la table "ROADS_GEOM" dans lequel l'objet géométrique serait égal à cette valeur.

Lorsque l'opérateur && est utilisé, vous pouvez spécifier soit une BOX3D soit un objet géométrique. Lorsque vous spécifiez une GEOMETRY, cependant, son cadre limite est utilisé pour réaliser la comparaison.

SELECT ID, NAME
  FROM ROADS_GEOM
  WHERE
    GEOM && ST_GeomFromText('POLYGON((191232 243117,191232 243119,191234 243117,191232 243117))',-1);

La requête ci-dessus utilisera le cadre limite du polygone pour effectuer la comparaison.

La requête spatiale la plus communément utilisée par une logiciel client, comme par exemple pour des navigateurs de données et des générateurs de cartes sur internet, sera probablement une requête basée sur des cadres limites, pour saisir la valeur du cadre limite d'une carte des données pour affichage. En utilisant un objet de type BOX3D pour le cadre, une telle requête ressemblerait à cela :

SELECT ST_AsText(GEOM) AS GEOM
  FROM ROADS_GEOM
  WHERE
    GEOM && SetSRID('BOX3D(191232 243117,191232 243119)'::box3d,-1);

Vous remarquerez l'utilisation d'un SRID, pour spécifier le système de projection de l'objet de type BOX3D. La valeur -1 est utilisée pour indiquer que le SRID n'est pas défini.

haut de la page | table des matières

4.4.2. Utilisation de l'exporteur

L'exporteur de table pgsql2shp se connecte directement à la base de données et convertit une table (potentiellement définie par une requête) en fichier vecteur (shapefile). La syntaxe de base est :

pgsql2shp [<options>] <database> [<schema>.]<table>
pgsql2shp [<options>] <database> <query>

Les options en ligne de commande sont les suivants :

-f <nom_de_fichier>Écrit le résultat dans le fichier spécifié.
-h <hôtet>Le nom du serveur de base de données auquel se connecter.
-p <port>Le port utilisé pour se connecter au serveur.
-P <mot_de_passe> Le mot de passe à utiliser lors de la connection au serveur.
-u <utilisateur>Le nom d'utilisateur à utiliser lors de la connection au serveur.
-g <colonne géometrique>Dans le cas de tables avec des colonnes géométriques multiples, la colonne géométrique à utiliser lors de la rédaction du fichier vecteur (shapefile).
-b Utilise un curseur binaire. Cela rend l'opération d'extraction plus rapide, mais ne fonctionnera pas si un attribut non-géométrique dans la table n'a pas de conversion en texte possible.
-r mode raw. Ne supprime pas le champ gid, ou échappe les noms de colonnes.
-d Pour une compatibilité en arrière : crée un fichier vecteur en 3 dimensions lorsque l'on exporte à partir de vieilles versions (pre-1.0.0) de bases de données PostGIS (par défaut il crée des fichiers vecteurs en 2 dimensions dans ce cas). À partir des versions 1.0.0 et supérieures de PostGIS, les dimensions sont complètement encodées.

haut de la page | table des matières

4.5. Création d'index

Les index rendent possible l'utilisation de base de données spatiales avec de grandes quantités de données. Sans indexation, chaque recherche de propriété pourrait requérir un "parcours séquentiel" de chaque enregistrement de la base de données. L'indexation rend plus rapide les recherches en organisant les données dans un arbre de recherche qui peut être parcouru plus rapidement afin de trouver un enregistrement particulier. Par défaut PostgreSQL supporte trois type d'indexes : les arbres B, les arbres R et les arbre de recherche généralisés (GiST).

haut de la page | table des matières

4.5.1. Les index GiST

GiST signifie "arbre de recherche généralisé" et est une forme générique d'indexation. En plus pour l'indexation GiST, GiST est utilisé pour accélérer les recherches de tout type de données irrégulières (tableau d'entier, données spectrales, etc) qui ne sont pas utilisables avec l'indexation normale par arbre B.

Une fois que les tables de données SIG dépassent quelques milliers d'enregistrements, vous voudrez créer des index pour accélérer les recherches spatiales des données (à moins que vos recherches soient basées sur des attributs, auquel cas vous devrez créer des index normaux sur les champs de ces attributs).

La syntaxe pour créer un index GiST sur une colonne géométrique est la suivante :

CREATE INDEX [nom_de_l_index ON [nom_de_la_table
  USING GIST ( [champ_géographique] GIST_GEOMETRY_OPS );

Créer un index spatial est un calcul informatique important : sur les tables d'environ un million d'enregistrements, sur une machine Solaris à 300MHz, nous avons trouvé que la création d'un index GiST prend environ une heure. Après avoir créer un index, il est important de forcer PostgreSQL à collecter les statistiques sur les tables, qui sont utilisées pour optimiser les planifications de requêtes :

VACUUM ANALYZE [table_name] [column_name];
-- Ceci n'est nécessaire que pour les installations de PostgreSQL 7.4 et précédentes :
SELECT UPDATE_GEOMETRY_STATS([table_name], [column_name]);

Dans PotgreSQL, les index GiST ont deux avantages par rapport aux arbres R. Premièrement, les arbres de recherches généralisées acceptent les valeurs null, ce qui signifie qu'ils peuvent indexer des colonnes incluant des valeurs null. Deuxièmement, les arbre de recherches généralisées supportent le concept de "déperdition" qui est important lorsqu'on utilise des objets SIG d'une taille supérieur à la taille de 8K des pages de PostgreSQL. La "déperdition" permet à PostgreSQL de stocker uniquement les parties "importantes" d'un objet dans un index - dans le cas d'objets SIG, uniquement le cadre limite. Les objets SIG plus larges que 8K impliquent que le processus de création des arbres R échouera.

haut de la page | table des matières

4.5.2. Utilisation des index

Habituellement, les index accélèrent l'accès aux données de façon transparente : une fois les index créés, le planificateur de requêtes décide de manière transparente quand utiliser l'index pour accélérer le plan de requête. Hélas, le planificateur de requête de PostgreSQL n'optimise pas bien l'utilisation d'index GiST, donc parfois les recherches qui devraient utiliser les index spatiaux par défaut au lieu d'un parcours séquentiel sur la table entière ne sont pas utilisés.
Si vous constatez que vos index spatiaux ne sont pas utilisés (ou vos index sur les champs, par exemple) il y a quelques "trucs" que vous pouvez tenter :

Note :
Comme pour la version 0.6, il n'est pas nécessaire de forcer le planificateur à utiliser l'index avec ENABLE_SEQSCAN.
Si vous constatez que le planificateur a tort à propos du cout d'un parcours séquentiel par rapport à l'index, essayez de réduire la valeur du paramètre random_page_cost dans votre postgresql.conf ou utilisez la commande SET random_page_cost=#. La valeur par défaut pour ce paramètre est 4, essayez d'y attribuer les valeurs 1 ou 2. Décrémenter cette valeur rend le planificateur plus enclin à utiliser les parcours via l'index.

haut de la page | table des matières

4.6. Requêtes complexes

La raison d'être des fonctionnalités spatiales des base de données est de vous permettre d'effectuer des requêtes qui requièrent habituellement des outils SIG bureautiques. Utiliser PostGIS de manière efficace nécessite de connaitre qu'elles sont les fonctions spatiales disponibles et de s'assurer que les indexes appropriés sont en place pour obtenir de bonne performances.

haut de la page | table des matières

4.6.1. Tirer avantage des indexes.

Lorsque vous construisez une requête il est important de se souvenir que seuls les opérateurs du cadre-limite comme && tirent avantage des indexes spatiaux GIST. Les fonctions comme distance() ne peuvent pas utiliser les indexes pour optimiser leur opérations. Par exemple, la requête suivante pourrait être légèrement lente sur une grosse table :

SELECT the_geom FROM geom_table WHERE distance( the_geom, GeomFromText( 'POINT(100000 200000)', -1 ) ) < 100

Cette requête sélectionne toutes les géométries de geom_table qui sont dans un rayon de 100 unités du point (100000, 200000). Elle est lente parce qu'elle calcule la distance entre chaque point de la table et le point que nous avons spécifié, par exemple un calcul de distance() pour chaque enregistrement de la table. Nous pouvons éviter cela en utilisant l'opérateur && pour réduire le nombre de distance requit :

SELECT the_geom FROM geom_table
WHERE the_geom && 'BOX3D(90900 190900, 100100 200100)'::box3d
AND distance( the_geom, GeomFromText( 'POINT(100000 200000)', -1 ) ) < 100

Cette requête sélectionne les même géométries, mais il le fait de manière plus efficace. Supposons qu'il existe un indexe GiST sur the_geom, le planificateur de requêtes constatera qu'il peut utiliser l'indexe pour réduire le nombre de ligne avant de calculer le résultat de la fonction distance(). Notez que la géométrie BOX3D qui est utilisé dans l'opération && est un cadre carré de 200 unités centré sur le point original - c'est notre "cadre de requête". L'opérateur && utilise l'indexe pour réduire rapidement l'ensemble résultant aux géométries qui ont un cadre limite qui recouvre le "cadre de requête". En supposant que notre "cadre de requête" est plus petit que l'extension de la totalité de la table, cela réduira considérablement le nombre de calculs de distance qui devra être effectué.

Note : depuis PostGIS 1.3.0, la plupart des fonctions relationnelles, à l'exception de ST_Disjoint and ST_Relate, utilisent implicitement l'opérateur de superposition du cadre limite.

haut de la page | table des matières

4.6.2. Exemple de SQL spatial

Les exemples de cette section utiliseront deux tables, une table de routes linéaires, et une table de limite polygonales des municipalités. La définition pour la table bc_routes est la suivante :

Column   | Type              | Description
---------+-------------------+-------------------
gid      | integer           | Unique ID
name     | character varying | Road Name
the_geom | geometry          | Location Geometry (Linestring)

La définition pour la table bc_minicipalitees est la suivante :

Column     | Type              | Description
-----------+-------------------+-------------------
gid        | integer           | Unique ID
code       | integer           | Unique ID
name       | character varying | City / Town Name
the_geom   | geometry          | Location Geometry (Polygon)

haut de la page | table des matières

4.6.2.1. Quelle est la longueur totale en kilomètres de toutes les routes ?

Vous pouvez répondre à cette question avec une requête SQL simple :

postgis=# SELECT sum(length(the_geom))/1000 AS longueur_routes_en_km FROM bc_routes :

longueur_routes_en_km
------------------
70842.1243039643
(1 row)

haut de la page | table des matières

4.6.2.2. Quelle est l'aire en hectare de la ville Prince George ?

Cette requête combine une condition attributaire (sur le nom de la municipalité) avec un calcul spatial (de l'aire) :

postgis=# SELECT area(the_geom)/10000 AS hectares FROM bc_municipalite WHERE name = 'PRINCE GEORGE';
hectares
------------------
32657.9103824927
(1 row)
haut de la page | table des matières

4.6.2.3. Quelle est la plus grande municipalité (aire) de la province ?

Cette requête utilise une mesure spatiale comme condition. Il y a plusieurs manières d'approcher ce problème, mais la plus efficace est la suivante :

postgis=# SELECT name, area(the_geom)/10000 AS hectares
          FROM bc_municipalite
          ORDER BY hectares DESC LIMIT 1;

     name      |    hectares
---------------+-----------------
TUMBLER RIDGE  | 155020.02556131
(1 row)

Vous remarquerez que pour répondre à cette question nous devons calculer l'aire de tous les polygones. Si nous faisons souvent cela, il serait judicieux d'ajouter une colonne "aire" à la table que nous pourrions alors indexer pour plus de performance. En ordonnant le résultat par ordre décroissant, et en utilisant la commende LIMIT de PostgreSQL nous pouvons aisément récupérer la plus grande valeur sans avoir à utiliser de fonction d'agrégation comme max().

haut de la page | table des matières

4.6.2.4. Quelle est la longueur des routes totalement contenues dans chaque municipalités ?

Ceci est un exemple de "jointure spatiale', parce que nous utilisons les données de deux tables (en faisant une jointure) mais en utilisant une condition d'interaction spatiale ("contenue") comme condition de jointure au lieu d'utiliser l'approche relationnelle habituelle de jointure sur une clef commune :

postgis=# SELECT m.name, sum(length(r.the_geom))/1000 as roads_km
         FROM bc_roads AS r,bc_municipality AS m
         WHERE r.the_geom && m.the_geom
               AND contains(m.the_geom,r.the_geom)
         GROUP BY m.name
         ORDER BY roads_km;

           name             |    roads_km
----------------------------+------------------
SURREY                      | 1539.47553551242
VANCOUVER                   | 1450.33093486576
LANGLEY DISTRICT            | 833.793392535662
BURNABY                     | 773.769091404338
PRINCE GEORGE               | 694.37554369147
...

Cette requête dure un moment, parce que chaque route de la table est disponible dans le résultat final (environ 250K routes pour notre table d'exemple). Pour des couvertures plus petites (quelques milliers ou centaines d'enregistrements) la réponse peut être très rapide.

haut de la page | table des matières

4.6.2.5. Créer une nouvelle table contenant toutes les routes de la ville de Prince George.

Ceci est un exemple de "couverture", qui extrait les données de deux tables et retourne une nouvelle table qui contient l'ensemble des résultantes incluses ou partiellement coupées. Contrairement à la "jointure spatiale" présentée précédemment, cette requête crée de nouvelles géométries. Une couverture est comme une jointure spatiale turbo-cached, et est utile pour un travail d'analyse plus précis :

postgis=# CREATE TABLE pg_roads as
SELECT intersection(r.the_geom, m.the_geom) AS intersection_geom,
length(r.the_geom) AS rd_orig_length,
r.*
FROM bc_roads AS r, bc_municipality AS m
WHERE r.the_geom && m.the_geom
AND intersects(r.the_geom, m.the_geom)
AND m.name = 'PRINCE GEORGE';
haut de la page | table des matières

4.6.2.6. Quelle est la longueur en kilomètre de "Douglas St" à Victoria ?

postgis=# SELECT gid, name, area(the_geom) AS area
          FROM bc_municipality
          WHERE nrings(the_geom) > 1
          ORDER BY area DESC LIMIT 1;
gid  | name         | area
-----+--------------+------------------
12   | SPALLUMCHEEN | 257374619.430216
(1 row)
haut de la page | table des matières

4.7. Utilisation de Mapserver

Minnesota Mapserver est un serveur cartographique Internet qui se conforme aux spécifications "Web Mapping Server" de l'OpenGIS.

haut de la page | table des matières

4.7.1. Utilisation de base

Pour utiliser PostGIS avec Mapserver vous aurez besoin de savoir comment configurer Mapserver, ce qui dépasse le cadre de cete documentation. Cette section va couvrir les particularités d'une utilisation avec Postgis et les détails de la configuration.

Pour utiliser PostGIS avec Mapserver, vous aurez besoin de :

Mapserver accède aux données PostgreSQL/PostGIS comme n'importe quel autre client PostgreSQL - c'est à dire en utilisant la libpq. Cela signifie que Mapserver peut être installé sur chaque machines ayant un accès réseau vers un serveur PostGIS, temps que le système possède la libraire client de PostgreSQL (libpq).

  1. Compilez et installez Mapserver, avec les supports qui vous souhaitez activer, incluant l'option de configuration : "--with-postgis".
  2. Dans votre fichier map de Mpaserver, ajouté une couche PostGIS. Par exemple :
    LAYER
      CONNECTIONTYPE postgis
      NAME "widehighways"
      # Connect to a remote spatial database
      CONNECTION "user=dbuser dbname=gisdatabase host=bigserver"
      # Get the lines from the 'geom' column of the 'roads' table
      DATA "geom from roads"
      STATUS ON
      TYPE LINE
      # Of the lines in the extents, only render the wide highways
      FILTER "type = 'highway' and numlanes >= 4"
      CLASS
        # Make the superhighways brighter and 2 pixels wide
        EXPRESSION ([numlanes] >= 6)
        COLOR 255 22 22
        SYMBOL "solid"
        SIZE 2
      END
      CLASS
        # All the rest are darker and only 1 pixel wide
        EXPRESSION ([numlanes] < 6)
        COLOR 205 92 82
      END
    END

    Dans l'exemple ci-dessus, les directives spécifiques à PostGIS sont les suivantes :

    CONNECTIONTYPE
    Pour les couches PostGIS, cela sera toujours "postgis".

    CONNECTION
    La connection à la base de données est gouvernée par "la chaine de charatères de connection" ("connection string") qui est contituée d'un ensemble de couples nom/valeur comme ceci (avec la valeur par défaut entre < >) :
    user=<nom_d_utilisateur> password=<mot_de_passe> dbname=<nom_de_la_base_de_données> hostname=<serveur> port=<5432>
    Une chaine de charactères de connection vide reste valide, et chacun des couples nom/valeur peut être omis. Au minimum vous aurez généralement besoin de spécifier le nom de la base de données et le nom d'utilisateur avec lequel vous souhaitez vous connecter.

    DATA
    La forme de ce paramètre est : "<colonne> from <nom_de_la_table>" où la colonne est une colonne spatiale qui doit être affiché sur la carte.

    FILTER
    Le filtre doit être une chaîne de charactères SQL valide correspondant à la logique normale suivant le mot clef "WHERE" dans les requêtes SQL. Donc, par exemple, pour afficher uniquement les routes ayant 6 voies ou plus, utilisé le filtre "nombre_de_voies >= 6".

  3. Dans votre base de données spatiale, assurez vous que vous avez des indexes spatiaux (GiST) pour chaque couches que vous souhaitez afficher.
    CREATE INDEX [nom_de_l_index]
    ON [nom_de_la_table]
    USING GIST ( [colonne_géometrique] GIST_GEOMETRY_OPS );
  4. Si vous allez interroger vos couches en utilisant Mpaserver vous aurez aussi besoin d'un "index oid".
    Mapserver requière des indentifiants uniques pour chaque enregistrement spatial lorsque vous souhaitez effetuer des interrogations, et le module PostGIS de Mapserver utilise les valeurs d'oid de PostgreSQL pour fournir ces identifiants uniques. Cela implique comme effet de bord que si vous souhaitez effectuer des accès aléatoires rapides aux enregistrements durant les requêtes, un index sur les oid est necessaires.
    Pour construire un tel index, utilisez la requête SQL suivante :
    CREATE INDEX [nom_de_l_index] ON [nom_de_la_table] ( oid );

haut de la page | table des matières

4.7.2. Questions fréquemment posées


haut de la page | table des matières

4.7.2.1. Lorsque j'utilise une EXPRESSION dans ma map, la condition ne retourne jamais vrai, même si elle devrait.

Contrairement aux fichiers vecteurs (shapefile), les noms de champs PostGIS doivent être référencés dans EXPRESSIONS en utilisant des lettres en minuscule.

EXPRESSION ([nombre_de_voies] >= 6)
haut de la page | table des matières

4.7.2.2. Le FILTER que j'utilise pour mon fichier vecteur ne fonctionne pas pour ma table PostGIS contenant les mêmes données.

Contrairement aux fichiers vecteurs (shapefile), les filtres pour les couches PostGIS utilisent la syntaxe SQL (ils sont concaténés à l'état SQL que le connecteur PostGIS génère pour afficher les couches dans Mapserver).

FILTER "type = 'autoroute' and nombre_de_voies >= 4"
haut de la page | table des matières

4.7.2.3. Ma couche PostGIS se dessine plus doucement que mon fichier vecteur, est-ce normal?

En général, les couches PostGIS sont 10 % plus lentes que les couches équivalentes en fichier vecteurs, ceci est due au temps qui incombe à la connection au serveur de base de données, les transformations et la transmission des données entre la base et Mapserver.

Si vous avez des problèmes de performance d'affichage, cela est généralement lié au fait que vous n'avez pas créé les indexes spatiaux pour vos tables.

postgis# CREATE INDEX geotable_gix ON geotable USING GIST ( geocolumn );
postgis# SELECT update_geometry_stats(); -- Pour PGSQL < 8.0
postgis# VACUUM ANALYZE; -- Pour PGSQL >= 8.0
haut de la page | table des matières

4.7.2.4. Mes couches PostGIS s'affichent correctement, mais les requêtes sont vraiment lentes. Que se passe-t-il ?

Pour que les requêtes soient rapides, vous devez avoir une clef unique pour vos tables spatiales et un index sur cette clef unique.
Vous pouvez spécifier quelle clef unique doit être utilisée par Mapserver, en utilisant la clause : USING UNIQUE dans votre ligne DATA :
DATA "the_geom FROM geotable USING UNIQUE gid"
Si votre table n'a pas de colonne explicitement unique, vous pouvez "faire semblant" de rendre une colonne unique en utilisant la colonne PostgreSQL "oid" comme colonne unique. "oid" est la colonne unique par défaut si vous n'en déclarez pas une, donc pour améliorer le temps d'exécution de vos requêtes vous devez créer des indexes sur les valeurs oid de vos tables spatiales.
postgis# CREATE INDEX geotable_oid_idx ON geotable (oid);

haut de la page | table des matières

4.7.3. Utilisation avancée

La clause pseudo-SQL USING est utilisée afin d'ajouter des informations pour aider Mapserver à comprendre les résultats de plusieurs requêtes complexes. Plus précisément, lorsqu'une vue ou une sous-requête de sélection est utilisée comme table source (le terme à la droite du FROM dans la définition de DATA) il est plus difficile pour Mapserver de déterminer automatiquement un identifiant unique pour chaque tuple et le SRID pour la table. La clause USING peut fournir à Mapserver ces deux types d'informations :

DATA "the_geom FROM (SELECT table1.the_geom AS the_geom, table1.oid AS oid, table2.data AS data
FROM table1 LEFT JOIN table2 ON table1.id = table2.id) AS new_table USING UNIQUE oid USING SRID=-1"

USING UNIQUE <idunique>

Mapserver requière un identifiant unique pour chaque tuple dans le but d'identifier une ligne lorsque l'on effectue des interrogations de la carte. Normalement, il devrait utiliser l'oid comme identifiant unique, mais les vues et les sous-requêtes de sélection n'ont pas obligatoirement cette colonne oid. Si vous souhaitez utiliser les fonctionnalités d'interrogation de Mapserver, vous aurez besoin d'ajouter une colonne unique à vos vues ou vos sous-requêtes de sélection, et déclarer ceci en utilisant : USING UNIQUE. Pour ce faire, vous pouvez, par exemple, explicitement sélectionner une des valeurs d'oid de la table, ou l'une des autres colonnes pour laquelle vous garantissez l'unicité dans l'ensemble résultant.

L'état USING peut aussi être utile pour de simples état DATA, si vous effectuez des interrogations de la carte. Il était jadis recommandé d'ajouter un indexe sur la colonne oid des tables utilisées dans les couches interrogeables, dans le but d'accélérer les requêtes de la carte. Cependant, avec la clause USING, il est possible de spécifier à Mapserver d'utiliser la clef primaire de votre table comme identifiant pour interroger la carte, il n'est ainsi plus nécessaire d'avoir un indexe supplémentaire.

Note :
"Interroger une carte" est l'action qui consiste à cliquer sur la carte pour demander les informations relatives à la zone géographique sélectionnée. Ne confondez pas "interrogation de carte" avec requête SQL dans la définition de DATA.

USING SRID=<srid>

PostGIS a besoin de connaitre quel système de référence spatial doit être utilisé par les géométries afin de retourner correctement les données à Mapserver. Normalement il est possible de trouver ces informations dans la table "geometry_columns" dans une base de données PostGIS, cependant, il n'est pas possible pour les tables qui ont été créées à la volée comme des sous-requêtes de sélection ou des vues. Donc l'option USING SRID= vous permet de spécifier le SRID correspondant à vos données dans la définition de DATA.

Attention :
Le parser pour les couches PostGIS de Mapserver est légérement primitif et est sensible à la casse dans certaines parties. Faites attention à ce que tous les mots clefs SQL et toutes les clauses USING soient en lettres majuscules, et que vos clauses USING UNIQUE précèdent bien vos clauses USING SRID.

haut de la page | table des matières

4.7.4. Exemples

Commençons avec un exemple simple et qui nous servira de base pour la suite. Considérons la définition de couche Mapserver suivante :

LAYER
 CONNECTIONTYPE postgis
 NAME "routes"
 CONNECTION "user=lutilisateur password=lemotdepasse dbname=labase host=leserveur"
 DATA "the_geom FROM routes"
 STATUS ON
 TYPE LINE
 CLASS
  COLOR 0 0 0
 END
END

Cette couche affichera toutes les géométries de la table routes comme des lignes noires.

Maintenant, supposons que nous voulions uniquement afficher les autoroutes lorsque nous zoomons au moins à une échelle de 1:100000, les deux prochaines couches permettent cela :

LAYER
 CONNECTION "user=lutilisation password=lemotdepasse dbname=labase host=leserveur"
 DATA "the_geom FROM routes"
 MINSCALE 100000
 STATUS ON
 TYPE LINE
 FILTER "type_de_route = 'autotourte'"
 CLASS
  COLOR 0 0 0
 END
END
LAYER
 CONNECTION "user=lutilisateur password=lemotdepasse dbname=labase host=leserveur"
 DATA "the_geom FROM routes"
 MAXSCALE 100000
 STATUS ON
 TYPE LINE
 CLASSITEM type_de_route
 CLASS
  EXPRESSION "autoroute"
  SIZE 2
  COLOR 255 0 0
 END
 CLASS
  COLOR 0 0 0
 END
END

La première couche est utilisée lorsque l'échelle est plus grande que 1:100000, et affiche uniquement des lignes noires pour les routes de type "autoroute". L'option FILTER entraine que seules les routes de type "autoroute" doivent être affichées.

La seconde couche est utilisée lorsque l'échelle est plus petite que 1:100000, et affichera les autoroutes comme des lignes rouges à double-profondeurs, et les autre routes comme des lignes noires standards.

Donc, nous avons fait un couple de choses intéressantes en utilisant uniquement les fonctionnalités de Mapserver, mais nos états SQL dans les définitions de DATA sont restées simples. Supposons que le nom des routes soit stocké dans une autre table (pour une raison quelconque) et que nous souhaitions faire une jointure pour récupérer et étiqueter nos routes.

LAYER
 CONNECTION "user=lutilisateur password=lemotdepasse dbname=labase host=leserveur"
 DATA "the_geom FROM (SELECT routes.oid AS oid, routes.the_geom AS the_geom, nom_des_routes.nom as nom
  FROM routes LEFT JOIN nom_des_routes ON routes.id_nom_de_routes = nom_des_routes.id_nom_de_routes) AS routes_nommées
  USING UNIQUE oid USING SRID=-1"
 MAXSCALE 20000
 STATUS ON
 TYPE ANNOTATION
 LABELITEM nom
 CLASS
  LABEL
   ANGLE auto
   SIZE 8
   COLOR 0 192 0
   TYPE truetype
   FONT arial
  END
 END
END

Cette couche d'annotation ajoute des étiquettes vertes à toutes les routes lorsque l'échelle atteint 1:20000 ou moins. Cela montre aussi comment utiliser les jointures SQL dans une définition de DATA.

haut de la page | table des matières

4.8. Clients Java (JDBC)

Les clients Java peuvent accéder aux objets géométriques de PostGIS dans une base de données PostgreSQL soit directement via les représentations textuelles ou en utilisant les objets de l'extension JDBC distribuée avec PostGIS. Dans le but d'utiliser les objets de l'extension, le fichier "postgis.jar" doit être ajouté à votre CLASSPATH ainsi que le driver JDBC de PostgreSQL "postgresql.jar".

import java.sql.*;
import java.util.*;
import java.lang.*;
import org.postgis.*;

public class JavaGIS {
public static void main(String[] args)
{
java.sql.Connection conn;
try
{
/*
* Chargement du pilote JDBC et établissement d'une connection.
*/
Class.forName("org.postgresql.Driver");
String url = "jdbc:postgresql://localhost:5432/database";
conn = DriverManager.getConnection(url, "postgres", "");

/*
* Ajout du type géométrique à la connection. Notez que vous devez effectuer
* une convertion de type pour la connection avant de faire appèle à la méthode
* addDataType().
*/
((org.postgresql.Connection)conn).addDataType("geometry","org.postgis.PGgeometry");
((org.postgresql.Connection)conn).addDataType("box3d","org.postgis.PGbox3d");

/*
* Crée un état et exécute la requête de selection.
*/
Statement s = conn.createStatement();
ResultSet r = s.executeQuery("select AsText(geom) as geom,id from geomtable");
while( r.next() )
{
/*
* Récupération de la géométrie comme un objet puis convertion de type en
* vers le type geometry. Affichage des résultats.
*/
PGgeometry geom = (PGgeometry)r.getObject(1);
int id = r.getInt(2);
System.out.println("Row " + id + ":");
System.out.println(geom.toString());
}
s.close();
conn.close();
}
catch( Exception e )
{
e.printStackTrace();
}
}
}

L'objet "PGgeometry" est un objet de transition qui contient un objet géométrique à topologie spécifique (sous-classe de la classe abstraite "Geometry") dépendant du type : Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon.

PGgeometry geom = (PGgeometry)r.getObject(1);
if( geom.getType() = Geometry.POLYGON )
{
Polygon pl = (Polygon)geom.getGeometry();
for( int r = 0; r < pl.numRings(); r++ )
{
LinearRing rng = pl.getRing(r);
System.out.println("Ring: " + r);
for( int p = 0; p < rng.numPoints(); p++ )
{
Point pt = rng.getPoint(p);
System.out.println("Point: " + p);
System.out.println(pt.toString());
}
}
}

La JavaDoc fournit, pour les objets de l'extension, une référence pour les diverses méthodes d'accès aux données dans les objets géométriques.

haut de la page | table des matières

4.9. Clients C (libpq)


haut de la page | table des matières

4.9.1. Curseurs Text


haut de la page | table des matières

4.9.2. Curseurs Binaires


haut de la page | table des matières

Chapitre 5. Performance, trucs et astuces


haut de la page | table des matières

5.1. Petites tables comportant de vastes objets géométriques


haut de la page | table des matières

5.1.1. Description du problème

Les versions actuelles de PostgreSQL (dont 8.0) souffrent d'un défaut de l'optimiseur de requêtes en ce qui concerne les tables TOAST. Les tables TOAST sont une sorte
d'"espace supplémentaire" servant à stocker de "grandes" valeurs (grandes au sens de la taille des données) qui ne peuvent loger dans des pages de données normales (comme les longs textes, les images, ou les géométries complexes comportant un grand nombre d'arcs), voir http://www.postgresql.org/docs/8.0/static/storage-toast.html pour plus d'information).
Le problème apparait si vous possédez une table avec des géométries de taille importantes, mais avec peu de tuples (par exemple une table contenant les frontières des pays européens en haute résolution). La table elle-même est relativement petite, mais elle utilise énormément d'espace TOAST. Dans notre exemple, la table compte environ 80 lignes (ou tuples), et n'utilise que 3 pages de données, mais la table TOAST utilise 8225 pages.
A présent, essayez de lancer une requête en utilisant l'opérateur géométrique && pour rechercher une boite englobante qui ne comprend que quelques-uns de ces tuples.
L'optimiseur de requête constate que votre table ne compte que 3 pages et 80 lignes. Il estime par conséquent qu'un scan séquentiel sur une si petite table est beaucoup plus rapide que d'utiliser un index. Et il choisir d'ignorer l'index GIST. D'ordinaire, son estimation est juste mais dans notre cas, l'opérateur && doit aller récupérer chaque objet géométrique sur le disque pour comparer les boites englobantes, et il parcoure par la même occasion toutes les pages TOAST.
Pour vérifier si vous pâtissez de ce bogue, utilisez la commande "EXPLAIN ANALYZE" de postgresql. Pour plus d'informations et des détails techniques, vous pouvez lire ce sujet sur la liste de discussion des performances de postgres : http://archives.postgresql.org/pgsql-performance/2005-02/msg00030.php

haut de la page | table des matières

5.1.2. Solutions de contournement

Les développeurs de PostgreSQL essayent de résoudre ce problème en faisant en sorte que l'estimateur de la requête prenne en considération l'espace TOAST. Pour le moment, voici deux solutions de contournement :

La première est de forcer le préparateur de requête à utiliser l'index. Envoyez "SET enable_seqscan TO off;" au serveur avant de lancer la requête. Cela force le préparateur de requête à éviter les scans séquentiels intempestifs lorsque c'est possible. Il utilise alors l'index GIST comme d'habitude. Cependant, ce drapeau doit être fixé à chaque connexion, et il conduit le préparateur de requête à faire des erreurs d'estimation dans d'autres cas de figure, il faut donc le remettre à "SET enable_seqscan TO on;" après la requête.

La seconde solution est de rendre le scan séquentiel aussi rapide que le préparateur de requête le pense. Cela peut se faire en créant un champ additionnel qui met la boîte englobante en cache, et de se servir de ce nouveau champ pour opérer les comparaisons. Dans notre exemple, les commandes sont :

SELECT addGeometryColumn('myschema','mytable','bbox','4326','GEOMETRY','2');

UPDATE mytable set bbox = Envelope(Force_2d(the_geom));

Maintenant, changez votre requête en utilisant l'opérateur && sur la boîte englobante à la place de geom_column, comme suit:

SELECT geom_column FROM mytable WHERE bbox && SetSrid('BOX3D(0 0,1 1)'::box3d,4326);

Bien entendu, si vous changez ou ajoutez des lignes à mytable, vous devrez veiller à ce que la boîte englobante reste à jour. La façon la plus transparente de faire cela est par une moulinette automatique, mais vous pouvez aussi modifier votre application pour que le champ de la boîte englobante reste à jour de façon permanente ou lancer la requête UPDATE après chaque modification.

haut de la page | table des matières

5.2. Faire des CLUSTER sur des index géométriques

Pour des tables qui sont essentiellement en lecture seule et où un simple index sert à la majorité des requêtes, PostgreSQL offre la commande CLUSTER. Cette commande réordonne physiquement toutes les lignes de données dans l'ordre du critère de l'index, ce qui offre deux avantages du point de vue des performances. D'abord pour les scans d'index, le nombre de recherche dans la table est considérablement réduit. Deuxièmement, si votre ensemble de travaille ne concerne que de petits intervalles sur l'index, vous obtenez une recherche plus efficace car les données sont dispersées sur moins de pages. (Merci de vous référer à la documentation de la commande CLUSTER du manuel PostgreSQL pour davantage d'informations).

Cependant, PostgreSQL ne permet actuellement pas le clustering sur les index GIST de PostGIS car les index GIST ignorent les valeurs NULL, vous obtenez un message d'erreur du type :

lwgeom=# CLUSTER my_geom_index ON my_table;
ERREUR: impossible de faire un cluster quand la méthode d'indexation ne tolère pas les valeurs null
TRUC : Vous pourrez contourner cet incovénient en marquant la colonne "the_geom" NOT NULL.

Comme le message vous le spécifie, on peut contourner cet inconvénient en ajoutant une contrainte NOT NULLl à la table :

lwgeom=# ALTER TABLE my_table ALTER COLUMN the_geom SET not null;
ALTER TABLE

Bien sûr, cela ne fonctionnera pas si vous avez de fait besoin de valeurs NULL dans votre colonne de géométrie. En plus vous devez donc utiliser la méthode ci-dessus pour ajouter la contrainte, utiliser une vérification du style ALTER TABLE blubb ADD CHECK (geometry is not null); ne fonctionnera pas.

haut de la page | table des matières

5.3. Eviter la conversion de dimensions des données

Il arrive quelquefois que vous ayez des données 3D ou 4D dans votre table, mais vous n'y accéder qu'au travers de fonctions conformes aux standards de l'OpenGIS telles que Text() ou Binary() qui ne fournissent en sortie que des données géométriques 2D. Ces fonctions utilisent en effet un appel à la fonction force_2d(), qui induit une perte de temps pour les géométries de grandes tailles. Pour l'éviter, vous pouvez au préalable vous débarrasser des dimensions superflues une bonne fois pour toutes en exécutant :

UPDATE mytable SET the_geom = force_2d(the_geom);
VACUUM FULL ANALYZE mytable;

Veuillez noter que si vous avez ajouter votre champ géométrique au moyen de AddGeometryColumn() vous subirez une contrainte sur la dimension géométrique.

Pour la dépasser, vous devrez d'abord lever la contrainte. Rappelez-vous ensuite de mettre à jour l'entrée de la table geometry_columns et de recréer par la suite la contrainte.

Dans le cas de manipulation de grandes tables, il est préférable de diviser l'UPDATE entre plus petites parties en restreignant l'UPDATE à une partie de la table au moyen d'une clause WHERE et de votre clef primaire, ou d'un autre critère quelconque, et d'exécuter un simple nétoyage ("VACUUM;") entre vos UPDATEs. Cela réduit votre besoin temporaire en espace disque de manière radicale. De plus, si vous avez des données géométriques avec différentes dimensions, restreindre l'UPDATE à "WHERE dimension(the_geom)>2" vous évite de réécrire les géométries qui sont d'ores et déjà en 2D.

haut de la page | table des matières

Chapitre 6. Référence des fonctions PostGIS

Les fonctions listées ci-dessous font partie de celles qu'un utilisateur PostGIS utilise couramment. Il existe d'autres fonctions qui servent à la manipulation d'objets PostGIS mais qui ne sont d'aucune utilité à l'utilisateur Lambda.

haut de la page | table des matières

6.1. Fonctions OpenGIS


haut de la page | table des matières

6.1.1. Fonctions de gestion

AddGeometryColumn(varchar, varchar, varchar, integer, varchar, integer)

Syntax : AddGeometryColumn(<nom_du_schema>, <nom_de_la_table>, <nom_de_la_colonne>, <srid>, <type>, <dimension>). Ajouter une colonne géométrique aux attributs d'une table existante. Le nom du schéma est le nom du schéma de la table (inutilisé pour les installations de PostgreSQL ne supportant pas les schémas). Le SRID doit être une valeur entière faisant référence à une entrée de la table spatial_ref_sys. Le type doit être une chaine de caractères en majuscule correspondant au type géométrique, par exemple, POLYGON ou MULTILINESTRING.

DropGeometryColumn(varchar, varchar, varchar)

Syntax : DropGeometryColumn(<nom_du_schema>, <nom_de_la_table>, <nom_de_la_colonne>). Supprimer une colonne géométrique d'une table spatiale. Notez que le nom_du_schéma devra correspondre au champ f_schema_name du tuple correspondant dans la table geometry_columns.

SetSRID(geometry, integer)

Attribut au SRID sur une géométrie une valeur entière particulière. Utile pour construire des cadres limites pour des requêtes.

haut de la page | table des matières

6.1.2. Fonctions "relationelles"

Distance(geometry, geometry)

Renvoie la distance cartésienne entre deux géométries dans l'unité de projection.

Equals(geometry, geometry)

(Effectué par le module GEOS) : retourne 1 (vrai) si les géométries passées en paramètres sont "spatialement égales". Utilisez ceci pour un meilleur résultat que l'opération '='. equals('LINESTRING(0 0, 10 10)','LINESTRING(0 0, 5 5, 10 10)') est vrai.
OGC SPEC s2.1.1.2

Disjoint(geometry, geometry)

(Effectué par le module GEOS) : retourne 1 (vrai) si les géométries sont spatialement disjointes.
Ne pas appeler avec une GeometryCollection en argument.
NOTE : c'est la version "permissive" qui retourne un booléen, pas un entier.
OGC SPEC s2.1.1.2 //s2.1.13.3 - a.Relate(b, 'FF*FF****')

Intersects(geometry, geometry)

(Effectué par le module GEOS) : retourne 1 (vrai) si les géométries "s'intersectent spatialement"
Ne pas appeler avec une GeometryCollection en argument.
NOTE : c'est la version "permissive" qui retourne un booléen, pas un entier.
OGC SPEC s2.1.1.2 //s2.1.13.3 - Intersects(g1, g2 ) --> Not (Disjoint(g1, g2 ))

Touches(geometry, geometry)

(Effectué par le module GEOS) : retourne 1 (vrai) si les géométries se "touchent spatialement".
Ne pas appeler avec une GeometryCollection en argument.
NOTE : c'est la version "permissive" qui retourne un booléen, pas un entier.
OGC SPEC s2.1.1.2 // s2.1.13.3- a.Touches(b) -> (I(a) intersection I(b) = {empty set} ) and (a intersection b) not empty

Crosses(geometry, geometry)

(Effectué par le module GEOS) : retourne 1 (vrai) si les géométries se "croisent spatialement".
Ne pas appeler avec une GeometryCollection en argument.
NOTE : c'est la version "permissive" qui retourne un booléen, pas un entier.
OGC SPEC s2.1.1.2 // s2.1.13.3 - a.Relate(b, 'T*T******')

Within(geometry A, geometry B)

(Effectué par le module GEOS) : retourne 1 (vrai) si la géométrie A est "spatialement inclue" dans la géométrie B.
Ne pas appeler avec une GeometryCollection en argument.
NOTE : c'est la version "permissive" qui retourne un booléen, pas un entier.
OGC SPEC s2.1.1.2 // s2.1.13.3 - a.Relate(b, 'T*F**F***')

Overlaps(geometry, geometry)

(Effectué par le module GEOS) : retourne 1 (vrai) si les géométries se superposent spatialement.
Ne pas appeler avec une GeometryCollection en argument.
NOTE : c'est la version "permissive" qui retourne un booléen, pas un entier.
OGC SPEC s2.1.1.2 // s2.1.13.3

Contains(geometry A, geometry B)

(Effectué par le module GEOS) : retourne 1 (vrai) si la géométrie A "contient spatialement" la géométrie B.
Ne pas appeler avec une GeometryCollection en argument.
NOTE : c'est la version "permissive" qui retourne un booléen, pas un entier.
OGC SPEC s2.1.1.2 // s2.1.13.3 - same as within(geometry B, geometry A)


Relate(geometry, geometry, intersectionPatternMatrix)

(Effectué par le module GEOS) : retourne 1 (vrai) si cette géométries est spatialement reliée à une autre géométrie, en testant l'intersections entre l'intérieur, la limite et l'extérieur des deux géométries comme spécifié par les valeurs dans l'intersectionPatternMatrix.
Ne pas appeler avec une GeometryCollection en argument.
NOTE : c'est la version "permissive" qui retourne un booléen, pas un entier.
OGC SPEC s2.1.1.2 // s2.1.13.3

Relate(geometry, geometry)

(Effectué par le module GEOS) : retourne la DE-9IM (la neuvième matrice d'intersection dimentionellement étendue)
Ne pas appeler avec une GeometryCollection en argument.
NOTE : c'est la version "permissive" qui retourne un booléen, pas un entier.
pas dans les specs de l'OGC, mais implémenté. voir s2.1.13.2

haut de la page | table des matières

6.1.3. Fonctions de traitement géométrique

Centroid(geometry)

Renvoie le barycentre de l'entité géométrique sous forme de point. Le calcul sera plus précis si vous utilisez le module GEOS (mis en place au moment de la compilation).

Area(geometry)

Renvoie la superficie de l'entité géométrique s'il s'agit d'un polygone ou d'un multi-polygone.

Length(geometry)

Renvoie la longueur d'un segment dans son système de référencement courant. Synonyme de length2d().
OGC SPEC 2.1.5.1

PointOnSurface(geometry)

Renvoie un point situé en surface.
Implémenté grâce à GEOS.
OGC SPEC 3.2.14.2 and 3.2.18.2 -

Boundary(geometry)

Renvoie le contour fermé du graphe de cet objet géométrique (geometry). Le graphe (combinatorial boundary) se définit comme décrit aux sections 3.12.3.2 des spécifications OGC. Comme le résultat de cette opération est un contour fermé, et par conséquent topologiquement fermé, le contour résultant peut se représenter au moyen des primitives géométriques décrites à la section 3.1.2.2. des spécifications OGC.
Exécuté par le module GEOS.
OGC SPEC s2.1.1.1

Buffer(geometry, double, [integer])

Renvoie un objet géométrique qui représente tous les points dont la distance à l'objet géométrique est inférieure ou égale à la distance fixée. Les calculs se font dans le système de référencement courant de cet objet géométrique. Le troisième paramètre optionnel fixe le nombre de segments à utiliser pour fournir une approximation du cercle quadratique (par défaut 8 ).
Exécuté par le module GEOS.
Ne l'appelez jamais avec une GeometryCollection en argument.
OGC SPEC s2.1.1.3

ConvexHull(geometry)

Renvoie un objet de type geometry qui représente la partie convexe de la géométrie passée en argument.
Exécuté par le module GEOS.
OGC SPEC s2.1.1.3

Intersection(geometry, geometry)

Renvoie un objet géométrique qui représente l'ensemble d'intersection des objets géométriques désignés.
Exécuté par le module GEOS.
Ne l'appelez jamais avec une GeometryCollection en argument
OGC SPEC s2.1.1.3

SymDifference(geometry A, geometry B)

Renvoie un objet géométrique qui représente l'ensemble d'exclusion de l'objet géométrique A avec l'objet géométrique B.
Ne l'appelez jamais avec une GeometryCollection en argument.
OGC SPEC s2.1.1.3

Difference(geometry A, geometry B)

Renvoie un objet géométrique qui représente l'ensemble de différence entre l'objet géométrique A et l'objet géométrique B.
Exécuté par le module GEOS.
Ne l'appelez jamais avec une GeometryCollection en argument.
OGC SPEC s2.1.1.3

GeomUnion(geometry, geometry)

Renvoie un objet géométrique qui représente l'ensemble d'union des objets géométriques désignés.
Exécuté par le module GEOS.
Ne l'appelez jamais avec une GeometryCollection en argument.
NOTE : initialement nommé "union", cette fonction a été renommé GeomUnion car Union est un mot-clef SQL.
OGC SPEC s2.1.1.3

GeomUnion(geometry set)

Renvoie un objet géométrique qui représente l'union de l'ensemble des objets géométriques pour un ensemble donné.
Exécuté par le module GEOS.
Ne l'appelez jamais avec une GeometryCollection en argument.
Non défini de façon explicite dans les OGC SPEC

MemGeomUnion(geometry set)

Identique à la fonction ci-dessus, mais travaille en utilisant moins de mémoire et plus de temps de calcul du processeur.

haut de la page | table des matières

6.1.4. Accès aux caractéristiques géométriques

AsText(geometry)

Renvoie la représentation textuelle de l'objet géométrique. Par exemple : POLYGON(0 0,0 1,1 1,1 0,0 0)
OGC SPEC s2.1.1.1

AsBinary(geometry)

Renvoie la géométrie au format binaire de l'OGC, en utilisant l'encodage endian (small endian/big endian) du serveur sur lequel la base de données tourne. C'est utile dans le cas de parseurs binaires, pour extraire des données de la base sans avoir à les convertir en chaines de caractères.
OGC SPEC s2.1.1.1 - voir aussi asBinary(,'XDR') et asBinary(,'NDR')

SRID(geometry)

Renvoie l'entier SRID du système de référence spatial de l'objet géométrique.
OGC SPEC s2.1.1.1

Dimension(geometry)

La dimension propre à l'objet géométrique, qui doit être inférieure ou égale à la dimension de ses coordonnées. OGC SPEC s2.1.1.1 - renvoie 0 pour des points, 1 pour des lignes, 2 pour des polygones, et la plus grande dimension trouvée parmi les composants d'une GEOMETRYCOLLECTION.

select dimension('GEOMETRYCOLLECTION(LINESTRING(1 1,0 0),POINT(0 0)');

 dimension
-----------
 1
Envelope(geometry)

Renvoie un POLYGON représentant le cadre limite de l'objet géométrique.
OGC SPEC s2.1.1.1 - Le cadre limite minimale de cet objet géométrique, retournée sous forme de géométrie. Le polygone est défini par les angles du cadre limite ((MINX, MINY), (MAXX, MINY), (MAXX, MAXY), (MINX, MAXY), (MINX, MINY)).
NOTE : PostGIS ajoutera des coordonnées Zmin/Zmax aussi.

IsEmpty(geometry)

Renvoie vrai si la géométrie est vide. Si c'est vrai, Geometry représente alors l'ensemble vide - i.e. GEOMETRYCOLLECTION(EMPTY).
OGC SPEC s2.1.1.1

IsSimple(geometry)

Renvoie vrai si l'objet geometry ne comporte pas d'anomalies, telle qu'une auto-intersection ou une auto-tangence de l'objet.
Exécuté par le module GEOS
OGC SPEC s2.1.1.1

IsClosed(geometry)

Renvoie vrai si les points de départ et d'arrivée de l'objet géométrique coïncident.

IsRing(geometry)

Renvoie vrai si le contour est fermé (StartPoint ( ) = EndPoint ( )) et si le contour est simple (ne passe pas plus d'une fois par le même point).
Exécuté par le module GEOS
OGC spec 2.1.5.1

NumGeometries(geometry)

Si la géométrie est une GEOMETRYCOLLECTION (or MULTI*) renvoie le nombre d'objets géométriques, autrement renvoie NULL.

GeometryN(geometry,int)

Renvoie le nième objet géométrique si la géométrie est une GEOMETRYCOLLECTION, MULTIPOINT, MULTILINESTRING ou MULTIPOLYGON.
Sinon, renvoie NULL.
Note : l'index débute à 1conformément aux spécifications OGC depuis la version 0.8.0. Les versions antérieures débutaient à 0.

NumPoints(geometry)

Trouve et renvoie le nombre de points de la première ligne géométrique. Renvoie NULL s'il n'y a pas de ligne dans la géométrie.

PointN(geometry,integer)

Renvoie le nième point de la première ligne de la géométrie. Renvoie NULL s'il n'y a pas de ligne dans la géométrie.

Note : l'index débute à 1 conformément aux spécifications OGC depuis la version 0.8.0. Les versions antérieures débutaient à 0.

ExteriorRing(geometry)

Renvoie le pourtour extérieur de la géométrie d'un polygone. Retourne NULL si l'objet n'est pas un polygone.

NumInteriorRings(geometry)

Retourne le nombre de pourtours intérieurs du premier polygone de la géométrie. Renvoie NULL s'il n'y a aucun polygone dans la géométrie.

NumInteriorRing(geometry)

Équivalent à NumInteriorRings(geometry). Les spécifications OpenGIS donnent les deux appellations sans lever l'ambiguïté sur le nom réel de la fonction, nous fournissons par conséquent les deux appellations.

InteriorRingN(geometry,integer)

Renvoie le nième pourtour intérieur de la géométrie du polygone. Renvoie NULL si la géométrie n'est pas un polygone, ou si la valeur N ne se trouve pas dans l'intervalle considéré.

Note : l'index débute à 1conformément aux spécifications OGC depuis la version 0.8.0. Les versions antérieures débutaient à 0.

EndPoint(geometry)

Renvoie le dernier point d'une ligne géométrique en tant que point.

StartPoint(geometry)

Renvoie le premier point d'une ligne géométrique en tant que point.

GeometryType(geometry)

Renvoie le type géométrique sous forme de chaine. Par exemple : LINESTRING, POLYGON, MULTIPOINT, etc.
OGC SPEC s2.1.1.1 - Renvoie le nom du sous-type géométrique instanciable dont la géométrie fait partie. Le nom du sous-type géométrique instanciable est renvoyé sous forme de chaine.

X(geometry)

Renvoie la coordonnée X du point. L'objet en entrée doit être un point.

Y(geometry)

Renvoie la coordonnée Y du point. L'objet en entrée doit être un point.

Z(geometry)

Renvoie la coordonnée Z du point, ou NULL si la valeur n'est pas disponible. L'objet en entrée doit être un point.

M(geometry)

Renvoie la coordonnée M du point, ou NULL si la valeur n'est pas disponible. L'objet en entrée doit être un point.
Note : cela ne fait pas (encore) partie des spécifications OGC, mais on les donne ici afin de compléter la liste de fonctions d'extraction de coordonnées ponctuelles.

haut de la page | table des matières

6.1.5. Constructeurs géométriques

GeomFromText(text,[<srid>]) :
Construit une géométrie à partir d'un WKT et d'un SRID donné.
OGC SPEC 3.2.6.2 - l'option SRID correspond à la mise en conformité
PointFromText(text,[<srid>]) :
Construit une géométrie à partir d'un WKT et d'un SRID donné. Si aucun SRID n'est passé en paramètre, la valeur utilisée sera -1.
OGC SPEC 3.2.6.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKT n'est pas un POINT.
LineFromText(text,[<srid>]) :
Construit une géométrie à partir d'un WKT et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.6.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKT n'est pas une LINE.
LinestringFromText(text,[<srid>]) :
Construit une géométrie à partir d'un WKT et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
Retourne une erreur si le WKT n'est pas une LINE.
PolyFromText(text,[<srid>]) :
Construit une géométrie à partir d'un WKT et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.6.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKT n'est pas un polygone
PolygonFromText(text,[<srid>]) :
Construit une géométrie à partir d'un WKT et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
correspond à la mise en conformité
Retourne une erreur si le WKT n'est pas un POLYGON.
MPointFromText(text,[<srid>]) :
Construit une géométrie à partir d'un WKT et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.6.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKT n'est pas un MULTIPOINT.
MLineFromText(text,[<srid>]) :
Construit une géométrie à partir de WKT avec un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.6.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKT n'est pas un MULTILINESTRING.
MPolyFromText(text,[<srid>]) :
Construit une géométrie à partir d'un WKT et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.6.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKT n'est pas un MULTIPOLYGON.
GeomCollFromText(text,[<srid>]) :
Construit une géométrie à partir d'un WKT et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.6.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKB n'est pas un GEOMETRYCOLLECTION.
GeomFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir d'un WKB et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.6.2 - l'option SRID correspond à la mise en conformité
GeomFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir d'un WKB et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.7.2 - l'option SRID correspond à la mise en conformité
PointFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir d'un WKB et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.7.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKB n'est pas un POINT.
LineFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir d'un WKB et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.7.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKB n'est pas une LINESTRING.
LinestringFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir d'un WKB et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
correspond à la mise en conformité
Retourne une erreur si le WKB n'est pas une LINESTRING.
PolyFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir d'un WKB et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.7.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKB n'est pas un POLYGON.
PolygonFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir de WKB avec un SRID donné. Si aucun SRID n'est donné, on prend par défaut la valeur -1.
correspond à la mise en conformité
Retourne une erreur si le WKB n'est pas un POLYGON.
MPointFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir d'un WKB et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.7.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKB n'est pas un MULTIPOINT.
MLineFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir d'un WKB et d'un SRID donné. Si aucun SRID n'est donné, on prend par défaut la valeur -1.
OGC SPEC 3.2.7.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKB n'est pas un MULTILINESTRING.
MPolyFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir d'un WKB et d'un SRID donné. Si aucun SRID n'est donné, la valeur utilisée sera -1.
OGC SPEC 3.2.7.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKB n'est pas un MULTIPOLYGON.
GeomCollFromWKB(bytea,[<srid>]) :
Construit une géométrie à partir d'un WKB et d'un SRID donné. Si aucun SRID n'est donné, on prend par défaut la valeur -1.
OGC SPEC 3.2.7.2 - l'option SRID correspond à la mise en conformité
Retourne une erreur si le WKB n'est pas un GEOMETRYCOLLECTION.
BdPolyFromText(text WKT, integer SRID) :
Construit un polygone à partir d'une collection quelconque de polylignes fermées en tant que représentation texte MultiLineString.
Retroune une erreur si le WKB n'est pas un MULTILINESTRING. Retourne une erreur si la sortie est un MULTIPOLYGON; utilisez BdMPolyFromText dans ce cas, ou voyez BuildArea() pour une approche spécifique à PostGIS.
OGC SFSQL 1.1 - 3.2.6.2
Disponibilité : 1.1.0 - requiert GEOS >= 2.1.0.
BdMPolyFromText(text WKT, integer SRID) :
Construit un MULTIPOLYGON à partir d'une collection quelconque de polylignes fermées en tant que représentation texte MultiLineString.
Retourne une erreur si le WKT n'est pas un MULTILINESTRING. Forcez la sortie en MULTIPOLYGON même si le résultat ne comportte qu'un seul POLYGON; utilisez BdPolyFromText si vous êtes sûr qu'un seul POLYGON sortira de l'opération, ou voyez BuildArea() pour une approche spécifique à PostGIS.
OGC SFSQL 1.1 - 3.2.6.2
Disponibilité : 1.1.0 - requiert GEOS >= 2.1.0.

haut de la page | table des matières

6.2. Extensions PostGIS


haut de la page | table des matières

6.2.1. Fonctions de gestion

DropGeometryTable([<nom_de_schéma>], <nom_de_la_table>) :
Supprime une table ainsi que toutes ses références dans geometry_columns.
NOTE : utilise current_schema() pour des installations de PostgreSQL supportant les schémas si le schéma n'est spécifié.
UpdateGeometrySRID([<schema_name>], <table_name>, <column_name>, <srid>) :
Met à jour le SRID de toutes les propriétés dans une colonne géographique mettant à jour les contraintes et les références dans geometry_column.
NOTE : utilise current_schema() sur des installations PostgreSQL supportant les schémas si le schéma n'est pas spécifié.
update_geometry_stats([<table_name>, <column_name>]) :
Met à jour les statistiques concernant les tables spatiales qui seront utilisées par le planificateur de requête. Vous aurait aussi besoin d'exécuter : VACUUM ANALYZE [nom_de_la_table] [nom_de_colonne] pour compléter le processus de rapatriement des statistiques.
NOTE : à partir de la version 8.0 de PostgreSQL le rapatriement des statistiques est automatiquement effectué lors de l'exécution du VACUUM ANALYZE.
postgis_version() :
Renvoie le numéro de version de PostGIS et les options de compilation utilisées.
NOTE : avant la version 1.1.0 c'était une fonction procédurale, elle pouvait donc retourner des informations imprécises (dans le cas d'une mise à jour incomplète de la base de données).
postgis_lib_version() :
Renvoie le numéro de version de la bibliothèque PostGIS.
Disponible depuis la version : 0.9.0
postgis_lib_build_date() :
Renvoie la date de compilation de la bibliothèque PostGIS.
Disponible depuis la version : 1.0.0RC1
postgis_script_build_date() :
Renvoie la date de création des scripts PostGIS.
Disponible depuis la version : 1.0.0RC1
postgis_scripts_installed() :
Renvoie la version des scripts PostGIS installée dans la base de données.
NOTE : si le résultat de cette fonction ne correspond pas à celui obtenu avec postgis_scripts_released() cela signifie que vous avez sans doute oublié de mettre à jour convenablement vos bases de données existantes. Rapportez vous à la section "Mise à jour" du présent manuel pour de plus amples informations.
Disponible depuis la version : 0.9.0
postgis_scripts_released() :
Renvoie le numéro de version du script lwpostgis.sql fournit avec la bibliothèque PostGIS installée.
NOTE : à partir de la version 1.1.0, cette fonction renvoie la même valeur que postgis_lib_version(). Conservé pour des raisons de compatibilité arrière.
Disponible depuis la version : 0.9.0
postgis_geos_version() :
Renvoie le numéro de version de la bibliothèque GEOS, ou NULL si la gestion de GEOS n'est pas activée.
Disponible depuis la version : 0.9.0
postgis_jts_version() :
Renvoie le numéro de version de la bibliothèque JTS ou NULL si la gestion de JTS n'est pas activée.
Disponible depuis la version : 1.1.0
postgis_proj_version() :
Renvoie le numéro de version de la bibliothèque PROJ4 ou NULL si la gestion de PROJ4 n'est pas activée.
Disponible depuis la version : 0.9.0
postgis_uses_stats() :
Renvoie vrai si l'utilisation de STATS a été activé, faux sinon.
Disponible depuis la version : 0.9.0
postgis_full_version() :
Retourne la version complète de PostGIS et les informations de compilation.
Disponible depuis la version : 0.9.0

haut de la page | table des matières

6.2.2. Opérateurs

A &< B
L'opérateur "&<" renvoie vrai si le cadre limite de A "recouvre" ou "est à la gauche" du cadre limite de B.

A &> B
L'opérateur "&>" renvoie vrai si le cadre limite de A "recouvre" ou "est à la droite" du cadre limite de B.

A << B
L'opérateur "<<" renvoie vrai si le cadre limite de A est strictement à la gauche du cadre limite de B.

A >> B
L'opérateur ">>" renvoie vrai si le cadre limite de A est strictement à la droite du cadre limite de B.

A &<| B
L'opérateur "&<|" renvoie vrai si le cadre limite de A recouvre ou est en dessous du cadre limite de B.

A |&> B
L'opérateur "|&>" renvoie vrai si le cadre limite de A recouvre ou est au dessus du cadre limite de B.

A <<| B
L'opérateur "<<|" renvoie vrai si le cadre limite de A est strictement au dessous du cadre limite de B.

A |>> B
L'opérateur "|>>" renvoie vrai si le cadre limite de A est strictement au dessus du cadre limite de B.

A ~= B
L'opérateur "~=" est l'opérateur "même que". Il vérifie l'égalité géométrique de deux propriétés. Donc si A et B ont les même propriétés, point-par-point, l'opérateur retourne vrai.

A @ B
L'opérateur "@" renvoie vrai si le cadre limite de A est totalement inclus dans le cadre limite de B.

A ~ B
L'opérateur "~" renvoie vrai si le cadre limite de A contient entièrement le cadre limite de B.

A && B
L'opérateur "&&" est l'opérateur de superposition.Si le cadre limite de A recouvre le cadre limite de B, l'opérateur renvoie vraie.

haut de la page | table des matières

6.2.3. Fonctions de mesure

area2d(geometry) :
renvoie la superficie d'un objet géométrique si c'est un polygone ou multi-polygone.

distance_sphere(point, point) :
renvoie la distance linéaire en mètre entre deux points en latitude/longitude. Utilise une Terre sphérique avec un rayon de 6370986 mètres. Plus rapide que distance_spheroid(), mais moins précis. N'est implémenté que pour des points.

distance_spheroid(point, point, spheroid) :
renvoie la distance linéaire en mètre entre deux points en latitude/longitude pour un sphéroïde donné. Voir l'explication sur les sphéroïdes donnés dans length_spheroid(). N'est implémenté que pour des points.

length2d(geometry) :
renvoie la longueur bi-dimensionnelle de l'objet géométrique si c'est un linestring ou multi-linestring.

length3d(geometry) :
renvoie la longueur tri-dimensionnelle de l'objet géométrique si c'est un linestring ou multi-linestring.

length_spheroid(geometry,spheroid) :
calcule la longueur d'un objet géométrique sur un ellipsoïde. C'est très pratique si les coordonnées de l'objet géométrique sont en latitude/longitude et qu'on veut connaitre la longueur sans avoir à reprojeter les données. L'ellipsoïde est un type spécifique de la base de données et peut se construire comme suit :

    SPHEROID[<NAME>,<SEMI-MAJOR AXIS>,<INVERSE FLATTENING>]
Par exemple :
    SPHEROID["GRS_1980",6378137,298.257222101]
Voici un exemple de calcul :
SELECT length_spheroid( geometry_column, 'SPHEROID["GRS_1980",6378137,298.257222101]' ) FROM geometry_table;
length3d_spheroid(geometry,spheroid) :
calcule la longueur de l'objet géométrique sur un ellipsoïde, en prenant en compte l'altitude. C'est exactement comme length_spheroid sauf que les coordonnées verticales (exprimées dans les mêmes unités que les valeurs d'axes du sphéroïde) sont utilisées pour calculer la distance supplémentaire ajoutée par le positionnement vertical.
distance(geometry, geometry) :
renvoie la distance la plus courte entre deux objets géométriques.
max_distance(linestring,linestring) :
renvoie la plus grande distance entre deux "line strings".
perimeter(geometry) :
renvoie le périmètre bi-dimensionnel d'un objet géométrique, si c'est un polygon ou un multi-polygon.
perimeter2d(geometry) :
renvoie le périmètre bi-dimensionnel d'un objet géométrique, si c'est un polygon ou un multi-polygon.
perimeter3d(geometry) :
renvoie le périmètre tri-dimensionnel d'un objet géométrique, si c'est un polygon ou un multi-polygon.
azimuth(geometry, geometry) :
renvoie l'azimut du segment défini par les géométries des points désignés, ou NULL si les deux points sont superposés. La valeur retournée est en radians. Disponibilité : 1.1.0
haut de la page | table des matières

6.2.4. Extraction d'informations géométriques

AsBinary(geometry,{'NDR'|'XDR'}) :
Renvoie la géométrie au format "binaire bien connu" de l'OGC en temps que bytea, en utilisant l'encodage little-endian (NDR) ou big-endian (XDR). C'est utile avec les curseurs binaires pour extraire de la base des données sans avoir à les convertir en chaine de caractères.

AsEWKT(geometry) :
Renvoie la géométrie au format EWKT (en tant que text).

AsEWKB(geometry, {'NDR'|'XDR'}) :
Renvoie la géométrie au format EWKB (en tant que bytea ) en utilisant soit l'encodage little-endian (NDR) soit big-endian (XDR).

AsHEXEWKB(geometry, {'NDR'|'XDR'}) :
Renvoie la géométrie au format HEXEWKB (en tant que text ) en utilisant soit l'encodage little-endian (NDR) soit big-endian (XDR).

AsSVG(geometry, [rel], [precision]) :
Renvoie la géométrie sous forme de donnée chemin SVG. Utilisez 1 comme second paramètre pour obtenir la donnée chemin représentée en terme de mouvements relatifs, la valeur par défaut (0) utilise le mouvement absolu. Le troisième argument peut être utilisé pour réduire le nombre maximal de chiffres après la virgule à utiliser dans le résultat (sa valeur par défaut est 15). Les points seront représentés sous la forme cx/cy si le paramètre "rel" vaut 0 et x/y lorsque "rel" vaut 1.

AsGML(geometry, [precision]) :
Renvoie la géométrie en temps qu'élément GML. Le second paramètre peut être utilisé pour réduire le nombre maximum de chiffres après la virgule à utiliser dans le résultat (par défaut sa valeur est 15).

AsKML(geometry, [precision]) :
Renvoie la géométrie en temps qu'élément KML. Le second paramètre peut être utilisé pour réduire le nombre maximum de chiffres après la virgule à utiliser dans le résultat (par défaut sa valeur est 15).

haut de la page | table des matières

6.2.5. Constructeurs géométriques

GeomFromEWKT(text) :

Construit une géométrie à partir de EWKT.

GeomFromEWKB(bytea) :

Construit une géométrie à partir de EWKB.

MakePoint(<x>, <y>, [<z>], [<m>]) :

Construit une géométrie de points 2d,3dz ou 4d.

MakePointM(<x>, <y>, <m>) :

Construit une géométrie de points 3dm.

MakeBox2D(<LL>, <UR>) :

Construit une BOX2D définie par la géométrie de points 2D.

MakeBox3D(<LLB>, <URT>) :

Construit une BOX3D définie par la géométrie de points 2D.

MakeLine(geometry set) :

Construit une Linestring à partir d'un ensemble de points géométriques. Vous aurez probablement besoin d'utiliser un sous-ensemble pour les ordonner avant de les traiter au moyen de cette fonction.

MakeLine(geometry, geometry) :

Construit une Linestring à partir de deux points géométriques donnés.

LineFromMultiPoint(multipoint) :

Construit une LineString à partir d'une géométrie MultiPoint.

MakePolygon(linestring, [linestring[]]) :

Construit un Polygon formé de l'enveloppe donnée et d'une liste de trous. Vous pouvez construire cette liste en utilisant Accum. Les objets géométriques choisis doivent être des contours LINESTRINGS fermés (voir IsClosed et GeometryType).

BuildArea(geometry) :

Construit une géométrie surfacique formée par le contour d'un objet géométrique donné. Le type renvoyé peut être un Polygon ou un Multipolygon, tout dépend de l'objet géométrique en entrée. Si l'objet en entrée ne forme pas un polygone, la fonction renvoie NULL.

Voir aussi BdPolyFromText et BdMPolyFromText - interface de cette fonction aux stantards OGC.

Disponibilité : 1.1.0 - requiert GEOS >= 2.1.0.

Polygonize(geometry set) :

Agrégat. Construit une GeometryCollection contenant des polygones potentiels formés à partir des contours d'un ensemble d'objets géométriques.

Disponibilité : 1.0.0RC1 - requiert GEOS >= 2.1.0.

Collect(geometry set) :

Cette fonction renvoie une GEOMETRYCOLLECTION ou un objet MULTI à partir d'un ensemble d'objets géométriques. La fonction collect() est une fonction "aggrégative" dans la terminologie de PostgreSQL. Cela signifie qu'elle opère sur des listes de données, de la même façon que les fonctions sum() et mean(). Par exemple, "SELECT COLLECT(GEOM) FROM GEOMTABLE GROUP BY ATTRCOLUMN" va renvoyer une GEOMETRYCOLLECTION séparée pour chaque valeur distincte de ATTRCOLUMN.

Collect(geometry, geometry) :

Cette fonction renvoie une géométrie qui est la collection de deux géométries en entrée. Le type en sortie peut être un MULTI* ou une GEOMETRYCOLLECTION.

Dump(geometry) :

Il s'agit d'une fonction retournant un ensemble (SRF). Elle renvoie un ensemble de lignes de geometry_dump, formée par une géométrie (geom) et un tableau d'entier (path). Quand la géométrie en entrée est un type simple (POINT,LINESTRING,POLYGON), on obtiendra en sortie un seul enregistrement avec un tableau vide et la géométrie donnée en entrée comme geom. Quand la géométrie en entrée est une collection ou multi, on obtiendra un enregistrement pour chacun des composants de la collection, et le chemin indiquera la position de chaque composant à l'intérieur de la collection.

NOTE : cette fonction n'est pas accessible en compilant avec PostgreSQL 7.2.x

haut de la page | table des matières

6.2.6. Éditeur géométriques

AddBBOX(geometry) :

Ajoute le cadre limite à une géométrie. Cela devrait rendre les requêtes basées sur le cadre limite plus rapide, mais cela augmentera la taille de la géométrie.

DropBBOX(geometry) :

Supprimer le cache du cadre limite de la géométrie. Cela réduit la taille de la géométrie, mais rend les requêtes basées sur le cadre limite plus lentes.

AddPoint(linestring, point, [<position>]) :

Ajoute un point à une LINESTRING avant le point <position> (index d'origine 0). Le troisième paramètre peut être omis ou prendre la valeur -1 si vous souhaitez ajouter le point à la fin.

RemovePoint(linestring, décalage) :

Supprime un point d'une LINESTRING. Le décalage commence à 0.
Disponibilité : 1.1.0

SetPoint(linestring, N, point) :

Remplace le point N de la LINESTRING par le point passé en argument. L'index à pour origine 0.
Disponibilité : 1.1.0

Force_collection(geometry) :

Convertie une géométrie en une GEOMETRYCOLLECTION. Cela est utile pour simplifier la représentation en WKB.

Force_2d(geometry) :

Passe une géométrie dans le mode 2d, toutes les géométries auront donc uniquement les coordonnées X et Y. Cela est utile pour forcer la compatibilité avec l'OGC (pouisuqe l'OCG ne spécifie que des géométries 2d).

Force_3dz(geometry), Force_3d(geometry) :

Passe un géométrie dans le mode XYZ.

Force_3dm(geometry) :

Passe une géométrie dans le mode XYM.

Force_4d(geometry) :

Passe un géométrie dans le mode XYZM.

Multi(geometry) :

Renvoi la géométrie comme une géométrie multiple (MULTI*). Si la géométrie est déjà une MULTI*, elle est renvoyée inchangée.

Transform(geometry,entier) :

Renvoi une nouvelle géométrie dont les coordonnées sont transformées à l'aide du SRID représenté par le paramètre entier. Le SRID de destination doit exister dans la table SPATIAL_REF_SYS.

Translate(geometry,float8,float8,float8) :

Effectue la translation d'une géométrie vers une nouvelle position en utilisant les paramètres numériques comme vecteur de translation. Par exemple : translate(geom, X, Y, Z).

Scale(geometry,float8,float8,float8) :

Effectue une homothétie de la géométrie en multipliant les coordonnées par les paramètres. Par exemple : scale(geom, facteurX, facteurY, facteurZ).
Disponibilité : 1.1.0

TransScale(geometry,float8,float8,float8,float8) :

Commence par effectuer une translation de la géométrie en utilisant les deux flottants, puis effectue l'homothétie en utilisant les deux paramètres suivant, fonctionne uniquement dans le mode 2d. Utiliser transcale(geom, X, Y, facteurX, facteurY) est un raccourci efficace pour scale(translate(geom,X,Y,0),facteurX,facteurY,1).
Disponibilité : 1.1.0

Reverse(geometry) :

Renvoit la géométrie avec les sommets en ordre inverse.

ForceRHR(geometry) :

Force une collection de polygones à abéïr à la règle de la main droite.

Simplify(geometry, tolerance) :

Renvoi un version "simplifiée" de la géométrie passée en argument en utilisant l'algorithme Douglas-Peuker. Cela n'effectue actuellement une simplification que pour des (MULTI)LINES et des (MULTI)POLYGONS mais vous pouvez l'utiliser sans risque avec tout type de géométries. Puisque les simplifications se font objet par objet, vous pouvez aussi passé en argument une GEOMETRYCOLLECTION à cette fonction. Notez que la géométrie retournée peut avoir perdu sa simplicité (voir IsSimple).


SnapToGrid(geometry, originX, originY, sizeX, sizeY), SnapToGrid(geometry, sizeX, sizeY), SnapToGrid(geometry, size)
Snap all points of the input geometry to the grid defined by its origin and cell size. Remove consecutive points falling on the same cell, eventually returning NULL if output points are not enough to define a geometry of the given type. Collapsed geometries in a collection are stripped from it.
Note

The returned geometry might loose its simplicity (see IsSimple).
Note

Before release 1.1.0 this function always returned a 2d geometry. Starting at 1.1.0 the returned geometry will have same dimensionality as the input one with higher dimension values untouched. Use the version taking a second geometry argument to define all grid dimensions.

Availability: 1.0.0RC1


SnapToGrid(geometry, geometry, sizeX, sizeY, sizeZ, sizeM)
Snap all points of the input geometry to the grid defined by its origin (the second argument, must be a point) and cell sizes. Specify 0 as size for any dimension you don't want to snap to a grid.

Availability: 1.1.0

Segmentize(geometry, maxlength)
Return a modified [multi]polygon having no ring segment longer then the given distance. Interpolated points will have Z and M values (if needed) set to 0. Distance computation is performed in 2d only.

LineMerge(geometry) :

Renvoit un (ensemble d') objet(s) de type linestring composé(s) des lignes contigües inclues dans l'objet de type geometry passé en paramètre.
ndrpf: si le résultat est un ensemble, ce dernier semble être ordonné suivant la valeur minimal des coordonnées des points startpoint et endpoint (à vérifier).


Disponibilité : 1.1.0 - nécessite GEOS >= 2.1.0

Exemple concrêt : (ndrpf)


Cas d'un ensemble de linestring contigües :

select astext(linemerge(geometryfromtext('MULTILINESTRING((0 0,5 5),(5 5,6 10))',-1)));
LINESTRING(0 0,5 5,6 10)



Cas d'un ensemble de linestring non contigües :

select astext(linemerge(geometryfromtext('MULTILINESTRING((0 0,5 5),(5 4,6 10))',-1)));
MULTILINESTRING((0 0,5 5),(5 4,6 10))

haut de la page | table des matières

6.2.7. Mise en référence linéaire

line_interpolate_point(linestring, location) :

Retourne un point interpolé le long d'une ligne. Le premier argument doit être une LINESTRING. Le second argument est un flotant (float8) dont la valeur est comprise entre 0 et 1 et qui représente une fraction de la longuer 2d totale où le point doit être localisé.

Voir la fonction line_locate_point() pour localiser l'endroit le plus prêt d'un point sur une ligne.

Note : depuis la version 1.1.1 cette fonction interpole aussi les valeurs M et Z (lorsqu'elles sont présentes), tandis que les versions précédantes leur attribut la valeur 0.0.

Disponibilité : 0.8.2

line_substring(linestring, debut, fin) :

Retourne une ligne étant une sous partie de celle passée en argument commençant et terminant aux fractions de la longueur totale passées en argument. Le second et le troisième argument sont des flotants (float8) dont la valeur est comprise entre 0 et 1.

Si les valeurs de debut et fin sont identiques cette fonction est alors équivalente à line_interpolate_point().

Voir line_locate_point() pour localiser l'endroit le plus prêt d'un point sur une ligne.

Note : depuis la version 1.1.1 cette fonction interpole aussi les valeurs M et Z (lorsqu'elles sont présentes), tandis que les versions précédantes leur attribut des valeurs non spécifiées.

Disponibilité : 1.1.0

line_locate_point(LineString, Point) :

Retourne un flotant compris entre 0 et 1 représentant la position du point sur une LINESTRING le plus proche du point donné, sous la forme d'une fraction de la longuer 2d totale.

Vous pouvez utiliser la position retournée pour extraire un POINT (avec line_interpolate_point) ou la sous partie d'une ligne (line_substring).

Disponibilité : 1.1.0

locate_along_measure(geometry, float8) :

Renvoie un ensemble d'éléments géométriques dont les éléments respecte la mesure spécifiée. Les éléments de type POLYGON ne sont pas supportés.


La sémantique est spécifiée par : ISO/IEC CD 13249-3:200x(E) - Text for Continuation CD Editing Meeting

Availability: 1.1.0

locate_between_measures(geometry, float8, float8) :

Retourne un ensemble de valeurs géométriques dont les éléments sont inclues dans l'intervale de valeurs spécifié. Les éléments de type POLYGON ne sont pas supportés.

La sémantique est spécifiée par : ISO/IEC CD 13249-3:200x(E) - Text for Continuation CD Editing Meeting

Availability: 1.1.0

haut de la page | table des matières

6.2.8. Fonctions diverses

Summary(geometry) :

Renvoie un résumé textuel du contenu géométrique.

box2d(geometry) :

Renvoie une BOX2D représentant le cadre limite de l'objet géométrique.

box3d(geometry) :

Renvoie une BOX3D représentant le cadre limite de l'objet géométrique.

extent(geometry set) :

La fonction extent() est une fonction d'agrégation, selon la terminologie de PostgreSQL. Cela signifie qu'elle opère sur des ensembles de données, à la manière des fonctions sum() et mean(). Par exemple, "SELECT EXTENT(GEOM) FROM GEOMTABLE" renverra une boîte BOX3D qui correspond au cadre limite de tout les objets géométriques contenus dans la table. De la même façon, "SELECT EXTENT(GEOM) FROM GEOMTABLE GROUP BY CATEGORY" renverra un résultat d'emprise pour chacune des catégories.

zmflag(geometry) :

Renvoie le drapeau ZM (dimension(s) de la géométrie) des objets géométriques sous forme de small int. Il peut prendre les valeurs : 0=2d, 1=3dm, 2=3dz, 3=4d.

HasBBOX(geometry) :

Renvoie vrai si le cadre limite de l'objet géométrique est en cache, et faux sinon. Utilisez addBBOX() et dropBBOX() pour contrôler la mise en cache.

ndims(geometry) :

Renvoie le nombre de dimensions de l'objet géométrique sous forme de small int. Il peut prendre les valeurs 2,3 ou 4.

nrings(geometry) :

Si l'objet géométrique est un polygon ou un multi-polygon renvoie le nombre de rings.

npoints(geometry) :

Renvoie le nombre de points dans l'objet géométrique.

isvalid(geometry) :

Renvoie vrai si l'objet géométrique est valide.

expand(geometry, float) :

Cette fonction renvoie un cadre limite étendue dans chacune des directions à partir du cadre limite de l'objet géométrique en entrée, en fonction d'une variable spécifiée en second argument. Très utile pour les requêtes de distance(), pour ajouter un filtre d'index à la requête.

estimated_extent([schema], table, geocolumn) :

Renvoie l'emprise 'estimé' de la table spatiale désignée. L'estimation provient des statistiques du champ de géométrie. Le schéma courant sera utilisé si rien d'autre n'est précisé.

Pour PostgreSQL>=8.0.0, les statistiques sont rassemblées par VACUUM ANALYZE et l'emprise résultante représentera à peu près 95% de l'emprise réelle.

Pour PostgreSQL< 8.0.0, les statistiques sont rassemblées par update_geometry_stats() et l'emprise résultante sera exacte.

find_srid(varchar,varchar,varchar) :

La syntaxe est find_srid(<db/schema>, <table>, <column>) et la fonction renvoie l'entier SRID du champ spécifié en cherchant dans la table geometry_columns. Si le champ géométrie n'a pas été ajouté à l'aide la fonction adéquate AddGeometryColumns(), cette fonction ne marchera pas non plus.

mem_size(geometry) :

Renvoie la quantité d'espace disque (en bytes) qu'occupe l'objet géométrique.

numb_sub_objects(geometry) :

Renvoie le nombre d'objet stockés dans la géométrie. C'est spécialement utile pour les MULTI-géométries et les GEOMETRYCOLLECTIONs.

point_inside_circle(geometry,float,float,float) :

La syntaxe de cette fonction est point_inside_circle(<geometry>,<circle_center_x>,<circle_center_y>,<radius>). Renvoie vrai si l'objet géométrique est un point et se trouve à l'intérieur d'un cercle. Sinon renvoie faux.

xmin(box3d) ymin(box3d) zmin(box3d) :

Renvoie le minima spécifié d'une bounding box.

xmax(box3d) ymax(box3d) zmax(box3d) :

Renvoie le maxima spécifié d'une bounding box.

Accum(geometry set) :

Agrégat. Construit un tableau d'objets géométriques.

haut de la page | table des matières

6.2.9. Support des transactions longues

Ce module et les fonctions pl/pgsql associées (définies dans le fichier lwgeom/long_xact.sql.in du répertoire des sources de PostGIS) ont été implémentés afin de fournir le support pour de longs vérouillages requis par les spécifications Web Feature Service (page 34 du document).

Note : les utilisateurs doivent utiliser le mode d'isolation serializable sans quoi le méchanisme de vérouillage devrait ne pas fonctionner.

EnableLongTransactions() :

Active le support des transactions longues. Cette fonction crée les tables de métadonnées nécessaires, elle a besoin d'être appeler une seule fois avant l'utilisation de l'une des autres fonctions décrites dans cette partie. L'appeler une deuxième fois serait inutile.
Disponibilité : 1.1.3

DisableLongTransactions() :

Désactive le support des transactions longues. Cette fonctione supprime les tables de métadonnées du support des transactions longues, et enlève tout les triggers utilisés par les tables de vérification du vérouillage.
Disponibilité : 1.1.3

CheckAuth([<schema>], <table>, <rowid_col>) :

Vérifie si les mises à jour et les suppressions des lignes de la table spécifiée sont possibles (autorisables). Identifie les lignes en utilisant la colonne : <rowid_col>.
Disponibilité : 1.1.3

LockRow([<schema>], <table>, <rowid>, <authid>, [<expires>]) :

Attribut le verroux/l'autorisation pour une ligne spécific dans la table.
<authid> est une chaîne de charactère.
<expires> est une durée (de type timestamp) dont la valeur par défaut est : now()+1heure.
Renvoit 1 si le verroux a pu être assigné, 0 sinon (déjà verrouillé par un autre processus).
Disponibilité : 1.1.3

UnlockRows(<authid>) :

Supprime tout les verroux rattachés à l'identifiant d'autorisation spécifié. Renvoit le nombre de verroux relachés.
Disponibilité : 1.1.3

AddAuth(<authid>) :

Ajoute un marqueur d'autorisation à utiliser dans la transaction courrante.
Disponibilité : 1.1.3

haut de la page | table des matières

6.3. Fonctions SQL-MM

Voici une liste des fonctions SQL-MM que PostGIS supporte. L'implémentation de ces fonctions est calquée sur celle d'ArcSDE, certaines parties, qui seront explicitées ici, varient donc des spécifications.

Avec la version 1.2.0, ces fonctions ont été implémentées par encapsulation des fonctions existantes de PostGIS. Ce qui à pour résultat, que certaines fonctionalités des objets géométriques de type courbes ne soient pas disponibles.

Note

SQL-MM définie le SRID par défaut à 1 pour les contructeurs d'entité géométriques. PostGIS utilise quand à lui la valeur -1.

ST_Area

Revoie l'aire d'une ST_Surface ou ST_MultiSurface.

SQL-MM 3: 8.1.2, 9.5.3

ST_AsBinary

Renvoie la représentation binaire d'une ST_Geometry.

SQL-MM 3: 5.1.37

ST_AsText

Renvoie la représentation textuelle d'une ST_Geometry.

SQL-MM 3: 5.1.25

ST_Boundary

Return the boundary of the ST_Geometry value.

SQL-MM 3: 5.1.14

ST_Buffer

Renvoie l'ensemble des points dans l'espace autour d'une ST_Geometry.

SQL-MM 3: 5.1.17

ST_Centroid

Renvoie le barycentre d'une ST_Surface ou ST_MultiSurface.

SQL-MM 3: 8.1.4, 9.5.5

ST_Contains

Test si une ST_Geometry en contient spatialement une autre.

SQL-MM 3: 5.1.31

ST_ConvexHull

Renvoie l'enveloppe convexe d'une typeST_Geometry.

SQL-MM 3: 5.1.16

ST_CoordDim

Renvoie la dimension des coordonnées d'une ST_Geometry.

SQL-MM 3: 5.1.3

ST_Crosses

Test si deux ST_Geometry se croisent spatialement.

SQL-MM 3: 5.1.29

ST_Difference

Renvoie un objet de type ST_Geometry qui représente l'ensemble des points différents de deux objets de type ST_Geometry.

SQL-MM 3: 5.1.20

ST_Dimension

Renvoie la dimension d'un objet de type ST_Geometry.

SQL-MM 3: 5.1.2

ST_Disjoint

Test si un objet de type ST_Geometry est spatialement disjoint
d'un autre ST_Geometry.

SQL-MM 3: 5.1.26

ST_Distance

Renvoie la distance entre deux entités géométriques.

SQL-MM 3: 5.1.23

ST_EndPoint

Renvoie un objet de type ST_Point qui est le point final d'une entité de type ST_Curve.

SQL-MM 3: 7.1.4

ST_Envelope

Renvoie le rectangle englobant une entité de type ST_Geometry.

SQL-MM 3: 5.1.15

ST_Equals

Test si deux valeurs de type ST_Geometry sont spatialement égales.

SQL-MM 3: 5.1.24

ST_ExteriorRing

Renvoie l'anneau extérieur d'une ST_Surface.

SQL-MM 3: 8.2.3, 8.3.3

ST_GeometryN

Renvoie la valeur de type ST_Geometry à partir de l'index indiquée dans un ensemble de type ST_GeomCollection.

SQL-MM 3: 9.1.5

ST_GeometryType

Renvoie le type d'une ST_Geometry.

SQL-MM 3: 5.1.4

ST_GeomFromText

Renvoie une ST_Geometry à partir de sa représentation textuelle.

SQL-MM 3: 5.1.40

ST_GeomFromWKB

Renvoie une ST_Geometry à partir de sa représentation binaire.

SQL-MM 3: 5.1.41

ST_InteriorRingN

Renvoie l'anneau intérieur d'une entité géométrique de type ST_Surface.

SQL-MM 3: 8.2.6, 8.3.5

ST_Intersection

Renvoie un objet de type ST_Geometry représentant l'ensemble des points d'intersection de deux objets de types ST_Geometry.

SQL-MM 3: 5.1.18

ST_Intersects

Test si une valeur de type ST_Geometry intersecte spatialement un autre objet de type ST_Geometry.

SQL-MM 3: 5.1.27

ST_IsClosed

Test si un objet de type ST_Curve or ST_MultiCurve est fermé.

Note

SQL-MM spécifie que le résultat de ST_IsClosed(NULL) doit être 0, alors que PostGIS renvoie NULL.

SQL-MM 3: 7.1.5, 9.3.3

ST_IsEmpty

Test si une entité de type ST_Geometry correspond à l'ensemble vide.

Note

SQL-MM spécifie que le résultat de ST_IsEmpty(NULL) doit être 0, alors que PostGIS renvoie la valeur NULL.

SQL-MM 3: 5.1.7

ST_IsRing

Test si une entité de type ST_Curve est un anneau.

Note

SQL-MM spécifie que le résultat de ST_IsRing(NULL) doit être 0, alors ue PostGIS renvoie la valeur NULL.

SQL-MM 3: 7.1.6

ST_IsSimple

Test si une entité de type ST_Geometry ne contient pas d'anomalies géométriques, comme par exemple l'auto-intersection ou l'auto-tangent.

Note

SQL-MM spécifie que le résultat de ST_IsSimple(NULL) doit être 0, alors que PostGIS renvoie la valeur NULL dans ce cas.

SQL-MM 3: 5.1.8

ST_IsValid

Test si une entité de type ST_Geometry est bien formée.

Note

SQL-MM spécifie que le résultat de ST_IsValid(NULL) doit être 0, alors que PostGIS renvoie la valeur NULL dans ce cas.

SQL-MM 3: 5.1.9

ST_Length

Renvoie la longuer d'une ST_Curve ou ST_MultiCurve.

SQL-MM 3: 7.1.2, 9.3.4

ST_LineFromText

Renvoie une ST_LineString à parti de sa représentation textuelle.

SQL-MM 3: 7.2.8

ST_LineFromWKB

Renvoie une ST_LineString à parti de sa représentation binaire.

SQL-MM 3: 7.2.9

ST_MLineFromText

Renvoie un ST_MultiLineString à parti de sa représentation textuelle.

SQL-MM 3: 9.4.4

ST_MLineFromWKB

Renvoie un ST_MultiLineString à parti de sa représentation binaire.

SQL-MM 3: 9.4.5

ST_MPointFromText

Renvoie un ST_MultiPoint à parti de sa représentation textuelle.

SQL-MM 3: 9.2.4

ST_MPointFromWKB

Renvoie un ST_MultiPoint à parti de sa représentation binaire.

SQL-MM 3: 9.2.5

ST_MPolyFromText

Renvoie un ST_MultiPolygon à parti de sa représentation textuelle.

SQL-MM 3: 9.6.4

ST_MPolyFromWKB

Return a specified ST_MultiPolygon à parti de sa représentation binaire.

SQL-MM 3: 9.6.5

ST_NumGeometries

Renvoie le nombre l'éléments dans ST_GeomCollection.

SQL-MM 3: 9.1.4

ST_NumInteriorRing

Return the number of interior rings in an ST_Surface.

SQL-MM 3: 8.2.5

ST_NumPoints

Return the number of points in an ST_LineString or
ST_CircularString value.

SQL-MM 3: 7.2.4

ST_OrderingEquals

ST_OrderingEquals compare deux entités géométriques et renvoie t (vraie) si les entités géométriques sont égales et que les coordonées sont dans le même ordre, sinon revoie f (faux).

Note

Cette fonction est implémentée comme dans l'api SQL d'ArcSDE plutôt que comme spécifié par SQL-MM.

SQL-MM 3: 5.1.43

ST_Overlaps

Test si un objet de type ST_Geometry en recouvre spatialement une autre.

SQL-MM 3: 5.1.32

ST_Perimeter

Return the length measurement of the boundary of an
ST_Surface or ST_MultiRSurface value.

SQL-MM 3: 8.1.3, 9.5.4

ST_Point

Renvoie un objet de type ST_Point à partir des coordonées passés en paramètre.

SQL-MM 3: 6.1.2

ST_PointFromText

Renvoie un objet de type ST_Point à partir de sa représentation textuelle.

SQL-MM 3: 6.1.8

ST_PointFromWKB

Renvoie un objet de type ST_Point à partir de sa représentation binaire.

SQL-MM 3: 6.1.9

ST_PointN

Return the specified ST_Point value in an ST_LineString or
ST_CircularString

SQL-MM 3: 7.2.5, 7.3.5

ST_PointOnSurface

Renvoie une valeur ST_Point garantie pour intersecter spatialement la valeur de ST_Surface ou de ST_MultiSurface.

SQL-MM 3: 8.1.5, 9.5.6

ST_PolyFromText

Renvoie un objet de type ST_Polygon à partir de sa représentation textuelle.

SQL-MM 3: 8.3.6

ST_PolyFromWKB

Renvoie un objet de type ST_Polygon à partir de sa représentation binaire.

SQL-MM 3: 8.3.7

ST_Polygon

Renvoie un polygone construit à partir de la polyligne définie SRID.

SQL-MM 3: 8.3.2

ST_Relate

Test if an ST_Geometry value is spatially related to another
ST_Geometry value.

SQL-MM 3: 5.1.25

ST_SRID

Renvoie l'identifiant du SRID d''une entité géométrique de type ST_Geometry.

SQL-MM 3: 5.1.5

ST_StartPoint

Renvoie un objet de type ST_Point qui est le point de départ d'une entité géométrique de type ST_Curve.

SQL-MM 3: 7.1.3

ST_SymDifference

Renvoie un objet de type ST_Geometry qui représente l'ensemble d'exclusion de deux entités géométriques de type ST_Geometry value that represents the point set
symmetrcy difference of two ST_Geometry values.

SQL-MM 3: 5.1.21

ST_Touches

Test si un entité géométrique de type ST_Geometry en touche spatialement une autre.

SQL-MM 3: 5.1.28

ST_Transform

Renvoie un objet de type ST_Geometry value transformed to the specified
spatial reference system.

SQL-MM 3: 5.1.6

ST_Union

Renvoie un objet de type ST_Geometry qui représente l'ensemble des points de l'union de deux entités géométriques de type ST_Geometry.

SQL-MM 3: 5.1.19

ST_Within

Test si une entité gémétrique de type ST_Geometry est contenue dans une autre.

SQL-MM 3: 5.1.30

ST_WKBToSQL

Renvoie un objet de type ST_Geometry à partir de sa représentation binaire.

SQL-MM 3: 5.1.36

ST_WKTToSQL

Renvoie une entité géométrique de type ST_Geometry à partir de sa représentation textuelle.

SQL-MM 3: 5.1.34

ST_X

Renvoie la composante x des coordonées d'un ST_Point.

SQL-MM 3: 6.1.3

ST_Y

Renvoie la composante y des coordonées d'un ST_Point.

SQL-MM 3: 6.1.4

haut de la page | table des matières

6.4 Fonctions ArcSDE

Des fonctions supplémentaires ont été ajoutées pour améliorer le support d'une interface de style ArcSDE.

SE_EnvelopesIntersect :

Renvoie vrai si les emprises de deux objets géométriques s'intersectent, sinon, elle renvoie faux.

SE_Is3d :

Test si une valeur géométrique a une composante z.

SE_IsMeasured :

Test si une valeur géométrique a une composante m.

SE_LocateAlong :

Renvoie un ensemble d'objet géométriques dont les éléments respectent la mesure spécifiée.

SE_LocateBetween :

Renvoie un ensemble d'objet géométriques dont les éléments sont inclues dans l'intervalle de valeur spécifié.

SE_M :

Renvoie la composante m d'une valeur de type ST_Point

SE_Z :

Renvoie la composante z d'une valeur géométrique de type ST_Point .

haut de la page | table des matières

Chapitre 7. Signaler des bogues

Signaler des bogues est essentiel pour soutenir le développement de PostGIS. La manière la plus efficace de produire un rapport de bogue est de faire en sorte que les développeurs puissent le reproduire. L'idéal est qu'il contienne un script qui déclenche le bogue et des renseignements complets sur l'environnement dans lequel il s'est produit. D'assez bonnes infos peuvent être trouvées grâce à
SELECT postgis_full_version() (pour postgis) et SELECT version() (pour postgresql).
Si vous n'utilisez pas actuellement la dernière version sortie, il vaut mieux d'abord jeter un coup d'œil aux derniers correctifs apportés afin de voir si votre bogue a déjà été corrigé.
L'utilisation du traqueur de bogue PostGIS vous garantit que vos rapports ne tomberont pas aux oubliettes et vous tiendra informé de sa résolution. Avant de dresser votre rapport de bogue, veuillez faire une recherche dans la base de données pour voir s'il s'agit d'un bogue déjà connu, et ajoutez y toute information utile que vous auriez.
Peut-être serez vous intéressés par l'article de Simon Tatham intitulé 'How to Report Bugs Effectively' (Comment faire de bons rapports sur les bogues) avant de remplir votre propre rapport.

haut de la page | table des matières

Appendix A. Release Notes


haut de la page | table des matières

A.1. Release 1.1.1

Release date: 2006/01/23
This is an important Bugfix release, upgrade is highly recommended. Previous version contained a bug in postgis_restore.pl preventing hard upgrade procedure to complete and a bug in GEOS-2.2+ connector preventing GeometryCollection objects to be used in topological operations.

haut de la page | table des matières

A.1.1. Upgrading

If you are upgrading from release 1.0.3 or later follow the soft upgrade procedure.
If you are upgrading from a release between 1.0.0RC6 and 1.0.2 (inclusive) and really want a live upgrade read the upgrade section of the 1.0.3 release notes chapter.
Upgrade from any release prior to 1.0.0RC6 requires an hard upgrade.

haut de la page | table des matières

A.1.2. Bug fixes

Fixed a premature exit in postgis_restore.pl
BUGFIX in geometrycollection handling of GEOS-CAPI connector
Solaris 2.7 and MingW support improvements
BUGFIX in line_locate_point()
Fixed handling of postgresql paths
BUGFIX in line_substring()
Added support for localized cluster in regress tester

haut de la page | table des matières

A.1.3. New functionalities

New Z and M interpolation in line_substring()
New Z and M interpolation in line_interpolate_point()
added NumInteriorRing() alias due to OpenGIS ambiguity

haut de la page | table des matières

A.2. Release 1.1.0

Release date: 2005/12/21
This is a Minor release, containing many improvements and new things. Most notably: build procedure greatly simplified; transform() performance drastically improved; more stable GEOS connectivity (CAPI support); lots of new functions; draft topology support.
It is highly recommended that you upgrade to GEOS-2.2.x before installing PostGIS, this will ensure future GEOS upgrades won't require a rebuild of the PostGIS library.

haut de la page | table des matières

A.2.1. Credits

This release includes code from Mark Cave Ayland for caching of proj4 objects. Markus Schaber added many improvements in his JDBC2 code. Alex Bodnaru helped with PostgreSQL source dependency relief and provided Debian specfiles. Michael Fuhr tested new things on Solaris arch. David Techer and Gerald Fenoy helped testing GEOS C-API connector. Hartmut Tschauner provided code for the azimuth() function. Devrim GUNDUZ provided RPM specfiles. Carl Anderson helped with the new area building functions. See the credits section for more names.

haut de la page | table des matières

A.2.2. Upgrading

If you are upgrading from release 1.0.3 or later you DO NOT need a dump/reload. Simply sourcing the new lwpostgis_upgrade.sql script in all your existing databases will work. See the soft upgrade chapter for more informations.
If you are upgrading from a release between 1.0.0RC6 and 1.0.2 (inclusive) and really want a live upgrade read the upgrade section of the 1.0.3 release notes chapter.
Upgrade from any release prior to 1.0.0RC6 requires an hard upgrade.

haut de la page | table des matières

A.2.3. New functions

scale() and transscale() companion methods to translate()
line_substring()
line_locate_point()
M(point)
LineMerge(geometry)
shift_longitude(geometry)
azimuth(geometry)
locate_along_measure(geometry, float8)
locate_between_measures(geometry, float8, float8)
SnapToGrid by point offset (up to 4d support)
BuildArea(any_geometry)
OGC BdPolyFromText(linestring_wkt, srid)
OGC BdMPolyFromText(linestring_wkt, srid)
RemovePoint(linestring, offset)
ReplacePoint(linestring, offset, point)

haut de la page | table des matières

A.2.4. Bug fixes

Fixed memory leak in polygonize()
Fixed bug in lwgeom_as_anytype cast funcions
Fixed USE_GEOS, USE_PROJ and USE_STATS elements of postgis_version() output to always reflect library state.

haut de la page | table des matières

A.2.5. Function semantic changes

SnapToGrid doesn't discard higher dimensions
Changed Z() function to return NULL if requested dimension is not available

haut de la page | table des matières

A.2.6. Performance improvements

Much faster transform() function, caching proj4 objects
Removed automatic call to fix_geometry_columns() in AddGeometryColumns() and update_geometry_stats()

haut de la page | table des matières

A.2.7. JDBC2 works

Makefile improvements
JTS support improvements
Improved regression test system
Basic consistency check method for geometry collections
Support for (Hex)(E)wkb
Autoprobing DriverWrapper for HexWKB / EWKT switching
fix compile problems in ValueSetter for ancient jdk releases.
fix EWKT constructors to accept SRID=4711; representation
added preliminary read-only support for java2d geometries

haut de la page | table des matières

A.2.8. Other new things

Full autoconf-based configuration, with PostgreSQL source dependency relief
GEOS C-API support (2.2.0 and higher)
Initial support for topology modelling
Debian and RPM specfiles
New lwpostgis_upgrade.sql script

haut de la page | table des matières

A.2.9. Other changes

JTS support improvements
Stricter mapping between DBF and SQL integer and string attributes
Wider and cleaner regression test suite
old jdbc code removed from release
obsoleted direct use of postgis_proc_upgrade.pl
scripts version unified with release version

haut de la page | table des matières

A.3. Release 1.0.6

Release date: 2005/12/06
Contains a few bug fixes and improvements.

haut de la page | table des matières

A.3.1. Upgrading

If you are upgrading from release 1.0.3 or later you DO NOT need a dump/reload.
If you are upgrading from a release between 1.0.0RC6 and 1.0.2 (inclusive) and really want a live upgrade read the upgrade section of the 1.0.3 release notes chapter.
Upgrade from any release prior to 1.0.0RC6 requires an hard upgrade.

haut de la page | table des matières

A.3.2. Bug fixes

Fixed palloc(0) call in collection deserializer (only gives problem with --enable-cassert)
Fixed bbox cache handling bugs
Fixed geom_accum(NULL, NULL) segfault
Fixed segfault in addPoint()
Fixed short-allocation in lwcollection_clone()
Fixed bug in segmentize()
Fixed bbox computation of SnapToGrid output

haut de la page | table des matières

A.3.3. Improvements

Initial support for postgresql 8.2
Added missing SRID mismatch checks in GEOS ops

haut de la page | table des matières

A.4. Release 1.0.5

Release date: 2005/11/25
Contains memory-alignment fixes in the library, a segfault fix in loader's handling of UTF8 attributes and a few improvements and cleanups.
Note
Return code of shp2pgsl changed from previous releases to conform to unix standards (return 0 on success).

haut de la page | table des matières

A.4.1. Upgrading

If you are upgrading from release 1.0.3 or later you DO NOT need a dump/reload.
If you are upgrading from a release between 1.0.0RC6 and 1.0.2 (inclusive) and really want a live upgrade read the upgrade section of the 1.0.3 release notes chapter.
Upgrade from any release prior to 1.0.0RC6 requires an hard upgrade.

haut de la page | table des matières

A.4.2. Library changes

Fixed memory alignment problems
Fixed computation of null values fraction in analyzer
Fixed a small bug in the getPoint4d_p() low-level function
Speedup of serializer functions
Fixed a bug in force_3dm(), force_3dz() and force_4d()

haut de la page | table des matières

A.4.3. Loader changes

Fixed return code of shp2pgsql
Fixed back-compatibility issue in loader (load of null shapefiles)
Fixed handling of trailing dots in dbf numerical attributes
Segfault fix in shp2pgsql (utf8 encoding)

haut de la page | table des matières

A.4.4. Other changes

Schema aware postgis_proc_upgrade.pl, support for pgsql 7.2+
New "Reporting Bugs" chapter in manual

haut de la page | table des matières

A.5. Release 1.0.4

Release date: 2005/09/09
Contains important bug fixes and a few improvements. In particular, it fixes a memory leak preventing successful build of GiST indexes for large spatial tables.

haut de la page | table des matières

A.5.1. Upgrading

If you are upgrading from release 1.0.3 you DO NOT need a dump/reload.
If you are upgrading from a release between 1.0.0RC6 and 1.0.2 (inclusive) and really want a live upgrade read the upgrade section of the 1.0.3 release notes chapter.
Upgrade from any release prior to 1.0.0RC6 requires an hard upgrade.

haut de la page | table des matières

A.5.2. Bug fixes

Memory leak plugged in GiST indexing
Segfault fix in transform() handling of proj4 errors
Fixed some proj4 texts in spatial_ref_sys (missing +proj)
Loader: fixed string functions usage, reworked NULL objects check, fixed segfault on MULTILINESTRING input.
Fixed bug in MakeLine dimension handling
Fixed bug in translate() corrupting output bounding box

haut de la page | table des matières

A.5.3. Improvements

Documentation improvements
More robust selectivity estimator
Minor speedup in distance()
Minor cleanups
GiST indexing cleanup
Looser syntax acceptance in box3d parser

haut de la page | table des matières

A.6. Release 1.0.3

Release date: 2005/08/08
Contains some bug fixes - including a severe one affecting correctness of stored geometries - and a few improvements.

haut de la page | table des matières

A.6.1. Upgrading

Due to a bug in a bounding box computation routine, the upgrade procedure requires special attention, as bounding boxes cached in the database could be incorrect.
An hard upgrade procedure (dump/reload) will force recomputation of all bounding boxes (not included in dumps). This is required if upgrading from releases prior to 1.0.0RC6.
If you are upgrading from versions 1.0.0RC6 or up, this release includes a perl script (utils/rebuild_bbox_caches.pl) to force recomputation of geometries' bounding boxes and invoke all operations required to propagate eventual changes in them (geometry statistics update, reindexing). Invoke the script after a make install (run with no args for syntax help). Optionally run utils/postgis_proc_upgrade.pl to refresh postgis procedures and functions signatures (see Soft upgrade).

haut de la page | table des matières

A.6.2. Bug fixes

Severe bugfix in lwgeom's 2d bounding box computation
Bugfix in WKT (-w) POINT handling in loader
Bugfix in dumper on 64bit machines
Bugfix in dumper handling of user-defined queries
Bugfix in create_undef.pl script

haut de la page | table des matières

A.6.3. Improvements

Small performance improvement in canonical input function
Minor cleanups in loader
Support for multibyte field names in loader
Improvement in the postgis_restore.pl script
New rebuild_bbox_caches.pl util script

haut de la page | table des matières

A.7. Release 1.0.2

Release date: 2005/07/04
Contains a few bug fixes and improvements.

haut de la page | table des matières

A.7.1. Upgrading

If you are upgrading from release 1.0.0RC6 or up you DO NOT need a dump/reload.
Upgrading from older releases requires a dump/reload. See the upgrading chapter for more informations.

haut de la page | table des matières

A.7.2. Bug fixes

Fault tolerant btree ops
Memory leak plugged in pg_error
Rtree index fix
Cleaner build scripts (avoided mix of CFLAGS and CXXFLAGS)

haut de la page | table des matières

A.7.3. Improvements

New index creation capabilities in loader (-I switch)
Initial support for postgresql 8.1dev

haut de la page | table des matières

A.8. Release 1.0.1

Release date: 2005/05/24
Contains a few bug fixes and some improvements.

haut de la page | table des matières

A.8.1. Upgrading

If you are upgrading from release 1.0.0RC6 or up you DO NOT need a dump/reload.
Upgrading from older releases requires a dump/reload. See the upgrading chapter for more informations.

haut de la page | table des matières

A.8.2. Library changes

BUGFIX in 3d computation of lenght_spheroid()
BUGFIX in join selectivity estimator

haut de la page | table des matières

A.8.3. Other changes/additions

BUGFIX in shp2pgql escape functions
better support for concurrent postgis in multiple schemas
documentation fixes
jdbc2: compile with "-target 1.2 -source 1.2" by default
NEW -k switch for pgsql2shp
NEW support for custom createdb options in postgis_restore.pl
BUGFIX in pgsql2shp attribute names unicity enforcement
BUGFIX in Paris projections definitions
postgis_restore.pl cleanups

haut de la page | table des matières

A.9. Release 1.0.0

Release date: 2005/04/19
Final 1.0.0 release. Contains a few bug fixes, some improvements in the loader (most notably support for older postgis versions), and more docs.

haut de la page | table des matières

A.9.1. Upgrading

If you are upgrading from release 1.0.0RC6 you DO NOT need a dump/reload.
Upgrading from any other precedent release requires a dump/reload. See the upgrading chapter for more informations.

haut de la page | table des matières

A.9.2. Library changes

BUGFIX in transform() releasing random memory address
BUGFIX in force_3dm() allocating less memory then required
BUGFIX in join selectivity estimator (defaults, leaks, tuplecount, sd)

haut de la page | table des matières

A.9.3. Other changes/additions

BUGFIX in shp2pgsql escape of values starting with tab or single-quote
NEW manual pages for loader/dumper
NEW shp2pgsql support for old (HWGEOM) postgis versions
NEW -p (prepare) flag for shp2pgsql
NEW manual chapter about OGC compliancy enforcement
NEW autoconf support for JTS lib
BUGFIX in estimator testers (support for LWGEOM and schema parsing)

haut de la page | table des matières

A.10. Release 1.0.0RC6

Release date: 2005/03/30
Sixth release candidate for 1.0.0. Contains a few bug fixes and cleanups.

haut de la page | table des matières

A.10.1. Upgrading

You need a dump/reload to upgrade from precedent releases. See the upgrading chapter for more informations.

haut de la page | table des matières

A.10.2. Library changes

BUGFIX in multi()
early return [when noop] from multi()

haut de la page | table des matières

A.10.3. Scripts changes

dropped {x,y}{min,max}(box2d) functions

haut de la page | table des matières

A.10.4. Other changes

BUGFIX in postgis_restore.pl scrip
BUGFIX in dumper's 64bit support

haut de la page | table des matières

A.11. Release 1.0.0RC5

Release date: 2005/03/25
Fifth release candidate for 1.0.0. Contains a few bug fixes and a improvements.

haut de la page | table des matières

A.11.1. Upgrading

If you are upgrading from release 1.0.0RC4 you DO NOT need a dump/reload.
Upgrading from any other precedent release requires a dump/reload. See the upgrading chapter for more informations.

haut de la page | table des matières

A.11.2. Library changes

BUGFIX (segfaulting) in box3d computation (yes, another!).
BUGFIX (segfaulting) in estimated_extent().

haut de la page | table des matières

A.11.3. Other changes

Small build scripts and utilities refinements.
Additional performance tips documented.

haut de la page | table des matières

A.12. Release 1.0.0RC4

Release date: 2005/03/18
Fourth release candidate for 1.0.0. Contains bug fixes and a few improvements.

haut de la page | table des matières

A.12.2. Library changes

BUGFIX (segfaulting) in geom_accum().
BUGFIX in 64bit architectures support.
BUGFIX in box3d computation function with collections.
NEW subselects support in selectivity estimator.
Early return from force_collection.
Consistency check fix in SnapToGrid().
Box2d output changed back to 15 significant digits.

haut de la page | table des matières

A.12.3. Scripts changes

NEW distance_sphere() function.
Changed get_proj4_from_srid implementation to use PL/PGSQL instead of SQL.

haut de la page | table des matières

A.12.4. Other changes

BUGFIX in loader and dumper handling of MultiLine shapes
BUGFIX in loader, skipping all but first hole of polygons.
jdbc2: code cleanups, Makefile improvements
FLEX and YACC variables set *after* pgsql Makefile.global is included and only if the pgsql *stripped* version evaulates to the empty string
Added already generated parser in release
Build scripts refinements
improved version handling, central Version.config
improvements in postgis_restore.pl

haut de la page | table des matières

A.13. Release 1.0.0RC3

Release date: 2005/02/24
Third release candidate for 1.0.0. Contains many bug fixes and improvements.

haut de la page | table des matières

A.13.1. Upgrading

You need a dump/reload to upgrade from precedent releases. See the upgrading chapter for more informations.

haut de la page | table des matières

A.13.2. Library changes

BUGFIX in transform(): missing SRID, better error handling.
BUGFIX in memory alignment handling
BUGFIX in force_collection() causing mapserver connector failures on simple (single) geometry types.
BUGFIX in GeometryFromText() missing to add a bbox cache.
reduced precision of box2d output.
prefixed DEBUG macros with PGIS_ to avoid clash with pgsql one
plugged a leak in GEOS2POSTGIS converter
Reduced memory usage by early releasing query-context palloced one.

haut de la page | table des matières

A.13.3. Scripts changes

BUGFIX in 72 index bindings.
BUGFIX in probe_geometry_columns() to work with PG72 and support multiple geometry columns in a single table
NEW bool::text cast
Some functions made IMMUTABLE from STABLE, for performance improvement.

haut de la page | table des matières

A.13.4. JDBC changes

jdbc2: small patches, box2d/3d tests, revised docs and license.
jdbc2: bug fix and testcase in for pgjdbc 8.0 type autoregistration
jdbc2: Removed use of jdk1.4 only features to enable build with older jdk releases.
jdbc2: Added support for building against pg72jdbc2.jar
jdbc2: updated and cleaned makefile
jdbc2: added BETA support for jts geometry classes
jdbc2: Skip known-to-fail tests against older PostGIS servers.
jdbc2: Fixed handling of measured geometries in EWKT.

haut de la page | table des matières

A.13.5. Other changes

new performance tips chapter in manual
documentation updates: pgsql72 requirement, lwpostgis.sql
few changes in autoconf
BUILDDATE extraction made more portable
fixed spatial_ref_sys.sql to avoid vacuuming the whole database.
spatial_ref_sys: changed Paris entries to match the ones distributed with 0.x.

haut de la page | table des matières

A.14. Release 1.0.0RC2

Release date: 2005/01/26
Second release candidate for 1.0.0 containing bug fixes and a few improvements.

haut de la page | table des matières

A.14.1. Upgrading

You need a dump/reload to upgrade from precedent releases. See the upgrading chapter for more informations.

haut de la page | table des matières

A.14.2. Library changes

BUGFIX in pointarray box3d computation
BUGFIX in distance_spheroid definition
BUGFIX in transform() missing to update bbox cache
NEW jdbc driver (jdbc2)
GEOMETRYCOLLECTION(EMPTY) syntax support for backward compatibility
Faster binary outputs
Stricter OGC WKB/WKT constructors

haut de la page | table des matières

A.14.3. Scripts changes

More correct STABLE, IMMUTABLE, STRICT uses in lwpostgis.sql
stricter OGC WKB/WKT constructors

haut de la page | table des matières

A.14.4. Other changes

Faster and more robust loader (both i18n and not)
Initial autoconf script

haut de la page | table des matières

A.15. Release 1.0.0RC1

Release date: 2005/01/13
This is the first candidate of a major postgis release, with internal storage of postgis types redesigned to be smaller and faster on indexed queries.

haut de la page | table des matières

A.15.1. Upgrading

You need a dump/reload to upgrade from precedent releases. See the upgrading chapter for more informations.

haut de la page | table des matières

A.15.2. Changes

Faster canonical input parsing.
Lossless canonical output.
EWKB Canonical binary IO with PG>73.
Support for up to 4d coordinates, providing lossless shapefile->postgis->shapefile conversion.
New function: UpdateGeometrySRID(), AsGML(), SnapToGrid(), ForceRHR(), estimated_extent(), accum().
Vertical positioning indexed operators.
JOIN selectivity function.
More geometry constructors / editors.
Postgis extension API.
UTF8 support in loader.

haut de la page | table des matières

Manuel PostGIS avec JTS

Dans ce manuel nous allons vous présenter comment installer PostGIS en utilisant la librarie JTS à la place GEOS.

haut de la page | table des matières

Prérequis

Afin de pouvoir compiler PostGIS en utilisant la librairie JTS il vous faudra disposer de certains outils.

Tout d'abort, afin de compiler les source java du projet JTS qui se trouvent dans le répertoire src vous aurez besoin d'un compilateur JAVA : javac. À prioris, le moyen le plus simple pour vous assurer que vous disposez bien de cet outils consiste à utiliser la commande javac --help. Si vous n'avez pas de résultat ou une erreur vous informant que javac n'a pas été trouvé, installez un des jdk disponibles pour votre système.

Pour notre part nous avons utilisé le jdk de SUN® dont voici les informations relatives à l'environnement d'exécution, obtenues avec la commande java -version :

java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode)

En plus des outils nécessaires à la compilation, vous aurez besoin d'installer un paquet java : jdbc3-oracle.

Pour pouvoir créer la librairie C libjts.so et libgeom_static.so vous aurez besoin d'avoir un compilateur gcj ainsi que les outils associés tel que gcjh qui permet de générer automatiquement des fichiers d'entêtes (.h) à partir de classes java compilées. Vous pouvez vérifier aisément si cet outil est déjà installé sur cotre système en utilisant la commande gcj --version, sur le système où nous avons effectuer les tests nous obtenons les informations ci-dessous :

gcj (GCC) 4.1.2 (Gentoo 4.1.2)
Copyright © 2006 Free Software Foundation, Inc.
Ce logiciel est libre; voir les sources pour les conditions de copie. Il n'y a PAS
GARANTIE; ni implicite pour le MARCHANDAGE ou pour un BUT PARTICULIER.

Je pense que si vous avez le compilateur gcj l'ensemble des ses outils annexes seront aussi disponibles (vous pouvez néanmoins tester la présence de gcjh en lançant la commende du même nom).

haut de la page | table des matières

Compilation des sources de JTS et création de l'archive JAR

Maintenant que vous savez que les outils nécessaires à la compilation des sources java du projet JTS sont installées sur votre système, nous allons les utiliser afin de créer les archives JAR contenant l'ensemble du code binaire de la machine virtuelle JAVA.

Dans ce qui suit nous considérons que vous savez où sont installés les jars du paquet java que nous avons mentioné dans la section précédente, nous supposerons qu'ils sont tous installés au même endroit, dans le répertoire que nous noterons : $JAR_DIR.

Pour ce faire, il suffit de suivre le indications fournits ci-dessous :

  1. Rendez-vous dans le répertoire où vous avez décompressé les sources du projet JTS :
    cd jts-1.7.2
  2. Mise à jour de la variable d'environnement CLASSPATH permettant de définir l'ensemble des paquets java à utiliser lors de la compilation :
    machine jts-1.7.2 # for i in ${JAR_DIR}/*jar; do
    export CLASSPATH="${CLASSPATH}:$i"
    done
    
  3. Création des répertoires où seront compiler les classes java :
    machine jts-1.7.2 # for i in jts jtsio; do mkdir build/$i; done
    
  4. Compilation de JTS et création de l'archive jar :
    machine jts-1.7.2 # javac -nowarn -d build/jts $(find ./src/com/vividsolutions/jts/ -name "*.java") 
    machine jts-1.7.2 # jar -cfm jts.jar src/MANIFEST.MF -C build/jts .
    
  5. Ajout de la librairie JTS fraichement compimlée à notre variable CLASSPATH :
    machine jts-1.7.2 # export CLASSPATH="${CLASSPATH}:./jts.jar"
  6. Compilation des classes du répertoire jtsexample et création de l'archive jar :
    machine jts-1.7.2 # javac -d build/jtsexample $(find ./src/com/vividsolutions/jtsexample -name "*.java")
    machine jts-1.7.2 # jar -cfm jtsexample.jar src/MANIFEST.MF -C build/jtsexample .
    
  7. Compilation des classes du répertoire jtsio et création de l'archive jar :
    machine jts-1.7.2 # javac -d build/jtsio $(find ./src/jtsio/src -name "*.java")
    machine jts-1.7.2 # jar -cfm jtsio.jar src/MANIFEST.MF -C build/jtsio .
    
Si tout c'est passé correctement vous devriez trouver à la racine des sources du projet JTS (jts-1.7.2 dans notre exemple) trois archives binaires JAR : jts.jar, jtsexample.jar et jtsio.jar. haut de la page | table des matières

Création des librairies dynamiques et des fichiers d'entêtes

Maintenant que vous avez compiler les sources du projet JTS, vous devez créer des librairies dynamiques C. En effet vous savez sans doute que le code source de PostGIS est en C et non en java, un convertion est donc nécessaire. Heureusement GNU met à disposition, avec son compilateur gcc, un compilateur java permettant une telle convertion. Vous verrez de plus qu'il est aussi possible de générer des fichiers d'entête avec la commande gcjh.

Pour créer ces librairies dynamique ainsi que les fichiers d'entêtes requis lors de la compilation de PostGIS que nous verrons dans la section suivante, je vous invite à suivre les quelques instructions ci-dessous :

  1. Rendez vous dans le répertoire des sources du projet JTS et créez le répertoire où seront stoquées les classes java compilées :
    machine ~ # cd jts-1.7.2
    machine jts-1.7.2 # mkdir classes
    
  2. Compilation de l'ensemble des classes java avec gcj :
    machine jts-1.7.2 # gcj -C -d classes -classpath jts.jar $(find src/com/vividsolutions/jts -name '*.java')
    
  3. Définition de la variable d'environnement JTSCLASSES qui liste l'ensemble des classes requisent lors de la compimlation de PostGIS :
    machine jts-1.7.2 # export JTSCLASSES="com.vividsolutions.jts.geom.Geometry \
                com.vividsolutions.jts.geom.Point \
                com.vividsolutions.jts.geom.MultiPoint \
                com.vividsolutions.jts.geom.LineString \
                com.vividsolutions.jts.geom.LinearRing \
                com.vividsolutions.jts.geom.MultiLineString \
                com.vividsolutions.jts.geom.Polygon \
                com.vividsolutions.jts.geom.MultiPolygon \
                com.vividsolutions.jts.geom.GeometryCollection \
                com.vividsolutions.jts.geom.GeometryFactory \
                com.vividsolutions.jts.geom.PrecisionModel \
                com.vividsolutions.jts.geom.Coordinate \
                com.vividsolutions.jts.geom.CoordinateSequenceFactory \
                com.vividsolutions.jts.geom.CoordinateSequence \
                com.vividsolutions.jts.geom.IntersectionMatrix \
                com.vividsolutions.jts.io.WKTReader \
                com.vividsolutions.jts.io.WKTWriter \
                com.vividsolutions.jts.JTSVersion"
    
  4. Création du répertoire et de ses sous-répertoires destinés à contenir les fichiers d'entêtes générés avec gcjh :
    machine jts-1.7.2 # mkdir -p include
    machine jts-1.7.2 # jts_include_path="com/vividsolutions/jts/" \
    for i in geom io ;do
     mkdir -p include/${jts_include_path}/${i} ;
    done
    
  5. Rendez vous dans le répertoire nouvellemenet créé puis créez les fichiers d'entêtes correspondants :
    machine jts-1.7.2 # cd include
    machine jts-1.7.2/include # gcjh -classpath ../jts.jar ${JTSCLASSES}
    machine jts-1.7.2/include # cd ..
    machine jts-1.7.2 #
    
  6. Génération du fichier d'entête principal jts.h :
    machine jts-1.7.2 # gcjh -I jts.jar -stub -o ./include/jts.h ${JTSCLASSES}
    
  7. Génération de la librairie dynamique libjts.soà partir de l'archive binaire jts.jar :
    machine jts-1.7.2 # gcj -fPIC -O2 -shared -o libjts.so ./jts.jar
    
  8. Compilation de la classe Geometry.java :
    machine jts-1.7.2 # gcj -C -classpath jts.jar src/com/vividsolutions/jts/geom/Geometry.java
    machine jts-1.7.2 # mv src/com/vividsolutions/jts/geom/Geometry*class ./
    
  9. Génération de librairie libstatis_geom.so
    machine jts-1.7.2 # gcj -fPIC -classpath jts.jar -shared -o libstatic_geom.so "Geometry\$1.class"
    
Si tout c'est déroulé correctement vous devriez avoir des fichiers d'entêtes dans le répertoire include (find ./include pour s'en assurer) et les libraries dynamiques dans le répertoire où vous avez décompmressé les sources du projet JTS (jts-1.7.2 dans notre exemple). haut de la page | table des matières

Tester la liaison à la librairie libjts.so à l'aide des exemples fournis

Maintenant que nous avons créé notre librairie dynamique, il serait bon de la tester avant de tenter une installation.

Pour ce faire nous avons créé une boucle simple permettant la compilation et l'exécution des binaires compilé (en utilisant la classe java puis le binaire C correspondant). C'est ce que vous trouverez ci-dessous :

count=1;
sep="########################################################################" ;
for jf in $(find src/com/vividsolutions/jtsexample/ | grep .java); do 
    echo $sep;
    echo "Test n° $count : $jf";
    echo $sep;
    jc=$(echo $jf | sed "s:src.::g;s:.java::g;s:/:.:g") ;
    target=$(echo $jc | cut -d'.' -f5); 
    echo $jf \($jc\) $target; 
    gcj -L./ -ljts -O2 -classpath ./jts.jar $jf --main=$jc -o $target && \
    echo $sep && \
    echo "Executing in java mode" && \
    time java $jc &&  \
    echo && \
    echo $sep && \
    echo "Executing in C mode" && \
    time LD_LIBRARY_PATH="./" ./$target && \
    echo && \
    echo $sep && \
    echo; count=$(expr $count + 1); 
done
Si tout c'est passé correctement vous devriez obtenir des résultat équivalents à ceux fournis ci-dessous :
########################################################################
Test n° 1 : src/com/vividsolutions/jtsexample/geom/BasicExample.java
########################################################################
src/com/vividsolutions/jtsexample/geom/BasicExample.java (com.vividsolutions.jtsexample.geom.BasicExample) BasicExample
########################################################################
Executing in java mode
Geometry 1: LINESTRING (0 0, 10 10, 20 20)
Geometry 2: LINESTRING (0 0, 10 10, 20 20)
G1 intersection G2: MULTILINESTRING ((0 0, 10 10), (10 10, 20 20))

real    0m0.299s
user    0m0.230s
sys     0m0.024s

########################################################################
Executing in C mode
Geometry 1: LINESTRING (0 0, 10 10, 20 20)
Geometry 2: LINESTRING (0 0, 10 10, 20 20)
G1 intersection G2: MULTILINESTRING ((0 0, 10 10), (10 10, 20 20))

real    0m0.138s
user    0m0.115s
sys     0m0.023s

########################################################################

########################################################################
Test n° 2 : src/com/vividsolutions/jtsexample/geom/ConstructionExample.java
########################################################################
src/com/vividsolutions/jtsexample/geom/ConstructionExample.java (com.vividsolutions.jtsexample.geom.ConstructionExample) ConstructionExample
########################################################################
Executing in java mode
POINT (0 0)
POINT (0 0)
MULTIPOINT (0 0, 1 1)

real    0m0.194s
user    0m0.153s
sys     0m0.023s

########################################################################
Executing in C mode
POINT (0 0)
POINT (0 0)
MULTIPOINT (0 0, 1 1)

real    0m0.139s
user    0m0.118s
sys     0m0.021s

########################################################################

########################################################################
Test n° 7 : src/com/vividsolutions/jtsexample/geom/PrecisionModelExample.java
########################################################################
src/com/vividsolutions/jtsexample/geom/PrecisionModelExample.java (com.vividsolutions.jtsexample.geom.PrecisionModelExample) PrecisionModelExample
########################################################################
Executing in java mode
-------------------------------------------
Example 1 shows roundoff from computing in different precision models
A = POLYGON ((60 180, 160 260, 240 80, 60 180))
B = POLYGON ((200 260, 280 160, 80 100, 200 260))
Running example using Precision Model = Floating
A intersection B = POLYGON ((174.88372093023256 226.51162790697674, 213.33333333333334 140, 160.5194805194805 124.15584415584415, 116.47058823529412 148.62745098039215, 174.88372093023256 226.51162790697674))
Running example using Precision Model = Floating-Single
A intersection B = POLYGON ((174.883728 226.511627, 213.333328 140, 160.519485 124.155846, 116.470589 148.627457, 174.883728 226.511627))
Running example using Precision Model = Fixed (Scale=1.0)
A intersection B = POLYGON ((175 227, 213 140, 161 124, 116 149, 175 227))
-------------------------------------------
Example 2 shows that roundoff can change the topology of geometry computed in different precision models
A = POLYGON ((0 0, 160 0, 160 1, 0 0))
B = POLYGON ((40 60, 40 -20, 140 -20, 140 60, 40 60))
-------------------------------------------
Running example using Precision Model = Floating
A intersection B = MULTIPOLYGON (((40 0, 0 0, 40 0.25, 40 0)), ((140 0.875, 160 1, 160 0, 140 0, 140 0.875)))
-------------------------------------------
Running example using Precision Model = Fixed (Scale=1.0)
A intersection B = GEOMETRYCOLLECTION (LINESTRING (0 0, 40 0), POLYGON ((140 1, 160 1, 160 0, 140 0, 140 1)))

real    0m0.303s
user    0m0.237s
sys     0m0.028s

########################################################################
Executing in C mode
-------------------------------------------
Example 1 shows roundoff from computing in different precision models
A = POLYGON ((60 180, 160 260, 240 80, 60 180))
B = POLYGON ((200 260, 280 160, 80 100, 200 260))
Running example using Precision Model = Floating
A intersection B = POLYGON ((174.8837209302325561 226.5116279069767415, 213.3333333333333428 140, 160.5194805194805098 124.1558441558441501, 116.4705882352941159 148.6274509803921546, 174.8837209302325561 226.5116279069767415))
Running example using Precision Model = Floating-Single
A intersection B = POLYGON ((174.883728 226.511627, 213.333328 140, 160.519485 124.155846, 116.470589 148.627457, 174.883728 226.511627))
Running example using Precision Model = Fixed (Scale=1.0)
A intersection B = POLYGON ((175 227, 213 140, 161 124, 116 149, 175 227))
-------------------------------------------
Example 2 shows that roundoff can change the topology of geometry computed in different precision models
A = POLYGON ((0 0, 160 0, 160 1, 0 0))
B = POLYGON ((40 60, 40 -20, 140 -20, 140 60, 40 60))
-------------------------------------------
Running example using Precision Model = Floating
A intersection B = MULTIPOLYGON (((40 0, 0 0, 40 0.25, 40 0)), ((140 0.875, 160 1, 160 0, 140 0, 140 0.875)))
-------------------------------------------
Running example using Precision Model = Fixed (Scale=1.0)
A intersection B = GEOMETRYCOLLECTION (LINESTRING (0 0, 40 0), POLYGON ((140 1, 160 1, 160 0, 140 0, 140 1)))

real    0m0.131s
user    0m0.110s
sys     0m0.021s

########################################################################

########################################################################
Test n° 8 : src/com/vividsolutions/jtsexample/geom/SimpleMethodsExample.java
########################################################################
src/com/vividsolutions/jtsexample/geom/SimpleMethodsExample.java (com.vividsolutions.jtsexample.geom.SimpleMethodsExample) SimpleMethodsExample
########################################################################
Executing in java mode
A = POLYGON ((40 100, 40 20, 120 20, 120 100, 40 100))
B = LINESTRING (20 80, 80 60, 100 140)
A intersection B = LINESTRING (40 73.33333333333333, 80 60, 90 100)
A relate C = 1F20F1102

real    0m0.297s
user    0m0.223s
sys     0m0.025s

########################################################################
Executing in C mode
A = POLYGON ((40 100, 40 20, 120 20, 120 100, 40 100))
B = LINESTRING (20 80, 80 60, 100 140)
A intersection B = LINESTRING (40 73.3333333333333285, 80 60, 90 100)
A relate C = 1F20F1102

real    0m0.127s
user    0m0.105s
sys     0m0.022s

########################################################################

########################################################################
Test n° 9 : src/com/vividsolutions/jtsexample/linearref/LinearRefExample.java
########################################################################
src/com/vividsolutions/jtsexample/linearref/LinearRefExample.java (com.vividsolutions.jtsexample.linearref.LinearRefExample) LinearRefExample
########################################################################
Executing in java mode
=========================
Input Geometry: LINESTRING (0 0, 10 10, 20 20)
Indices to extract: 1.0 10.0
Extracted Line: LINESTRING (0.7071067811865475 0.7071067811865475, 7.071067811865475 7.071067811865475)
Indices of extracted line: 1.0 10.0
Midpoint of extracted line: (3.8890872965260117, 3.8890872965260117, NaN)
=========================
Input Geometry: MULTILINESTRING ((0 0, 10 10), (20 20, 25 25, 30 40))
Indices to extract: 1.0 20.0
Extracted Line: MULTILINESTRING ((0.7071067811865475 0.7071067811865475, 10 10), (20 20, 24.14213562373095 24.14213562373095))
Indices of extracted line: 1.0 20.0
Midpoint of extracted line: (7.424621202458749, 7.424621202458749, NaN)

real    0m0.193s
user    0m0.155s
sys     0m0.030s

########################################################################
Executing in C mode
=========================
Input Geometry: LINESTRING (0 0, 10 10, 20 20)
Indices to extract: 1.0 10.0
Extracted Line: LINESTRING (0.7071067811865474 0.7071067811865474, 7.0710678118654746 7.0710678118654746)
Indices of extracted line: 1.0 10.0
Midpoint of extracted line: (3.8890872965260117, 3.8890872965260117, NaN)
=========================
Input Geometry: MULTILINESTRING ((0 0, 10 10), (20 20, 25 25, 30 40))
Indices to extract: 1.0 20.0
Extracted Line: MULTILINESTRING ((0.7071067811865474 0.7071067811865474, 10 10), (20 20, 24.142135623730951 24.142135623730951))
Indices of extracted line: 1.0 20.0
Midpoint of extracted line: (7.424621202458749, 7.424621202458749, NaN)

real    0m0.127s
user    0m0.105s
sys     0m0.022s

########################################################################

########################################################################
Test n° 10 : src/com/vividsolutions/jtsexample/operation/distance/ClosestPointExample.java
########################################################################
src/com/vividsolutions/jtsexample/operation/distance/ClosestPointExample.java (com.vividsolutions.jtsexample.operation.distance.ClosestPointExample) distance
########################################################################
Executing in java mode
-------------------------------------
Geometry A: POLYGON ((200 180, 60 140, 60 260, 200 180))
Geometry B: POINT (140 280)
Distance = 57.05597791103589
Closest points: LINESTRING (111.6923076923077 230.46153846153845, 140 280) (distance = 57.055977911035896)
-------------------------------------
Geometry A: POLYGON ((200 180, 60 140, 60 260, 200 180))
Geometry B: MULTIPOINT (140 280, 140 320)
Distance = 57.05597791103589
Closest points: LINESTRING (111.6923076923077 230.46153846153845, 140 280) (distance = 57.055977911035896)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 100, 200 200, 100 200, 100 100)
Geometry B: POINT (10 10)
Distance = 127.27922061357856
Closest points: LINESTRING (100 100, 10 10) (distance = 127.27922061357856)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 200)
Geometry B: LINESTRING (100 200, 200 100)
Distance = 0.0
Closest points: LINESTRING (150 150, 150 150) (distance = 0.0)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 200)
Geometry B: LINESTRING (150 121, 200 0)
Distance = 20.506096654409877
Closest points: LINESTRING (135.5 135.5, 150 121) (distance = 20.506096654409877)
-------------------------------------
Geometry A: POLYGON ((76 185, 125 283, 331 276, 324 122, 177 70, 184 155, 69 123, 76 185), (267 237, 148 248, 135 185, 223 189, 251 151, 286 183, 267 237))
Geometry B: LINESTRING (153 204, 185 224, 209 207, 238 222, 254 186)
Distance = 13.788860460124573
Closest points: LINESTRING (139.4956500724988 206.78661188980183, 153 204) (distance = 13.788860460124573)
-------------------------------------
Geometry A: POLYGON ((76 185, 125 283, 331 276, 324 122, 177 70, 184 155, 69 123, 76 185), (267 237, 148 248, 135 185, 223 189, 251 151, 286 183, 267 237))
Geometry B: LINESTRING (120 215, 185 224, 209 207, 238 222, 254 186)
Distance = 0.0
Closest points: LINESTRING (120 215, 120 215) (distance = 0.0)

real    0m0.247s
user    0m0.175s
sys     0m0.027s

########################################################################
Executing in C mode
-------------------------------------
Geometry A: POLYGON ((200 180, 60 140, 60 260, 200 180))
Geometry B: POINT (140 280)
Distance = 57.055977911035896
Closest points: LINESTRING (111.6923076923076934 230.4615384615384527, 140 280) (distance = 57.055977911035896)
-------------------------------------
Geometry A: POLYGON ((200 180, 60 140, 60 260, 200 180))
Geometry B: MULTIPOINT (140 280, 140 320)
Distance = 57.055977911035896
Closest points: LINESTRING (111.6923076923076934 230.4615384615384527, 140 280) (distance = 57.055977911035896)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 100, 200 200, 100 200, 100 100)
Geometry B: POINT (10 10)
Distance = 127.27922061357856
Closest points: LINESTRING (100 100, 10 10) (distance = 127.27922061357856)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 200)
Geometry B: LINESTRING (100 200, 200 100)
Distance = 0.0
Closest points: LINESTRING (150 150, 150 150) (distance = 0.0)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 200)
Geometry B: LINESTRING (150 121, 200 0)
Distance = 20.506096654409877
Closest points: LINESTRING (135.5 135.5, 150 121) (distance = 20.506096654409877)
-------------------------------------
Geometry A: POLYGON ((76 185, 125 283, 331 276, 324 122, 177 70, 184 155, 69 123, 76 185), (267 237, 148 248, 135 185, 223 189, 251 151, 286 183, 267 237))
Geometry B: LINESTRING (153 204, 185 224, 209 207, 238 222, 254 186)
Distance = 13.788860460124573
Closest points: LINESTRING (139.4956500724987904 206.7866118898018328, 153 204) (distance = 13.788860460124573)
-------------------------------------
Geometry A: POLYGON ((76 185, 125 283, 331 276, 324 122, 177 70, 184 155, 69 123, 76 185), (267 237, 148 248, 135 185, 223 189, 251 151, 286 183, 267 237))
Geometry B: LINESTRING (120 215, 185 224, 209 207, 238 222, 254 186)
Distance = 0.0
Closest points: LINESTRING (120 215, 120 215) (distance = 0.0)

real    0m0.130s
user    0m0.107s
sys     0m0.023s

########################################################################

########################################################################
Test n° 11 : src/com/vividsolutions/jtsexample/operation/linemerge/LineMergeExample.java
########################################################################
src/com/vividsolutions/jtsexample/operation/linemerge/LineMergeExample.java (com.vividsolutions.jtsexample.operation.linemerge.LineMergeExample) linemerge
########################################################################
Executing in java mode
Lines formed (5):
[LINESTRING (60 210, 30 190, 30 160, 40 150, 70 150, 100 180, 100 200, 90 210, 60 210), LINESTRING (160 310, 130 300, 100 290, 70 270, 60 260, 50 240, 50 220, 60 210), LINESTRING (70 430, 100 430, 120 420, 140 400, 150 370, 160 340, 
160 310), LINESTRING (160 310, 200 330, 220 340, 240 360, 260 390, 260 410, 250 430), LINESTRING (160 310, 160 280, 160 250, 170 230, 180 210, 200 180, 220 160, 240 150, 270 150, 290 170)]

real    0m0.299s
user    0m0.240s
sys     0m0.031s

########################################################################
Executing in C mode
Lines formed (5):
[LINESTRING (60 210, 30 190, 30 160, 40 150, 70 150, 100 180, 100 200, 90 210, 60 210), LINESTRING (160 310, 130 300, 100 290, 70 270, 60 260, 50 240, 50 220, 60 210), LINESTRING (70 430, 100 430, 120 420, 140 400, 150 370, 160 340, 
160 310), LINESTRING (160 310, 200 330, 220 340, 240 360, 260 390, 260 410, 250 430), LINESTRING (160 310, 160 280, 160 250, 170 230, 180 210, 200 180, 220 160, 240 150, 270 150, 290 170)]

real    0m0.270s
user    0m0.207s
sys     0m0.044s

########################################################################

########################################################################
Test n° 12 : src/com/vividsolutions/jtsexample/operation/polygonize/PolygonizeExample.java
########################################################################
src/com/vividsolutions/jtsexample/operation/polygonize/PolygonizeExample.java (com.vividsolutions.jtsexample.operation.polygonize.PolygonizeExample) polygonize
########################################################################
Executing in java mode
Polygons formed (2):
[POLYGON ((185 221, 88 275, 180 316, 292 281, 185 221)), POLYGON ((189 98, 83 187, 185 221, 325 168, 189 98))]

real    0m0.480s
user    0m0.411s
sys     0m0.047s

########################################################################
Executing in C mode
Polygons formed (2):
[POLYGON ((189 98, 83 187, 185 221, 325 168, 189 98)), POLYGON ((185 221, 88 275, 180 316, 292 281, 185 221))]

real    0m0.252s
user    0m0.206s
sys     0m0.045s

########################################################################

########################################################################
Test n° 13 : src/com/vividsolutions/jtsexample/precision/EnhancedPrecisionOpExample.java
########################################################################
src/com/vividsolutions/jtsexample/precision/EnhancedPrecisionOpExample.java (com.vividsolutions.jtsexample.precision.EnhancedPrecisionOpExample) EnhancedPrecisionOpExample
########################################################################
Executing in java mode
This call to intersection will throw a topology exception due to robustness problems:
com.vividsolutions.jts.geom.TopologyException: Directed Edge visited twice during ring-building at (708522.7796120486, 2402268.6542990115, NaN)
        at com.vividsolutions.jts.geomgraph.EdgeRing.computePoints(EdgeRing.java:141)
        at com.vividsolutions.jts.geomgraph.EdgeRing.(EdgeRing.java:70)
        at com.vividsolutions.jts.operation.overlay.MaximalEdgeRing.(MaximalEdgeRing.java:65)
        at com.vividsolutions.jts.operation.overlay.PolygonBuilder.buildMaximalEdgeRings(PolygonBuilder.java:106)
        at com.vividsolutions.jts.operation.overlay.PolygonBuilder.add(PolygonBuilder.java:80)
        at com.vividsolutions.jts.operation.overlay.PolygonBuilder.add(PolygonBuilder.java:69)
        at com.vividsolutions.jts.operation.overlay.OverlayOp.computeOverlay(OverlayOp.java:180)
        at com.vividsolutions.jts.operation.overlay.OverlayOp.getResultGeometry(OverlayOp.java:127)
        at com.vividsolutions.jts.operation.overlay.OverlayOp.overlayOp(OverlayOp.java:66)
        at com.vividsolutions.jts.geom.Geometry.intersection(Geometry.java:1051)
        at com.vividsolutions.jtsexample.precision.EnhancedPrecisionOpExample.run(EnhancedPrecisionOpExample.java:77)
        at com.vividsolutions.jtsexample.precision.EnhancedPrecisionOpExample.main(EnhancedPrecisionOpExample.java:53)
Using EnhancedPrecisionOp allows the intersection to be performed with no errors:
MULTIPOLYGON (((708653.498611049 2402311.54647056, 708657.0443590372 2402304.6290913913, 708522.7796120486 2402268.6542990115, 708653.498611049 2402311.54647056)), ((708258.7634430077 2402197.914011042, 708257.0393502527 2402206.5716
68428, 708257.0393502527 2402206.571668428, 708258.7634430077 2402197.9140110426, 708258.7634430077 2402197.914011042)))

real    0m0.589s
user    0m0.529s
sys     0m0.049s

########################################################################
Executing in C mode
This call to intersection will throw a topology exception due to robustness problems:
com.vividsolutions.jts.geom.TopologyException: Directed Edge visited twice during ring-building at (708522.7796120486, 2402268.6542990115, NaN)
   at com.vividsolutions.jts.geomgraph.EdgeRing.computePoints(libjts.so)
   at com.vividsolutions.jts.geomgraph.EdgeRing.(libjts.so)
   at com.vividsolutions.jts.operation.overlay.MaximalEdgeRing.(libjts.so)
   at com.vividsolutions.jts.operation.overlay.PolygonBuilder.buildMaximalEdgeRings(libjts.so)
   at com.vividsolutions.jts.operation.overlay.PolygonBuilder.add(libjts.so)
   at com.vividsolutions.jts.operation.overlay.PolygonBuilder.add(libjts.so)
   at com.vividsolutions.jts.operation.overlay.OverlayOp.computeOverlay(libjts.so)
   at com.vividsolutions.jts.operation.overlay.OverlayOp.getResultGeometry(libjts.so)
   at com.vividsolutions.jts.operation.overlay.OverlayOp.overlayOp(libjts.so)
   at com.vividsolutions.jts.geom.Geometry.intersection(libjts.so)
   at com.vividsolutions.jtsexample.precision.EnhancedPrecisionOpExample.run(EnhancedPrecisionOpExample)
   at com.vividsolutions.jtsexample.precision.EnhancedPrecisionOpExample.main(EnhancedPrecisionOpExample)
Using EnhancedPrecisionOp allows the intersection to be performed with no errors:
MULTIPOLYGON (((708653.4986110490281134 2402311.5464705601334571, 708657.0443590371869504 2402304.6290913913398981, 708522.7796120486455038 2402268.6542990114539861, 708653.4986110490281134 2402311.5464705601334571)), ((708258.763443
0077159777 2402197.914011042099446, 708257.0393502527149394 2402206.5716684279032051, 708257.0393502527149394 2402206.5716684279032051, 708258.7634430077159777 2402197.9140110425651073, 708258.7634430077159777 2402197.914011042099446
)))

real    0m0.309s
user    0m0.220s
sys     0m0.052s

########################################################################

########################################################################
Test n° 14 : src/com/vividsolutions/jtsexample/technique/LineStringSelfIntersections.java
########################################################################
src/com/vividsolutions/jtsexample/technique/LineStringSelfIntersections.java (com.vividsolutions.jtsexample.technique.LineStringSelfIntersections) LineStringSelfIntersections
########################################################################
Executing in java mode
Line: LINESTRING (0 0, 10 10, 20 20)
Self Intersections: GEOMETRYCOLLECTION EMPTY
Line: LINESTRING (0 40, 60 40, 60 0, 20 0, 20 60)
Self Intersections: POINT (20 40)

real    0m0.528s
user    0m0.427s
sys     0m0.051s

########################################################################
Executing in C mode
Line: LINESTRING (0 0, 10 10, 20 20)
Self Intersections: GEOMETRYCOLLECTION EMPTY
Line: LINESTRING (0 40, 60 40, 60 0, 20 0, 20 60)
Self Intersections: POINT (20 40)

real    0m0.251s
user    0m0.203s
sys     0m0.047s

########################################################################

########################################################################
Test n° 15 : src/com/vividsolutions/jtsexample/technique/PolygonUnionUsingBuffer.java
########################################################################
src/com/vividsolutions/jtsexample/technique/PolygonUnionUsingBuffer.java (com.vividsolutions.jtsexample.technique.PolygonUnionUsingBuffer) PolygonUnionUsingBuffer
########################################################################
Executing in java mode
POLYGON ((80 140, 80 200, 100 200, 100 260, 180 260, 180 240, 240 240, 240 160, 200 160, 200 140, 80 140))

real    0m0.531s
user    0m0.470s
sys     0m0.057s

########################################################################
Executing in C mode
POLYGON ((80 140, 80 200, 100 200, 100 260, 180 260, 180 240, 240 240, 240 160, 200 160, 200 140, 80 140))

real    0m0.253s
user    0m0.212s
sys     0m0.039s

########################################################################

Vous aurez noté que les test numérotés de 3 à 6 n'ont pas été stipulés ici. En effet, ils renvoient tous une erreur qui est simplement liée au fait que la classe java ne contient pas de méthode main ce qui implique que la compilation échoue. Néanmoins grâce à ces quelques vérifications vous pouvez être assuré que votre librairie dynamique est utilisable. Vous aurez noté au passage que l'exécution des binaires C générés sont plus rapide que leurs équivalents java. haut de la page | table des matières

Installation de JTS et création de l'utilitaire jts-config

Maintenant que nous avons compiler les classes java, généré les fichiers d'entêtes et les librairies dynamique, il ne reste plus qu'à installer JTS dans notre système afin que nous souyons capable de compiler PostGIS en utilisant JTS à la place de GEOS.

Pour ce faire, rien de plus simple, il suffit d'installer les archives binaires jar où vous les installez d'habitude ($JAR_ DIR dans notre exemple) puis d'installer les fichier d'entêtes et le librairies dynamiques.

Comme d'habitude nous respecterons le standard FHS et nous installerons donc les librairies dans /usr/lib (sur un système x86, ou encore lib64 dans le cas d'une architecture amd64 ...) et le fichiers d'entêtes dans le répertoire /usr/include.

Voici les quelques commandes qui vous permettrons d'installer JTS dans l'arborescence de votre système :

machine jts-1.7.2 # mkdir /usr/share/doc/jts-1.7.2
machine jts-1.7.2 # cp -r ./test /usr/share/doc/jts-1.7.2/
machine jts-1.7.2 # cp -r doc/javadoc/ /usr/share/doc/jts-1.7.2/
machine jts-1.7.2 # cp *so /usr/lib/
machine jts-1.7.2 # cp -r include/* /usr/include/
machine jts-1.7.2 # cp -r src/ /usr/share/doc/jts-1.7.2/
machine jts-1.7.2 # cp *jar lib/JTS_Test.jar lib/acme.jar ${JAR_DIR}
Notez que JAR_DIR est une variable d'environnement que nous avons déjà utilisé et qui permet de savoir où sont installé les archives binaires jar sur votre système. Voilà tout est en ordre, vous devriez même être capable d'exécuter les binaires que nous avons généré lors de nos tests (cf section précédente) sans avoir à utiliser la variable d'environnement LD_LIBRARY_PATH que nous utilisions du fait que les librairies dynamiques que nous utilisions n'étaient pas encore installées. Comme vous le savez déjà, PostGIS lors de l'exécution du script condigure cherche un utilitaire du doux nom de jts-config, vous savez de plus que la librairie GEOS fournie un tel outils. Nous allons donc le copier dans notre répertoire courant (jts-1.7.2 dans notre exemple) afin de le modifier pour qu'il fournisse les informations nécessaire au bon déroulement de la compilation de PostGIS.
  1. Copie de geos-config et renomage en jts-config :
    machine jts-1.7.2 # cp $(type -P geos-config) ./jts-config
    
  2. Éditez le fichier pour qu'il fournisse les bonnes informations lors de la compilation de PostGIS, ili devrait donc contenir les informations suivantes :
    #!/bin/sh
    prefix=/usr
    exec_prefix=${prefix}
    libdir=${exec_prefix}/lib
    
    usage()
    {
        cat <&2
    fi
    while test $# -gt 0; do
    case "$1" in
        -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
        *) optarg= ;;
    esac
    case $1 in
        --prefix)
        echo ${prefix}
         ;;
        --version)
        echo 1.7.2
         ;;
        --libdir)
          echo ${libdir}
          ;;
        --includedir)
          echo ${prefix}/include
          ;;
        *)
          usage 1 1>&2
          ;;
      esac
      shift
    done
    
  3. Copiez ce fichier dans le répertoire /usr/bin puis donnez lui les droits nécessaires à son exécution :
    machine jts-1.7.2 # cp jts-config /usr/bin
    machine jts-1.7.2 # chmod 755 /usr/bin/jts-config
    
Voilà, si tout déroulé correctement vous devriez maintenant être capable de lancer la commande jts-config. haut de la page | table des matières

Compilation de PostGIS et liaison avec JTS

Mainetant que JTS est convenablement installée, il nous faut encore compiler PostGIS en utilisant cette librairie à la place de GEOS.

Pour ce faire, il suffiit de lancer le script configue avec les options : --with-proj pour activer le support de la reprojection (cf. lwgeom/lwgeom_transform.c du répertoire des source de PostGIS pour plus d'information) et --with-jts=$(type -P jts-config) afin que PostGIS soit informé de notre souhait de compiler la librairie dynamique liblwgeom.so en la liant à la libjts.so.

Pour résuler, il suffit de lancer les commandes ci-dessous :

machine postgis-1.2.1 # ./configure  --prefix=/usr --datadir=/usr/share/postgresql/contrib/ --libdir=/usr/lib/postgresql/ --with-proj --with-jts=$(type -P jts-config)
machine postgis-1.2.1 # make
machine postgis-1.2.1 # make install
Si tout c'est bien passé vous devriez être capable de vérifier si la liaison a été correctement effectué en utilisant l'outil ldd de lma manière suivante :
machine postgis-1.2.1 # ldd /usr/lib/postgresql/liblwgeom.so
        linux-gate.so.1 =>  (0xffffe000)
        libgcj.so.7 => /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/libgcj.so.7 (0xb69df000)
        libjts.so => /usr/X11R6/lib/libjts.so (0xb68aa000)
        libstdc++.so.6 => /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/libstdc++.so.6 (0xb67c8000)
        libproj.so.0 => /usr/X11R6/lib/libproj.so.0 (0xb6796000)
        libgcc_s.so.1 => /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/libgcc_s.so.1 (0xb678a000)
        libc.so.6 => /lib/libc.so.6 (0xb6664000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb664d000)
        libdl.so.2 => /lib/libdl.so.2 (0xb6649000)
        libz.so.1 => /lib/libz.so.1 (0xb6637000)
        /lib/ld-linux.so.2 (0x80000000)
        libm.so.6 => /lib/libm.so.6 (0xb6612000)
Faite ici attention à ne pas avoir de lien cassé, c'est à dire des liens innexistant (des lignes contenant les charactères "not found"). Si le ldd vous a renvoyé les valeurs correctes, vous êtes alors fin prêt à créer votre première base de données spatiales utilisant JTS. Une fois votre base créé, connectez-vous à celle-ci et lancez ces deux commandes afin de vérifier que votre base PostGIS utilise bien JTS et non GEOS :
test_jts=# select postgis_full_version();
                         postgis_full_version     
---------------------------------------------------------------------- 
POSTGIS="1.2.1" JTS="1.7.2" PROJ="Rel. 4.5.0, 22 Oct 2006" USE_STATS
(1 ligne)

test_jts=# select postgis_jts_version(); 
 postgis_jts_version
 --------------------- 
 1.7.2
(1 ligne)
haut de la page | table des matières

Manuels Mapserver

Dans cette section vous trouverez divers manuels concernant l'utilisation de Mapserver.

haut de la page | table des matières

Génération d'une imagemap à partir d'une couche PostGIS

Dans ce manuel nous allons expliquer, dans un premier temps, comment générer simplement une imagemap à l'aide du script cgi mapserv, puis nous expliquerons comment résoudre le problème de génération d'une imagemap cohérente lorsque vous utilisez des éléments area de type POLYGON avec des données de type MULTIPOLYGON.

haut de la page | table des matières

1. Génération d'une imagemap simple

Ici nous présentons comment générer un imagemap pour les communes du Languedoc-Roussillon.

Dans un premier temps nous allons définir la requête à utliser dans la mapfile (plus précisément dans la section DATA de la couche représentant ces communes) afin d'extraire les informations dont nous aurons besoin plus tard :

select gid, LOWER(nom_commun) as nom, numeroinse as value, simplify(the_geom,10) as the_geom from commune_lr ORDER BY gid

ndrpf : vous noterez que nous utilisons ici la fonction PostGIS simplify décrite ici.

Cette couche est supposée de type PostGIS (la couche contient un ligne du type : CONNECTIONTYPE POSTGIS), nous ne mentionnons pas ici la chaîne de connection au serveur PostgreSQL (la ligne CONNECTION) étant donné qu'elle dépend fortement de votre configuration.

Cette couche utilisera les trois modèles suivant :

imagemap_header.html :
pour l'entête (section HEADER de la couche) qui contiendra la ligne :

<map name="mymap">

imagemap_template.html :
pour le corps (section TEMPLATE de la couche), ce modèle sera utilisé pour chaque élément retourné par la requête que nous avons défini ci-dessus, et il contiendra les lignes :

<area shape="polygon" coords="[shpxy precision=0 proj=image] " href="#?[gid]" title="[nom]" alt="[nom]" onmouseover="displayData('[gid]',this.title,'[value]');" style="border: 1px #eee solid;background-color: #aaa;" />

et imagemap_footer.html :
pour le pied de page (section FOOTER de la couche) qui contiendra la ligne :

</map>

Nous vous donnons ci-dessous les lignes de la section format sortie de la mapfile (OUTPUTFORMAT) :

OUTPUTFORMAT
  NAME "imagemap"
  MIMETYPE "text/html"
  DRIVER "imagemap"
  EXTENSION "html"
  IMAGEMODE "PC256"
  TRANSPARENT FALSE
END

Si comme nous vous souhaitez sauvegarder l'imagemap résultante dans un fichier XML nommé imagemap.xml, utilisez la commande ci-dessous afin de récupérer le fichier désiré :

wget -O imagemap.xml "http://127.0.0.1/cgi-bin/mapserv?map=/[chemin]/imagemap.map&qlayer=[couche]&mode=nquery&searchmap=true"

ndrpf : vous noterez que nous utilisons ici le script cgi mapserv par souci de simplicité de ce manuel, néanmoins il est évident que vous pourriez générer l'imagemap en utilisant votre language de programmation préféré si le support mapscript pour ce lanaguage est installé sur votre système.

Nous avons donc maintenant notre imagemap dans le fichier imagemap.xml.

Dans notre page de consultation et plus précisément dans la balise img correspondant à l'image de la carte, il faut lui ajouter l'attribut usemap et y affecter le nom de notre imagemap.

Il va sans dire qu'il faut aussi ajouter le contenu de l'imagemap elle-même. Cela se fait facilement, par exemple si vous utilisez un script php, il vous suffira d'utiliser la commande include.

Dans notre cas, nous aurrons donc dans la page de consultation quelque chose du genre :

<map name="mymap">
[...]
</map>
<img src="ma_carte_generee.png" id="map" width="[ma_largeur]" height="[ma_hauteur]" border="1" style="[mon_style]" usemap="#mymap" />

Si vous souhaitez plus d'information concernant le support des imagemaps pour Mapserver vous pouvez consulter cette page (en anglais).

haut de la page | table des matières

2. Problème avec les géométries de type MULTIPOLYGON

Vous pourriez facilement vous contenter de la section 1 du présent manuel afin de générer des imagemaps. Cependant, si vous utilisez des MULTIPOLYGON, vous devriez rencontrer le problème décrit ici.

En effet dans notre exemple, lors du chargement de la page de consultation avec Firefox 2.0, nous avons eu, dans la console de débogage, le message suivant :

L'attribut « coords » de la balise <area shape="poly"> ne contient pas la dernière coordonnée « y » (le format correct est u00ab x1,y1,x2,y2 … »).
Après consultation de l'imagemap générée à l'étape précédente nous avons effectivement constaté qu'il y avait certaines des balises area qui contenaient un point pour le moins étrange ayant trois coordonnées... En effet, si vous essayez de générer une imagemap à partir d'une couche PostGIS qui contient des MULTIPOLYGON avec une version 4.10.1 de Mapserver, vous rencontrerez alors ce type problème pour tout les MULTIPOLYGON qui contiennent plus d'une composante (c'est-à-dire plus d'un POLYGON). Vous pouvez obtenir cette information en utilisant la fonction NumGeometries (décrite ici) ou encore avec Summary (décrite ici). Il est facile de récupérer l'ensemble des lignes contenant une balise area de type polygon ayant un "point" à trois composantes à l'aide de la commande suivante :
# grep "[1-9]*,[1-9]*,[1-9]*" /chemin/vers/votre/imagemap.xml
Pour résoudre ce problème je me suis contenté d'éditer le fichier maptemplate.c pour y modifier les lignes 1144 et 1148 pour qu'elles contiennent, repectivement :
pointFormatLength = strlen("xh") + strlen("xf") + strlen("yh") + strlen("yf") + strlen("cs") + 10 + 2;
et
snprintf(pointFormat2, pointFormatLength, "%s%%.%dlf%s%s%%.%dlf%s ", xh, precision, xf, yh, precision, yf);
Une fois ceci fait, il vous faut bien entendu recompiler Mapserver afin que les modifications apportées soient prises en compte. Une fois le nouveau binaire mapserv créé et copié dans le répertoire cgi-bin de votre serveur web, il vous suffit de relancer la commande pour récupérer l'imagemap générée. Lors de vos modifications, vous pouvez utiliser un autre nom que mapserv pour le programme cgi, par exemple mapserv<version> afin de garantir que les applications utilisant l'ancienne version (mapserv) continuent de fonctionner sans problème. Ainsi si vous faisiez une erreur, l'ensemble de vos applciations ne serait pas touché. En effet, les modifications décrites ici sont appliquées à la fonction processCoords qui est responsable du remplacement de shpxy dans les modèles par les coordonnées correspondantes, ce qui peut avoir des incidences suivant l'utilisation qui est faite de la variable shpxy. De plus, cette modification n'a été apportée que pour modifier le comportement de Mapserver lors de la génération d'imagemap pour des géométries de type MULTIPOLYGON qui posaient problème. Nous ne nous sommes pas encore penchés sur l'ensemble des incidences que cette modification pouvait avoir sur le comportement général de Mapserver. Vous pouvez vérifier que l'imagemap ainsi générée est correcte avec la même commande que précédemment, qui ne devrait rien renvoyer si tout s'est bien passé. haut de la page | table des matières

PostGIS.fr au Colloque SIG Libres : Logiciels et données, Services géographiques de Toulouse.

Même si je suis resté relativement discret, j'étais là! Et c'est avec plaisir que je fais un résumé de ce colloque sur le site.

Étant un inconditionnel du logiciel libre (on va dire ll à partir de maintenant), certains diront un extremiste, je vais essayé de rester le plus impartial possible (et c'est pas gagné)...

Le programme est disponible ici: Colloque Logiciel SIG libres
libre1

Je vais faire un petit résumé sur chaque intervention, la plupart du temps je n'ai fait que noter les remarques importantes et un résumé des présentations (que du powerpoint grrrr...) dont certaines sont disponibles en lien pdf.

Je rajouterais une impression très personnel sur la forme de la presentation et sa qualité (oui oui je fais critique aussi Smiling )...

Enfin je parlerais également de la table ronde, je regrette de ne pas avoir pris plus de note au cours de cette table ronde: de nombreuses affirmations m'ont fait bondir de mon siège (je tiens d'ailleurs à m'excuser pour mes voisins de derrière), ou bien m'ont fait faire une mou perplexe, voir parfois un sourire grimaçant...

Bref c'est parti...

haut de la page | table des matières

Accueil, ambiance générale et organisation

J'arrive avec un bon quart d'heure d'avance (accueil de 9h à 9h30), et déjà il y a beaucoup de monde, un peu de queue pour me faire badger (l'attente est devenu bien pire au fur et à mesure), et zou au buffet:
café, thé, jus de fruit, viennoiseries (mais pourquoi j'ai pris un petit déjeuner avant ).
Le personnel d'accueil est souriant et chaleureux, les professeurs de l'association disponibles, bref l'organisation est parfaite tout au long de la journée.
Le repas de midi est un buffet froid de très bonne qualité, il y a même un apéro a la fin de la journée, parfait je vous dit.

haut de la page | table des matières

Le monde du libre _ Jean-Christophe BECQUET (APITUX)

Première présentation sous forme de présentation et définition du ll, mené par Jean-Christophe BECQUET (APITUX Formation et conseil en logiciel libre).
Sa présentation est disponible ici : le monde du libre.
Là je vous la fait courte puisqu'on a la présentation:

Cette présentation fut très claire et très simple, quoique qu'un peu longue pour les afficionados, mais elle fait le tour de la question de manière exhaustive.
La présentation suivante s'interesse plus précisement aux logiciels libres SIG.

haut de la page | table des matières

PostgreSQL et Stunnel

Introduction

Pour protéger ses données lors d'une connexion entre un serveur et un client avec PostgreSQL, plusieurs solutions existent: soit en utilisant PostgreSQL compilé avec OpenSSL en natif, utiliser un tunnel SSH avec redirection de Port ect...Un des moyens que j'aime bien est d'utiliser Stunnel/OpenSSL.

Stunnel est une enveloppe SSL, permettant donc d'étendre les fonctionnalités de SSL à un démon qui à l'origine n'est pas prévu pour être une couche de sécurité. On peut donc par exemple créer une connexion sécurisée entre vers une base de données, consolidant ainsi la connexion du système.

Un autre intérêt de l'installation avec Stunnel est qu'il peut-être installé en tant que service (automatiquement relancé au démarrage de la machine). Ce que ne propose pas une redirection par SSH. Je ne propose pas ici l'installation de stunnel avec xinetd, trop contrariant à mon sens.

Pré-requis

Je pars du principe ici que les configurations réseaux avec PostgreSQL sont acquises par le lecteur. Pour les test ici, nous aurons besoin de deux machines. Sur mon réseau domestique, j'ai deux machines dont les noms sont respectivement jenna et bremko:

Pour vérifier que les données sont bien chiffrées où non, nous avons besoin d'installer un sniffer comme nast ou etherreal (...) entre jenna et bremko! J'opte ici pour NAST (Network Analize Sniffer Tool/http://nast.berlios.de/) que j'installe en faisant - en tant que root - sur bremko -

apt-get install nast

Pour les besoins de mes tests, je crée un super-utilisateur damien sur jenna dont le mot de passe sera 'morphine'

root@jenna:/root$ su postgres
postgres@jenna:/root$createuser -sEPe damien
Entrez le mot de passe pour le nouvel rôle :
Entrez-le de nouveau :
CREATE ROLE damien ENCRYPTED PASSWORD 'morphine' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;
CREATE ROLE

Motivations: sniffer une connexion non sécurisée avec NAST, limites d'une connexion par mot de passe en md5!

Test sans mot de passe

Commençons donc par vérifier que si je laisse le mot de passe par défaut sur à 'password' sur le réseau on arrive quand même à le récupérer. Pour celà, dans le pg_hba.conf de jenna, je fais la modification suivante

host 192.168.0.4 255.255.255.255 password

et je redémarre ensuite mon serveur

/etc/init.d/postgresql restart

Sur bremko, dans un terminal pour sniffer les connexion je fais

nast -i eth0 -pd -f "dst 192.168.0.5" -f  "port 5432"

Dans un autre terminal (toujous depuis bremko), j'ouvre ma connexion à jenna en faisant

psql -h jenna -U damien template1

Dans le terminal que contient le processus actif de nast, je vois a un moment passé le message

---[ TCP Data ]------------------------------------------------------

   (    user damien database template1
---[ TCP ]-----------------------------------------------------------
192.168.0.5:5432(postgresql) -> 192.168.0.4:50884(unknown)
TTL: 64         Window: 1448    Version: 4      Lenght: 61
FLAGS: ---PA--  SEQ: 1495197601 - ACK: 923679297
Packet Number: 26

---[ TCP Data ]------------------------------------------------------

R
---[ TCP ]-----------------------------------------------------------
192.168.0.4:50884(unknown) -> 192.168.0.5:5432(postgresql)
TTL: 64         Window: 1460    Version: 4      Lenght: 66
FLAGS: ---PA--  SEQ: 923679297 - ACK: 1495197610
Packet Number: 27

---[ TCP Data ]------------------------------------------------------

morphine
---[ TCP ]-----------------------------------------------------------

preuve que ça ne suffit pas!

Test avec MD5

Allons donc! Changeons donc le mot-clé 'password' par 'md5' dans le fichier pg_hba.conf de jenna

host 192.168.0.4 255.255.255.255 md5

et redémarrons le serveur (/etc/init.d/postgresql restart). Relançons donc une connexion au serveur depusi bremko. Maintenant depuis nast, j'obtiens

---[ TCP Data ]------------------------------------------------------

   (    user damien database template1
---[ TCP ]-----------------------------------------------------------
192.168.0.5:5432(postgresql) -> 192.168.0.4:45585(unknown)
TTL: 64         Window: 1448    Version: 4      Lenght: 65
FLAGS: ---PA--  SEQ: 1852264915 - ACK: 1258303094
Packet Number: 85

---[ TCP Data ]------------------------------------------------------

R         +F
---[ TCP ]-----------------------------------------------------------
192.168.0.4:45585(unknown) -> 192.168.0.5:5432(postgresql)
TTL: 64         Window: 1460    Version: 4      Lenght: 93
FLAGS: ---PA--  SEQ: 1258303094 - ACK: 1852264928
Packet Number: 86

---[ TCP Data ]------------------------------------------------------

p   (md5063971165646bb85c855953e66c01196
---[ TCP ]-----------------------------------------------------------

Gagné! Enfin ne nous réjouissons pas trop vite car si je tape une requête depuis le client je vois apparaître par exemple

---[ TCP Data ]------------------------------------------------------

Q   %select * from geometry_columns ;
---[ TCP ]-----------------------------------------------------------
192.168.0.5:5432(postgresql) -> 192.168.0.4:48508(unknown)
TTL: 64         Window: 6091    Version: 4      Lenght: 52
FLAGS: ----A--  SEQ: 2056534420 - ACK: 1484467451
Packet Number: 161

---[ TCP ]-----------------------------------------------------------
192.168.0.5:5432(postgresql) -> 192.168.0.4:48508(unknown)
TTL: 64         Window: 6091    Version: 4      Lenght: 1500
FLAGS: ----A--  SEQ: 2056534420 - ACK: 1484467451
Packet Number: 162

---[ TCP Data ]------------------------------------------------------

T      f_table_catalog                   f_table_schema                   f_table_name                   f_geometry_column                  
 coord_dimension                   srid                   type                "  D   E          public    apb_lr    the_geom    2   
 -1    MULTIPOLYGOND   U          public   a_cours_d_eau_n2_v3    the_geom    2    -1    MULTILINESTRING

Oups!

En effet, depuis bremko j'ai envoyé la requête

selectfrom geometry_columns

à jenna. Les résultats me sont envoyés en claire comme me le confirme la ligne 192.168.0.5:5432(postgresql) 192.168.0.4:48508(unknown) ainsi que le reste des résultats.

Première conclusion: Bon md5 protège bien mon mot de passe mais pas mes requêtes ainsi que les résultats renvoyés par le serveur! Et c'est là justement qu'intervient Stunnel!

Stunnel: sécurisation de la connexion

Nous devons commencer par installer OpenSSL pour utiliser Stunnel par la suite

Pré-requis: OpenSSL

Stunnel a besoin de OpenSSL pour pouvoir fonctionner

apt-get install openssl libssl-dev

Installation de Stunnel

Le site de stunnel est http://www.stunnel.org. Nous aurons besoin ici de l'installer à la fois sur le serveur et sur le client. Je fournis ici les commandes que j'ai utilisé pour l'installer sans plus de détails

wget http://www.stunnel.org/download/stunnel/src/stunnel-4.20.tar.gz
tar xvzf  stunnel-4.20.tar.gz
cd stunnel-4.20
./configure --with-ssl=/usr --prefix=/opt/stunnel
make
make install

L'installation aura donc lieu ici dans le répertoire /opt/stunnelmais vous pouvez l'installer où bon vous semble.

Lors de l'installation, un certificat auto-signé stunnel.pem sera généré dont voici une copie d'écran de ce que j'ai renseigné pour jenna

Generating a 1024 bit RSA private key
.................++++++
............++++++
writing new private key to 'stunnel.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [PL]:FR
State or Province Name (full name) [Some-State]:Hérault
Locality Name (eg, city) []:Castelnau-Le-Lez
Organization Name (eg, company) [Stunnel Developers Ltd]:01MAP
Organizational Unit Name (eg, section) []:01MAP
Common Name (FQDN of your server) [localhost]:jenna

Je renouvelle l'installaltion sur bremko, en changeant la ligne Common Name (FQDN of your server) [localhost]:bremko

Le certificat autu-signé stunnel.pem est utilisé ici uniquement sur la base de test et pour les besoins de l'article. Il pourra être remplacé plus tard par un certificat signé par une autorité de certification (CA).

Mise en oeuvre

J'ouvre maintenant un terminal sur jenna et j'y tape

root@jenna:/opt/stunnel/sbin/stunnel3 -D 7 -f -P /opt/stunnel/stunnel.pid \
-o /opt/stunnel/stunnel.log -p /opt/stunnel/etc/stunnel/stunnel.pem -d 9000 -r localhost:5432

avec les options suivantes:

  • -D 7: pour spécifier le niveau de déboggage afin de collecter le maximum d'informatios;

  • -f: me permet de faire tourner le processus en arrière-plan dans le terminal. Un simple [CTRL]+[C] me suffira
    donc pour arrêter le processus si besoin est;

  • -P /opt/stunnel/stunnel.pid pour le PID du processus;

  • -o /opt/stunnel/stunnel.log pour spécifier un fichier de log;

  • -p /opt/stunnel/etc/stunnel/stunnel.pem pour le certificat auto-signé

  • Un processus démon de Stunnel par cette commande est donc lancée. Le paramètre -d 9000 est le port d'écoute du démon et lui demande d'attendres de données chiffrées sur ce port. Le paramètre -r localhost:5432 indique au démon que les données reçues sur son port d'écoute (9000), il devra les déchiffrer et les envoyer sur le port 5432 de la machine locale. Or ce dernier port n'est autre que le port d'écoute du serveur PostgreSQL sur jenna.

    Sur bremko, je lance

    root@bremko:/opt/stunnel# /opt/stunnel/sbin/stunnel3 -D 7 -f \
    -P/opt/stunnel/stunnel.pid -o /opt/stunnel/log/stunnel.log -c -d localhost:5433 \
     -c -d localhost:5433 -r 192.168.0.5:9000

    Dans la commande précédente c'estla potion -c -d localhost:5433 -r 192.168.0.5:9000 qui nous intéresse. Une instance de Stunnel est ainsi lancée en mode client grâce au paramètre c et lui demander d'écouter sur le port 5433.Le paramètre -r 192.168.0.5:9000 indique à cette instance que la machine-serveur (jenna) a pour adresse 192.168.0.5 et que son port d'écoute est le 9000.

    Pour m'assurer que les connexions seront chiffrées dans un troisème terminal sur bremko, je fais

    nast -pd -i eth0 -f "dst 192.168.0.5" -f "port 9000"

    Dans un nouveau terminal toujours - sur bremko - j'ouvre maintenant une connexon PostgreSQL en faisant

    psql -h localhost -p 5433 -U damien direnlr

    Je saisis quelques requêtes et j'apprécie le travail en regardant les lignes retournées par nast depuis le troisième terminal en question. Par exemple pour la requête

    direnlr=# select * from geometry_columns limit 1;
    -[ RECORD 1 ]-----+-------------
    f_table_catalog   |
    f_table_schema    | public
    f_table_name      | apb_lr
    f_geometry_column | the_geom
    coord_dimension   | 2
    srid              | -1
    type              | MULTIPOLYGON
    

    j'obtiens avec nast

    ---[ TCP ]-----------------------------------------------------------
    192.168.0.4:45480(unknown) -> 192.168.0.5:9000(unknown)
    TTL: 64         Window: 2546    Version: 4      Lenght: 126
    FLAGS: ---PA--  SEQ: 2814905551 - ACK: 2149157549
    Packet Number: 1
    
    ---[ TCP Data ]------------------------------------------------------
    
            ' jP;o  , 9     e nH}  .
    ---[ TCP ]-----------------------------------------------------------
    192.168.0.5:9000(unknown) -> 192.168.0.4:45480(unknown)
    TTL: 64         Window: 1984    Version: 4      Lenght: 126
    FLAGS: ---PA--  SEQ: 2149157549 - ACK: 2814905625
    Packet Number: 2
    
    ---[ TCP Data ]------------------------------------------------------
    
          D n~  %   N 4; r M   { g.X= > q     v 1     -N{W   u @  A 9 *4l   _K
    ---[ TCP ]-----------------------------------------------------------
    192.168.0.4:45480(unknown) -> 192.168.0.5:9000(unknown)
    TTL: 64         Window: 2546    Version: 4      Lenght: 52
    FLAGS: ----A--  SEQ: 2814905625 - ACK: 2149157623
    Packet Number: 3

    Installation en service de Stunnel

    Pour l'installation en service sur les deux machines, il suffit de modifer le script de démarrage de Ubuntu à savoir /etc/init.d/rc.local. J'y ai par exemple effectuer les modifications suivantes sur jenna

    #! /bin/sh
    # Modications du PATH pour accéder à stunnel
    PATH=/sbin:/bin:/usr/sbin:/usr/bin:/opt/stunnel/sbin
    [ -f /etc/default/rcS ] && . /etc/default/rcS
    . /lib/lsb/init-functions
    
    do_start() {
            if [ -x /etc/rc.local ]; then
                    log_begin_msg "Running local boot scripts (/etc/rc.local)"
                    /etc/rc.local
                    log_end_msg $?
            fi
    }
    # Ma ligne pour lancer stunnel sur jenna (Serveur PostgreSQL)
    # à adapter en conséquence sur bremko (voir ci-dessus dans la doc)
    /opt/stunnel/sbin/stunnel3 -D 7 -f -P /opt/stunnel/stunnel.pid -p /opt/stunnel/etc/stunnel/stunnel.pem -d 9000 -r localhost:5432 -o /opt/stunnel/log/stunnel.log
    
    case "$1" in
        start)
            do_start
            ;;
        restart|reload|force-reload)
            echo "Error: argument '$1' not supported" >&2
            exit 3
            ;;
        stop)
            ;;
        *)
            echo "Usage: $0 start|stop" >&2
            exit 3
            ;;
    esac

    Ne pas oublier d'adapter votre script de démarrage (/etc/init.d/rc.local (pour Ubuntu) ou /etc/rc.d/rc.local...) sur la machine-cliente pour le commande

    /opt/stunnel/sbin/stunnel3 -D 7 -f \
    -P/opt/stunnel/stunnel.pid -o /opt/stunnel/log/stunnel.log -c -d localhost:5433 \
    -o /opt/stunnel/log/stunnel.log -c -d localhost:5433 -r 192.168.0.5:9000

    Pour aller plus loin

    Il est tout à fait possible avec Stunnel d'utiliser le fichier de configuration de stunnel dans /opt/stunnel/etc/stunnel ou lui proposer un fichier personnel de configuration. Je ne me suis pas attarder à le proposer dans cette article afin de ne pas trop le surcharger.

    haut de la page | table des matières

    Sécurisation simple en utilisant un tunnel ssh

    Dans cette documentation nous allons vous montrer comment sécuriser simplement et efficacement une connexion à un serveur de bases de données PostgreSQL qui n'écoute que le réseau local ou même uniquement sur son adresse de loopback.

    haut de la page | table des matières

    Prérequis

    Pour être à même d'utiliser ce manuel, il vous faudra un serveur PostgreSQL installé sur une machine ayant aussi un serveur OpenSSH, ce qui est le cas sur des systèmes GNU/Linux, pour les utilisateurs de plateformes win32 vous pouvez vous reportez à cette documentation afin d'installer et de configurer votre serveur OpenSSH sur votre serveur Windows™.
    Il vous faudra de plus un client OpenSSH disponible par défaut sur les plateformes GNU/Linux et Unix. La documentation mentionnée précédament peut aussi être utilisée afin d'installer le client OpenSSH (il est contenu dans la distribution OpenSSH utilisée pour installer le serveur SSH).

    haut de la page | table des matières

    Démarrage du serveur PostgreSQL

    Nous expliqons ici comment lancer le serveur PostgreSQL qui n'écoute que sur l'adresse local de la machine (cad l'adresse de loopback : 127.0.0.1) :

    # pg_ctl start

    Nous supposons ici que vous avez affecté une valeur à la variable d'environnement PGDATA spécifiant où se trouve le répertoire d'installation de votre système de gestion de bases de données PostgreSQL (se qui fait simplement en utilisant la commandes suivantes : export PGDATA="/var/lib/postgres/data" pour les système Unix et GNU/Linux ou set PGDATA=\PostgreSQL\8.2\data dans une invite de commande cmd sur plateforme win32).

    Nous allons maintenant vérifier que le serveur écoute belle et bien uniquement sur l'adresse de loopback et sur le socket de domaine unix (qui nous garanti lui aussi qu'aucune connexion n'est possible de l'extérieur). Pour ce faire nous allons simplement utiliser la commande netstat existante aussi bien sur les systèmes Unix et GNU/Linux que sur plateformes win32 de la manière suivante :

    # netsta -na | grep 5432
    tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN
    unix 2 [ ACC ] STREAM LISTENING 16088006 /tmp/.s.PGSQL.5432

    Nous sommes donc sûr que notre serveur PostgreSQL n'écoute que sur le socket de domaine Unix et sur l'adresse de loopback. Si vous avez quelque chose comme 0.0.0.0:5432 c'est sans doute que vous avez lancé le serveur PostgreSQL avec l'option -i qui stipule que le serveur doit écouter sur l'ensemble des adresses réseau disponible. Cela revient à affecter la valeur * au paramètre de configuration listen_addresses, comme cela est mentionné dans la page de manuel de postmaster.

    haut de la page | table des matières

    Création du tunnel ssh

    Maintenant que nous avons lancé le serveur PostgreSQL est que nous nous sommes assuré que ce dernier n'écouté que sur l'adresse local de la machine, il nous semle alors dificile d'accéder à distance au serveur de bases de données. Pourtant nous allons vous montrer combien il est simple d'y accéder si on a un compte utilisateur sur la machine utilisée comme serveur de bases de données.
    Si vous vous connectez à la machine utilisée comme serveur de bases de données, vous pourrez toujours utiliser les outils en lignes de commande pour interragir avec vos données, c'est souvent bien suffisant. Néanmoins, la plupart des utilisateurs préfèrent utiliser des outils graphique pour interragir avec leurs données, c'est pourquoi nous allons vous montrer ici comment utiliser un tunnel ssh afin de vous connecter à distance avec des outils graphiques comme par exemple pgAdmin.
    La première chose à faire est de créer un tunnel ssh entre votre machine (celle à partir de laquelle vous voulez vous connecter au serveur PostgreSQL) et la machine utilisée comme serveur PostgreSQL. Ce n'est pas très compliqué et cela peut être trouvé facilement dans la page de manuel de OpenSSH.
    # ssh -L 5432:127.0.0.1:5432 utilisateur@serveur
    Dans la commande ci-dessus, vous devez remplacer utilisateur par le nom de votre compte Unix et serveur par le nom ou l'adresse ip du serveur PostgreSQL. Vous pouvez de plus utiliser le premier numéro dee port que vous souhaitez, il suffira d'utliser le même pour les paramètres de connexion mentionnés ci-dessous.
    Notez de plus que si vous utilisez la commande netstat -na vu précédament sur votre propre machine, une fois le tunnel ssh ouvert vous avez effectivement ouvert le port 5432 sur votre adresse local, ce qui vous permet donc d'être sur de pouvoir vous conecter de façon sécurisée à votre serveur de bases de donées PostgreSQL.
    Au moment ou vous aurez lancé cette commande, et temps que cette connexion reste ouverte, vous serez alors capable de vous connecter au serveur distant en utilisant les paramètres de configuration suivant :

    Nous ne mentionnons pas ici les autre paramètres car ils sont identique aux paramètres de connexion que vous utilisez pour vous connecter localement au serveur PostgreSQL.

    haut de la page | table des matières