Serve your map layers with a usual Web hosting service

Someone asked me about serving map tiles from a basic Web host. I agreed to reply with a blog post, since it completes the stories I've been telling in my last two talks.

How to serve your map layers (tiles) with the simplest Apache or nginx ?

Get the MBTiles file

We start from a tiles package (MBTiles). Depending on where your layers come from, you can either choose :

To publish your Tilemill map

Design your map in Tilemill, even your own OpenStreetMap style customization, and export it as MBTiles ! MapBox hosting is the prefered solution, but you can still host and serve your exported MBTiles file yourself !

To mirror a WMS server

Again, using landez, you can build a MBTiles file from a WMS source (orthophoto...), and then serve those layers yourself as tiles (at the speed of light !).

To mirror tiles services

Using landez, you can gather tiles from a tiles service, and package them in a .mbtiles file locally.

If you plan on mirroring public tile services, do not forget to add attributions and make sure it respects the terms of service. Most services restrict bulk downloads [1].

Extract files on disk

Using mbutil, we can extract the .mbtiles file into a destination folder.

Unfortunately, the pypi mirror is quite old, we'll install the last development version.

wget https://github.com/mapbox/mbutil/zipball/master -O mbutil.zip
unzip mbutil
cd mapbox-mbutil*
sudo python setup.py install

Done. Now extract. (Note that the ``DEST`` folder must not exist) :

mb-util --scheme=osm FILE.mbtiles /path/to/DEST/

If your MBTiles has an interaction layer (UTFGrid), both .png and .json files will be expanded in folders.

Just push the folder to your hosting, and you're done !

Cache headers

If you the master on board, tweak the cache headers :

With Apache :

ExpiresActive On
ExpiresDefault "access plus 7 days"
Alias /DEST /path/to/DEST/;

With nginx :

server {
    location /DEST {
        expires 7d;
        alias /path/to/DEST/;
    }
}

Boost with subdomains

Browsers limit parallel downloads on the same domain. If you can declare subdomains (a.yourserver.org, b.yourserver.org, ...), it will speed-up tiles download.

Use it in your mapping library

With Leaflet for example :

var map = new L.Map('map');
map.addLayer(new L.TileLayer('http://{s}.yourserver.org/DEST/{z}/{x}/{y}.png'));
map.setView(new L.LatLng(43.60, 1.45), 14)

Or Modestmaps :

var provider = new MM.TemplatedLayer('http://{s}.yourserver.org/DEST/{z}/{x}/{y}.png');
var map = new MM.Map('map', provider);
map.setCenter({lat: 43.60, lon: 1.45}).setZoom(14);

It will also work with interaction layers if you use Wax :)

[1]MapBox strictly forbids proxying and further distribution of their tiles. Bulk downloading from OpenStreetMap.org is strongly discouraged too. And mass downloads cost money on Cloudmade.

#tilemill, #landez, #mbutil, #gis - Posted in the Sys category