Chapitre 9. MapServer: faire une image avec zones réactives

Table des matières

9.1. Démo en ligne et ressource en ligne
9.2. Création de la base de données
9.3. Importation des données dans une base PostGIS
9.4. La mapfile
9.5. Script php

MapServer permet de générer des images au format raster (png,gif,jpg). Mais il est aussi possible de pouvoir générer des images avec des zones réactives.

Avertissement

Avant de consulter ce chapitre merci de vous avoir assurer que vous avez consulté le chapitre 4, notamment la section "Cas pratiques avec MapServer"

9.1. Démo en ligne et ressource en ligne

La ressource qui a permis la rédaction de ce chapitre peut être consulté à http://mapserver.gis.umn.edu/cgi-bin/wiki.pl?ImageMap

La démo est visible ici

Figure 9.1. ImageMap à l'initialisation

ImageMap à l'initialisation

Figure 9.2. ImageMap lors du passage du pointeur de la souris sur l'Hérault

ImageMap lors du passage du pointeur de la souris sur l'Hérault

9.2. Création de la base de données

La création de la base de données aura lieu en faisant

Exemple 9.1. Création de la base de données

createdb madatabase
createlang plpgsql madatabase
psql -d madatabase -f C:\PostgreSQL\8.2.1\share\contrib\lwpostgis.sql
psql -d madatabase -f C:\PostgreSQL\8.2.1\share\contrib\spatial_ref_sys.sq

9.3. Importation des données dans une base PostGIS

Nous allons importer nos données en faisant tout simplement

Exemple 9.2. Importation des données issues du shapefile dans la base

shp2pgsql -DI -s 27582 departements_lr.shp departements_lr | psql madatabase

Les données peuvent être téléchargées ici.

9.4. La mapfile

La mapfile se présente ainsi

Exemple 9.3. Contenu de la mapfile

MAP
  EXTENT 547293 1703209.875 801423 1997767.125
  IMAGECOLOR 125 125 125
  SIZE 500 579.540491087239
  FONTSET "../etc/fonts.txt"
  SYMBOLSET "../etc/symbols.sym"
  #==========================================================
  # Les divers outputs possibles
  #==========================================================
  #
  # Pour le raster en png
  #
  OUTPUTFORMAT
    NAME png
    MIMETYPE image/png
    DRIVER GD/PNG
    EXTENSION png
    IMAGEMODE PC256
    TRANSPARENT FALSE
  END
  #
  # Pour imagemap: image avec zones réactives
  #
  OUTPUTFORMAT
    NAME imagemap
    MIMETYPE imagemap
    DRIVER imagemap
    EXTENSION html
    IMAGEMODE PC256
    TRANSPARENT FALSE
    # Ce qui permet d'émuler le MouseOver en JavaScript 
    FORMATOPTION "POLYMOUSEOVER=javascript:getdata('%s')"
  END
  #==========================================================
  # Web pour MapServer
  #==========================================================
  WEB
    IMAGEPATH "/var/www/demoimagemap/tmp/"
    IMAGEURL "/demoimagemap/tmp/"
  END
 

Exemple 9.4. Contenu de la mapfile (suite)

 #==========================================================
  # Couche des départements
  #=========================================================
  LAYER
    NAME "departements_lr"
    CONNECTION "user=david dbname=madatabase host=localhost"
    CONNECTIONTYPE POSTGIS
    DATA "the_geom from departements_lr"
    STATUS DEFAULT
    TYPE POLYGON
    LABELITEM "nom"
    CLASS
      LABEL
        SIZE MEDIUM
        TYPE BITMAP
        BUFFER 0
        COLOR 22 8 3
        FORCE FALSE
        MINDISTANCE -1
        MINFEATURESIZE -1
        OFFSET 0 0
        PARTIALS TRUE
        POSITION CC
      END
      STYLE
        OUTLINECOLOR 0 0 255
        SIZE 3
        SYMBOL "circle"
      END
    END
  END
#========================================================
#  FIN DE LA MAPFILE
#========================================================
END

Voyons quelques points importants concernant cette mapfile. Déjà concernant EXTENSION, nous avons vu ce paramètre au chapitre précédent. Le plus important ici réside dans l'ajout des deux sections OUTPUTFORMAT appelé respectivement png et imagemap.En effet ces deux sections sont ici nécessaires:

  • png: permettra de générer le fond de l'image figée;

  • imagemap: permettra de créer les images réactives

