User:Moresby/Understanding Mapnik/Plotting lines

From OpenStreetMap Wiki
Jump to: navigation, search
Understanding Mapnik
A Mapnik tutorial
Starting with Python
Using XML and CSS
CartoCSS and PostGIS
030-lines.png - roads shown with simple lines

As well as plotting points, Mapnik allows us to plot lines. Here we plot some of the rail and road connections between our locations.

 1 #!/usr/bin/python
 2 
 3 # Load the Python mapnik libraries.
 4 import mapnik
 5 
 6 # Create a new map.
 7 m = mapnik.Map(480, 320)
 8 
 9 # Set the background colour.
10 m.background = mapnik.Color('ghostwhite')
11 
12 # Create a line symbolizer.
13 line_symbolizer = mapnik.LineSymbolizer()
14 
15 # Create a new rule and add the symbolizer.
16 r = mapnik.Rule()
17 r.symbols.append(line_symbolizer)
18 
19 # Create a new style and add the rule.
20 s = mapnik.Style()
21 s.rules.append(r)
22 
23 # Add the style to the map.
24 m.append_style('basic_style', s)
25 
26 # Specify that our data is coming from a CSV file called "data-roads.csv".
27 ds = mapnik.CSV(file='data-roads.csv')
28 
29 # Create a new layer for the map, called "main_map" and add the data
30 #   source and style to that layer.
31 l = mapnik.Layer('main_map')
32 l.datasource = ds
33 l.styles.append('basic_style')
34 
35 # Add the layer to the map.
36 m.layers.append(l)
37 
38 # Zoom to the part of the map we are interested in.
39 m.zoom_to_box(mapnik.Box2d(0, 0, 480, 320))
40 
41 # Save the map as a PNG image.
42 mapnik.render_to_file(m, '030-lines.png', 'png')

We also need to have some data to plot. The following data represent some of the roads and rail links between some of the towns and cities we used earlier. Save the following lines in a file called data-roads.csv:

name,       type,      wkt

"A1",       mainroad,  "LINESTRING(119  17, 108 133, 131 188, 113 308)"
"A10",      mainroad,  "LINESTRING(221 125, 179  51)"
"A11",      road,      "LINESTRING(409 231, 307 146, 259  39)"
"M11",      motorway,  "LINESTRING(220 -81, 259  39, 221 125)"
"A14",      mainroad,  "LINESTRING(483 119, 398 147, 307 146, 221 125, 131 188, -29 222)"
"A30",      mainroad,  "LINESTRING(221 125, 220 144, 248 204, 263 222)"
"A134",     road,      "LINESTRING(409 231, 398 147)"
"A141",     road,      "LINESTRING(213 297, 131 188)"
"A142",     road,      "LINESTRING(307 146, 263 222)"
"A421",     road,      "LINESTRING(108 133,  48  93)"
"A422",     road,      "LINESTRING( 48  93, -22  79)"
"A428",     road,      "LINESTRING(108 133, 221 125)"
"A505",     road,      "LINESTRING(179  51, 119  17)"
"A605",     road,      "LINESTRING(113 308, 120 300, 204 312, 213 297)"
"A1101",    road,      "LINESTRING(398 147, 263 222)"
"A1123",    road,      "LINESTRING(263 222, 164 190, 131 188)"
"A1198",    road,      "LINESTRING(179  51, 131 188)"
"railway",  rail,      "LINESTRING(113 308, 213 297, 263 222, 409 231)"
"railway",  rail,      "LINESTRING(263 222, 221 125)"

Well-known text

The rather cryptically named "well-known text" is a standardised way of representing geometry objects, including points, lines and polygons. Here we are using the LineString WKT type to represent roads and railways. In the data-places.csv file in previous examples, we could have represented town and city coordinates using the Point WKT type. This version of the data-places.csv file gives identical results in our examples:

name,              type,     wkt

"Bedford",         town,     "POINT( 48  93)"
"Bury St Edmunds", town,     "POINT(398 147)"
"Cambridge",       city,     "POINT(221 125)"
"Ely",             city,     "POINT(263 222)"
"Harlow",          town,     "POINT(220 -81)"
"Huntingdon",      town,     "POINT(131 188)"
"Kettering",       town,     "POINT(-29 222)"
"Letchworth",      town,     "POINT(119  17)"
"March",           town,     "POINT(213 297)"
"Newmarket",       town,     "POINT(307 146)"
"Peterborough",    city,     "POINT(113 308)"
"Royston",         town,     "POINT(179  51)"
"Saffron Walden",  town,     "POINT(259  39)"
"Sherington",      town,     "POINT(-22  79)"
"St Ives",         town,     "POINT(164 190)"
"St Neots",        town,     "POINT(108 133)"
"Stowmarket",      town,     "POINT(483 119)"
"Thetford",        town,     "POINT(409 231)"

Save this program in a file called 030-lines.py and run it by typing:

python 030-lines.py

You should see no error messages, and you should see a new file in your working directory called 030-lines.png. This is a new map image, and should be a light-coloured rectangle 480 pixels wide by 320 pixels high, with a series of interconnected black lines, as shown above.