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 :
- La version 0.6 ou supérieure de PostGIS.
- La version 3.5 ou supérieure de Mapserver.
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).
- Compilez et installez Mapserver, avec les supports qui vous souhaitez activer, incluant l'option de configuration : "--with-postgis".
- Dans votre fichier map de Mpaserver, ajouté une couche PostGIS. Par exemple :
LAYER
CONNECTIONTYPE postgis
NAME "widehighways"
# Connect to a remote spatial database
CONNECTION "user=dbuser dbname=gisdatabase host=bigserver"
# Get the lines from the 'geom' column of the 'roads' table
DATA "geom from roads"
STATUS ON
TYPE LINE
# Of the lines in the extents, only render the wide highways
FILTER "type = 'highway' and numlanes >= 4"
CLASS
# Make the superhighways brighter and 2 pixels wide
EXPRESSION ([numlanes] >= 6)
COLOR 255 22 22
SYMBOL "solid"
SIZE 2
END
CLASS
# All the rest are darker and only 1 pixel wide
EXPRESSION ([numlanes] < 6)
COLOR 205 92 82
END
END
Dans l'exemple ci-dessus, les directives spécifiques à PostGIS sont les suivantes :
CONNECTIONTYPE
Pour les couches PostGIS, cela sera toujours "postgis".
CONNECTION
La connection à la base de données est gouvernée par "la chaine de charatères de connection" ("connection string") qui est contituée d'un ensemble de couples nom/valeur comme ceci (avec la valeur par défaut entre < >) :
user=<nom_d_utilisateur> password=<mot_de_passe> dbname=<nom_de_la_base_de_données> hostname=<serveur> port=<5432>
Une chaine de charactères de connection vide reste valide, et chacun des couples nom/valeur peut être omis. Au minimum vous aurez généralement besoin de spécifier le nom de la base de données et le nom d'utilisateur avec lequel vous souhaitez vous connecter.
DATA
La forme de ce paramètre est : "<colonne> from <nom_de_la_table>" où la colonne est une colonne spatiale qui doit être affiché sur la carte.
FILTER
Le filtre doit être une chaîne de charactères SQL valide correspondant à la logique normale suivant le mot clef "WHERE" dans les requêtes SQL. Donc, par exemple, pour afficher uniquement les routes ayant 6 voies ou plus, utilisé le filtre "nombre_de_voies >= 6".
- Dans votre base de données spatiale, assurez vous que vous avez des indexes spatiaux (GiST) pour chaque couches que vous souhaitez afficher.
CREATE INDEX [nom_de_l_index]
ON [nom_de_la_table]
USING GIST ( [colonne_géometrique] GIST_GEOMETRY_OPS );
- Si vous allez interroger vos couches en utilisant Mpaserver vous aurez aussi besoin d'un "index oid".
Mapserver requière des indentifiants uniques pour chaque enregistrement spatial lorsque vous souhaitez effetuer des interrogations, et le module PostGIS de Mapserver utilise les valeurs d'oid de PostgreSQL pour fournir ces identifiants uniques. Cela implique comme effet de bord que si vous souhaitez effectuer des accès aléatoires rapides aux enregistrements durant les requêtes, un index sur les oid est necessaires.
Pour construire un tel index, utilisez la requête SQL suivante :
CREATE INDEX [nom_de_l_index] ON [nom_de_la_table] ( oid );
haut de la page | table des matières Contrairement aux fichiers vecteurs (shapefile), les noms de champs PostGIS doivent être référencés dans EXPRESSIONS en utilisant des lettres en minuscule.
EXPRESSION ([nombre_de_voies] >= 6)
haut de la page | table des matières Contrairement aux fichiers vecteurs (shapefile), les filtres pour les couches PostGIS utilisent la syntaxe SQL (ils sont concaténés à l'état SQL que le connecteur PostGIS génère pour afficher les couches dans Mapserver).
FILTER "type = 'autoroute' and nombre_de_voies >= 4"
haut de la page | table des matières En général, les couches PostGIS sont 10 % plus lentes que les couches équivalentes en fichier vecteurs, ceci est due au temps qui incombe à la connection au serveur de base de données, les transformations et la transmission des données entre la base et Mapserver.
Si vous avez des problèmes de performance d'affichage, cela est généralement lié au fait que vous n'avez pas créé les indexes spatiaux pour vos tables.
postgis# CREATE INDEX geotable_gix ON geotable USING GIST ( geocolumn );
postgis# SELECT update_geometry_stats(); -- Pour PGSQL < 8.0
postgis# VACUUM ANALYZE; -- Pour PGSQL >= 8.0
haut de la page | table des matières Pour que les requêtes soient rapides, vous devez avoir une clef unique pour vos tables spatiales et un index sur cette clef unique.
Vous pouvez spécifier quelle clef unique doit être utilisée par Mapserver, en utilisant la clause : USING UNIQUE
dans votre ligne DATA
:
DATA "the_geom FROM geotable USING UNIQUE gid"
Si votre table n'a pas de colonne explicitement unique, vous pouvez "faire semblant" de rendre une colonne unique en utilisant la colonne PostgreSQL "oid" comme colonne unique. "oid" est la colonne unique par défaut si vous n'en déclarez pas une, donc pour améliorer le temps d'exécution de vos requêtes vous devez créer des indexes sur les valeurs oid de vos tables spatiales.
postgis# CREATE INDEX geotable_oid_idx ON geotable (oid);
haut de la page | table des matières La clause pseudo-SQL USING
est utilisée afin d'ajouter des informations pour aider Mapserver à comprendre les résultats de plusieurs requêtes complexes. Plus précisément, lorsqu'une vue ou une sous-requête de sélection est utilisée comme table source (le terme à la droite du FROM
dans la définition de DATA
) il est plus difficile pour Mapserver de déterminer automatiquement un identifiant unique pour chaque tuple et le SRID pour la table. La clause USING
peut fournir à Mapserver ces deux types d'informations :
DATA "the_geom FROM (SELECT table1.the_geom AS the_geom, table1.oid AS oid, table2.data AS data
FROM table1 LEFT JOIN table2 ON table1.id = table2.id) AS new_table USING UNIQUE oid USING SRID=-1"
USING UNIQUE <idunique>
Mapserver requière un identifiant unique pour chaque tuple dans le but d'identifier une ligne lorsque l'on effectue des interrogations de la carte. Normalement, il devrait utiliser l'oid comme identifiant unique, mais les vues et les sous-requêtes de sélection n'ont pas obligatoirement cette colonne oid. Si vous souhaitez utiliser les fonctionnalités d'interrogation de Mapserver, vous aurez besoin d'ajouter une colonne unique à vos vues ou vos sous-requêtes de sélection, et déclarer ceci en utilisant : USING UNIQUE
. Pour ce faire, vous pouvez, par exemple, explicitement sélectionner une des valeurs d'oid de la table, ou l'une des autres colonnes pour laquelle vous garantissez l'unicité dans l'ensemble résultant.
L'état USING
peut aussi être utile pour de simples état DATA
, si vous effectuez des interrogations de la carte. Il était jadis recommandé d'ajouter un indexe sur la colonne oid des tables utilisées dans les couches interrogeables, dans le but d'accélérer les requêtes de la carte. Cependant, avec la clause USING
, il est possible de spécifier à Mapserver d'utiliser la clef primaire de votre table comme identifiant pour interroger la carte, il n'est ainsi plus nécessaire d'avoir un indexe supplémentaire.
Note :
"Interroger une carte" est l'action qui consiste à cliquer sur la carte pour demander les informations relatives à la zone géographique sélectionnée. Ne confondez pas "interrogation de carte" avec requête SQL dans la définition de DATA
.
USING SRID=<srid>
PostGIS a besoin de connaitre quel système de référence spatial doit être utilisé par les géométries afin de retourner correctement les données à Mapserver. Normalement il est possible de trouver ces informations dans la table "geometry_columns" dans une base de données PostGIS, cependant, il n'est pas possible pour les tables qui ont été créées à la volée comme des sous-requêtes de sélection ou des vues. Donc l'option USING SRID=
vous permet de spécifier le SRID correspondant à vos données dans la définition de DATA
.
Attention :
Le parser pour les couches PostGIS de Mapserver est légérement primitif et est sensible à la casse dans certaines parties. Faites attention à ce que tous les mots clefs SQL et toutes les clauses USING
soient en lettres majuscules, et que vos clauses USING UNIQUE
précèdent bien vos clauses USING SRID
.
haut de la page | table des matières Commençons avec un exemple simple et qui nous servira de base pour la suite. Considérons la définition de couche Mapserver suivante :
LAYER
CONNECTIONTYPE postgis
NAME "routes"
CONNECTION "user=lutilisateur password=lemotdepasse dbname=labase host=leserveur"
DATA "the_geom FROM routes"
STATUS ON
TYPE LINE
CLASS
COLOR 0 0 0
END
END
Cette couche affichera toutes les géométries de la table routes comme des lignes noires.
Maintenant, supposons que nous voulions uniquement afficher les autoroutes lorsque nous zoomons au moins à une échelle de 1:100000, les deux prochaines couches permettent cela :
LAYER
CONNECTION "user=lutilisation password=lemotdepasse dbname=labase host=leserveur"
DATA "the_geom FROM routes"
MINSCALE 100000
STATUS ON
TYPE LINE
FILTER "type_de_route = 'autotourte'"
CLASS
COLOR 0 0 0
END
END
LAYER
CONNECTION "user=lutilisateur password=lemotdepasse dbname=labase host=leserveur"
DATA "the_geom FROM routes"
MAXSCALE 100000
STATUS ON
TYPE LINE
CLASSITEM type_de_route
CLASS
EXPRESSION "autoroute"
SIZE 2
COLOR 255 0 0
END
CLASS
COLOR 0 0 0
END
END
La première couche est utilisée lorsque l'échelle est plus grande que 1:100000, et affiche uniquement des lignes noires pour les routes de type "autoroute". L'option FILTER
entraine que seules les routes de type "autoroute" doivent être affichées.
La seconde couche est utilisée lorsque l'échelle est plus petite que 1:100000, et affichera les autoroutes comme des lignes rouges à double-profondeurs, et les autre routes comme des lignes noires standards.
Donc, nous avons fait un couple de choses intéressantes en utilisant uniquement les fonctionnalités de Mapserver, mais nos états SQL dans les définitions de DATA
sont restées simples. Supposons que le nom des routes soit stocké dans une autre table (pour une raison quelconque) et que nous souhaitions faire une jointure pour récupérer et étiqueter nos routes.
LAYER
CONNECTION "user=lutilisateur password=lemotdepasse dbname=labase host=leserveur"
DATA "the_geom FROM (SELECT routes.oid AS oid, routes.the_geom AS the_geom, nom_des_routes.nom as nom
FROM routes LEFT JOIN nom_des_routes ON routes.id_nom_de_routes = nom_des_routes.id_nom_de_routes) AS routes_nommées
USING UNIQUE oid USING SRID=-1"
MAXSCALE 20000
STATUS ON
TYPE ANNOTATION
LABELITEM nom
CLASS
LABEL
ANGLE auto
SIZE 8
COLOR 0 192 0
TYPE truetype
FONT arial
END
END
END
Cette couche d'annotation ajoute des étiquettes vertes à toutes les routes lorsque l'échelle atteint 1:20000 ou moins. Cela montre aussi comment utiliser les jointures SQL dans une définition de DATA
.
haut de la page | table des matières