Ces deux OUTPUT sont en fait superposés! Le fond de l'image accueille les zones réactives par-dessus. Maintenant que nous avons les deux fonds attendus, il faut pouvoir les générer à partir de PHP

9.5. Script php

Le script php utilisé est le suivant

Exemple 9.5. Script php utilisé pour générer l'image à zones réactives

<script type="text/javascript" src="getdata.js"></script>
<?php
/*
     Vérifiacation des chargements des extensions pour
     PostgreSQL et PhpMapScript

     ATTENTION: Prévu pour Windows et GNU/Linux
                Pas encore pour Mac OS X!
*/
 switch (PHP_OS)
    {

     case "WINNT": $Ext_Suffix = "dll";// suffixe pour Win32
                    break;

     default:  $Ext_Suffix = "so";// Suffixe pour GNU/Linux
               break;
  }

if ( extension_loaded('MapScript')+extension_loaded('pgsql') != 2)
{
     if (!extension_loaded('MapScript'))
     {
      if(!dl("php_mapscript.".$Ext_Suffix ))
        {echo "<b>ATTENTION: Impossible de trouver la librairie pour PHPMAPSCRIPT</b>";
        exit("");
        }
      }
     if (!extension_loaded('pgsql'))
     {
      if(!dl("php_pgsql.".$Ext_Suffix ))
        {echo "<b>ATTENTION: Impossible de trouver la librairie pour POSTGRESQL</b>";
        exit("");
        }
      }

}
    $sw_MapFile = "/var/www/demoimagemap/mapfiles/lr.map";
    /* Chargement de la mapfile */
    $map = ms_newMapObj( $sw_MapFile );
    /*  Commencons par charger le fond de couleur en blanc*/
    $map->imagecolor->setRGB(255,255,255);
    // On modifie les dimensions de l'image
    $map->set("width",300);
    $map->set("height",347.72429);
       /*  On agit sur le layer "departements_lr"*/
         $layer=$map->getLayerByName("departements_lr");
          $layer->set("status",MS_ON);

         $class = $layer->getclass(0);
         $class->deletestyle(0);
         $style = ms_newStyleObj($class);
         $style->set("size",3);
         $style->color->setRGB(255,255,255);
         $style->outlinecolor->setRGB(255,0,0);

       $map->selectOutputFormat("png");
       $image = $map->draw();
       $image_url = $image->saveWebImage();

Exemple 9.6. Script php utilisé pour générer l'image à zones réactives (suite)

      $map->selectOutputFormat("imagemap");
       $imagemap = $map->draw();
       $imagemap_url = $imagemap->saveWebImage();


printf("<TABLE BGCOLOR=WHITE BORDER='0' BORDERSPACE=0>");
printf("<tr>");
printf("<td>");


echo "<FORM NAME='mymap' METHOD=POST ACTION='".$self."'>";
/*
   En fonction, du nvavigateur FireFox ou IE, on adapte s'il faut
   ajoutet les balises <object></object> ou pas!
*/
if (substr_count($_ENV["HTTP_USER_AGENT"],"FireFox") > 0)
{
       echo "<OBJECT TYPE='image/png' NAME='mapa' usemap='#map1' BORDER=0 DATA='http://".$_ENV["SERVER_NAME"].":".$_ENV["SERVER_PORT"]."".$image_url."'>";
      include "http://".$_ENV["SERVER_NAME"].":".$_ENV["SERVER_PORT"]."".$imagemap_url;
     echo "</OBJECT><BR>";
}
else
{
       echo "<IMG NAME='IEmapa' usemap='#map1' BORDER=0 SRC='http://".$_ENV["SERVER_NAME"].":".$_ENV["SERVER_PORT"]."".$image_url."'/><BR>";
       include "http://".$_ENV["SERVER_NAME"].":".$_ENV["SERVER_PORT"]."".$imagemap_url;
}

echo "</FORM>";
?>
<?php
printf("</td>\n");
printf("<td>");
printf("</td>\n");
?>
<td>
<!--
     Un tableau sur lequel on affiche les données attributaires attendus
