Skip To Content

Personnalisation d'une réponse WMS GetFeatureInfo

Les services WMS prennent en charge une gamme d'opérations telles que GetCapabilities, GetMap, GetStyles, etc., qui permettent aux applications client de fonctionner avec le service, en ajoutant des paramètres à l'URL du service. L'opération GetFeatureInfo fonctionne de manière similaire et vise à renvoyer les attributs des entités demandées dans une carte dans différents formats tels que HTML, XML et texte brut.

L'exemple suivant présente une demande GetFeatureInfo et la réponse correspondante au format HTML par défaut.

Demande

http://gisserver.domain.com/arcgis/services/ihs_petroleum/MapServer/WMSServer?&service=WMS&version=1.1.0&request=GetFeatureInfo&layers=fields&query_layers=fields&styles=&bbox=47.130647,8.931116,48.604188,29.54223&srs=EPSG:4326&feature_count=10&x=562&y=193&height=445&width=1073&info_format=text/html&

Réponse

Réponse GetFeatureInfo au format HTML par défaut

Dans bien des cas, la réponse HTML, XML ou texte brut par défaut convient, mais vous pourriez vouloir personnaliser le format ou la structure de la réponse dans certaines situations, afin d'exécuter une logique métier particulière. Par exemple, pour des raisons d'interopérabilité, vous pourriez désirer recevoir les informations sur l'entité dans une structure standard telle que GML ou GeoJSON.

Modèles XSLT

Les modèles XSLT (Extensible Stylesheet Language Transformation) offrent une façon de générer une sortie lisible à partir d'une réponse WMS GetFeatureInfo. Par exemple, lorsque vous envoyez une demande WMS GetFeatureInfo au serveur, ce dernier répond en renvoyant les entités demandées en format XML. Le modèle XSLT "traduit" alors le code XML dans le format spécifié, par exemple HTML ou texte brut, rendant ainsi lisible la réponse finale.

Un examen de la réponse XML de WMS GetFeatureInfo et des modèles XSLT par défaut fournis lors de l'installation du serveur ArcGIS vous aidera à mieux comprendre comment personnaliser une réponse GetFeatureInfo. Les sections suivantes décrivent chacun d'entre eux plus en détail.

Réponse GetFeatureInfo au format XML

Vous trouverez ci-dessous un exemple de réponse GetFeatureInfo au format XML dans un service WMS :

<?xml version="1.0" encoding="UTF-8"?>
<esri_wms:FeatureInfoResponse version="1.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:esri_wms="http://www.esri.com/wms" xmlns="http://www.esri.com/wms">
  <esri_wms:FeatureInfoCollection layername="fields">
    <esri_wms:FeatureInfo>
      <esri_wms:Field>
        <esri_wms:FieldName><![CDATA[OBJECTID]]></esri_wms:FieldName>
        <esri_wms:FieldValue><![CDATA[1]]></esri_wms:FieldValue>
      </esri_wms:Field>
      <esri_wms:Field>
        <esri_wms:FieldName><![CDATA[Shape]]></esri_wms:FieldName>
        <esri_wms:FieldValue><![CDATA[Polygon]]></esri_wms:FieldValue>
      </esri_wms:Field>
      <esri_wms:Field>
        <esri_wms:FieldName><![CDATA[Shape_Area]]></esri_wms:FieldName>
        <esri_wms:FieldValue><![CDATA[0.009079]]></esri_wms:FieldValue>
      </esri_wms:Field>
        ...
        <!-- there could be more <esri_wms:Field> -->
        ...
    </esri_wms:FeatureInfo>
    ...
    <!-- there could be more <esri_wms:FeatureInfo> -->
    ...
  </esri_wms:FeatureInfoCollection>
  ...
  <!-- there could be more <esri_wms:FeatureInfoCollection> -->
  ...
</esri_wms:FeatureInfoResponse>

Remarquez les détails suivants :

  • La balise racine <FeatureInfoResponse> peut contenir plusieurs éléments <FeatureInfoCollection>.
  • Chaque élément <FeatureInfoCollection> contient les champs et valeurs d'attribut de toutes les entités identifiées dans une couche WMS.
  • Les informations relatives à une entité identifiée sont contenues dans une balise <FeatureInfo>. Remarquez la combinaison nom-valeur pour chaque champ.

Modèles XSLT par défaut

