X

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
Florian Delahaye: Passionné de Géomatique

View Comments (34)

  • 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

  • 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?

  • 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.

  • 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? :/

  • 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é.

  • 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?

  • 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).

  • 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.

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

  • 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);

    • 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

Related Post