4

I'm using Mapnik to render a list of points; for each of these points I want to render a plain round shape, and an icon inside the shape, using two different SVGs. To that end, I wrote a CartoCSS stylesheet like this (simplified):

[marker="true"] {
    marker-file: url('marker.svg');
    marker-allow-overlap: true;
    marker-fill: purple;
    marker-line-color: white;
    marker-line-width: 2;
    marker-height: 40;
    marker-transform: translate(0, @marker-height/-2);
}
[marker="true"]::inner-icon {
    marker-file: url('tree.svg');
    marker-allow-overlap: true;
    marker-height: @marker-icon-height;
    marker-fill: white;
    marker-transform: translate(0, @marker-icon-offset);
}

As far as I understood how Mapnik rendering works, I was expecting each point to render the two shapes together at once (marker.svg then tree.svg, in the order of the stylesheet) before rendering the next point, which would make sure that if two points overlap a bit, then the round plan shape would be drawn OVER the two shapes of the previous point.

However, the end result seems to draw all the marker.svg shapes, and then all the tree.svg shapes: render

I'm using Mapnik 3.0.0-pre.

1

After raising this question to the Mapnik team, I got a definitive answer from Dane: https://github.com/mapnik/mapnik-support/issues/26

Basically, using the :: syntax inside a MSS stylesheet generates a new Style inside Mapnik configuration. Each Style queries the data and renders the features. So, in my first stylesheet, I got all my marker.svg rendered in one pass, and all my tree.svg rendered in a second pass.

The solution is using another syntax to generate all the symbolizers inside the same Style:

[marker="true"] {
    marker/marker-file: url('marker.svg');
    marker/marker-allow-overlap: true;
    marker/marker-fill: purple;
    marker/marker-line-color: white;
    marker/marker-line-width: 2;
    marker/marker-height: 40;
    marker/marker-transform: translate(0, @marker-height/-2);

    inner-icon/marker-file: url('tree.svg');
    inner-icon/marker-allow-overlap: true;
    inner-icon/marker-height: @marker-icon-height;
    inner-icon/marker-fill: white;
    inner-icon/marker-transform: translate(0, @marker-icon-offset);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.