Des modèles XSLT sont fournis avec le serveur ArcGIS pour les formats pris en charge répertoriés dans les fichiers de fonctionnalités WMS. Par exemple, si vous ouvrez le répertoire de ces modèles dans <emplacement d'installation du serveur ArcGIS>\Styles\WMS, vous verrez ceci :

  • featureinfo_application_geojson.xsl
  • featureinfo_application_vnd.esri.wms_featureinfo_xml.xsl
  • featureinfo_application_vnd.ogc.wms_xml.xsl
  • featureinfo_text_html.xsl
  • featureinfo_text_plain.xsl
  • featureinfo_text_xml.xsl

Comme leur nom l'indique, chaque modèle sert à produire une réponse GetFeatureInfo par défaut dans un format lisible, tel que GeoJSON, texte brut et XML.

La table HTML avec légende en bleu présenté en exemple au début de cette rubrique a été produite à l'aide du modèle XSLT HTML par défaut. En revanche, si vous désirez la réponse XML brute, vous pouvez définir le paramètre de demande GetFeatureInfo INFO_FORMAT sur application/vnd.esri.wms_raw_xml. Vous pouvez utiliser cette méthode pour créer votre propre modèle XSLT.

Personnalisation de la réponse GetFeatureInfo

Maintenant que vous comprenez mieux la réponse XML de GetFeatureInfo et les modèles XSLT, vous pouvez explorer différentes façons de personnaliser la réponse WMS GetFeatureInfo.

Modification des modèles XSLT par défaut

La première façon de personnaliser la réponse consiste à modifier les modèles XSLT. Par exemple, si vous ouvrez le modèle HTML featureinfo_text_html.xsl dans un éditeur de texte et remplacez la balise <Style> par le code XML suivant, la couleur de la légende de la table passera au rouge.

Exemple XML

<style type="text/css">
          table, th, td {
            border:1px solid #e5e5e5;
            border-collapse:collapse;
            font-family: arial;          
            font-size: 80%;            
            color: #333333
          }             
          th, td {
            valign: top;
            text-align: center;
          }          
          th {
            background-color: #ffb7b7
          }
          caption {
            border:1px solid #e5e5e5;
            border-collapse:collapse;
            font-family: arial;          
            font-weight: bold;
            font-size: 80%;      
            text-align: left;      
            color: #333333;    
          }
        </style>

Exemple de réponse

Réponse HTML GetFeatureInfo avec légende de table en rouge

Cependant, si vous décidez de modifier ces modèles, tout élément WMS mis à disposition par l'intermédiaire du serveur ArcGIS sera directement touché. Pour cette raison, évitez de mettre dans les modèles toute logique spécifique au service de carte.

Utilisation du paramètre xslt_template

Une autre façon de personnaliser la réponse GetFeatureInfo consiste à remplacer le comportement des modèles XSLT par défaut à l'aide du paramètre xslt_template. Le paramètre xslt_template est un paramètre propre à Esri que vous pouvez définir dans l'URL d'un fichier de modèle XSLT. Lorsque le modèle est spécifié dans la chaîne d'URL, WMS remplace le modèle par défaut par celui que vous avez indiqué. Si vous avez déjà créé un modèle personnalisé, il s'agit de la meilleure méthode pour utiliser votre modèle dans la réponse GetFeatureInfo.

Remarque :

Lorsque vous utilisez le paramètre xslt_template, il n'est pas obligatoire que votre modèle suive la même convention d'affectation de noms que les modèles par défaut, mais il doit tout de même être disponible par l'intermédiaire d'une URL. La spécification d'un chemin local ou d'un chemin UNC entraîne l'échec de la requête.

Vous trouverez ci-dessous un exemple de demande GetFeatureInfo avec le paramètre xslt_template :

http://gisserver.domain.com/arcgis/services/ihs_petroleum/MapServer/WMSServer?&service=WMS&version=1.1.1&request=GetFeatureInfo&layers=pipelines&query_layers=pipelines&styles=&bbox=47.119661,28.931116,48.593202,29.54223&srs=EPSG:4326&feature_count=10&x=389&y=120&height=445&width=1073&info_format=text/plain&xsl_template=http://server/resources/xsl/featureinfo_application_geojson.xsl

L'URL ci-dessus renvoie à un modèle externe qui remplace le modèle par défaut. Le modèle XML personnalisé se présente comme suit :

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:esri_wms="http://www.esri.com/wms" xmlns="http://www.esri.com/wms">  
  <xsl:output 
    method="text" 
    indent="yes" 
    encoding="ISO-8859-1"/>     
  
  <xsl:template match="/">{  
  "type": "FeatureCollection",
  "features": [<xsl:for-each select="esri_wms:FeatureInfoResponse/esri_wms:FeatureInfoCollection/esri_wms:FeatureInfo">
    {
      "type": "Feature",
      "properties": 
        {<xsl:for-each select="esri_wms:Field">                  
          "<xsl:value-of select="esri_wms:FieldName"/>":"<xsl:value-of select="esri_wms:FieldValue"/>",</xsl:for-each>
        },
      "layerName":"<xsl:value-of select="../@layername"/>"  
    },</xsl:for-each>
  ]
}
  </xsl:template>
</xsl:stylesheet>

Le modèle a été créé afin que WMS renvoie ses réponses GetFeatureInfo en texte brute GeoJSON, au lieu du format HTML par défaut. GeoJSON peut être analysé par de nombreuses bibliothèques JavaScript, ce qui vous permet d'intégrer vos réponses à des pages Web dans un format facile à lire.

Vous trouverez ci-dessous un exemple de réponse GetFeatureInfo au format GeoJSON en tant que source de données d'une grille Ext.Grid dans une application de cartes Web OpenLayers.

Réponse GetFeatureInfo au format GeoJSON en tant que source de données d'une grille Ext.Grid dans une application de cartes Web OpenLayers

En s'appuyant sur l'exemple précédent, l'exemple de modèle ci-dessous peut être utilisé pour incorporer un objet vidéo dans la réponse :

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:esri_wms="http://www.esri.com/wms" xmlns="http://www.esri.com/wms">
  <!--
    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  -->    
  <xsl:output 
    method="html" 
    indent="yes" 
    encoding="UTF-8" 
    omit-xml-declaration="yes"/> 
  <xsl:template match="/">    
  <!--<html>
      <head>-->
        <style type="text/css">
          table, th, td {
            border:1px solid #e5e5e5;
            border-collapse:collapse;
            font-family: arial;          
            font-size: 80%;            
            color: #333333
          }             
          th, td {
            valign: top;
            text-align: center;
          }          
          th {
            background-color: #aed7ff;
          }
          caption {
            border:1px solid #e5e5e5;
            border-collapse:collapse;
            font-family: arial;          
            font-weight: bold;
            font-size: 80%;      
            text-align: left;      
            color: #333333;
            background-color: #aed7ff;            
          }
        </style>
      
    <!--</head>
      <body>-->  
      <div>        
        <xsl:for-each select="esri_wms:FeatureInfoResponse/esri_wms:FeatureInfoCollection">                              
          <table width="100%" cellpadding="0" cellspacing="0" border="1">
            <tbody>                          
              <caption>layer names: '<xsl:value-of select="@layername"/>'</caption>
              <xsl:for-each select="esri_wms:FeatureInfo[1]/esri_wms:Field">
                <xsl:variable name="fieldName" select="esri_wms:FieldName"/>
                <xsl:variable name="fieldValue" select="esri_wms:FieldValue"/>                              
                <xsl:if test="$fieldName = 'PLOT_SYMBOL_GROUP'">                  
                  <xsl:choose>
                    <xsl:when test="$fieldValue = 2">                      
                      <tr>
                        <td>
                          wiki link
                        </td>
                        <td>
                          <a target="_blank">
                            <xsl:attribute name="href">
                              http://en.wikipedia.org/wiki/Oil_well
                            </xsl:attribute>
                            Oil Well
                          </a>  
                        </td>
                      </tr>                      
                      <tr>
                        <td>
                          video
                        </td>
                        <td>
                          <div>
                          <object width="425" height="344">
                            <param name="movie" value="http://www.youtube.com/v/HVxsbb1lDsQ"></param>
                            <param name="allowFullScreen" value="true"></param>
                            <param name="allowscriptaccess" value="always"></param>
                            <embed src="http://www.youtube.com/v/HVxsbb1lDsQ" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
                          </object>
                          </div>
                        </td>
                      </tr>
                    </xsl:when>                        
                  </xsl:choose>                    
                </xsl:if>                                    
              </xsl:for-each>                              
            </tbody>
          </table>          
        </xsl:for-each>
      </div>
    <!--</body>
    </html>-->
  </xsl:template>

Vous trouverez ci-dessous un exemple de la réponse GetFeatureInfo avec vidéo incorporée dans une application de cartes Web OpenLayers.

Réponse GetFeatureInfo avec vidéo incorporée dans une application de cartes Web OpenLayers

