Accueil / Blog / Métier / Web mapping : comparaison des serveurs de tuiles vectorielles depuis Postgres / PostGIS

Web mapping : comparaison des serveurs de tuiles vectorielles depuis Postgres / PostGIS

Par Frédéric Rodrigo — publié 30/07/2020
Un ensemble de serveurs de tuiles vectorielles basés sur la fonction ST_AsMVT() de PostGIS sont disponibles. Makina Corpus vous propose un tour d’horizon des spécificités des différentes solutions.
Web mapping : comparaison des serveurs de tuiles vectorielles depuis Postgres / PostGIS

Tuiles vectorielles

Les cartes sur le web sont constituées de tuiles, c’est-à-dire de morceaux de cartes qui sont chargées au fur et à mesure du déplacement de la carte ou de l'utilisation du zoom. Ces morceaux peuvent être des images, nommées "raster", ou des géométries - point, ligne, polygones - nommées "vecteur". Les cartes composées de tuiles vecteurs représentent une technique plus récente et offrent plus de fluidité et d’interactivité. Cela est dû au fait que les données composant la carte sont dans le navigateur et pas seulement une représentation image de celles-ci.

Un service de tuiles vectorielles peut-être décrit par un TileJSON. C’est un fichier de méta-information qui donne notamment la liste des couches attendues dans les tuiles ainsi que les listes d’attributs disponibles sur les objets. Le TileJSON donne également les plages d’application des couches : zone géographique et niveaux de zooms disponibles.

Technique de production de tuiles vectorielles

Nous nous intéressons ici aux données cartographiques stockées en base de données que nous souhaitons présenter sur le web sous forme de tuiles vectorielles. Le type de base de données utilisé pour faire cela est essentiellement Postgres avec son extension de données spatiales PostGIS.

Pour une vision plus large et l’intégration de ces serveurs de tuiles à un écosystème vous pouvez également consulter l’article Tour d’horizon des serveurs de tuiles vectorielles pour fond de carte.

Historiquement pour une tuile, des requêtes sont faites en base de données. Les données - géométries et attributs - sont récupérées, puis traitées par le programme appelant. Dans le cas de tuiles rasters, les données sont dessinées dans une image puis envoyées au navigateur web. Dans le cas de tuiles vectorielles, elles sont converties au format binaire Mapbox Vector Tile (MVT), puis envoyées au navigateur web.

PostGIS a dans ces dernières versions implémenté, puis optimisé, le support des tuiles vectorielles MVT. Auparavant, il était possible de produire du GeoJSON ou du SVG. Aujourd'hui, le support du format MVT implémenté directement en base de données simplifie les choses. Servir des tuiles ne consiste plus alors qu’à récupérer le MVT et à l’envoyer au navigateur web.

Les tuiles MVT utilisent des coordonnées à valeurs entières pour représenter les géométries. PostGIS se charge de la simplification des géométries, de la discrétisation en valeurs entières et des problèmes de cohérence que cela peut engendrer. Elles peuvent être composées de plusieurs couches, par exemple les cours d’eau, une frontière, la voirie…

Toute une série de logiciels sont progressivement apparus pour produire et servir des tuiles MVT depuis une base Postgres / PostGIS. Ces logiciels permettent de servir en HTTP des tuiles dont le contenu est défini par des requêtes SQL. Ils ont tous en commun d’être construis sur la fonction ST_AsMVT() de PostGIS.

SELECT
    ST_AsMVT(*)
FROM (
    SELECT
        ST_AsMVTGeom(
            geom,
            ST_TileEnvelope(12, 513, 412),
            extent => 4096,
            buffer => 64
        ) AS geom,
        name,
        description
    FROM
        points_of_interest
    WHERE
        geom && ST_TileEnvelope(12, 513, 412, margin => (64.0 / 4096))
) AS t

Utilisation de ST_AsMVT() et de ST_AsMVTGeom().

Ces logiciels sont bâtis pour répondre à deux objectifs un peu distincts :

  • produire des tuiles pour fond de carte,
  • produire des tuiles de données « métiers » qui vont venir être affichées en complément d’un fond de carte.

Serveur de tuiles vectorielles pour fond de carte

Ce type de serveurs retourne des tuiles qui dépendent seulement des cordonnées des tuiles (x, y) et du niveau de zoom (z). Typiquement ces tuiles contiennent beaucoup de couches de données.

Postserv

Postserv est un serveur très simple qui fait partie de l’outillage du projet OpenMapTiles. Il est décrit comme n’étant pas taillé pour de la production.

