Ce document vous explique comment contribuer à la rédaction de documentations pour le site PostGIS.fr.
haut de la page | table des matières: 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.
Ce document vous explique comment contribuer à la rédaction de documentations pour le site PostGIS.fr.
haut de la page | table des matièresAvant 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 ).
haut de la page | table des matièresDans 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èresAfin 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 :
Lorsque vous souhaitez lister un ensemble de fonctions dans une documentation vous devez utiliser la syntaxe suivante :
description
</dd>
<dt><span class="term"> nom d'une autre fonction : </span></dt>
<dd>
une autre description
</dd>
[...]
</dl>
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 :
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èresLe 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 :
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:
Pour procéder aux installations, il faudra avoir le compte root de la machine.
haut de la page | table des matièresNous 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 :
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èresAfin 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 :
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...)
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
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 :
geos-config --version
, devrait nous renvoyer 2.1.1
.
haut de la page | table des matières On va commencer par PostgreSQL. Nous nous occuperons de PostGIS plus tard.
On s'occupe maintenant de PostGIS
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 :
indiquant que PostgreSQL a bien été installé dans le répertoire /usr/local et que la version en cours est la 8.0.2.
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 ...).
Tout démarrage/arrêt doit être effectuer sous la session (terminal) de l'utilisateur postgres. On utilisera pour ce faire la commande :
su postgres -c "pg_ctl -o -i -D /home/postgres/pgdata start"
su postgres -c "pg_ctl -o -i -D /home/postgres/pgdata stop"
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
C'est une installation usuelle comme pour Geos et Proj:
ici, nous allons procéder à l'installation de PHP, puis sa configuration avec Apache en tant que CGI (Common Gateway Interface).
Si on souhaite vérifier que PHP a été installé, on effectuera le test suivant php-config --version
qui nous renverra 4.3.11
.
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
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.
C'est ici une installation standard
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
C'est l'avant-dernier outil à installer
La commande suivante for i in 'version' 'prefix'; do gdal-config --$i;done
, doit renvoyer comme résultat :
1.2.0
/usr/local
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
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 -
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`
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èresIci, 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èresL'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
On s'assurera d'abord que le serveur PostgreSQL est bien démarré en faisant
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.
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
Cette librairie contient l'implémentation des algortihmes suivants :
La documentation originale peut être trouvée ici.
É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 :
Pour augmenter la rapiditer d'exécution, créez des index pour la table kanagawa.
Chargez le fichier sql routing.sql pour installer les fonctions dans votre base de données
Charger le fichier routing_postgis.sql qui créera les fonctions PostGIS d'import et de manipulation des données.
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 :
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èresLes 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 :
La sortie devrait ressembler à cela :
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èresLa 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_resultLes arguments sont les suivants :
SELECT id, source, target, cost FROM edge_table;
has_reverse_cost
à vrai.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.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
La fonction shortest_path_astar
est définie de la façon suivante :
Les arguments sont :
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. Il y a une ligne pour chaque arc traversé et une en plus contenant le noeud terminal. Les colonnes de chaque lignes sont :
Exemple:
La fonction shortest_path_shooting_star
est définie de la façon suivante :
Les arguments sont :
to_cost
)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:
La fonction driving_distance est définie comme suit :
Les arguments sont :
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 :
Exemple:
La fonction tsp
est définie comme suit :
Les arguments sont :
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:
Ensuite la colonne vertex_id peut être utilisée pour le calcul du plus court chemin.
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".
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)
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.
Ensuite, pour agmenter le coût inverse de l'arc n°2 , une valeur de 1000000 sera ajouter à la valeur de la colonne rcoast.
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)
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 :
shp2pgsql
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 :
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 :
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 :
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 :
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 :
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.
(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 :
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èresRé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èresPostGIS 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èresVoici la liste des traducteurs du manuel PostGIS :
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èresPour être compilé et utilisé, PostGIS nécessite l'ensemble des outils suivants.
Nécessaires :
ST_Touches()
, ST_Contains()
, ST_Intersects()
) et les opérations (ST_Buffer()
, ST_GeomUnion()
, ST_Difference()
) avec PostGIS. GEOS est disponible en téléchargement depuis http://geos.refractions.net.Optionnels :
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.
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/.
Rendez-vous dans le nouveau répertoire postgis-1.4.0
pour continuer l'installation.
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.
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.
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 :
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
.
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.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=/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.shp2pgsql
intitulée : shp2pgsql-gui
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é.
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
Si vous souhaitez tester votre compilation de PostGIS, lancez la commande suivante
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.
LD_LIBRARY_PATH
.
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 :
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
Pour installer PostGIS, lancez la commande suivante :
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 :
[prefix]/bin
.[prefix]/share/contrib/
.[prefix]/lib
.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 :
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
.
La première étape pour créer une base de données PostGIS est de créer une simple base de données PostgreSQL.
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.
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).
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.
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
.
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 :
Pour le code SQL :
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.
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'.
La mise à jour 'légère' consiste à charger le script lwpostgis_upgrade.sql
dans votre base de données
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 :
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")
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
:
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
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 !!!
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 :
Il y a plusieurs choses à vérifier lorsque votre installation ou votre mise à jour ne se déroule pas comme prévu.
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.
postgis_config.h
. Vérifiez que les vairables POSTGIS_PGSQL_VERSION
, POSTGIS_PROJ_VERSION
et POSTGIS_GEOS_VERSION
ont la bonne valeur. 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.
java/jdbc
des sources de PostGIS.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 :
Les pilote JDBC PostgreSQL peuvent être télécharger depuis la page suivante : http://jdbc.postgresql.org.
haut de la page | table des matièresL'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 :
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èresVous 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èresAvant 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 :
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 :
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 :
Le résultat obtenu devrait ressembler à quelque chose comme ça :
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.
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 :
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é).
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()
.
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) :
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.
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 :
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).
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.
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 :
Par exemple, voici des commandes valides pour créer et insérer des objets géographiques OGC :
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 :
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 :
Par exemple cette requêtes lit du EWKT
et renvoie du HEXEWKB
dans le processus d'entrée/sortie canonique ascii
:
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 :
CIRCULARSTRING
est le type de base des courbes, semblable à un élément de type LINESTRING
dans le monde linéaire. Un ségment seul nécessite 3 points, les points de départ et d'arrivé (le premier et le troisième) et un autre point sur l'arc. À l'exception des cercles fermés, pour lesquels le poinr de départ et d'arrivé sont les mêmes.Dans ce cas, le deuxième point DOIT être le centre du cercle. Pour assembler les arcs ensemble, le dernier point du l'arc précédent devient le premier du suivant, exactement comme pour les géométries de type LINESTRING
. Cela signifie qu'une chaîne circulaire valide doit avoir un nombre impair de points supérieur à 1.
CURVEPOLYGON
est simplement un polygone, avec une partie extérieure et aucune ou plusieurs parties intérieures. La différence réside dans le fait que les différentes parties qui composent le polygone sont des courbes, des lignes ou des courbes composées.MULTICURVE
est une collection de courbes, qui peut contenir des lignes, des courbes et des courbes composées.
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
.
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èresLa 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 :
Et voici les colonnes de SPATIAL_REF_SYS :
Pour une liste des codes de projection EPSG et leur correspondance en WKT, suivez ce lien. Pour des explications sur le WKT, voir OpenGIS "Coordinate Transformation Services Implementation Specification".
Pour des informations sur "the European Petroleum Survey Group" (EPSG) et leur base de SRS voir ceci.
+proj=utm +zone=10 +ellps=clrk66 +datum=NAD27 +units=m
Le fichier spatial_ref_sys.sql contient les définitions de SRTEXT et de PROJ4TEXT pour toutes les projections EPSG.
La définition de la table GEOMETRY_COLUMNS est la suivante :
Les colonnes sont les suivantes :
Créer une table avec des données géographiques se déroule en deux étapes :
CREATE TABLE ROADS_GEOM ( ID int4, NAME varchar(25) )
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à) :
Voici un autre exemple, utilisant le type générique "geometry" et un SRID indéfinie de valeur -1 :
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()
:
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 :
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.
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èresSi 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 :
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
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 :
Une conversion et une importation des données peuvent être faites en une seule étape en utilisant les tubes UNIX :
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èresL'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 :
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 :
&&
: Cet opérateur vérifie si "le cadre limite d'un objet géométrique intersecte celui d'un autre".~=
: Cet opérateur vérifie si deux objets géométriques sont géographiquement identique. Par exemple, 'POLYGON((0 0,1 1,1 0,0 0))' est géographiquement identique à 'POLYGON((0 0,1 1,1 0,0 0))' (c'est le cas).=
: Cet opérateur est un peu moins naïf, il vérifie uniquement si les cadres limites des objets géographiques sont les mêmes.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 :
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.
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 :
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.
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 :
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. |
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).
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 :
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 :
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.
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 :
update_geometry_stats([nom_de_la_table, nom_de_colonne])
(calcul la distribution) et VACUUM ANALYZE [nom_de_la_table] [nom_de_colonne]
(calcul le nombre de valeurs). À partir de PostgreSQL 8.0, exécuter VACUUM ANALYZE
suffit pour effectuer les deux opérations. De toute manière, vous pouvez régulièrement nettoyer votre base de données - plusieurs administrateurs de base de données PostgreSQL exécutent dans leur crontab un nettoyage via VACUUM
.SET ENABLE_SEQSCAN=OFF
. Vous devez utiliser cette commande avec parcimonie, et uniquement des requêtes spatialement indexées : plus généralement, le planificateur de requêtes connait mieux que vous lorsqu'il faut utiliser normalement l'arbre B. Une fois que vous avez effectué votre requête, vous pouvez réaffecter la valeur initiale de ENABLE_SEQSCAN
, de sorte que les autres requêtes utiliseront normalement le planificateur.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.
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èresLorsque 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 :
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 :
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é.
ST_Disjoint
and ST_Relate
, utilisent implicitement l'opérateur de superposition du cadre limite.
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 :
La définition pour la table bc_minicipalitees est la suivante :
Vous pouvez répondre à cette question avec une requête SQL simple :
longueur_routes_en_km
------------------
70842.1243039643
(1 row)
Cette requête combine une condition attributaire (sur le nom de la municipalité) avec un calcul spatial (de l'aire) :
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 :
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()
.
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 :
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.
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 :
Minnesota Mapserver est un serveur cartographique Internet qui se conforme aux spécifications "Web Mapping Server" de l'OpenGIS.
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).
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".
Contrairement aux fichiers vecteurs (shapefile), les noms de champs PostGIS doivent être référencés dans EXPRESSIONS en utilisant des lettres en minuscule.
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).
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.
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);
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 :
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
.
Commençons avec un exemple simple et qui nous servira de base pour la suite. Considérons la définition de couche Mapserver suivante :
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 :
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.
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
.
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".
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.
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.
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
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 :
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:
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èresPour 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 :
Comme le message vous le spécifie, on peut contourner cet inconvénient en ajoutant une contrainte NOT NULLl
à la 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.
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 :
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.
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èresSyntax : 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
.
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
.
Attribut au SRID
sur une géométrie une valeur entière particulière. Utile pour construire des cadres limites pour des requêtes.
Renvoie la distance cartésienne entre deux géométries dans l'unité de projection.
(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
(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****')
(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 ))
(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
(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******')
(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***')
(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
(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)
(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
(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
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).
Renvoie la superficie de l'entité géométrique s'il s'agit d'un polygone ou d'un multi-polygone.
Renvoie la longueur d'un segment dans son système de référencement courant. Synonyme de length2d()
.
OGC SPEC 2.1.5.1
Renvoie un point situé en surface.
Implémenté grâce à GEOS.
OGC SPEC 3.2.14.2 and 3.2.18.2 -
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
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
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
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
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
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
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
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
Identique à la fonction ci-dessus, mais travaille en utilisant moins de mémoire et plus de temps de calcul du processeur.
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
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(
et asBinary(
Renvoie l'entier SRID
du système de référence spatial de l'objet géométrique.
OGC SPEC s2.1.1.1
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.
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.
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
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
Renvoie vrai si les points de départ et d'arrivée de l'objet géométrique coïncident.
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
Si la géométrie est une GEOMETRYCOLLECTION
(or MULTI*
) renvoie le nombre d'objets géométriques, autrement renvoie NULL
.
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.
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.
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.
Renvoie le pourtour extérieur de la géométrie d'un polygone. Retourne NULL
si l'objet n'est pas un polygone.
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.
É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.
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.
Renvoie le dernier point d'une ligne géométrique en tant que point.
Renvoie le premier point d'une ligne géométrique en tant que point.
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.
Renvoie la coordonnée X
du point. L'objet en entrée doit être un point.
Renvoie la coordonnée Y
du point. L'objet en entrée doit être un point.
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.
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.
POINT
.LINE
.LINE
.POLYGON
.MULTIPOINT
.MULTILINESTRING
.MULTIPOLYGON
.GEOMETRYCOLLECTION
.POINT
.LINESTRING
.LINESTRING
.POLYGON
.POLYGON
.MULTIPOINT
.MULTILINESTRING
.MULTIPOLYGON
.GEOMETRYCOLLECTION
.MULTILINESTRING
. Retourne une erreur si la sortie est un MULTIPOLYGON
; utilisez BdMPolyFromText dans ce cas, ou voyez BuildArea() pour une approche spécifique à PostGIS.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.geometry_columns
.current_schema()
pour des installations de PostgreSQL supportant les schémas si le schéma n'est spécifié.
current_schema()
sur des installations PostgreSQL supportant les schémas si le schéma n'est pas spécifié.
VACUUM ANALYZE [nom_de_la_table] [nom_de_colonne]
pour compléter le processus de rapatriement des statistiques.VACUUM ANALYZE
.
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.
postgis_lib_version()
. Conservé pour des raisons de compatibilité arrière.
SPHEROID[<NAME>,<SEMI-MAJOR AXIS>,<INVERSE FLATTENING>]Par exemple :
SPHEROID["GRS_1980",6378137,298.257222101]Voici un exemple de calcul :
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. text
).bytea
) en utilisant soit l'encodage little-endian (NDR) soit big-endian (XDR). text
) en utilisant soit l'encodage little-endian (NDR) soit big-endian (XDR). Construit une géométrie à partir de EWKT.
Construit une géométrie à partir de EWKB.
Construit une géométrie de points 2d,3dz ou 4d.
Construit une géométrie de points 3dm.
Construit une BOX2D définie par la géométrie de points 2D.
Construit une BOX3D définie par la géométrie de points 2D.
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.
Construit une Linestring à partir de deux points géométriques donnés.
Construit une LineString à partir d'une géométrie MultiPoint.
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).
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.
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.
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.
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.
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
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.
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.
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.
Supprime un point d'une LINESTRING
. Le décalage commence à 0.
Disponibilité : 1.1.0
Remplace le point N de la LINESTRING par le point passé en argument. L'index à pour origine 0.
Disponibilité : 1.1.0
Convertie une géométrie en une GEOMETRYCOLLECTION. Cela est utile pour simplifier la représentation en WKB.
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).
Passe un géométrie dans le mode XYZ.
Passe une géométrie dans le mode XYM.
Passe un géométrie dans le mode XYZM.
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.
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
.
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).
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
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
Renvoit la géométrie avec les sommets en ordre inverse.
Force une collection de polygones à abéïr à la règle de la main droite.
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).
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
Availability: 1.1.0
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 :
Cas d'un ensemble de linestring
non contigües :
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
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
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
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
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
Renvoie un résumé textuel du contenu géométrique.
Renvoie une BOX2D représentant le cadre limite de l'objet géométrique.
Renvoie une BOX3D représentant le cadre limite de l'objet géométrique.
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.
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.
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.
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.
Si l'objet géométrique est un polygon ou un multi-polygon renvoie le nombre de rings.
Renvoie le nombre de points dans l'objet géométrique.
Renvoie vrai si l'objet géométrique est valide.
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.
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.
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.
Renvoie la quantité d'espace disque (en bytes) qu'occupe l'objet géométrique.
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.
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.
Renvoie le minima spécifié d'une bounding box.
Renvoie le maxima spécifié d'une bounding box.
Agrégat. Construit un tableau d'objets géométriques.
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.
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
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
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
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
Supprime tout les verroux rattachés à l'identifiant d'autorisation spécifié. Renvoit le nombre de verroux relachés.
Disponibilité : 1.1.3
Ajoute un marqueur d'autorisation à utiliser dans la transaction courrante.
Disponibilité : 1.1.3
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.
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.
Revoie l'aire d'une ST_Surface
ou ST_MultiSurface
.
SQL-MM 3: 8.1.2, 9.5.3
Renvoie la représentation binaire d'une ST_Geometry
.
SQL-MM 3: 5.1.37
Renvoie la représentation textuelle d'une ST_Geometry
.
SQL-MM 3: 5.1.25
Return the boundary of the ST_Geometry value.
SQL-MM 3: 5.1.14
Renvoie l'ensemble des points dans l'espace autour d'une ST_Geometry
.
SQL-MM 3: 5.1.17
Renvoie le barycentre d'une ST_Surface
ou ST_MultiSurface
.
SQL-MM 3: 8.1.4, 9.5.5
Test si une ST_Geometry
en contient spatialement une autre.
SQL-MM 3: 5.1.31
Renvoie l'enveloppe convexe d'une typeST_Geometry
.
SQL-MM 3: 5.1.16
Renvoie la dimension des coordonnées d'une ST_Geometry
.
SQL-MM 3: 5.1.3
Test si deux ST_Geometry
se croisent spatialement.
SQL-MM 3: 5.1.29
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
Renvoie la dimension d'un objet de type ST_Geometry
.
SQL-MM 3: 5.1.2
Test si un objet de type ST_Geometry
est spatialement disjoint
d'un autre ST_Geometry
.
SQL-MM 3: 5.1.26
Renvoie la distance entre deux entités géométriques.
SQL-MM 3: 5.1.23
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
Renvoie le rectangle englobant une entité de type ST_Geometry
.
SQL-MM 3: 5.1.15
Test si deux valeurs de type ST_Geometry
sont spatialement égales.
SQL-MM 3: 5.1.24
Renvoie l'anneau extérieur d'une ST_Surface
.
SQL-MM 3: 8.2.3, 8.3.3
Renvoie la valeur de type ST_GeomCollection
.
SQL-MM 3: 9.1.5
Renvoie le type d'une ST_Geometry
.
SQL-MM 3: 5.1.4
Renvoie une ST_Geometry
à partir de sa représentation textuelle.
SQL-MM 3: 5.1.40
Renvoie une ST_Geometry
à partir de sa représentation binaire.
SQL-MM 3: 5.1.41
Renvoie l'anneau intérieur d'une entité géométrique de type ST_Surface
.
SQL-MM 3: 8.2.6, 8.3.5
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
Test si une valeur de type ST_Geometry
intersecte spatialement un autre objet de type ST_Geometry
.
SQL-MM 3: 5.1.27
Test si un objet de type ST_Curve
or ST_MultiCurve
est fermé.
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
Test si une entité de type ST_Geometry
correspond à l'ensemble vide.
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
Test si une entité de type ST_Curve
est un anneau.
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
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.
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
Test si une entité de type ST_Geometry
est bien formée.
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
Renvoie la longuer d'une ST_Curve
ou ST_MultiCurve
.
SQL-MM 3: 7.1.2, 9.3.4
Renvoie une ST_LineString
à parti de sa représentation textuelle.
SQL-MM 3: 7.2.8
Renvoie une ST_LineString
à parti de sa représentation binaire.
SQL-MM 3: 7.2.9
Renvoie un ST_MultiLineString
à parti de sa représentation textuelle.
SQL-MM 3: 9.4.4
Renvoie un ST_MultiLineString
à parti de sa représentation binaire.
SQL-MM 3: 9.4.5
Renvoie un ST_MultiPoint
à parti de sa représentation textuelle.
SQL-MM 3: 9.2.4
Renvoie un ST_MultiPoint
à parti de sa représentation binaire.
SQL-MM 3: 9.2.5
Renvoie un ST_MultiPolygon
à parti de sa représentation textuelle.
SQL-MM 3: 9.6.4
Return a specified ST_MultiPolygon
à parti de sa représentation binaire.
SQL-MM 3: 9.6.5
Renvoie le nombre l'éléments dans ST_GeomCollection
.
SQL-MM 3: 9.1.4
Return the number of interior rings in an ST_Surface.
SQL-MM 3: 8.2.5
Return the number of points in an ST_LineString or
ST_CircularString value.
SQL-MM 3: 7.2.4
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).
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
Test si un objet de type ST_Geometry
en recouvre spatialement une autre.
SQL-MM 3: 5.1.32
Return the length measurement of the boundary of an
ST_Surface or ST_MultiRSurface value.
SQL-MM 3: 8.1.3, 9.5.4
Renvoie un objet de type ST_Point
à partir des coordonées passés en paramètre.
SQL-MM 3: 6.1.2
Renvoie un objet de type ST_Point
à partir de sa représentation textuelle.
SQL-MM 3: 6.1.8
Renvoie un objet de type ST_Point
à partir de sa représentation binaire.
SQL-MM 3: 6.1.9
Return the specified ST_Point value in an ST_LineString or
ST_CircularString
SQL-MM 3: 7.2.5, 7.3.5
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
Renvoie un objet de type ST_Polygon
à partir de sa représentation textuelle.
SQL-MM 3: 8.3.6
Renvoie un objet de type ST_Polygon
à partir de sa représentation binaire.
SQL-MM 3: 8.3.7
Renvoie un polygone construit à partir de la polyligne définie SRID.
SQL-MM 3: 8.3.2
Test if an ST_Geometry value is spatially related to another
ST_Geometry value.
SQL-MM 3: 5.1.25
Renvoie l'identifiant du SRID d''une entité géométrique de type ST_Geometry
.
SQL-MM 3: 5.1.5
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
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
Test si un entité géométrique de type ST_Geometry
en touche spatialement une autre.
SQL-MM 3: 5.1.28
Renvoie un objet de type ST_Geometry
value transformed to the specified
spatial reference system.
SQL-MM 3: 5.1.6
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
Test si une entité gémétrique de type ST_Geometry
est contenue dans une autre.
SQL-MM 3: 5.1.30
Renvoie un objet de type ST_Geometry
à partir de sa représentation binaire.
SQL-MM 3: 5.1.36
Renvoie une entité géométrique de type ST_Geometry
à partir de sa représentation textuelle.
SQL-MM 3: 5.1.34
Renvoie la composante x des coordonées d'un ST_Point
.
SQL-MM 3: 6.1.3
Renvoie la composante y des coordonées d'un ST_Point
.
SQL-MM 3: 6.1.4
Des fonctions supplémentaires ont été ajoutées pour améliorer le support d'une interface de style ArcSDE.
Renvoie vrai si les emprises de deux objets géométriques s'intersectent, sinon, elle renvoie faux.
Test si une valeur géométrique a une composante z
.
Test si une valeur géométrique a une composante m
.
Renvoie un ensemble d'objet géométriques dont les éléments respectent la mesure spécifiée.
Renvoie un ensemble d'objet géométriques dont les éléments sont inclues dans l'intervalle de valeur spécifié.
Renvoie la composante m
d'une valeur de type ST_Point
Renvoie la composante z
d'une valeur géométrique de type ST_Point
.
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.
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.
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.
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
New Z and M interpolation in line_substring()
New Z and M interpolation in line_interpolate_point()
added NumInteriorRing() alias due to OpenGIS ambiguity
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.
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èresIf 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.
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)
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.
SnapToGrid doesn't discard higher dimensions
Changed Z() function to return NULL if requested dimension is not available
Much faster transform() function, caching proj4 objects
Removed automatic call to fix_geometry_columns() in AddGeometryColumns() and update_geometry_stats()
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
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
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
Release date: 2005/12/06
Contains a few bug fixes and improvements.
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.
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
Initial support for postgresql 8.2
Added missing SRID mismatch checks in GEOS ops
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).
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.
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()
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)
Schema aware postgis_proc_upgrade.pl, support for pgsql 7.2+
New "Reporting Bugs" chapter in manual
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.
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.
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
Documentation improvements
More robust selectivity estimator
Minor speedup in distance()
Minor cleanups
GiST indexing cleanup
Looser syntax acceptance in box3d parser
Release date: 2005/08/08
Contains some bug fixes - including a severe one affecting correctness of stored geometries - and a few improvements.
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).
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
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
Release date: 2005/07/04
Contains a few bug fixes and improvements.
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.
Fault tolerant btree ops
Memory leak plugged in pg_error
Rtree index fix
Cleaner build scripts (avoided mix of CFLAGS and CXXFLAGS)
New index creation capabilities in loader (-I switch)
Initial support for postgresql 8.1dev
Release date: 2005/05/24
Contains a few bug fixes and some improvements.
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.
BUGFIX in 3d computation of lenght_spheroid()
BUGFIX in join selectivity estimator
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
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.
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.
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)
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)
Release date: 2005/03/30
Sixth release candidate for 1.0.0. Contains a few bug fixes and cleanups.
You need a dump/reload to upgrade from precedent releases. See the upgrading chapter for more informations.
haut de la page | table des matièresBUGFIX in multi()
early return [when noop] from multi()
dropped {x,y}{min,max}(box2d) functions
haut de la page | table des matièresBUGFIX in postgis_restore.pl scrip
BUGFIX in dumper's 64bit support
Release date: 2005/03/25
Fifth release candidate for 1.0.0. Contains a few bug fixes and a improvements.
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.
BUGFIX (segfaulting) in box3d computation (yes, another!).
BUGFIX (segfaulting) in estimated_extent().
Small build scripts and utilities refinements.
Additional performance tips documented.
Release date: 2005/03/18
Fourth release candidate for 1.0.0. Contains bug fixes and a few improvements.
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.
NEW distance_sphere() function.
Changed get_proj4_from_srid implementation to use PL/PGSQL instead of SQL.
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
Release date: 2005/02/24
Third release candidate for 1.0.0. Contains many bug fixes and improvements.
You need a dump/reload to upgrade from precedent releases. See the upgrading chapter for more informations.
haut de la page | table des matièresBUGFIX 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.
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.
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.
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.
Release date: 2005/01/26
Second release candidate for 1.0.0 containing bug fixes and a few improvements.
You need a dump/reload to upgrade from precedent releases. See the upgrading chapter for more informations.
haut de la page | table des matièresBUGFIX 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
More correct STABLE, IMMUTABLE, STRICT uses in lwpostgis.sql
stricter OGC WKB/WKT constructors
Faster and more robust loader (both i18n and not)
Initial autoconf script
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.
You need a dump/reload to upgrade from precedent releases. See the upgrading chapter for more informations.
haut de la page | table des matièresFaster 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.
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èresAfin 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
:
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 :
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).
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 :
cd jts-1.7.2
machine jts-1.7.2 # for i in ${JAR_DIR}/*jar; do export CLASSPATH="${CLASSPATH}:$i" done
machine jts-1.7.2 # for i in jts jtsio; do mkdir build/$i; done
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 .
CLASSPATH
:
machine jts-1.7.2 # export CLASSPATH="${CLASSPATH}:./jts.jar"
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 .
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 .
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 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 :
machine ~ # cd jts-1.7.2 machine jts-1.7.2 # mkdir classes
gcj
:
machine jts-1.7.2 # gcj -C -d classes -classpath jts.jar $(find src/com/vividsolutions/jts -name '*.java')
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"
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
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 #
jts.h
:
machine jts-1.7.2 # gcjh -I jts.jar -stub -o ./include/jts.h ${JTSCLASSES}
libjts.so
à partir de l'archive binaire jts.jar
:
machine jts-1.7.2 # gcj -fPIC -O2 -shared -o libjts.so ./jts.jar
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 ./
libstatis_geom.so
machine jts-1.7.2 # gcj -fPIC -classpath jts.jar -shared -o libstatic_geom.so "Geometry\$1.class"
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 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); doneSi 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.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(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 ########################################################################
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.
geos-config
et renomage en jts-config
:
machine jts-1.7.2 # cp $(type -P geos-config) ./jts-config
#!/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
/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
jts-config
.
haut de la page | table des matières 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 installSi 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
Dans cette section vous trouverez divers manuels concernant l'utilisation de Mapserver.
haut de la page | table des matièresDans 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
.
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 :
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
: HEADER
de la couche) qui contiendra la ligne :
imagemap_template.html
: 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 :
imagemap_footer.html
: FOOTER
de la couche) qui contiendra la ligne :
Nous vous donnons ci-dessous les lignes de la section format sortie de la mapfile (OUTPUTFORMAT
) :
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é :
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 :
Si vous souhaitez plus d'information concernant le support des imagemaps pour Mapserver vous pouvez consulter cette page (en anglais).
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.xmlPour 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 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
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 )...
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èresJ'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.
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.
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.
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:
listen_adresses = '*'
est activé dans le fichier postgresql.conf
de configuration de PostgreSQL
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
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!
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.
Nous devons commencer par installer OpenSSL pour utiliser Stunnel par la suite
Stunnel a besoin de OpenSSL pour pouvoir fonctionner
apt-get install openssl libssl-dev
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).
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 -hlocalhost
-p5433
-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
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
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èresDans 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èresPour ê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).
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) :
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 :
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
.
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