20 Jul 2019 - by 'Maurits van der Schee'
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).
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.
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.
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.
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.
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.
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: