Génération d'une imagemap à partir d'une couche PostGIS


Dans ce manuel nous allons expliquer, dans un premier temps, comment générer simplement une imagemap à l'aide du script cgi mapserv, puis nous expliquerons comment résoudre le problème de génération d'une imagemap cohérente lorsque vous utilisez des éléments area de type POLYGON avec des données de type MULTIPOLYGON.

 Table des matières

1. Génération d'une imagemap simple
2. Problème avec les géométries de type MULTIPOLYGON

1. Génération d'une imagemap simple

Ici nous présentons comment générer un imagemap pour les communes du Languedoc-Roussillon.

Dans un premier temps nous allons définir la requête à utliser dans la mapfile (plus précisément dans la section DATA de la couche représentant ces communes) afin d'extraire les informations dont nous aurons besoin plus tard :

select gid, LOWER(nom_commun) as nom, numeroinse as value, simplify(the_geom,10) as the_geom from commune_lr ORDER BY gid

ndrpf : vous noterez que nous utilisons ici la fonction PostGIS simplify décrite ici.

Cette couche est supposée de type PostGIS (la couche contient un ligne du type : CONNECTIONTYPE POSTGIS), nous ne mentionnons pas ici la chaîne de connection au serveur PostgreSQL (la ligne CONNECTION) étant donné qu'elle dépend fortement de votre configuration.

Cette couche utilisera les trois modèles suivant :

imagemap_header.html :
pour l'entête (section HEADER de la couche) qui contiendra la ligne :

<map name="mymap">

imagemap_template.html :
pour le corps (section TEMPLATE de la couche), ce modèle sera utilisé pour chaque élément retourné par la requête que nous avons défini ci-dessus, et il contiendra les lignes :

<area shape="polygon" coords="[shpxy precision=0 proj=image] " href="#?[gid]" title="[nom]" alt="[nom]" onmouseover="displayData('[gid]',this.title,'[value]');" style="border: 1px #eee solid;background-color: #aaa;" />

et imagemap_footer.html :
pour le pied de page (section FOOTER de la couche) qui contiendra la ligne :

</map>

Nous vous donnons ci-dessous les lignes de la section format sortie de la mapfile (OUTPUTFORMAT) :

OUTPUTFORMAT
  NAME "imagemap"
  MIMETYPE "text/html"
  DRIVER "imagemap"
  EXTENSION "html"
  IMAGEMODE "PC256"
  TRANSPARENT FALSE
END

Si comme nous vous souhaitez sauvegarder l'imagemap résultante dans un fichier XML nommé imagemap.xml, utilisez la commande ci-dessous afin de récupérer le fichier désiré :

wget -O imagemap.xml "http://127.0.0.1/cgi-bin/mapserv?map=/[chemin]/imagemap.map&qlayer=[couche]&mode=nquery&searchmap=true"

ndrpf : vous noterez que nous utilisons ici le script cgi mapserv par souci de simplicité de ce manuel, néanmoins il est évident que vous pourriez générer l'imagemap en utilisant votre language de programmation préféré si le support mapscript pour ce lanaguage est installé sur votre système.

Nous avons donc maintenant notre imagemap dans le fichier imagemap.xml.

Dans notre page de consultation et plus précisément dans la balise img correspondant à l'image de la carte, il faut lui ajouter l'attribut usemap et y affecter le nom de notre imagemap.

Il va sans dire qu'il faut aussi ajouter le contenu de l'imagemap elle-même. Cela se fait facilement, par exemple si vous utilisez un script php, il vous suffira d'utiliser la commande include.

Dans notre cas, nous aurrons donc dans la page de consultation quelque chose du genre :

<map name="mymap">
[...]
</map>
<img src="ma_carte_generee.png" id="map" width="[ma_largeur]" height="[ma_hauteur]" border="1" style="[mon_style]" usemap="#mymap" />

Si vous souhaitez plus d'information concernant le support des imagemaps pour Mapserver vous pouvez consulter cette page (en anglais).

haut de la page | table des matières

2. Problème avec les géométries de type MULTIPOLYGON

Vous pourriez facilement vous contenter de la section 1 du présent manuel afin de générer des imagemaps. Cependant, si vous utilisez des MULTIPOLYGON, vous devriez rencontrer le problème décrit ici.

En effet dans notre exemple, lors du chargement de la page de consultation avec Firefox 2.0, nous avons eu, dans la console de débogage, le message suivant :

L'attribut « coords » de la balise <area shape="poly"> ne contient pas la dernière coordonnée « y » (le format correct est u00ab x1,y1,x2,y2 … »).
Après consultation de l'imagemap générée à l'étape précédente nous avons effectivement constaté qu'il y avait certaines des balises area qui contenaient un point pour le moins étrange ayant trois coordonnées... En effet, si vous essayez de générer une imagemap à partir d'une couche PostGIS qui contient des MULTIPOLYGON avec une version 4.10.1 de Mapserver, vous rencontrerez alors ce type problème pour tout les MULTIPOLYGON qui contiennent plus d'une composante (c'est-à-dire plus d'un POLYGON). Vous pouvez obtenir cette information en utilisant la fonction NumGeometries (décrite ici) ou encore avec Summary (décrite ici). Il est facile de récupérer l'ensemble des lignes contenant une balise area de type polygon ayant un "point" à trois composantes à l'aide de la commande suivante :
# grep "[1-9]*,[1-9]*,[1-9]*" /chemin/vers/votre/imagemap.xml
Pour résoudre ce problème je me suis contenté d'éditer le fichier maptemplate.c pour y modifier les lignes 1144 et 1148 pour qu'elles contiennent, repectivement :
pointFormatLength = strlen("xh") + strlen("xf") + strlen("yh") + strlen("yf") + strlen("cs") + 10 + 2;
et
snprintf(pointFormat2, pointFormatLength, "%s%%.%dlf%s%s%%.%dlf%s ", xh, precision, xf, yh, precision, yf);
Une fois ceci fait, il vous faut bien entendu recompiler Mapserver afin que les modifications apportées soient prises en compte. Une fois le nouveau binaire mapserv créé et copié dans le répertoire cgi-bin de votre serveur web, il vous suffit de relancer la commande pour récupérer l'imagemap générée. Lors de vos modifications, vous pouvez utiliser un autre nom que mapserv pour le programme cgi, par exemple mapserv<version> afin de garantir que les applications utilisant l'ancienne version (mapserv) continuent de fonctionner sans problème. Ainsi si vous faisiez une erreur, l'ensemble de vos applciations ne serait pas touché. En effet, les modifications décrites ici sont appliquées à la fonction processCoords qui est responsable du remplacement de shpxy dans les modèles par les coordonnées correspondantes, ce qui peut avoir des incidences suivant l'utilisation qui est faite de la variable shpxy. De plus, cette modification n'a été apportée que pour modifier le comportement de Mapserver lors de la génération d'imagemap pour des géométries de type MULTIPOLYGON qui posaient problème. Nous ne nous sommes pas encore penchés sur l'ensemble des incidences que cette modification pouvait avoir sur le comportement général de Mapserver. Vous pouvez vérifier que l'imagemap ainsi générée est correcte avec la même commande que précédemment, qui ne devrait rien renvoyer si tout s'est bien passé. haut de la page | table des matières