# Consommer les ressources distantes géospatiales sur data.gouv.fr

Le portail data.gouv.fr référence de nombreuses données OpenData. Certaines sont directement mises à disposition sur le site, d'autres jeux de données référencent des pages tierces avec les jeux de données ou bien un jeu de donnée référence une URL distante.

Nous allons nous concentrer sur le dernier cas en nous concentrant sur une partie spécifique, la donnée géospatiale. Si vous voulez une compilation des jeux de données géographiques les plus classiques, allez sur la page Les données à composante géographique Si vous êtes plutôt intéressés par les API, nous documentons déjà l'API Adresse, l'API découpage administratif et les API d'accès aux tuiles vectorielles.

# Pourquoi abordons nous spécifiquement ce cas?

Dans un passé pas si lointain, Etalab entretenait le site geo.data.gouv.fr mais la maintenance étant consommatrice de ressources, des choix pour le décommissionner ont été fait. Voir l'article "Extinction de geo.data.gouv.fr" pour en savoir plus.

La problématique est que la plateforme permettait de mettre en cache des données géospatiales qui sont normalement mises à disposition sous forme de service web, difficilement accessibles pour les néophytes. Généralement, ces formats ne sont bien compris par des spécialistes dans les données géographiques qu'on désigne sous des termes peu connu comme géomaticiens (métier associé au mot géographie et informatique), spécialiste SIG (Système d'Information Géographique) ou SIGiste. Le but est de rémédier à cette situation en facilitant la compréhension pour mieux réutiliser la donnée.

La plateforme data.gouv.fr avec l'extinction de geo.data.gouv consomme maintenant les données de catalogues contenant des données géospatiales, en particulier le geocatalogue. On parle de métadonnées. Ces dernières contiennent les descriptions des jeux de données et des listes de service.

Ces services peuvent prendre la forme:

  • de service pour afficher des données vecteur et/ou télécharger la donnée sous forme de flux (WFS)
  • de services pour consommer des fichiers directement téléchargeables (Atom)
  • de service pour l'affichage sous forme d'image et l'interrogation ponctuelle (WMS),

# L'intérêt des 3 cas illustrés:

Nous n'insistons pas ici sur les modalités pour faire les opérations mais sur l'intérêt que cela présente.

# WFS (Web Feature Service)

Cas 1:

Vous souhaitez disposer de données mises à jour régulièrement. Le WFS est un bon moyen pour cela car il contient les géométries et les attributs des données. Il vous permet d'avoir d'un côté la possibilité de rajouter un style comme si vous aviez un fichier SIG local type Shapefile/shp. Ainsi, on peut appliquer un style sur le WFS très facilement comme ci-dessous où on applique des motifs et où on a surtout accès aux attributs de la donnée visualisable sous forme tabulaire. url pour l'accès aux données sous forme GML ("Geography Markup Language", un dérivé de XML pour les données géographiques), ouvrable dans le navigateur.

Il économise de l'espace disque et/ou de la bande passante car il permet de ne récupérer la donnée que sur une emprise géographique ou des filtres suivant des conditions dans les champs et pas uniquement tout le jeu de données.

Les inconvénients: il peut s'avérer long à afficher car le contenu distant peut s'avérer lourd donc long à récupérer via votre connexion internet. Vous risquez d'avoir un jour le flux qui s'arrête donc plus rien à consommer.

Cas 2:

Vous pouvez aussi récupérer ce WFS et l'avoir sous forme de fichier sur votre machine. Cela évite si la donnée n'est pas mis à jour de la récupérer en permanence et d'avoir la lenteur du réseau qui vous affecte et ne plus dépendre du service si celui-ci disparait ou change (par exemple, ajout/suppression de colonnes ou nouvelle manière de remplir un même champ). Si c'est possible, il souvent recommandé de passer par le flux Atom s'il est disponible.

# Flux Atom

Il s'agit d'un format qui permet de diffuser une liste de flux pour permettre de suivre les mises à jour de données. Il permet aussi de récupérer les données associées à un WFS et/ou un WMS.

Dans le meilleur des cas, on a correspondance entre un flux WMS pour visualiser sous forme image, un WFS pour de la consultation en ligne vecteur ou du téléchargement et un flux Atom pour télécharger. Dans cette configuration, il faut généralement privilégier le flux Atom si on veut les données sur sa machine.