-->
<div align="center">
        <table width="300" cellpadding="0" cellspacing="0" border="0">
     <tr>
          <td width=10><img src="../img/truc4.gif" border="0" width="10" height="10" /></td>
          <td width=280 bgcolor=#FFB400><img src="../img/transparent.gif" border="0" width="1" height="1" /></td>
          <td width=10><img src="../img/truc3.gif" border="0" width="10" height="10" /></td>
     </tr>
     <tr>
          <td width="10" bgcolor="#FFB400"><img src="../img/transparent.gif" border="0" width="1" height="1"></td>
          <td width="280" bgcolor="#FFB400">
                          <p id="AffichageAdresse1"> </p>
                          <p id="AffichageAdresse2">Déplacez le curseur sur la carte pour commencer</p>
                          <p id="AffichageAdresse3"> </p>
                          <p id="AffichageAdresse4"> </p>

        </td>

Exemple 9.7. Script php utilisé pour générer l'image à zones réactives (suite)

          <td width="10" bgcolor="#FFB400"><img src="../img/transparent.gif" border="0" width="1" height="1"></td>
     </tr>
     <tr>
          <td width="10"><img src="../img/truc1.gif" border="0" width="10" height="10"></td>
          <td width="280" bgcolor="#FFB400"><img src="../img/transparent.gif" border="0" width="1" height="1"></td>
          <td width="10"><img src="../img/truc2.gif" border="0" width="10" height="10"></td>
     </tr>
        </table>
</div>
</td>
</tr>
</table>
<p align='left' style='font-size:10;'><b>Exemple MapServer+PostGIS - http://www.davidgis.fr</b></p>

La mapfile interagit avec la fonction getdata() (voir le paramètre FORMATOPTION "POLYMOUSEOVER=javascript:getdata('%s')" de la mapfile) qui est écrit ici en JavaScript. On mettra ici le code de cette fonction dans un fichier supplémentaire getdata.js dont le contenu est

Exemple 9.8. Script JavaScript utilisé pour un peu d'interactivité avec l'image à zones réactives

function getdata(departement)
{
dept = new Array(
"DDASS de l'Aude","14 rue rue du 4 septembre - BP 48","CARCASSONNE Cedex",
"DDASS du Gard","6, rue du Mail","30906 NIMES Cedex",
"DDASS de l'Hérault","85, avenue d'Assas","34967 MONTPELLIER Cedex 2",
"DDASS de la Lozère","Avenue du 11 novembre 1918","Immeuble le Saint-Clair - BP 136","48005 MENDE Cedex",
"DDASS des Pyrénées-Orientales","12, boulevard Mercader - BP 928","66020 PERPIGNAN Cedex");
 switch(departement)
 {
     case 'Aude':
                        document.getElementById("AffichageAdresse1").firstChild.nodeValue = dept[0];
                        document.getElementById("AffichageAdresse2").firstChild.nodeValue = dept[1];
                        document.getElementById("AffichageAdresse3").firstChild.nodeValue = dept[2];
                        document.getElementById("AffichageAdresse4").firstChild.nodeValue = '';
                        break
     case 'Gard':
                        document.getElementById("AffichageAdresse1").firstChild.nodeValue = dept[3];
                        document.getElementById("AffichageAdresse2").firstChild.nodeValue = dept[4];
                        document.getElementById("AffichageAdresse3").firstChild.nodeValue = dept[5];
                        document.getElementById("AffichageAdresse4").firstChild.nodeValue = '';
                        break
     case 'Herault':
                        document.getElementById("AffichageAdresse1").firstChild.nodeValue = dept[6];
                        document.getElementById("AffichageAdresse2").firstChild.nodeValue = dept[7];
                        document.getElementById("AffichageAdresse3").firstChild.nodeValue = dept[8];
                        document.getElementById("AffichageAdresse4").firstChild.nodeValue = '';
                        break
     case 'Lozère':
                        document.getElementById("AffichageAdresse1").firstChild.nodeValue = dept[9];
                        document.getElementById("AffichageAdresse2").firstChild.nodeValue = dept[10];
                        document.getElementById("AffichageAdresse3").firstChild.nodeValue = dept[11];
                        document.getElementById("AffichageAdresse4").firstChild.nodeValue = dept[12];
                        break
     default:
                        document.getElementById("AffichageAdresse1").firstChild.nodeValue = dept[13];
                        document.getElementById("AffichageAdresse2").firstChild.nodeValue = dept[14];
                        document.getElementById("AffichageAdresse3").firstChild.nodeValue = dept[15];
                        document.getElementById("AffichageAdresse4").firstChild.nodeValue = '';
                        break
}

}