1.1. Concept

Mapnik is a library, not a complete application program. So it always to be linked to at least a minimum of application code that controls the library operations.

The data flow of Mapnik basically is that it reads geospatial data sources and applies presentation styles on the input that decide how to visually present specific geometry objects:

Mapnik data flow

In a little more detailed view, starting bottom up from the output side, we have the following basic library objects:

  • Symbolizers do the actual output, by taking a geometry and its extra properties and creating actual graphic output from that

  • Filters decide what to actually pass to specific symbolizers instances for output

  • Rules contain one or more filters

  • Styles contain one or more rules

  • Data sources provide actual geometry objects to process

  • Layers combine a data source with one or more styles

  • A map contains one or more layers

TODO: class diagram

All these objects can be created and configured directly in code, but the usual approach is to so by specifying them in a XML style file which is then loaded as a whole into a Mapnik map object at run time.

In the most simple case the application program just creates a Mapnik Map object of a certain size, loads a XML style file, and renderers this style into an output file, e.g. when using the Python Mapnik bindings:

Example 1. A minimal Mapnik source and style

Python API code:

#! /usr/bin/env /usr/bin/python3

import mapnik

map = mapnik.Map(600,300) # create a 600x300 pixel map

mapnik.load_map(map, 'points.xml') # loat style file

map.zoom_all() # make sure all data is visible
map.zoom(-1.1) # zoom out a bit more to avoid clipping

mapnik.render_to_file(map, 'point.png', 'png') # render

Style file including inline data:

<?xml version="1.0" encoding="utf-8"?>
<Map background-color='lightgreen'>

  <Style name="style">
    <Rule>
      <PointSymbolizer/>
    </Rule>
  </Style>

  <Layer name="layer">
    <StyleName>style</StyleName>
    <Datasource>
      <Parameter name="type">csv</Parameter>
      <Parameter name="inline">
wkt
"POINT(10 10)"
"POINT(20 20)"
"POINT(30 30)"
      </Parameter>
    </Datasource>
  </Layer>

</Map>

Result:

introduction

TODO: do the same with pure python and no separate style file