Afficher des flux WM(T)S et WFS avec Openlayers depuis Geoserver

Dans les articles précédents, on a vu comment installer le serveur web Apache et le langage de programmation PHP, le Système de Gestion de Base de Données (SGBD) PostgreSQL et son extension spatiale PostGIS et le serveur cartographique Geoserver, il est temps maintenant de développer nos premières interfaces web.

Dans Geoserver, on a créé plusieurs espaces de travail et/ou entrepôts dans le serveur cartographique afin d’organiser les données spatiales. Dès lors, après avoir réalisé une première carte à l’aide de l’API d’Openlayers, l’objectif ici est de développer un script pour afficher des couches WFS et WM(T)S stockées dans le serveur cartographique. Un descriptif des protocoles WFS(-T), WM(T)S et WCS est disponible sur ce lien. Pour rappel, le WMTS permet de charger des données rasters tuilées plus rapidement qu’un WMS en format image.

Dans le code, il suffit de charger la feuille de style et la bibliothèque Openlayers (v 3.20.1 dans cet article) dans le <head> du code puis dans le <body> de déclarer la <div> de la carte et enfin, le Javascript affectée à cette carte. On prend comme exemple des vecteurs chargés par défaut lors de l’installation de Geoserver issus de deux espaces de travail distincts : topp et tiger.

Il faut bien distinguer les objets source et layer qui sont associés à différentes classes de l’API. La source permet de charger la structure de la donnée spatiale (attributs, géométrie, etc) alors que le layer définit comme son nom l’indique la couche affichée sur la carte par l’objet Map.

<!DOCTYPE html>
<html>
	<head>
		<title>Affichages de flux WMS, WMTS et WFS</title>
		<link rel="stylesheet" href="http://openlayers.org/en/v3.20.1/css/ol.css" type="text/css">
		<script src="http://openlayers.org/en/v3.20.1/build/ol.js"></script>
	</head>
	<body>
		<!-- Déclaration de la div map dans le corps du code -->
		<div id="map" class="map"></div>
		<!-- Code Javascript pour l'appel de la carte et des sources affichées -->
		<script>
			/* Déclaration de la source de la couche en format WMTS */
			var sourceWMTS = new ol.source.TileWMS({
				/* Chargement du lien WMS */
				url: 'http://localhost/geoserver/wms',
				/* Chargement de l'espace de travail : couche */
				params: {'LAYERS': 'topp:states', 'TILED': true},
				serverType: 'geoserver'
			})
			/* Déclaration de la couche WMTS */
			var coucheWMTS = new ol.layer.Tile({ 
				source: sourceWMTS,
				opacity: 0.5
			});

			/* Déclaration de la source de la couche en format WMS */
			var sourceWMS = new ol.source.ImageWMS({
				/* Chargement du lien WMS */
				url: 'http://localhost/geoserver/wms',
				/* Chargement de l'espace de travail : couche */
				params: {'LAYERS': 'tiger:poly_landmarks', 'TILED': true},
				serverType: 'geoserver'
			})
			/* Déclaration de la couche WMS */
			var coucheWMS = new ol.layer.Image({ source: sourceWMS });

			/* Déclaration de la source de la couche en format WFS */
			var sourceWFS = new ol.source.Vector({
				/* Chargement du lien WFS en format json*/
				url: 'http://localhost/geoserver/wfs?service=WFS&' +
				'version=1.1.0&request=GetFeature&typename=tiger:tiger_roads&' +
				'outputFormat=application/json',
				format: new ol.format.GeoJSON(),
				serverType: 'geoserver'
			})
			/* Déclaration de la couche WFS */
			var coucheWFS = new ol.layer.Vector({ source: sourceWFS });

			/* Déclaration des couches*/
			var couches = [coucheWMTS,coucheWMS,coucheWFS]; 

			/* Déclaration de la carte */
			var map = new ol.Map({
				/* Appel des couches de la carte */
				layers: couches,
				/* Cible de la div map */
				target: 'map',
				/* Caractéristiques de la vue de la carte */
				view: new ol.View({
					center: [-8233510, 4980620],
					zoom: 13
				})
			});
		</script>
	</body>
</html>

Le résultat est ce zoom sur New York avec les trois vecteurs affichés (figure 1) :

Figure 1 : Affichage des flux WM(T)S et WFS sur Openlayers depuis Geoserver.

En résumé, ce script montre comment afficher des vecteurs stockés dans Geoserver par les protocoles WFS et WM(T)S avec Openlayers. Il est aussi possible de charger le WFS en format image avec la source ImageVector.

