artemp/mapnik — Issue #350: Parallel LineSymbolizer
Author: artemp
Created: 2011-10-11 16:13:43+00:00
State: open
Labels: Symbolizers

== In short ==

Imagine following situation: A line is assigned 2 line-symbolizers and I need mapnik to paint them not one over another, but one next to the other. For example if a road, which normally looks like

{{{
---------------------
}}}

is assigned colours 'Yellow' and 'Blue'. With current mapnik capabilities, there is no problem to achieve a result like

{{{
---YYYBBB---YYYBBB---
}}}

However the desired result is more similar to

{{{
YYYYYYYYYYYYYYYYYYYYY
---------------------
BBBBBBBBBBBBBBBBBBBBB
}}}

== Motivation ==

In the Czech Repubic we have a large number of tourist trails, which are assigned one of 4 colours (red, blue, green, yellow). In some places, there are two trails going through the same road. The traditional way of painting them is exactly the way described above.

A typical result should look similar to the overlay in:
http://www.mapy.cz/#x=134865920@y=138622720@z=12@mm=TTtP

== Proposed solution ==

To add 'parallel_group=X' option to the line symbolizer. If there are at least two symbolizers within the same group X assigned to one line, algorithm for "shifting" symbolizers gets activated and automatically calculates the offset to each symbolizer on that road.

I can help to write the algorithm for calculating offsets, but I know nothing from the internals of mapnik.

== Solutions which (probably) will not work ==

=== Preprocessing ===

One way of dealing with such problem might be pre-computing the desired look of the map by shifting the trails a few meters left/right from the physical road.

Unfortunately we need to keep the distance between Red and Blue independent of zoom level and therefore such solution will not work.

=== Line symbolizer with offset ===

There is currently a similar ticket, which proposes to add a "shift" value in pixels to a line symbolizer.
http://trac.mapnik.org/ticket/180

Nevertheless I think that such solution will bring further problems when applied to the situation described here.

In case of Czech tourist trails, there are 4 colors and the map must consider every possible combination of trails on a road: {R}, {B}, {G}, {Y}, {RB}, {RG}, {RY}, ..., {RBG}, {RBY}, ..., {RBGY}. This gives total of 15 combinations (size of super-set -1), which is still manageable.

However such solution is hardly optimal. Imagine a "T" crossing, where Yellow goes from left to right, but Blue goes from left to down. The nicely looking solution is:

{{{
YYYYYYYYYYYYYYY
---------------
BBBBBBB|
B|
B|
B|
}}}

However with fixed "shift"s of each color in each combination, the Red and Blue might unnecessarily cross each other:

{{{
BBBBBBB
---------------
YYYYYYY|YYYYYYY
B|
B|
B|
}}}

There is an ugly solution, which consideres every permutation of every combinations in the superset: {R}, {B}, {G}, {Y}, {RB}, {BR}, {RG}, {GR, ..., {RBGY}, {RBYG}, {RYBG}, ... Only for 4 colours this gives 64 different line symbolizers.