Showing posts with label carto. Show all posts
Showing posts with label carto. Show all posts

Thursday, 19 May 2011

Rendering OpenStreetMap Data using Carto and Mapnik

Mapnik is often used to render OpenStreetMap (OSM) data.   The map style (line colours and sizes, icons etc.) are defined by a style file.  There is a very detailed one provided with OpenStreetMap's mapnik tools.   Unfortunately that level of detail means that the style definition is very complicated and it is hard to follow how it works.
A tool called carto is available which is a pre-processor that will take a simpler format of style file, and convert it into the mapnik file format.   I have been experimenting with trying to render OSM data using styles written for carto.   I had been hoping to use a nice graphical editor with map preview capability called tilemill, but tilemill does not work with postgresql datasources, which are necessary for OSM rendering.   Instead, I installed tilemill and used the version of carto that is included with it, but did not use the tilemill editor.

Carto Layer Definitions
Rendering data with carto needs you to do two things - define the data you want to plot on your map ('Layers'), and define how you want the data displayed ('Styles').

The datasource definitions go in a .mml file that looks something like this:

{
"_center":{"lat":36.870832154494,"lon":-113.79638671427,"zoom":5},
"_format":"png",
"srs":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs",
"Stylesheet":["style2.mss",
"areas2.mss",
"roads2.mss",
"labels2.mss",
"natural2.mss",
"contours2.mss",
"POIs2.mss"],

"Layer":[
  {"id":"coastline",
   "name":"coastline",
   "srs":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over",
   "class":"",
   "geometry":"polygon",
   "Datasource":{"file":"/home/graham/OSM/data/mapdata/world_boundaries/processed_p.shp","type":"shape"}},

 {"id":"landuse",
  "name":"landuse",
  "srs":"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs",
  "class":"",
  "geometry":"area",
  "Datasource": {
               "type":"postgis",
      "dbname":"kefalonia",
      "user":"www",
      "password":"1234",
      "host":"localhost",
      "port":"",
      "table":"(select way,landuse,name,\"name:en\" from planet_osm_polygon where landuse is not null) as landuse"
               }
  }
]
}
The first few lines define the projection of the output map, and the stylesheets that are to be used to define how to render the data.   The bulk of the file is layer definitions.   In this example two layers are defined.  One is a shapefile containing the coastlines (the same one that is used by the normal OSM style).   The second layer extracts all areas tagged with 'landuse=xxx'.

We have not told mapnik how to plot the data though - this is done in the style files.  The ones relevant to this example are "style2.mss" and "areas2.mss".  Style2.mss contains:

@land: #e0e0c0;
@water: #C0E0F8;
@waterline: #8CE;
Map {
  background-color:@water;
}
#coastline::outline {
  line-color:@waterline;
  line-width:1.6;
}
#coastline::fill {
  polygon-fill:@land;
  polygon-gamma:0.75;
}
Here the things starting '@' are variables which allow you to define colours etc.  at the top of the file, then use them several times throughout it, making future maintenance easier.   In this example we define the background colour for the map, fill it in blue to represent water.   We then draw a line around the costline, and fill in the land with a separate colour.

The areas2.mss style is slightly more complicated:
#landuse {
   [landuse="residential"]
   {
      polygon-fill: #b0b0b0;
   }
   [landuse="industrial"]
   {
      polygon-fill: #a0a0a0;
   }
   [landuse="forest"]
   {
      polygon-fill: #a0d0a0;
   }
}
In this example the [] expressions are filters, which allows us to define different fill colours depending on the landuse tag.

These are just extracts - the actual styles I am using are getting progressively more and more complicated.   You can see the files, and a modified version of the generate_image.py script provided by OSM, which takes a carto .mml file as input in my svn repository (soon to be copied to github..)

Using these styles, I have updated my kefalonia map to give this:
and this:




These styles are nowhere near as clever as the standard OSM ones.  In particular I have not tried to devine different styles fo rdifferent zoom levels  instead I have two sets of stylesheets for two different zoom levels - I think in the end I will have there - one for a 'country level', another for a 'town level', and a third for higher zoom levels.

There are also a few issues - the line styles do not look as nice as the OSM ones - I do not know why...and there is a problem with the road names where sometimes other roads crossing over each other obliterate the labels.   THe reason is that I draw the road and the label at the same time - it will probably look better if I do the labels after all roads have been drawn.   Will hav eto work out how to do that!



Friday, 29 April 2011

Installation of Carto Mapnik Style File Builder on Ubuntu

I find mapnik style files a bit clumsy to edit - lots of repetition that makes them hard to follow.
There are (at least) two utilities available that may make style file generation simpler.  These are Cascadenik and Carto.
It appears that Carto is being more actively developed at the moment, so I thought I would look at that first. Carto also reports to be much faster than Cascadenink.
The problem is that Carto is new-fangled and uses a javascript based language called node.js.   Despite my dislike of javascript, I thought I would persevere.  This is how I got it working on my Ubuntu 10.10 system:

  • Downloaded node.js version 0.4.7 from http://nodejs.org, and extracted it into /usr/local/node-v0.4.7.  Built with ./configure; make; make install.
  • Installed the node package manager npm using: curl http://npmjs.org/install.sh | sh
  • Installed carto dependencies:
    • npm install get     [used to be node-get, but the module has changed name]
    • npm install step
    • npm install srs
    • npm install underscore
    • npm install zipfile (actually did this twice because one of the document build actions failed on the first attempt...).
  • Downloaded carto using:  git clone https://github.com/mapbox/carto.git
  • No compilation necessary (it is javascript).  Executing cd carto; ./bin/carto gave no nasty errors, just "no input files", which looks promising.
I just need to work out how to use it now.

I have had a quick look at TileMill, which is a web based editor for carto stylesheets - it is very impressive - you can change the stylesheet and preview the map in real time.   The only problem that I have found with tilemill is that it does not seem to work with a postgresql database as the data source, which is where my OSM data is stored.  But at least I should get the idea about the structure of the files using that tool.