Aller au contenu

Exercices Webmapping - Hydro

Exercice - Architecture webmapping + diffusion flux WMS#

L’objectif de cet exercice est de visualiser les cours d’eau de France sur une carte. Pour cela, nous avons a disposition les données de la BD Topage, que nous allons connecter à un serveur cartographique GeoServer, pour créer un flux WMS tuilé, et ainsi l’afficher sur une carte OpenLayers.

Pour simplifier le déploiement, un Starter Kit Docker est disponible.

  • installez Docker
  • récupérez le code (git clone https://github.com/iamvdo/webaz-docker-starter-kit)
  • lancez la stack avec docker compose up -d

Les données#

  • connectez-vous à votre base Postgres/PostGIS avec pgadmin (http://localhost:5050)
  • vérifiez que PostGIS est activé (ou faites CREATE EXTENSION POSTGIS;) sur votre base mydb
  • téléchargez l’export au format Shapefile (~180Mo) (GeoJSON ou GeoPackage également disponibles) dans le dossier ./data
  • intégrez les données avec GDAL
    • ouvrir un shell dans le conteneur avec docker compose run --rm -it gdal sh
    • ogr2ogr -f "PostgreSQL" PG:"host=db dbname=mydb user=postgres password=postgres" CoursEau_FXX.shp -nln <nom-table> -nlt PROMOTE_TO_MULTI -lco OVERWRITE=YES
    • exit

Serveur cartographique#

  • accédez à votre GeoServer
    • URL: http://localhost:8080/geoserver
    • user admin, pass geoserver
  • créez un nouvel espace de travail (nom, url, espace par défaut)
  • créez un nouveau Store de type PostGIS (avec les bonnes informations de connexion)
  • publiez un nouveau Layer (données en EPSG:2154)
    • pensez à faire calculer les Bounding Boxes
  • vérifiez que le flux s’affiche dans Layers Preview
  • (créez ou modifiez le style graphique dans Styles)

Appli carto coté client#

Visualisation de la couche#

  • créez une nouvelle page
  • créez une carte OpenLayers
    • la carte doit être centrée sur Paris (2.35 / 48.85)
    • niveau de zoom 12
    • fond de carte au choix

<!-- Librairie OpenLayers -->
<link rel="stylesheet" href="https://unpkg.com/ol/ol.css">
<script src="https://unpkg.com/ol/dist/ol.js"></script>
new ol.Map({
    target: 'map',
    view: new ol.View({
        center: ol.proj.fromLonLat([2.35, 48.85]), // attention, OpenLayers par défaut en 3857
        zoom: 13,
    }),
});

  • ajoutez une nouvelle couche pour le flux WMS
    • couche de type ol.layer.Tile
    • source de type ol.source.TileWMS
      • avec URL de votre geoserver
      • params : LAYER le nom de votre couche, TILED: true pour un WMS tuilé
new ol.layer.Tile({
    source: new ol.source.TileWMS({
        url: 'http://localhost:8080/geoserver/wms',
        params: {'LAYERS': '<nom-du-layer>', 'TILED': true},
    })
})

Sélection d’un cours d’eau#

Lors du clic sur un tronçon, nous voulons visualiser le cours d’eau sélectionné, et afficher son toponyme dans la page. Pour cela :

  • créez d’abord un nouveau calque vectoriel qui servira à afficher le cours d’eau sélectionné (calque de type ol.layer.Vector, source ol.source.Vector)
new ol.layer.Vector({
    source: new ol.source.Vector(),
    style: new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: 'red',
            width: 5,
        }),
    }),
})
  • ajoutez un évenement click sur la carte
  • générez l’URL pour réaliser ensuite un getFeatureInfo sur votre flux WMS
    • attention, wmsSource n'existe pas encore: récupérez la source de votre couche
map.on('click', (evt) => {
    let viewResolution = map.getView().getResolution();
    let url = wmsSource.getFeatureInfoUrl(
        evt.coordinate, // la coordonnée cliquée
        viewResolution,
        'EPSG:3857', // projection par défaut dans OpenLayers
        {'INFO_FORMAT': 'application/json'} // format de retour souhaité
    );
});
  • faites un appel AJAX sur cette URL avec fetch
  • récupérez le résultat en geoJSON (par défaut) et ajoutez les features dans le calque vectoriel créé plus tôt. Pour cela :
    • récupérez les features du geoJSON : let features = new ol.format.GeoJSON().readFeatures(json)
    • ajoutez les features au calque : layer.getSource().addFeatures(features)

Afin de faire comprendre que la couche est cliquable, nous souhaitons gérer une interaction avancée sur les pixels de la couche WMS (un survol) :

  • ajoutez un événement pointermove sur la carte
  • utilisez la méthode getData de votre couche ol.layer.Tile (renvoie un tableau contenant les données colorimétriques, si la source définit crossOrigin: 'anonymous')
  • si le résultat contient des données (donc des couleurs), modifiez le curseur de la carte (voir exemple ci-dessous) pour simuler un effet de survol
// change cursor on hover
map.on('pointermove', evt => {
    let data = layer.getData(evt.pixel);
    let hit = data && (data[0] > 0 || data[1] > 0 || data[2] > 0);
    map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});

Enfin, à l’aide de Vue.js :

  • ajoutez le nom de la feature (clé topooh) dans un bloc de la page
  • pensez à supprimer tous les objets du calque (layer.getSource().clear()) à chaque clic

Vue SQL#

Dernière étape, nous allons créer une Vue SQL pour n’afficher que les cours d’eau de plus de 100km.

  • à l’aide de pgadmin, créez une nouvelle vue SQL cours-eau-100km
  • créez une requête SQL qui utilise ST_Length de PostGIS
    • SELECT * FROM <nom_table> WHERE ST_Length(wkb_geometry::geometry) >= 100000
  • visualisez les données

Dans GeoServer :

  • creéz une nouvelle couche, depuis l’entrepot correspondant à notre base
  • publiez la couche cours-eau-100km

Interface web :

  • modifiez votre code pour afficher cette nouvelle couche, à votre convenance