Self Hosted World Maps
- devops go geo
Maps are fun, self hosted maps are awesome !
Serving world maps was reserved to big companies like Google, thanks to the OpenStreetMap project, we now have access to an open world of data.
Generating Tiles
MapBox (and others) worked hard to create a vector format bundled in a SQLite file: mbtiles format.
It’s vector based as opposed to older raster maps containing 256x256 PNG images.
The Openmaptiles folks did a great job automating the map generation.
Grab Openmaptiles and with memory, cpu and patience you can generate your own map (they offer pre computed paying maps).
First you have to know that generating full zoom for the whole world is unlikely to work, but dividing the problem will.
Clone the repo and edit .env
to change QUICKSTART_MAX_ZOOM=
, I don’t always need map with street level zoom, it can reduce the generation time and the final file size.
Then using the quickstart.sh
command you can generate continent per continent files, (or country or subregion since it’s using Geofabrik).
./quickstart.sh north-america
Expect hours to complete.
Here are the generated files sizes for level 11:
347M africa11.mbtiles
1.6G asia11.mbtiles
167M australia-oceania11.mbtiles
54M central-america11.mbtiles
1.4G europe11.mbtiles
3.0M hawaii11.mbtiles
803M north_america11.mbtiles
344M south-america11.mbtiles
![](/img/Screen Shot 2019-10-04 at 14.28.04.png)
Assembling Maps
Having multiple maps to serve is painful, we can merge them using tippecanoe tile-join command
tile-join --maximum-zoom=11 -o planet11.mbtiles africa11.mbtiles asia11.mbtiles australia-oceania11.mbtiles europe11.mbtiles north_america11.mbtiles south-america11.mbtiles central-america11.mbtiles
Simply serve planet11.mbtiles
and your good to go for the whole world.
Serving Tiles
Serving the mbtiles file is as simple as reading an SQLite database for the right level and right tile.
I wrote a small Go web server to do so.
And a docker image that can start with an embedded level 11 map of Hawaii:
docker run -it --rm -p 8000:8000 -e HOSTNAME=myip:8000 akhenakh/mbmatch:latest
Replace myip
with your own ip address (not localhost) and you should see the map with your browser pointed at http://myip:8000
.
Conclusion
Those vector maps are wonderful since they are rendered on the fly on the browser, you can change colors, themes, labels… according to your need using the same mbtiles file.
You can of course add your own layers and even tweak the data if needed.
To serve a world map at large scale, you’ll need of course the infrastructure to handle it.
But those tools are proven to work for larger companies and a viable solution for anybody who needs mapping.
EDIT: Based on the same recipes, I’ve worked on a faster and simpler solution: kvtiles