This post shows how to use open software to
- create vector tiles using openmaptiles open source software
- serve those vector files with a very short jsnode program
- display those vector tiles with a very short Mapbox GL JS based app
Vector tiles are a potentially faster way than raster tiles for map tiles servers to send tile information to client apps. It is faster because the polygons and symbols of the vector format offer greater compression than can be achieved with raster format. Also, decisions such as which language to render can be made on the client end.
Of course that requires the client end to have a fast way to render the vector tiles. The free and open source Mapbox GL JS software provided by Mapbox fulfills that requirement.
However, there is no completely free source of vector tiles available for personal or business use. Fortunately, through the efforts of OpenSourceMap (OSM) and OSM Carto open source data for maps and open source software for building and displaying custom maps is available.
Mapbox introduced and made available as open source their Mapbox GS JS software capable of high speed rendering of vector tiles.
An effort (not under the aupices of OSM or OSM Carto) to build upon the work of OSM Carto and provide a convenient tool chain to create vector tiles compatible with Mapbox GS JS was made under the name osm2vectortiles. Unfortunately, rather than developing tiles which resemble the OSM Carto (raster) tile style, they ended up too closely resembling Mapbox‘s proprietary Mapbox Streets tile style. So the osm2vectortiles project was voluntarily shutdown.
“The roadmap to hell is paved with good intentions”
The non-Mapbox-proprietary parts of osm2vectortiles were adopted into a new open source project openmaptiles. A new style for vectors tiles was created which doesn’t resemble Mapbox‘s proprietary styles, but can still be used with Mapbox GL JS rendering software.
The very first part of this post describes creating tiles using the openmaptiles software. The parts thereafter describe serving tiles and displaying those served tiles in an app.
Unfortunately the openmaptiles github and openmaptiles.org sites do not offer simple straightforward minimalist examples showing how to serve tiles, and how to display served tiles in an application.
There is a serving program tileserver-gl associated with openmaptiles but it is overly complex for a newcomer who want to prepare a minimalist server.
There is an example for displaying vector tiles from a Mapbox GL JS app, but that is set up to get its tile data from a commercial site, rather than self hosted tiles.
So this post bridges the gap and describes a minimalist framework to serve and display self hosted vector openmaptiles tiles. It’s not really difficult, but there are a few frustrating gotchas which this post aims to make easier.
Note that this post keeps the tileserver and display app seperate served in order to test cross-origin conditions.
Clone the openmaptiles github project. We’ll refer to the resulting directory as $OMT. From the directory above where $OMT will be:
git clone https://github.com/openmaptiles/openmaptiles
Make sure the required software is installed as explained in the openmaptiles instructions.
Download the file SanFrancisco.osm.pbf. Put it in the folder $OMT/data.
curl -o data/SanFrancisco.osm.pbf \
Modify the following files:
to have BBOX and MAX_ZOOM values as follows:
BBOX: " -122.54, 37.54, -122.32, 37.93" MAX_ZOOM: "14"
Create the file
$OMT/data/docker-compose-config.yml with content
From the $OMT directory, execute
After a long while, the tiles will be created in the file
$OTM/data/tiles.mbtiles. From the $OMT directory run
That will a docker module running
tileserver-gl. Then open your browser to
to see the tile data.
The program ‘tileserver-gl’ is too complex to qualify as a minimalist server. To close the
tileserver-gl program and remove its docker image you may need commands such as:
docker image ls
The tile server will serve data from the ‘tiles.mbtiles’ data, sending it via http to the tile display app. The tile server will also serve the fonts and sprites necessary for drawing the map. That is all the data that the app requires to display the map.
The fonts are available from the github openmaptiles project.
Let $FND be a directory which will hold the fonts. The last directory will be named
fonts as a result of the clone process. Clone and execute as follows:
git clone firstname.lastname@example.org:openmaptiles/fonts.git
Finally the static font files will be ready under ‘$FND/_output`.
Add the sprites here too because, why not?:
Create a directory for the minimalist tile server. We’ll call that directory $MTS.
Create the following file
$MTS/index.js, (borrowed in part from this Git GIST by manuelroth):
var express = require("express"),
Install under $MTS the necessary node modules:
npm install express --save
Create a symbolic link to the tiles file
ln -s $OMT/data/tiles.mbtiles $MTS/tiles.mbtiles
Create a symbolic link to the fonts
ln -s $FND/_output $MTS/fonts
Create a symbolic link to the sprites directory
ln -s $FND/sprite $MTS/sprite
Create a directory for the front end app. We’ll call it $MGJ
Download the style file
osm-bright-gl-style.json from the openmaptiles project:
Backup the original:
cp osm-bright-gl-style.json osm-bright-gl-style.json.orig
osm-bright-gl-style.json as follows:
Create the file index.html in the $MGJ directory
In the next section, this
index.html will be served with the CLI invoked npm node server
Create a batch file to start up both the tile server and the app server
# kill any node processes left over from the last time this was run
-o argument to
http-server opens a browser window automatically, so your SF map should be already visible.
The style file could have been served from the tile server instead of being physically placed in the same directory as the display app.
The app shown does depend on Mapbox GS JL code served by Mapbox servers, as can be seen from the lines :
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.29.0/mapbox-gl.js'></script> <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.29.0/mapbox-gl.css' rel='stylesheet' />
Therefore, the system shown in this post is not completely self-hosted. However the Mapbox GS JL code is declared as open source and the same code is supposed to be available on gituhub, so self-hosting should be possible.