Utilisation de couches en WFS

Le support du WFS est assuré dans l'API étendue.

API Web 2D en Javascript

Configuration

L'ajout d'une couche WFS s'effectue de la façon suivante :

maCarte.getMap().addLayer(
    "WFS",
    nom_de_la_couche,
    "url_du_wfs",
    parametres_du_wfs,
    options_couche
);
  • le paramètre nom_de_la_couche contient le texte qui sera affiché dans le gestionnaire de couches. Ce nom peut être une chaîne de caractère ou un objet permettant le support du (Cf. multi-langues) ;
  • le paramètre url_du_wfs contient l'URL du WFS ;
  • le paramètre parametres_du_wfs contient tous les paramètres nécessaires au paramétrage du service WFS comme typename, filter, etc ...
  • le paramètre options_couche contient les paramètres pour gérer le comportement de la couche WFS comme ratio, projection, units, maxExtent, minZoomLevel, maxZoomLevel, isBaseLayer, visibility, originators, etc ... Il est important de noter que l'emprise maxExtent doit être exprimée dans le système de coordonnées projection. Un autre point important est que le support du WFS utilise le format GML, le chargement des attributs des objets nécessite donc l'utilisation de l'option extractAttributes à true (valeur par défaut). Les autres options utiles sont :
    • styleMap : par défaut, l'API crée un légende INSPIRE : les points, lignes et polygones sont en noir :
      styleMap: new OpenLayers.StyleMap({
          strokeColor: "black",
          strokeWidth: 2,
          strokeOpacity: 0.5,
          fillOpacity: 0.2
          fillColor: "black"
      }
    • onSelect, onUnselect, ... : l'API crée un sélecteur par survol par défaut en assignant à l'option onSelect la valeur Geoportal.Control.hoverFeature : il ouvre une popup avec un en-tête contenant la valeur de l'attribut name de l'objet et un corps contenant toutes les valeurs attributaires.

Quoiqu'il en soit il n'y a pas de différence notable entre l'utilisation OpenLayers.Layer.WFS et celle de Geoportal.Layer.WFS excepté pour la gestion de la gestion des droits des données géographiques qui sera :

  • soit ajouté automagiquement par les APIs standard et étendue ;
  • soit ajouté (par le développeur) comme suit (Cf. modes opératoires pour de plus amples informations) :
    • ajouter un paramètre GeoRM dans options_couche ;
    • affecter le code qui suit au paramètre GeoRM :
GeoRM: Geoportal.GeoRMHandler.addKey(
    gGEOPORTALRIGHTSMANAGEMENT.apiKey,
    gGEOPORTALRIGHTSMANAGEMENT[gGEOPORTALRIGHTSMANAGEMENT.apiKey].tokenServer.url,
    gGEOPORTALRIGHTSMANAGEMENT[gGEOPORTALRIGHTSMANAGEMENT.apiKey].tokenServer.ttl,
    maCarte)
Performances

Tout d'abord, relire cette FAQ peut aider à comprendre !

Voici quelques résultats de tests effectués sur un service WFS :

Taille de la réponse GetFeature Nombre d'objets Chargement
1.8Mo 205 échoué
564Ko 699 réussi
483Ko 36 réussi
283Ko 406 réussi
89Ko 89 réussi

Les diverses limitations sont une combinaison de plusieurs facteurs :

  • Taille des géométries des objets : OpenLayers indique 2500 coordonnées, on va plus loin, mais c'est surtout une limitation sur le nombre de coordonnées par objet qui prévaut;
  • Type des objets : pour le rendu en particulier, les polygones, c'est lourd;
  • Nombre d'objets : au delà de 200 objets, le refraichissement de l'affichage est ralenti, mais les deux facteurs précédents sont prépondérants ...
  • Taille de la réponse : il semble que la longueur maximale d'une chaîne Javascript soit "limitée". Cette limitation dépend du navigateur (par exemple, sous Firefox 2, on ne peut avoir de chaîne de plus d'un 1Mo). Jeter un oeil http://bytes.com/topic/javascript/answers/92088-max-allowed-length-javascript-string}là pour de plus amples informations.

    Finalement, que faire :

  • limiter les plages d'affichage pour limiter le nombre d'objets;
  • utiliser le paramètre maxFeatures pour ne pas charger trop d'objets;
  • découper les couches d'objets par plage d'échelles (bases multi-échelles) pour ramener les bons objets (pas trop, avec une géométrie ad hoc) ou le simuler avec Geoportal.Layer.Aggregate;
  • implémenter alors les SuperOverlays}SuperOverlays pour les formats vecteurs;
  • faire des cartes (WMS/Tile) et mettre les opérations GetFeature/GetFeatureInfo limitées à la zone cliquée;
  • passer à l'API Web 2D en ActionScript dès que prête !
Exemple de WFS : Sandre

La capture d'écran ci-dessus repose sur le fragment de code suivant :

function overRiver(feature) {
    if (feature) {
        if (!feature.popup) {
            var ll= feature.geometry.getBounds().getCenterLonLat();
            var me= maCarte.getMap().getExtent();
            var inView= me.containsLonLat(ll,false);
            if (!inView) {//hors de la visualisation
                ll= me.getCenterLonLat();
            }
            feature.popup= new OpenLayers.Popup.FramedCloud(
                "chicken",
                ll,
                null,
                // on affiche l'attribut 'NAME' dans l'info-bulle :
                "<div style='font-size:.75em'>" + feature.attributes['NAME']+ "</div>",
                null,
                false);
        }
        if (feature.popup) {
            maCarte.getMap().addPopup(feature.popup,true);
        }
    }
}

function outRiver(feature) {
    if (feature && feature.popup) {
        feature.popup.destroy();
        feature.popup= null;
    }
}

...

var rwbodyStyle= new OpenLayers.StyleMap({
    "default": new OpenLayers.Style({
        strokeColor:'#0000ff',
        strokeWidth:3
    }),
    "select": new OpenLayers.Style({
        strokeColor:'#3399ff',
        strokeWidth:3
    })
});
var sandre= maCarte.getMap().addLayer(
    "WFS",
    {
        'sandre.layer.name':
        {
            'de':"Wasser kurses",
            'en':"Water courses",
            'es':"Cursos de agua",
            'fr':"Cours d'eau",
            'it':"Corsi d'acqua"
        }
    },
    "http://services.sandre.eaufrance.fr/geo/zonage-shp?",
    {
        typename: 'RWBODY'
    },
    {
        projection: 'EPSG:4326',
        units:'degrees',
        // maxExtent est exprimée en EPSG:4326 :
        maxExtent: new OpenLayers.Bounds(-180,-90,180,90),
        minZoomLevel:10,
        maxZoomLevel:15,
        isBaseLayer: false,
        visibility: false,
        originators: [
            {
                logo:'sandre',
                pictureUrl: 'logo_sandre.gif',
                url: 'http://sandre.eaufrance.fr'
            }
        ],
        extractAttributes:true,
        styleMap:rwbodyStyle,
        onSelect: overRiver,
        onUnselect: outRiver,
        hover: true
    }
);