C'est le cas pour les données précédemment montrées en aperçu où on dispose d'un jeu de données Atom.

Dans ce cas précis, vous allez récupérer un ensemble de fichiers qui viennent du logiciel MapInfo car ils contiennent un fichier tab accompagné d'autres fichiers portant le même nom mais avec une autre extension (on parle de format MapInfo Tab) et un XML qui contient les métadonnées du fichier.

# WMS (Web Map Service)

Vous ne souhaitez pas télécharger les données mais les regarder dans votre SIG ou dans votre WebSIG, vous passez par un WMS. Pour illustrer, voici un exemple ci-dessous avec la superposition "Modelisation de l'urbanisation taches urbaines situation en 1980 en Franche Comte" (url de l'image consultable dans le navigateur) sur un fond de plan IGN.

# Prérequis:

Il est utile, voire nécessaire d'installer QGIS sur votre machine. Allez sur la page officielle QGIS "Téléchargez QGIS" puis déplier le menu "Téléchargement pour Windows". Un gros bouton vert "Télécharger QGIS 3.xx" apparaît . Si vous voulez les dernières fonctionnalités, téléchargez le fichier puis faites du "Suivant Suivant" pour installer QGIS.

Il faut noter la présence d'un texte juste en dessous du gros bouton vert, "En quête de la version la plus stable? Télécharger QGIS 3.xx LTR". Ceux qui prennent cette version cherche un support plus long dans le temps même s'ils ne disposeront de ce fait pas des fonctionnalités récemment introduites. Généralement, ce sont des entreprises, des collectivités qui préfèrent cette option afin de faire une mise à jour moins régulière pour maintenir leurs parcs de machine.

# Consommer le WFS

WFS comme Web Feature Service est un standard créé par l'OGC (comme Open Geospatial Consortium) qui permet de consommer des "features" (objets géographiques), c'est à dire des données vectorielles.

# Le standard WFS

Il existe plusieurs types de requêtes pour interroger un serveur WFS

<?xml version='1.0' encoding="UTF-8" ?>
<schema
   targetNamespace="http://mapserver.gis.umn.edu/mapserver" 
   xmlns:ms="http://mapserver.gis.umn.edu/mapserver" 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns="http://www.w3.org/2001/XMLSchema"
   xmlns:gml="http://www.opengis.net/gml/3.2"
   elementFormDefault="qualified" version="0.1" >

  <import namespace="http://www.opengis.net/gml/3.2"
          schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd" />

  <element name="Tache_urbaine_1980_R43" 
           type="ms:Tache_urbaine_1980_R43Type" 
           substitutionGroup="gml:AbstractFeature" />

  <complexType name="Tache_urbaine_1980_R43Type">
    <complexContent>
      <extension base="gml:AbstractFeatureType">
        <sequence>
          <element name="geometry" type="gml:SurfacePropertyType" minOccurs="0" maxOccurs="1"/>
          <element name="Id" minOccurs="0" type="string"/>
          <element name="Annee_tache" minOccurs="0" type="integer"/>
          <element name="Surface_ha" minOccurs="0" type="double"/>
        </sequence>
      </extension>
    </complexContent>
  </complexType>

</schema>

On déduit que la couche Tache_urbaine_1980_R43 dispose des colonnes Id de type string, Annee_tache de type integer et Surface_ha de type double et que la couche dispose d'une géométrie de type polygone.

Vous pouvez tomber sur d'autres types d'opération pour le WFS. Ils s'expliquent par l'existence d'un version du WFS dite WFS-T comme Transactionnel. C'est à dire qui permet de la mise à jour de la base de données depuis un service WFS qui permet l'écriture et pas seulement la lecture. On n'aborde pas ces opérations liées à ce dernier, étant dans une logique de consommation des données.

# Pour en savoir plus

Voir les documentations suivantes :

# L'écosystème autour du WFS

# Client lourd SIG bureautique QGIS

Pour QGIS, vous pouvez prendre le guide mis à disposition par l'IGN "Utiliser les données IGN en flux WFS". Les instructions sont similaires, la seule chose qui change est l'URL à remplir.

Pour mieux comprendre le WFS, un des meilleurs moyens est de passer par le pannel "Débogage/Outils de Développement" (raccourci clavier F12) pour pouvoir comprendre les requêtes réseaux effectuées par QGIS lorsqu'il fait les appels WFS. Voir la capture ci-dessous

# WFS client léger

Pour l'affichage de carte en WFS,

  • OpenLayers
  • Maplibre GL JS. Démo non fournie car compliquée à gérer. Cela dépend en effet selon si le serveur WFS retourne les données sous forme GeoJSON ou pas, ce qui relève de WFS au cas par cas.
  • Leaflet (Démo dédiée)

# bibliothèques WFS côté serveur

  • Utilitaires en ligne de commande de GDAL ogrinfo et ogr2ogr. Pour comprendre leur utilisation, voir le tutoriel pour le WFS de l'IGN. Ce qui change ici est le fait que les URLs changent mais les principes restent les mêmes.
  • owslib (Python)

# Consommer le WMS

# Le standard WMS

Ce standard WMS comme Web Map Service est ancien (1999). Il est comme le WFS, produit par l'OGC. Il est basé sur SOAP. La spécification a 2 versions officielles. Les serveurs généralement supportent 2 versions, la version 1.1.1 et la 1.3.0.

# Les deux principaux types de requêtes

# Les types de requête optionnels

Ils existent des opérations optionnelles qui selon les serveurs sont activées ou non selon ce qui est indiqué dans le bloc <Request> de GetCapabilities

# Pour en savoir plus

Voir les documentations suivantes :

# L'écosystème pour consommer des WMS

# Client lourd SIG bureautique QGIS

Pour QGIS, vous pouvez prendre le guide mis à disposition par l'IGN "Utiliser les données IGN en flux WMS/WMTS". Les instructions sont similaires, la seule chose qui change est l'URL à remplir.

# Client léger web

Pour utiliser les "capabilities" WMS,

JavaScript

Pour l'affichage de carte en WMS (opération GetMap),

Vous avoir un aperçu visuel rapide d'un couche, vous pouvez passer par le projet mviewer comme illustré via cet exemple via un proxy.

Attention: Pour le web, il faut généralement utiliser un proxy car tous les serveurs ne supportent pas qu'on accède depuis une page web à leur contenu hébergé sur un autre domaine. Il existe des proxy publics comme https://data.europa.eu/deu-proxy? ou https://corsproxy.io/? mais nous vous recommandons d'installer le vôtre si vous avez un usage en production. Il en existe dans la plupart des languages de programmation. Vous pouvez trouvez une liste sur https://github.com/topics/cors-proxy?o=desc&s=stars (filtrez selon votre language de programmation).

# Accès languages serveur WMS

Il sert à adresser l'accès à la liste des couches et leur description ou bien encore un aperçu image d'une couche. Voir ci-dessous pour des exemples en Python

Liste des informations du WMS

Python

Avec Owslib

from owslib.wms import WebMapService

wms = WebMapService('https://ogc.geo-ide.developpement-durable.gouv.fr/wxs?map=/opt/data/carto/geoide-catalogue/1.4/org_38154/aea04585-605e-4372-abec-ade0d2380076.internet.map', version='1.3.0')

for operation in wms.operations:
    print(operation.name)
    print(operation.methods)
    print(operation.formatOptions)

for name, content_metadata in wms.items():
    print('crsOptions', content_metadata.crsOptions)
    print('crs_list', content_metadata.crs_list)
    print('dataUrls', content_metadata.dataUrls)
    print('defaulttimeposition', content_metadata.defaulttimeposition)
    print('dimensions', content_metadata.dimensions)
    print('elevations', content_metadata.elevations)
    print('featureListUrls', content_metadata.featureListUrls)
    print('fixedHeight', content_metadata.fixedHeight)
    print('fixedWidth', content_metadata.fixedWidth)
    print('id', content_metadata.id)
    print('index', content_metadata.index)
    print('keywords', content_metadata.keywords)
    print('layers', content_metadata.layers)
    print('max_scale_denominator', content_metadata.max_scale_denominator.text if content_metadata.max_scale_denominator is not None else None)
    print('metadataUrls', content_metadata.metadataUrls)
    print('min_scale_denominator', content_metadata.min_scale_denominator.text if content_metadata.min_scale_denominator is not None else None)
    print('name', content_metadata.name)
    print('noSubsets', content_metadata.noSubsets)
    print('opaque', content_metadata.opaque)
    print('parent', content_metadata.parent)
    print('queryable', content_metadata.queryable)
    print('scaleHint', content_metadata.scaleHint)
    print('styles', content_metadata.styles)
    print('timepositions', content_metadata.timepositions)
    print('title', content_metadata.title)

Pour les autres languages de programmation, il faut vous appuyer sur le parsing XML natif ou fournit par des bibliothèques tierces.

Liste des couches et aperçu image de la couche

Python

import json
import logging
from urllib.request import urlopen
from urllib.parse import urlparse
from owslib.wms import WebMapService

url_str = "https://demo.data.gouv.fr/fr/datasets/service-de-visualisation-cartographique-wms-du-jeu-de-donnees-driaaf-idf-territoire-maet-en-ile-de-france/"
url_parsed = urlparse(url_str)
slug = [i for i in url_parsed.path.split('/') if i != ''][-1]
base_url = f'{url_parsed.scheme}://{url_parsed.hostname}'
api_url = f'{base_url}/api/1/datasets/{slug}'

with urlopen(f'{api_url}/') as req:
    json_content = json.load(req)

wms_json = [i for i in json_content.get('resources') if 'WMS' in i.get('description') or 'WMS' in i.get('title')]
if len(wms_json) > 0:
    wms = WebMapService(wms_json[0].get('url'), version='1.3.0')
    print(wms.identification.type)
    print(wms.identification.title)
    print(wms.identification.abstract)
    print(wms.getOperationByName('GetMap').formatOptions)
    for name, layer in wms.items():
        # layer = wms.contents[name]
        print("Abstract: ", layer.abstract)
        print("BBox WGS84: ", layer.boundingBoxWGS84)
        print("BBox: ", layer.boundingBox)
        print("CRS: ", layer.crsOptions)
        print("Styles: ", layer.styles)
        print("Timestamps: ", layer.timepositions)
        print(layer.parent.abstract)
        sizex = 800
        # Ne fonctionne pas. Bug côté Geo-IDE sur le décodage de caractères
        # https://github.com/geopython/OWSLib/issues/846
        # Marche avec owslib 0.25.0 mais pas après
        response = wms.getmap(layers=[name,],
            bbox=layer.boundingBoxWGS84, # Left, bottom, right, top
            format=wms.getOperationByName('GetMap').formatOptions[0],
            size=(sizex,round(sizex * ((layer.boundingBoxWGS84[3] - layer.boundingBoxWGS84[1]) / (layer.boundingBoxWGS84[2] - layer.boundingBoxWGS84[0])))),
            srs='EPSG:4326',
        )
        with open(f"{name}.{wms.getOperationByName('GetMap').formatOptions[0].split('/')[-1]}", 'wb') as out:
            out.write(response.read())
else:
    print("Pas de WMS disponible")

Exemple retournant une image statique

Python

from owslib.wms import WebMapService

wms = WebMapService('https://ogc.geo-ide.developpement-durable.gouv.fr/wxs?map=/opt/data/carto/geoide-catalogue/1.4/org_38154/aea04585-605e-4372-abec-ade0d2380076.internet.map', version='1.3.0')

response = wms.getmap(layers=['N_PERIM_MAET_ZINF_S_R11',],
    bbox=(1.44041, 48.1107, 3.56583, 49.2484),
    format='image/png',
    size=(800, 428),
    srs='EPSG:4326',
)
with open(f"N_PERIM_MAET_ZINF_S_R11.png", 'wb') as out:
    out.write(response.read())

# ATOM, une alternative au WFS sans complication

ATOM est le format qui est utilisé dans les flux RSS. Il est enrichi dans le cas des catalogues de données géographiques.

Il contient pour le cas des données géographiques les URLs des données à télécharger. C'est le plus simple à utiliser si le seul but est de récupérer la donnée puis de la traiter, l'ouvrir dans ses propres outils. On télécharge les données des liens RSS. Il s'agit généralement de données géographiques dans des formats communément admis même si on peut parfois avoir des données attributaires et/ou des fichiers PDF par exemple.

Dans le meilleur des cas, on a un WMS avec un WFS et un flux ATOM mais cela dépend des flux de chaque fournisseur de données et on a le choix en fonction de nos usages souhaités.