Mapnik & Cascadenik Tips
Some differences between Cascadenik and CSS
While Cascadenik works in a similar way to CSS, there are some differences. Here is a short list of things that might catch you:
- Colors can only be specified as #RGB or #RRGGBB - rgb(RRR,GGG,BBB) values won't work (even though Mapnik supports them)
- Every attribute requires a semicolon at the end, even the last one.
Overlapping dotted lines
Borders in many data sets are defined on both sides, an thus are actually two lines overlapping each other. If you want to make these lines dashed, the dashes may not line up exactly and appear longer than you wish, or perhaps even create a solid line. For example, all of these lines are meant to have the same style:

To work around this in Cascadenik, you can use an outline with a width of 0 that is the same color as the map background to block out whichever line is underneath. The code would look like this:
.class {
line-color: #000;
line-dasharray: 3, 4;
line-width: 1;
/* same as map background color: */
outline-color: #fff;
outline-width: 0;
}The caveat to this method is that it will not work well if you are rendering a transparent background, or a background which has a wide range of colors.
Simplify your code with XML entities
A lot of the information you need to enter into a Cascadenik or Mapnik XML file will be repetative. You can save some time and keystrokes by defining internal XML entities at the beginning of your document.
A Cascadenik file using entities looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[
<!-- projections -->
<!ENTITY srs_osm "+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 +wktext +no_defs">
<!ENTITY srs_wgs84 "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
]>
<Map srs="&srs_osm;">
<Stylesheet src="your-stylesheet.mss" />
<Layer class="one-or-more class" srs="&srs_wgs84;">
<Datasource>
<Parameter name="file">/path/to/shapefile</Parameter>
<Parameter name="type">shape</Parameter>
</Datasource>
</Layer>
</Map>Entities are defined before the tag, but after the tag. In the above example there are two entities defined, named "srs_osm" and "srs_wgs84". The values for these entities are the projection strings I would normally have to write into the Map tag and every Layer tag. With entities defined, all you have to type is "&entity_name;", and it will be interpreted as if the full string had been typed out.
Another great use of entities is be to store PostGIS server information. If the server's URL or login credentials ever change, the information only has to be edited in one place.
Example PostGIS entity definitions:
<!DOCTYPE Map[
<!-- database settings -->
<!ENTITY host "gis.example.com">
<!ENTITY port "5433">
<!ENTITY user "username">
<!ENTITY password "password">
<!ENTITY dbname "database_name">
]>With those entities defined, the Datasource entry in your PostGIS layers would look like this:
<Datasource>
<Parameter name="type">postgis</Parameter>
<Parameter name="host">&host;</Parameter>
<Parameter name="port">&port;</Parameter>
<Parameter name="user">&user;</Parameter>
<Parameter name="password">&password;</Parameter>
<Parameter name="dbname">&dbname;</Parameter>
<Parameter name="table">table_name</Parameter>
</Datasource>