On my previous post I've played around with various tools on the Mapbox vector tiles ecosystem. On this post I'm taking it further: generating my own vector tiles.
There are various options to generate vector tiles:
- using a server that generates the vector tiles dynamically based on other data (such as PostGIS)
- programatically generating the protobuf (rolling your own code or using existing libs)
- using a tool that receives various inputs and outputs the corresponding vector tiles, which can then be used as shown on my previous post
Most options for these approaches are properly identified at this page: https://github.com/mapbox/awesome-vector-tiles
On this post I'm going to focus on this third option, particularly using a tool from Mapbox called Tippecanoe. I'm not an expert on any of these alternatives (I'm learning as I'm writing this post) but Tippecanoe seems incredibly robust, including a great deal of customisation options when generating the tiles.
It's simply a command-line tool that receives one or more GeoJson files as input and generates the corresponding vector tiles.
The readme is great so I'm not going to duplicate everything on this post. Basically installing is as simple as:
And running as
Let me create a very basic map to see how this works.
- I've started by downloading a world shapefile from http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_0_countries.zip (and extracting it obviously)
- To convert a Shapefile to Geojson the easiest way is probably to use ogr2ogr from GDAL with the following command:
- Now running tippecanoe on it:
The "z" param is used to specify the highest zoom level to which tiles are generated. The default of 14 would take a looong time to finish. For the sake of this demo I'm going to keep things small and fast. For reference each zoom level requires 4^(zoom level) tiles.
After the tiles are generated we end-up with a .mbtiles file. This is basically a SQLite database including all the generated tiles inside, making it quite convenient to store, transfer and use.
I can try these vector tiles immediately but, without a style, nothing would be displayed. Fortunately tileserver-gl also provides a "data" mode where it shows the various layers of a mbtiles set.
So, simply running it against my "world.mbtiles" output from the previous step:
Opening http://localhost:8080/data/world will show our map with a single layer called "worldgeojson"
I'm ready to create my style:
Using an editor is obviously ideal (I'll get to that later) but we can easily create a really dumb style "by hand":
This is basically:
- Creating a source for vector tiles (as in defining where to load the tiles from)
- Creating a style layer to paint the background with a blue color
- Creating a style layer that points to the "worldgeojson" layer from the vector data and filling it with a flat color
Running tileserver-gl as:
Opening a page at: http://localhost:8080/styles/world/#0/0/0 will show our custom map with our custom style:
Creating the styles manually is not very practical. Fortunately there are various tools that might help with that:
- The best one if obviously www.mapbox.com/studio
It provides a rich UI where one can define colors, filters, fonts, etc in a very user friendly fashion.
It's particularly useful for maps created and hosted in Mapbox. Regardless, you can still edit the styles online and then download them to use with your local mbtiles, although requiring a little bit of editing on the output to point to the relevant sources.
- A simple alternative is https://github.com/erikandre/mapbox-gl-style-editor.
- The best alternative to Mapbox Studio is definitely http://maputnik.com/.
Using it is very simple. You can either go directly to http://maputnik.com/editor/ or clone the git repo from https://github.com/maputnik/editor and run it as:
By default the editor runs on port 8888. The first thing to do is to add a source for our generated tiles. If you still have tileserver-gl running from one of the previous steps you'll have a tilejson file automatically prepared at: http://localhost:8080/data/v3.json.
Go to "Source" on the top and create a new source as:
- Source ID: mysource
- Source Type: Vector (TileJSON URL)
- TileJSON URL: http://localhost:8080/data/v3.json
Afterwards we're ready to create a new layer that references data from this particular source. Press Add Layer on the left and add the layer data:
Also, create another layer for the background:
Now just choose a flat color for these layers. You'll end-up with something like this:
That's it for now. On my third and final post I'm going to build up on these techniques and do something more advanced/interesting.