Web mapping: comparing vector tile servers from Postgres / PostGIS

Frédéric Rodrigo
6 min readAug 3, 2020

--

Many vector tile servers based on the ST_AsMVT() function of PostGIS are available. Makina Corpus presents here an overview of the specificity of the different solutions.

This article is an English translation of my own French article from Makina Corpus Blog.

Vector tiles

Maps on the web are made up of tiles, i.e. pieces of maps that are loaded when the map is moved or zoomed. These pieces can be images, called “raster”, or geometries — point, line, polygons — called “vector”. Maps composed of vector tiles represent a more recent technique and offer more fluidity and interactivity. This is due to the fact that the data composing the map is in the browser and not just an image representing it.

A vector tile service can be described by a TileJSON. It is a meta-information file which gives, in particular, the list of layers expected in the tiles as well as the lists of attributes available on the objects. The TileJSON also gives the application ranges of the layers: geographical area and available zoom levels.

Vector tiles production technique

We are interested here in the geographic data stored in databases that we wish to present on the web in the form of vector tiles. The type of database used to do this is essentially Postgres with its spatial data extension PostGIS.

Historically for a tile, queries are made in the database. The data — geometries and attributes — are retrieved and then processed by the calling program. In the case of raster tiles, the data is drawn in an image and then sent to the web browser. In the case of vector tiles, they are converted to the Mapbox Vector Tile (MVT) binary format and sent to the web browser.

PostGIS has in these last versions implemented, then optimized, the support of MVT vector tiles. Previously, it was possible to produce GeoJSON or SVG. Today, the support of the MVT format implemented directly in the database simplifies things. Serving tiles is now “just” a matter of retrieving the MVT and sending it to the web browser.

MVT tiles use integer coordinates to represent geometries. PostGIS takes care of the simplification of geometries, discretization into integer values and the consistency problems this can cause. They can be composed of several layers, for example rivers, a boundary, roads…

A full range of software has appeared to produce and serve MVT tiles from a Postgres / PostGIS base. These softwares allow to serve tiles in HTTP from the content defined in SQL queries. They all have in common to be built on the ST_AsMVT() function of 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

Usage of ST_AsMVT() and ST_AsMVTGeom().

These software are built to meet two somewhat distinct objectives:

  • produce tiles for map backgrounds,
  • produce “subject” data tiles that will be displayed in addition to a background map.

Vector tile servers for background maps

This kind of server returns tiles that depend only on the tile coordinates (x, y) and the zoom level (z). Typically these tiles contain many layers of data.

Postserv

Postserv is a very simple server that is part of the OpenMapTiles project toolkit. It is described as not production-ready.

It has the advantage of using a layer description in tm2source format (in yaml). This is a common format for listing layers used in a background map. The tm2source includes one SQL query per layer. The SQL can contain variables to adjust the behaviour, such as the zoom level.

- 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 is a solution close to Postserv. It is designed for production while taking a tm2source as a list of layers to be served.

It offers access to the layers one by one. It also allows to use an MBTiles archive of pre-calculated tiles rather than building them on demand.

Tilekiln

Build by Paul Norman, Tilekiln is a project that is not yet mature. This one has the particularity of using jinja2 templates to set up SQL queries in the software before sending them to 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

The project is able to produce a TileJSON descriptor from its configuration.

T-rex

T-rex is one of the most advanced servers in its category. This server can, in addition of PostGIS, use GDAL data sources. The SQL definition of the layers is done in a configuration file in toml format. Variables — such as zoom — can be injected into the SQL code.

[[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"""

The server provides a TileJSON descriptor and a test web interface.

Tegola

Tegola is also a mature solution. Tegola can use data from PostGIS or in GeoPackage. This solution can serve multiple tile definitions and offers access by layer. In addition, Tegola has a tile cache and cache invalidation system.

This server also provides a TileJSON descriptor and a test web interface.

Overlaying data vector tile server

Servers providing overlay data include only the requested layer in the tile. Some servers allow parameters in the tile URL. These parameters are sent to the SQL query to control the content of the produced tiles: for example filtering the data by date, by user…

This type of server does not deal with SQL queries, they access existing tables or functions returning records.

Functions returning tiles can be defined in SQL. They can be considered as views with parameters.

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;

Example of a function returning tiles.

Dirt

dirt-simple-postgis-http-api allows you to obtain the contents of a table in vector tiles or in other formats such as GeoJSON. It also allows to apply some simple functions, such as obtaining the centroid of geometries while using filters.

It does not allow to define your own SQL queries.

pg_tileserv

pg_tileserv is a young project, developed by the famous Paul Ramsey (among others, the creator of PostGIS). The project already contains all the good ideas for this kind of server: data from a table or a function returning records, parameters to filter the data, parameters to adjust the creation of vector tiles, etc.

Martin

Martin is a more mature project that served as a model for pg_tileserv. It also can use a table or function as a data source and supports parameters to filter data.

Overview

Vector tile servers for background maps
Overlaying data vector tile server

The features of the different alternatives presented are similar, especially for the most advanced projects. However, there are some small differences that may lead to choose them for certain use cases. For example:

  • only T-rex allows to choose the projection,
  • only Postserv and Postile can use a tm2source,
  • not all servers offer a TileJSON descriptor,
  • only Martin and pg_tileserv produce URL-based configurable tile.

In summary, use Postserv and Postile for generic background map (usable with OpenMapTiles for example), T-rex and Tegola for the variety of their functionalities for custom background map. For on-demand and URL customizable data tile layer, Martin is the most advanced solution while the new pg_tileserv is a promising one.

--

--