Vous trouverez ci-dessous un exemple plus complet qui personnalise considérablement la réponse GetFeatureInfo afin d'incorporer un bout de code JavaScript. Le code lance une visite dans l'application Web Google Earth. Gardez à l'esprit que ce modèle XSLT contient une logique spécifique à ce service WMS. Par conséquent, il doit toujours être référencé au moyen du paramètre xslt_template. Il ne doit pas devenir le modèle par défaut.

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:esri_wms="http://www.esri.com/wms" xmlns="http://www.esri.com/wms">
  <!--
    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  -->    
  <xsl:output 
    method="html" 
    indent="yes" 
    encoding="UTF-8" 
    omit-xml-declaration="yes"/> 
  <xsl:template match="/">    
  <!--<html>
      <head>-->
        <style type="text/css">
          table, th, td {
            border:1px solid #e5e5e5;
            border-collapse:collapse;
            font-family: arial;          
            font-size: 80%;            
            color: #333333
          }             
          th, td {
            valign: top;
            text-align: center;
          }          
          th {
            background-color: #aed7ff;
          }
          caption {
            border:1px solid #e5e5e5;
            border-collapse:collapse;
            font-family: arial;          
            font-weight: bold;
            font-size: 80%;      
            text-align: left;      
            color: #333333;
            background-color: #aed7ff;            
          }
        </style>
      
    <!--</head>
      <body>-->  
      <div>        
        <xsl:for-each select="esri_wms:FeatureInfoResponse/esri_wms:FeatureInfoCollection">                              
          <table width="100%" cellpadding="0" cellspacing="0" border="1">
            <tbody>                          
              <caption>layer names: '<xsl:value-of select="@layername"/>'</caption>
              <xsl:for-each select="esri_wms:FeatureInfo[1]/esri_wms:Field">
                <xsl:variable name="fieldName" select="esri_wms:FieldName"/>
                <xsl:variable name="fieldValue" select="esri_wms:FieldValue"/>                
                <xsl:if test="$fieldName = 'WGS84_LONGITUDE'">
                  <xsl:variable name="lon" select="esri_wms:FieldValue"/>
                  <tr>
                    <td>lon</td>
                    <td><xsl:value-of select="$lon"/></td>
                    <script type="text/javascript">
                      popup_lon = '<xsl:value-of select="$lon"/>';
                    </script>
                  </tr>
                </xsl:if>
                <xsl:if test="$fieldName = 'WGS84_LATITUDE'">
                  <xsl:variable name="lat" select="esri_wms:FieldValue"/>
                  <tr>
                    <td>lat</td>
                    <td><xsl:value-of select="$lat"/></td>
                    <script type="text/javascript">
                      popup_lat = '<xsl:value-of select="$lat"/>';
                    </script>
                  </tr>
                </xsl:if>                                                                              
                <xsl:if test="$fieldName = 'PLOT_SYMBOL_GROUP'">                  
                  <xsl:choose>                    
                    <xsl:when test="$fieldValue = 14">                                                                                      
                      <tr>
                        <td>
                          3d map
                        </td>
                        <td>
                          <div id="map3d" style="width:384px;height:256px;"></div>
                          <script type="text/javascript">
                            google.earth.createInstance(
                              'map3d', 
                              function(instance) {
                                ge = instance;
                                ge.getWindow().setVisibility(true);
                                
                                var kmlStr = ''                                        
                                  + '<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">'
                                  + '<gx:Tour>'
                                  + '<gx:Playlist><gx:FlyTo>'
                                  + '<gx:duration>20.0</gx:duration>'
                                  + '<LookAt>'
                                  + '<longitude>' + popup_lon + '</longitude>'
                                  + '<latitude>' + popup_lat + '</latitude>'
                                  + '<altitude>0</altitude>'
                                  + '<heading>0</heading>'
                                  + '<tilt>0</tilt>'
                                  + '<range>500</range>'
                                  + '<altitudeMode>relativeToGround</altitudeMode>'
                                  + '</LookAt>'
                                  + '</gx:FlyTo></gx:Playlist>'
                                  + '</gx:Tour>'
                                  + '</kml>';
                                        
                                var kmlObj = ge.parseKml(kmlStr);
                                ge.getTourPlayer().setTour(kmlObj);
                                ge.getTourPlayer().play();                                
                              }, 
                              function() {
                                
                              }
                            );
                          </script>
                        </td>
                      </tr>
                    </xsl:when>  
                  </xsl:choose>                    
                </xsl:if>                                    
              </xsl:for-each>                              
            </tbody>
          </table>          
        </xsl:for-each>
      </div>
    <!--</body>
    </html>-->
  </xsl:template>