To better understand how the various parts of Mapnik work together, let's write a simple Python program to generate the map shown at the start of this chapter. This map makes use of the World Borders Dataset, which you downloaded in an earlier chapter; copy the TM_WORLD_BORDERS-0.3 shapefile directory into a convenient place, and create a new Python script in the same place. We'll call this program createExampleMap.py.
We'll start by importing the Mapnik toolkit and defining some constants the program will need:
import mapnik MIN_LAT = -35 MAX_LAT = +35 MIN_LONG = -12 MAX_LONG = +50 MAP_WIDTH = 700 MAP_HEIGHT = 800
The MIN_LAT, MAX_LAT, MIN_LONG, and MAX_LONG constants define the lat/long coordinates for the portion of the world to display on the map, while the MAP_WIDTH and MAP_HEIGHT constants define the size of the generated map image, measured in pixels. Obviously, you can change these if you want.
We're now ready to define the contents of the map. This map will have two layers, one for drawing the polygons and another for drawing the labels. We'll define a Mapnik Style object for each of these two layers. Let's start with the style for the Polygons layer:
polygonStyle = mapnik.Style()
As we discussed in the previous section, a Filter object lets you choose which particular features a rule will apply to. In this case, we want to set up two rules, one to draw Angola in dark red, and another to draw all the other countries in dark green:
rule = mapnik.Rule()
rule.filter = mapnik.Filter("[NAME] = 'Angola'")
symbol = mapnik.PolygonSymbolizer(mapnik.Color("#604040"))
rule.symbols.append(symbol)
polygonStyle.rules.append(rule)
rule = mapnik.Rule()
rule.filter = mapnik.Filter("[NAME] != 'Angola'")
symbol = mapnik.PolygonSymbolizer(mapnik.Color("#406040"))
rule.symbols.append(symbol)
polygonStyle.rules.append(rule)Notice how we use a PolygonSymbolizer to fill each country's outline with an appropriate color and then add this symbolizer to our current rule. As we define the rules, we add them to our polygon style.
Now that we've filled the country polygons, we'll define an additional rule to draw the polygon outlines:
rule = mapnik.Rule()
symbol = mapnik.LineSymbolizer(mapnik.Color("#000000"), 0.1)
rule.symbols.append(symbol)
polygonStyle.rules.append(rule)This is all that's required to display the country polygons on the map. Let's now go ahead and define a second Mapnik Style object for the "Labels" layer:
labelStyle = mapnik.Style()
rule = mapnik.Rule()
symbol = mapnik.TextSymbolizer(mapnik.Expression("[NAME]"),
"DejaVu Sans Book", 12,
mapnik.Color("#000000"))
rule.symbols.append(symbol)
labelStyle.rules.append(rule)This style uses a TextSymbolizer to draw the labels onto the map. Notice that we create an Expression object to define the text to be displayed—in this case, we want to display the shapefile's NAME attribute; as you might expect, this attribute contains the name of the country.
In this example, we are only using a single Mapnik style for each layer. When generating a more complex map, you will typically have a number of styles that can be applied to each layer, and styles may be shared between layers as appropriate. For this example, though, we are keeping the map definition as simple as possible.
Now that we have set up our styles, we can start to define our map's layers. Before we do this, though, we need to set up our data source:
datasource = mapnik.Shapefile(file="TM_WORLD_BORDERS-0.3/" +
"TM_WORLD_BORDERS-0.3.shp")We can then define the two layers used by our map:
polygonLayer = mapnik.Layer("Polygons")
polygonLayer.datasource = datasource
polygonLayer.styles.append("PolygonStyle")
labelLayer = mapnik.Layer("Labels")
labelLayer.datasource = datasource
labelLayer.styles.append("LabelStyle")We can now finally create our Map object. A Mapnik Map object has a width and height, a projection, a background color, a list of styles, and a list of the layers that make up the map:
map = mapnik.Map(MAP_WIDTH, MAP_HEIGHT,
"+proj=longlat +datum=WGS84")
map.background = mapnik.Color("#8080a0")
map.append_style("PolygonStyle", polygonStyle)
map.append_style("LabelStyle", labelStyle)
map.layers.append(polygonLayer)
map.layers.append(labelLayer)The last thing we have to do is tell Mapnik to zoom in on the desired area of the world and then render the map into an image file:
map.zoom_to_box(mapnik.Box2d(MIN_LONG, MIN_LAT,
MAX_LONG, MAX_LAT))
mapnik.render_to_file(map, "map.png")If you run this program and open the resulting map.png file, you will see the map you generated:

Obviously, there's a lot more that you can do with Mapnik, but this example covers the main points and should be enough to let you start generating your own maps. Make sure that you play with this example to become familiar with the way Mapnik works. Here are some things you might like to try:
MIN_LAT, MIN_LONG, MAX_LAT, and MAX_LONG constants at the start of the program to zoom in on the country where you reside