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 !).
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