Self Hosted World Maps Oct 04, 2019 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