Il a l’avantage d’utiliser une description des couches au format tm2source (du yaml). Il s'agit d'un format répandu pour lister des couches utilisées dans un fond de carte. Le tm2source inclut une requête SQL par couche. Le SQL peut contenir des variables pour ajuster le comportement, notamment le niveau de zoom.

- Datasource:
    dbname: openmaptiles
    geometry_field: geometry
    max_size: 512
    srid: 900913
    table: (SELECT geometry, ref, class FROM layer_aeroway(!bbox!, z(!scale_denominator!)))
      AS t
  id: aeroway
  properties:
    buffer-size: 4

Postile

Postile est une solution proche de Postserv. Il est taillé pour de la production tout en prenant un tm2source comme liste des couches à servir.

Il offre en plus l’accès aux couches une par une. Il permet également d’utiliser une archive MBTiles de tuiles pré-calculées plutôt que de les construire à la demande.

Tilekiln

Réalisé par Paul Norman, Tilekiln est un projet qui n’est pas encore mature. Celui-ci a la particularité d’utiliser des templates jinja2 pour paramétrer les requêtes SQL dans le logiciel avant de les envoyer à Postgres.

SELECT
    ST_AsMVTGeom(ST_PointOnSurface(way), {{bbox}}, {{extent}}) AS way
  FROM planet_osm_polygon
  WHERE way && {{bbox}}
    AND boundary = 'administrative'
    AND admin_level = '2'
    AND name IS NOT NULL
{% if zoom <= 12 %}
    AND way_area > {{tile_area}}*0.05^2
{% endif %}
    AND osm_id < 0

Le projet est capable de produire un descripteur TileJSON depuis sa configuration.

T-rex

T-rex fait parti des serveurs de sa catégorie le plus abouti. Ce serveur peut, en plus de PostGIS, utiliser des sources de données GDAL. La définition SQL des calques se fait dans un fichier de configuration au format toml. Des variables - comme le zoom - peuvent être injectées dans le code SQL.

[[tileset.layer]]
name = "buildings"
datasource = "buildings"
geometry_field = "geometry"
geometry_type = "POLYGON"
buffer_size = 10
simplify = true
  [[tileset.layer.query]]
  sql = """
    SELECT name, type, 0 as osm_id, ST_Union(geometry) AS geometry
    FROM osm_buildings_gen0
    WHERE geometry && !bbox!
    GROUP BY name, type
    ORDER BY sum(area) DESC"""

Le serveur fournit un descripteur TileJSON et une interface web de test.

Tegola

Tegola est également une solution très aboutie. Tegola peut utiliser des données depuis PostGIS ou en GeoPackage. cette solution peut servir plusieurs définitions de tuiles et offre un accès par couche. De plus, Tegola possède un système de cache de tuiles et d’invalidation de ce cache.

Ce serveur fournit également un descripteur TileJSON et une interface web de test.

Serveur de tuiles vectorielles en surcouche de données

Les serveurs fournissant des surcouches de données n’incluent que la couche demandée dans la tuile. Certains serveurs autorisent des arguments en paramètre d’URL des tuiles. Ces paramètres sont envoyés à la requête SQL pour influencer sur le contenu des tuiles produites : par exemple filtrer les données par date, par utilisateur…

Ce type de serveur ne s’occupe par des requêtes SQL, ils accèdent à des tables ou des fonctions retournant des enregistrements déjà en place.

Des fonctions retournant des tuiles peuvent être définies en SQL. Ellles peuvent être considérées comme des vues prenant des paramètres.

CREATE OR REPLACE FUNCTION tile_source(z integer, x integer, y integer, query_params json) RETURNS bytea AS $$
DECLARE
  mvt bytea;
BEGIN
  SELECT INTO mvt ST_AsMVT(tile, 'public.function_source', 4096, 'geom') FROM (
    SELECT
      ST_AsMVTGeom(ST_Transform(geom, 3857), TileBBox(z, x, y, 3857), 4096, 64, true) AS geom
    FROM public.table_source
    WHERE geom && TileBBox(z, x, y, 4326)
  ) as tile WHERE geom IS NOT NULL;
  RETURN mvt;
END
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

Exemple de fonction retournant des tuiles.

Dirt

dirt-simple-postgis-http-api permet d’obtenir le contenu d’une table en tuiles vectorielles ou dans d’autres formats comme le GeoJSON. Il permet aussi d’appliquer certaines fonctions simples, comme obtenir le centroïde des géométries tout en utilisant des filtres.

Il ne permet pas de définir ces propres requêtes SQL.

pg_tileserv

