Blog about software development


Handling GeoJSON tiles in Leaflet

20 Jul 2019 - by 'Maurits van der Schee'

Leaflet is world's most popular open-source JavaScript "Tiled web map" library offering Google maps like functionality on your own (or public) data. In the past weeks I have implemented a GeoJSON vector tile plugin for Leaflet. In this post I will explain when to use raster tiles, Mapbox Vector Tiles, GeoJSON tiles or a GeoJSON bounding box.

Why tiles?

When somebody has a free pan and zoom over a map, no two maps are the same, as you have a lot possible visible maps and sizes and zoom levels. For a single user this would be fine, but as soon as you have multiple users then you want to use some form of caching to reduce the load on the server. You could fix the map size and pan and zoom in fixed steps, but that does not feel good. This is why tiling is introduced. It allows you to have the caching advantages of fixed steps, while allowing the user custom map sizes and seamless pan and zoom (Google Maps has fixed zoom steps, Google Earth has seamless zoom).

Why raster?

In order to determine what should be shown on a tile you have to do a bounding box query on the storage that hold the features (points, lines or polygons) that make up the map layer. If you want to show a base map with buildings, roads, rivers, parks and many more layers then you need to do a lot of those queries. Those bounding box queries can be optimized using a geospatial index, but then you also need to draw them to the screen (while converting geospatial coordinates to screen coordinates), which may be expensive as well. Raster tiles allow you to do all these steps in advance and store the results in a bitmap for future use in a map.

1) Raster tile layer

Raster tiles are the square PNG images that make up Google maps. Creating them is an expensive task, while displaying them is quite cheap. These images are often cached for long times on web servers all over the globe. Since the maps are images, there is no way to interact with them or select map features. This makes raster tiles good for high detail, but non-interactive and static map layers. A typical use case is a base map layer, that serves as a reference for a more specific or thematic map layer.

2) Mapbox vector tile layer

Mapbox vector tiles (the de-facto standard for vector tiles) is a binary format (like raster tiles) that can hold many map layers (like raster tiles) and is expressed in screen coordinates (like raster tiles). Unlike raster tiles it holds a set of vectors (geometries) and not a bitmap. Vector tiles hold identifying information on each shapes it draws on the screen for a map layer. This means you can click on an object to learn more about it. Note that the object may be partial due to clipping of the bounding box. A typical use case for vector tiles are sets of thematic maps that do not change too often.

3) GeoJSON vector tile layer

GeoJSON vector tiles are JSON documents (a text format) with geospatial coordinates that hold all full geometries (without clipping) that are located fully or partially within the bounding box of that tile. This means that a geometry that lies on the border of two tiles is represented fully in both the tiles. This means that you need to take care not to draw this geometry twice or remove it from the screen too early (when a tile is no longer visible). Since these shapes are sent the way they are stored they can be served directly from the database as a result from a bounding box query. A typical use case for this kind of tile is a real-time map layer that may not be cached longer than several minutes.

4) GeoJSON bounding box layer

A GeoJSON bounding box is no tiling technology. This means it has the described downside of not being able to cache effectively. The GeoJSON document holds all full geometries (without clipping) that are located fully or partially in the visible area of the map. Other than that is it the same technology as GeoJSON tiles. Since the resulting shapes are sent the way they are stored (using geospatial coordinates) they can be served directly from the database as a result from a single bounding box query. A typical use case for this kind of technology is a true real-time map layer where the information on the map must be actual and may not be cached.

GeoJSON vector tile plugin

I'm building PHP-CRUD-API, a full-featured (geospatial enabled) API in a single PHP file. The API can produce GeoJSON for a specific bounding box or a vector tile (specified in z,y,x coordinates). To showcase this functionality I have created a leaflet plugin for GeoJSON bounding box and GeoJSON vector tile layers. This allows you to quickly set up a map with a real-time or almost real-time map layer using Leaflet and PHP-CRUD-API. The source code can be found on Github:



PS: Liked this article? Please share it on Facebook, Twitter or LinkedIn.