Building tilesets with tilemill and OSM data
The problem of creating tiles seems to be really simple: You have the OSM data
in one end, which can be downloaded from here,
and the .png
tiles in the other. In the middle there should be
something that reads that data, applies some templates or description, and
generates the tiles. But life is never so simple.
mapnik
cannot read any of OSM's exported files (XML or .pbf
), but only from
a SQLite or PostgreSQL/GIS database; and we can only conver to the latter either
with imposm
or osm2pgsql
, so that road we go. It's mostly a matter of
following TileMill's page about
using OSM's data
(and some template called osm-bright
).
For Debian sid
you follow its instructions for Ubuntu Oneiric Ocelot.
Importing the data should be as simple as:
mdione@mustang:~/src/projects/osm$ sudo su -c "osm2pgsql --database osm --input-reader pbf --verbose --create $(pwd)/france.osm.pbf" postgres [...] Unable to open /home/mdione/src/projects/osm/data/france.osm.pbf
No error message. strace
gives us a clue:
open("/home/mdione/src/projects/osm/data/france.osm.pbf", O_RDONLY) = -1 EOVERFLOW (Value too large for defined data type)
A little bit cryptic, but basically it says the file is too large. So I downloaded only the region where I live (for some countries there are individual files) and after some cache tweaking:
mdione@mustang:~/src/projects/osm/data$ sudo su -c "osm2pgsql --database osm --input-reader pbf --verbose --cache $((1024+512)) --create $(pwd)/provence-alpes-cote-d-azur.osm.pbf" postgres
This time I got it right. Some numbers so you have an idea how much time and space this takes:
Input file size: 184054kB Processing: Node(19153k 832.8k/s) Way(3019k 23.59k/s) Relation(9110 112.47/s) parse time: 233s node cache: stored: 19153339(100.00%), storage efficiency: 16.41% (dense blocks: 113981, sparse nodes: 0), hit rate: 0.00% Osm2pgsql took 2125s overall Final DB size: ~1GiB
That's some 35 minutes.
Once finished you fire TileMill, create a new project and add a PostGIS layer. It took me some time to figure out what to put in the different fields, even when there is a tutorial for that, but I used these, mostly taken from inspecting the database's schemas:
- ID and Class: osm-roads
- Connection: dbname=osm host=localhost user=postgres
- Table or subquery: planet_osm_roads
- Unique key field: osm_id
- Geometry field: way
- The rest: default
And then add the following to the style.mss
which you can edit in the right
box of TileMill:
#osm-roads { ::outline { line-color: #7f0000; line-width: 2; line-join: round; } }
The result is kind of dissapointing: first, you have to specify more in the
"Table or subquery" field, because the data actually is not only some kind of
roads but also borders. I used
(select * from planet_osm_roads where highway!='') as foo
for all roads and
(select * from planet_osm_roads where boundary='administrative') as foo
for
borders as a first attempt to be more selective. Second, as I said, it's only
the main roads (down to
secondary in OSM's terms,
list which by the way seems to grow everytime I see it), but nothing smaller.
But as a start I think is enough.