pg_tileserv est un jeune projet, développé par l’emblématique Paul Ramsey (entre autres le créateur de PostGIS). Le projet contient déjà toutes les bonnes idées pour ce type de serveur : données depuis une table ou une fonction retournant des enregistrements, des paramètres pour filtrer les données, des paramètres pour ajuster la création des tuiles vectorielles…

Martin

Martin est un projet plus mature qui a servi de modèle à pg_tileserv. Il peut lui aussi utiliser une table ou une fonction comme source de données et supporte les paramètres pour filtrer les données.

Vue d’ensemble

Postserv Postile Tilekiln T-rex Tegola
Compagnie / Projet / Auteur OpenMapTiles Oslandia Paul Norman Sourcepole Go-spatial
Objectif fond de carte fond de carte / couche fond de carte fond de carte fond de carte
Dépôt https://github.com/openmaptiles/openmaptiles-tools/blob/master/bin/postserve https://gitlab.com/Oslandia/postile https://github.com/pnorman/tilekiln https://github.com/t-rex-tileserver/t-rex/ https://github.com/go-spatial/tegola
Langage python python python rust go
Configuration service - - yaml toml toml
Configuration layer tm2source (yaml) tm2source (yaml) sql / jinja2 sql / toml sql / toml
TileJSON - - x x x
Depuis d’autres sources - MBTiles - GDAL GPKG
Filtre depuis URL - - - - -
Depuis fonction Postgres - - - - -
Interface web de test - x - x x
Remarques Pas fait pour de la production Non mature Support des projections Plusieurs définitions de tuiles
Cache de tuiles
dirt-simple-postgis-http-api Martin pg_tileserv
Compagnie / Projet / Auteur - Urbica (Yandex) CrunchyData, Paul Ramsey
Objectif couche couche dynamique couche dynamique
Dépôt https://github.com/tobinbradley/dirt-simple-postgis-http-api https://github.com/urbica/martin https://github.com/CrunchyData/pg_tileserv
Langage js rust go
Configuration service json yaml toml
Configuration layer - yaml -
TileJSON - par couche par couche
Depuis d’autres sources - - -
Filtre depuis URL - x x
Depuis fonction Postgres - x x
Interface web de test - - -
Remarques Non mature

Les fonctionnalités des différentes solutions présentées sont proches, en particulier pour les projets les plus avancés. Elles offrent cependant des petites différences qui peuvent pousser à les choisir pour certains cas d’usages. Par exemple :

  • seul T-rex permet de choisir la projection,
  • seul Postserv et Postile peuvent utiliser un tm2source,
  • tous les serveurs n’offrent pas de descripteur TileJSON,
  • seul Martin et pg_tileserv produisent de la tuile paramétrable par URL.

A retenir, Postserv et Postile pour du fond de carte générique (utilisable avec OpenMapTiles par exemple), T-rex et Tegola pour la richesse de leurs fonctionnalités pour du fond de carte sur-mesure. Pour de la couche de tuiles de données à la demande et paramétrable par URL, Martin est la solution la plus accomplie mais le nouveau pg_tileserv est prometteur.

Formations en lien

ABONNEZ-VOUS À LA NEWSLETTER !
Voir aussi
QGIS : le nouveau support des tuiles rasters et vectorielles QGIS : le nouveau support des tuiles rasters et vectorielles 01/10/2020

La dernière version de QGIS 3.14 apporte deux nouveaux types de calques : les tuiles rasters et ...

Optimisation de la production de tuiles vectorielles de fond de carte OpenStreetMap pour un service à la demande : Makina Maps Optimisation de la production de tuiles vectorielles de fond de carte OpenStreetMap pour un service à la demande : Makina Maps 04/02/2020

Frédéric Rodrigo, expert OpenStreetMap, présente Makina Maps, une solution permettant de servir ...

Paralléliser des requêtes avec PostgreSQL 31/03/2020

PostgreSQL permet de découper les requêtes pour en exécuter des parties en parallèle. Il faut ...

Une Cagnotte reversée à la fondation OpenStreetMap a été organisée par Makina Corpus lors du Paris Open Source Summit ! Une Cagnotte reversée à la fondation OpenStreetMap a été organisée par Makina Corpus lors du Paris Open Source Summit ! 28/01/2020

Les 10 et 11 décembre derniers, Makina Corpus était présente à la 5ème édition du Paris Open ...

SIG : Préparation de données pour la création de tuiles vectorielles 30/01/2020

Pour servir des données sous forme des tuiles vectorielles une préparation est nécessaire comme ...