Shapefile(s) to vector tile set
graph LR
A[Vector source - eg. shapefile] --> |ogr2ogr| B[geoJSON]
B --> |tippecanoe| C[Set of .pbf tiles]
- Planet file mirrors: https://wiki.openstreetmap.org/wiki/Planet.osm#Planet.osm_mirrors
- Extracts: https://wiki.openstreetmap.org/wiki/Planet.osm#Planet.osm_mirrors
- Extracts (continents): https://download.geofabrik.de
Get a data source you can turn into geoJSON to use with tippecanoe
(see below).
For example, convert an ABS shapefile of postcode boudnaries using ogr2ogr
, which comes with GDAL (brew install gdal
):
ogr2ogr -f GeoJSON postcodes.geojson POA_2021_AUST_GDA2020.shp
ogr2ogr
doesn't reproject data into WGS 84, even though that's now the only projection supported by the geoJSON format (and what tippecanoe
expects). Might wanna reproject first!
From what I understand, MapLibre used MapTiler Desktop to create the tiles, but I'm having trouble getting it to create anything. Let's try and do it ourselves.
First we create the tiles (as an .mbtiles
archive) using TileMaker:
# create an .mbtiles from an osm planet file or extract (.pbf)
./tilemaker-macos-10.15/build/tilemaker \
--input tileset/australia-oceania-latest.osm.pbf \
--output aus.mbtiles \
--process ./tilemaker-macos-10.15/resources/process-openmaptiles.lua \
--config ./tilemaker-macos-10.15/resources/config-openmaptiles.json
Use tippecanoe
to turn a vector data source into a tile archive or a hierarchy of .pbf tiles
# .mbtiles output
tippecanoe -o postcodes.mbtiles postcodes.geojson
# folder of .pbf tiles output
tippecanoe --output-to-directory postcodes postcodes.geojson
Some things to note:
- Tippecanoe has a lot of options for controlling which features are visible at what zoom levels!
- In the absence of a custom name, Tippecanoe will name the layer in the tile archive after the file. Layer names are important when we start styling!
- I believe tippecanoe can combine several input files into a tile archive as separate layers. Good to know!
Use planetiler
Alternative: planetiler
can also do this and is explciitly designed to ingest the whole OSM planet file if you have the RAM for it... probably more than 32 GB 😬
Tippecanoe can output either an .mbtiles
archive or a folder of .pbf
tiles (using the --output-to-directory
option).
If we want to bundle our tiles directly with our code (eg. a JAMstack product), we can't put the tile archive directly in the project: it'll likely be bigger than the 50 MB file size limit imposed by GitHub. But we can extract the tiles into a {z}/{x}/{y).pbf
directory structure and commit those to our project, provided they don't blow the total repo size.
This might be the better solution for:
- Global maps where we don't need detail beyond zoom 6 or so; or
- Regional/city maps where we don't need to zoom out much.
To extract the individual tiles .mbtiles
archive (which is essentially an SQLite database), we can use Mapbox's mbutil
:
mb-util aus.mbtiles aus-tiles
(Apparently mb-util
produces gzipped output!, but it looks like you can turn this off with a --do_compression
option.)
For some maps, we may need both global overviews and regional details. In these case, we may want to put the .mbtiles
archive in a remote bucket and have an edge function perform the "tile server" role, pulling out individual tiles on demand.
This isn't free in an unlimited sense the way committing tiles to version control is (at least for Cloudflare Pages), but it is potentially hundreds of tiles cheaper than a SaaS offering like Mapbox or MapTiler. It may also be useful in cases where we have a large vector dataset that we want to serve.
So your map's style.json
will use a sources
field to point to your new tileset:
{
# ...
"sources": {
"maplibre": {
"url": "tiles/tiles.json",
"type": "vector"
}
}
}
But tippecanoe
doesn't produce tiles.json
, so you'll have to write it according to the Mapbox tilespec. (I've linked to version 2.0.0 here, as I'm unsure if MapLibre supports newer versions.)
(You can actually inline the tilespec in style.json
!)
Mapbox's node-mbtiles
has some utilities for working with .mbtiles
files.
Mapbox's tippecanoe
looks like it can also handle create .mbtiles
files from GeoJSON features as .json
files, .geobuf
s and potentially other input sources, so it could possible also replace the first step. It also looks quite configurable, allowing you to specify max zoom, detail, attributes, etc. It's the basis of Mapbox's Vector Tile Service, so it ought to be quite powerful.
maplibre/demotiles
has free vector tiles made with MapTiler Desktop that they've released under BSD and which are already laid out in folder format, ready to be served keyless. These only go to zoom 6, so they aren't detailed enough for regional maps, but for global ones they're great and can be restyled quickly.
openmaptiles/fonts
has pre-encoded versions of common open-source fonts, ready to drop into map styles.
These aren't really vector tiles, but you can do a similar thing with them: request a byte range that corresponds to a bounding box. The library's MapLibre example does this (demo here). The library handles parsing a bounding box and URL into a ranged fetch request.
PMTiles also looks like a tiled vector format designed for serverless, ranged requests. They have two MapLibre examples:
- US zip codes
- A buildings file (it says basemap, but I'm not sure if that's because it's comes from OSM)
The code on one of their demos converts a shapefile to PMTiles via .json
and .mbtiles
formats:
ogr2ogr -t_srs EPSG:4326 cb_2018_us_zcta510_500k.json cb_2018_us_zcta510_500k.shp
tippecanoe -zg --projection=EPSG:4326 --no-tile-compression --no-feature-limit --no-tile-size-limit -o cb_2018_us_zcta510_500k_nolimit.mbtiles -l zcta cb_2018_us_zcta510_500k.json
pmtiles-convert cb_2018_us_zcta510_500k_nolimit.mbtiles cb_2018_us_zcta510_500k_nolimit.pmtiles
Apparently PMTiles can hold arbitrary raster or vector data.
There're a few mapbox tools floating around to convert TrueType/OpenType fonts into .pbf
set sby glyph (which style.json
requires), but Protomaps' signed SDF tool is by far the easiest. Give it a font, it'll convert it client-side and give you a ZIP file with the .pbf
set.
Tilesets get bigger exponentially with zoom. Here're the file sizes I ended up with when I converted the ABS postcodes:
Zoom level | Size |
---|---|
0 | 84K |
1 | 116K |
2 | 164K |
3 | 236K |
4 | 332K |
5 | 516K |
6 | 816K |
7 | 1.4M |
8 | 3.0M |
9 | 8.2M |
10 | 27M |
11 | 104M |
12 | 406M |
13 | 1.6G |
14 | 6.2G |
It might be worth finding a suitable max zoom for tiles like those around 10 or 11 and just overzooming!