Note : Si tu utilises un autre domaine que localhost (par exemple localhost:8080) et que tu n’utilises pas de proxy sur ton serveur Apache (ou autre serveur web), tu dois rencontrer un problème pour charger ton vecteur par le protocole WFS? C’est une erreur fréquente car ton code est placé sur le serveur web alors que le protocole WFS provient du serveur cartographique. Cela signifie que le Cross Domain n’est pas autorisé sur le serveur cartographique. Tu peux trouver l’explication de ce concept et une résolution du problème, autre que celle de l’utilisation d’un proxy, dans cet article.

Partager l'article
Taggé , , , , , , , , , , , , .Mettre en favori le Permaliens.

A propos Florian Delahaye

Passionné de Géomatique

34 réponses à Afficher des flux WM(T)S et WFS avec Openlayers depuis Geoserver

  1. 95Berry dit :

    I must say you have high quality posts here. Your website can go viral.
    You need initial boost only. How to get it? Search for: Etorofer’s strategies

  2. Miko dit :

    Bonjour,

    dans l’option « url » => url: ‘http://localhost/geoserver/wms
    C’est le lien exact qu’on peut copier lorsqu’on affiche la couche via Openlayer sur geoserver?

  3. Florian Delahaye dit :

    Bonjour Miko,
    l’URL de la donnée dépend du chemin de l’installation du serveur et du port utilisé. Dans l’exemple, GeoServer est installé en local d’où l’utilisation de localhost. Si le port utilisé est autre que le 80, il faut utiliser : localhost:port (8080 par défaut pour GeoServer).
    Si maintenant GeoServer est installé dans un sous-domaine, il faut saisir l’URL : http://sous-domaine.domaine/geoserver/wms puis on appelle le couple : espace de travail:couche dans les paramètres.
    Il est aussi possible d’utiliser : http://localhost/geoserver/espace de travail/wms puis dans les paramètres, on saisit le nom de la couche seule.

    Vous pouvez tester l’URL de la requête de la couche dans le firebug qui devrait ressembler à cela pour GeoServer :
    http://localhost/geoserver/tiger/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image/png&TRANSPARENT=true&LAYERS=poly_landmarks&TILED=true&CRS=EPSG:3857&STYLES=&WIDTH=2471&HEIGHT=1243&BBOX=-8257114.709797316,4968753.1513587255,-8209905.290202684,4992486.8486412745

    N’hésitez pas si vous avez un souci.

  4. Miko dit :

    Merci beaucoup pour votre avis sur mon problème!!

    J’essaye de créer un plan de reseau de bus dynamique dans le cadre de mon stage. A partir de geoserver, j’ai importé une couche [stigo_lignes] de postgis dans mon plan de travail appelé ‘transdev77_be’. Jusque là tout va bien, sauf au moment où j’essaye de l’interger sur mon site carto hébergé en localhost 8080 encore pour le moment:

    var stigo_lignes = new ol.layer.Image({
    source: new ol.source.ImageWMS({
    url: ‘http://localhost:8080/geoserver/transdev77_be/wms?service=WMS&version=1.1.0&request=GetMap&layers=transdev77_be:stigo_lignes&styles=&bbox=674032.8125,6850417.5,677993.0625,6853271.0&width=768&height=553&srs=EPSG:3857&format=application/openlayers’,
    params:{‘LAYERS’:’transdev77_be:stigo_lignes’,
    ‘VERSION’:’1.1.0′,
    ‘FORMAT’:’image/png’
    }
    })
    });

    A ce moment précis, la couche n’apparzît pas et je n’ai pas de messages d’erreur qui s’affiche…d’où ma question hier sur l’url car je pense que c’est le problème, à moins que j’ai mal réaliser l’import de la couche de postgis?

    Avez-vous peut-être une idée? :/

  5. Florian Delahaye dit :

    Miko,
    l’url utilisé dans votre script contient tous les paramètres à l’appel de la couche : espace de travail, couche, styles, bbox, etc. Si vous saisissez l’URL dans un navigateur, vous obtiendrez l’image de votre couche.

    Dans le code, vous avez juste à déclarer l’URL du service wms puis dans params, les paramètres précités.
    Dans votre exemple, ce code devrait fonctionner :

    var stigo_lignes = new ol.layer.Image({
    source: new ol.source.ImageWMS({
    url: ‘http://localhost:8080/geoserver/wms’,
    params:{‘LAYERS’:’transdev77_be:stigo_lignes’,
    ‘VERSION’:’1.1.0′,
    ‘FORMAT’:’image/png’
    }
    })
    });

    Tenez-moi informé.

  6. Miko dit :

    J’ai réessayé et ça ne marche pas…par contre j’ai testé l’affichage des arrets et là aucun problème! Mais je n’arrive pas avec les lignes…existe-t-il un lien?

  7. Florian Delahaye dit :

    Pouvez-vous prévisualiser la couche des lignes à partir de GeoServer (onglet : prévisualisation de la couche > OpenLayers) ?
    Si non, il y a un problème lié à la publication de la couche (projection, style).

  8. Miko dit :

    Oui justement j’arrive à lire sur la prévisualisation Openlayers et la projection est la meêm par contre je peux verifier le style. Cependant, si le style n’est pas bon, je ne devrais pas voir la couche sur la prévisualisation? Je vais tester et je vous tiens au courant immédiatement.

  9. Florian Delahaye dit :

    Si vous arrivez à prévisualiser la couche, c’est que vous avez une coquille dans votre code. Vous pouvez me l’envoyer par mail?

  10. Miko dit :

    var map = new ol.Map({
    layers: [
    new ol.layer.Tile({
    source: new ol.source.OSM()
    })
    ]
    });

    var view = new ol.View({
    zoom: 15,
    projection: ‘EPSG:3857’,
    minZoom:10
    });

    var PositionSouris = new ol.control.MousePosition({ // Variable PositionSouris stocke l appli controle souris
    coordinateFormat: ol.coordinate.createStringXY(2), // Definit le format des coordonnées qui seront affichés
    projection: ‘EPSG:4326′
    });

    var PaysdeMeaux = new ol.layer.Vector({
    source: new ol.source.Vector({
    url:’Menus/Reseaux/MarneEtMorin/Reseau_PaysdeMeaux.kml’,
    format:new ol.format.KML()
    })
    });

    var arrets_idf_est = new ol.layer.Image({
    source: new ol.source.ImageWMS({
    url: ‘http://localhost:8080/geoserver/wms’,
    params:{‘LAYERS’:’transdev77_be:arrets_idf_est’,
    ‘VERSION’:’1.1.0′,
    ‘FORMAT’:’image/png’
    }
    })
    });

    var stigo_lignes = new ol.layer.Image({
    source: new ol.source.ImageWMS({
    url: ‘http://localhost:8080/geoserver/wms’,
    params:{‘LAYERS’:’transdev77_be:stigo_lignes’,
    ‘VERSION’:’1.1.0′,
    ‘FORMAT’:’image/png’
    }
    })
    });

    map.addLayer(PaysdeMeaux);
    map.addLayer(arrets_idf_est);
    map.addLayer(stigo_lignes);
    map.addControl(PositionSouris); // Afficher les contrôles sur la carte
    map.setTarget(‘js-map’); // Cible la classe js map

    view.setCenter([311484, 6249684]); // Centre de la carte
    map.setView(view);

    • Florian Delahaye dit :

      Je ne vois pas de souci particulier. Testez ce code qui change la source de donnée TileWMS et la version du WMS :
      var stigo_lignes = new ol.layer.Tile({
      source: new ol.source.TileWMS({
      url: ‘http://localhost:8080/geoserver/wms’,
      params: {‘FORMAT’: ’image/png’,
      ‘VERSION’: ‘1.1.1’,
      tiled: true,
      STYLES:  »,
      LAYERS: ‘transdev77_be:stigo_lignes’,
      }
      })
      });
      Redites-moi svp

  11. Miko dit :

    Du coup la couche arrets_idf_est fonctionnement mais pas stigo_lignes….

  12. Florian Delahaye dit :

    Étant donnée que la prévisualisation fonctionne, une autre solution est de sauvegarder le code de la page de prévisualisation d’OpenLayers et d’adapter le code.
    Par ailleurs, vous pouvez essayer d’attacher un style avec un trait plus grossier pour les lignes avec GeoServer.

  13. Miko dit :

    Merci pour vos conseils et d’avoir consacré du temps! Je vais essayer votre méthode en espérant réussir!

    • Florian Delahaye dit :

      S’il y a toujours un souci, je peux tester vos données linéaires en local. Si vous voulez me transmettre la couche SIG par mail (ou juste une partie), n’hésitez pas.

  14. Miko dit :

    Merci de votre part! Je le ferai sans hésitation. Si ej trouve la réponse, je la publierai également!

  15. MIKO dit :

    Bonsoir à tous,

    J’ai trouvé la solution à mon problème. Mon souci était lié à la base de donnée. En effet j’ai déclaré deux fois à travers Geoserver la même source de données sous des noms différents (« arrets » et « lignes ») quand on fait une connexion à Postgis pour importer de nouvelles couches! J’ai du coup tout supprimé et réimporté mes couches en me reconnectant à Postgis en utilisant la même source de données nommé ‘reseau’ et ça marche. Merci pour tout en tout cas!

  16. Miko dit :

    Merci Florian!

  17. bel dit :

    bonjour !
    je veux afficher des couches vecteur via WFS j’utilise l’url http://localhost:8080/geoserver mais ça n’affiche rien !

    • Florian Delahaye dit :

      Bonjour Bel,
      Pouvez-vous me donner plus de précisions pour vous aider?
      Depuis GeoServer, est-il possible de prévisualiser les couches concernées en WMS depusi prévisualisation des couches?
      Comment appelez-vous votre couche dans JavaScript?
      Quel est le message d’erreur renvoyé dans le navigateur web?

  18. bel dit :

    bonjour!
    1- pour le wms tout marche bien
    2- les couches sont appeler par typeNS,typeName,crs,geometryField sous le client leaflet.
    3- le navigateur m’affiche une erreur « Error: The provided object is not a Layer » et dépassement de mémoire.

    • Florian Delahaye dit :

      Bonjour,
      Je pense que vous ne saisissez pas les bonnes informations dans le typeNS et typeName puisque l’erreur indique qu’il ne reconnaît pas l’URL de la couche. Pouvez-vous copier votre code et m’indiquer le nom de l’espace de travail et de la couche?

  19. bel dit :

    je teste avec les données du geoserver

    var wfst = new L.WFST({
    url: ‘http://localhost:8880/geoserver/ows’ ,
    typeNS: ‘tiger’,//espace de travail
    typeName: ‘tiger_roads’, // nom de couche
    crs: L.CRS.EPSG4326,
    geometryField: ‘the_geom’,
    style: {
    color: ‘blue’,
    weight: 2
    }
    }).addTo(map)
    .once(‘load’, function () {
    map.fitBounds(wfst);
    });

  20. Florian Delahaye dit :

    Bel,
    Avez-vous installer un plugin pour lire les fluw wfs sur Leaflet, par exemple : https://github.com/Flexberry/Leaflet-WFST ? L’installation d’un plugin est nécessaire car nativement, l’API de Leaflet ne lit pas les WFS.
    Je ne connais pas votre projet mais personnellement, je vous conseille d’utiliser OpenLayers qui a beaucoup plus de possibilités natives à l’API, c’est un avantage dans l’évolution de projets.

  21. bel dit :

    bonjour!
    j’ai testé avec OpenLayers ça fonctionne très bien
    merci pour votre aide 🙂

  22. Laurent_Hood dit :

    Bonjour,
    J’ai suivi ce poste pour afficher mes données Geoserver en JSON avec OL via le WFS et tout fonctionne parfaitement (je remercie d’ailleurs M. Delahaye) Un problème subsiste néanmoins concernant le système de projection: mes données (wfs) sont bien identifiées en 2154 par Géoserver mais OL semble tourner en 3857. Malgré mes efforts pour trouver une solution je ne parviens pas à y remédier. Quelqu’un aurait-il une astuce ? Merci d’avance

    • Florian Delahaye dit :

      Bonjour Laurent,
      OL accepte nativement les SCR EPSG:4326 et 3857. Pour prendre en charge le 2154, soit vous « reprojetez » côté GeoServer ou soit côté OL, vous définissez la projection 2154 avec la bibliothèque proj4js. Pour cette dernière solution, vous avez un exemple en ligne sur le site d’OL : https://openlayers.org/en/latest/examples/wms-image-custom-proj.html ou vous pouvez accéder à ma formation en ligne sur demande.
      Bien Cordialement,
      FD

      • Laurent_Hood dit :

        Merci Beaucoup,
        Effectivement la solution 1, dans mon cas semble être la plus adaptée (et surtout la plus rapide) et en plus ça fonctionne.
        Bonne journée à vous

  23. Thomas dit :

    Bonjour,
    J’essaie d’afficher un service WFS (pour l’instant en localhost) émis depuis Geoserver par l’intermédiaire de Openlayer.
    Sur Openlayer, pour la même couche il n’y a aucun problème à l’afficher en WMS mais impossible pour le WFS.
    Par contre il n’y a aucun problème à afficher le flux sur Qgis. Si je prends votre exemple, les deux format WMS s’affichent correctement, mais rien pour le WFS.
    Est-ce qu’il y aurait un problème de configuration du Geoserver?
    Par avance merci pour votre temps
    Thomas

    • Florian Delahaye dit :

      Bonjour Thomas,

      Vous devez examiner les erreurs sur le navigateur web. Je pense que l’erreur est liée au Cross Origin. En clair, il faut que vous configurez GeoServer pour permettre de lire les flux sur votre serveur hébergeant le code avec OpenLayers. Un article sur le sujet est disponible sur le site. Cdlt. FD

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *