[Mapcss] Layering model enhancements

Paul Hartmann phaaurlt at googlemail.com
Wed Aug 10 15:16:53 BST 2011


On 08/10/2011 02:07 PM, Komяpa wrote:
> Whoops, really missed these answers - sorry for that.
> 
> 2011/4/20 Paul Hartmann <phaaurlt at googlemail.com>:
>>> Imagine a linear road that finishes as asphalted surface inside a
>>> forest. Let the road be highway=service; the asphalted surface -
>>> highway=service area=yes, and forest - landuse=forest.
>>>
>>> Currently, we draw:
>>>  - forest as green;
>>>  - highway=service area=yes polygon as white
>>>  - casings for both highways. The casing for linear service overlaps
>>> with white area's polygon.
>>>  - linear fill for highway.
>>
>> I don't understand completely. I assume the casing for the linear way is
>> grey and it is filled white. What do you mean by casing of the area? Is this
>> a simple line style that uses the same way as the area? What is it's colour,
>> is it grey?
> 
> Yes.
> 
> In terms of Mapnik, casing is a LineSymbolizer that lies under lines
> and is wider than the main line to get a thin line around the roads
> (and other ways).
> 
> To render OSM nicely using Painter's algorithm you need to:
>  - render background
>  - render coaslines as polygons
>  - render all the backgrounds (like forests, grass, different kinds of
> landuse=, ...)
>  - render hillshading (optionally, of course)
> 
> then, for each layer= tag in order from lowest to highest:
>  - render casings in order of z-index-es
>  - render *both* polygons and lines that represent foreground features
> (buildings, roads) in order of z-indexes
> 
> then, render icons and labels in order that is backward for z-indexes
> (if renderer can detect collisions) or in order of z-indexes (if
> renderer can detect collisions).

That's roughly, how JOSM used to work, but I found it too limiting.

E.g. turning circles in Mapnik require rendering an icon - the turning
circle casing - below the highway line. Then the turning circle fill
comes on top. This is not possible, if you draw lines in a first pass
and icons in a second pass.

Now my idea was, to render all symbolizers in one pass and to assign
default z-index, such that it will still render like you described by
default.

But I have to admit, that I haven't considered layer=*, and this could
be a show stopper. (But not so much for an editor.)

> The problem is that currently there's no way to describe "background" features.
>> Can't this be solved with explicit z-index?
> 
> If you assign a z-index, it should apply to both area, casing, line,
> text and all the other features, IMHO. Don't you want thick bright
> casing for motorway to be drawn over dark casing for footway on lower
> zooms (as example)?

JOSM assigns a z-index to the casing symbolizer, that is 100 below the
z-index explicitly specified in the declaration.

Now, your initial example renders fine with this style:

area[natural=wood] {
    fill-color: lightgreen;
}

area[highway=service]:closed {
    fill-color: white;
    z-index: -90;
}

way[highway=service] {
    color: white;
    casing-color: gray;
    width: 10;
    casing-width: +5;
}

That is, because a z-index of -90 moves the highway area above casings.

>> Now, you probably want to draw the asphalted area on top of the way casing,
>> so you could raise the area to a z-index of -50.
> 
> well, I think of the following situation:
> 
> way[highway=motorway]{color:red; width:10}
> way[highway=tertiary]{color:yellow; width:5}
> way[highway=footway]{color:green; width:2}
> 
> area[highway]{fill-color:eval(prop(color)); width:0}

Should be all right, see above.

Generally, the painter's algorithm is a simple and powerful concept
because you don't have to specify an explicit z-index, but still have
full control over the painting order.

E.g. you need leisure=pitch on top of leisure=track on top of
leisure=stadium on top of landuse=residential and so on (considering
only areas). This is a piece of cake for osmarender, because the order
is implied by the order of rendering rules.

In MapCSS, you have to assign explicit z-index and in addition have a
reasonable order for casing, text, etc. I'm not sure if background-* is
the ultimate answer for all these issues, but it might solve the problem
at hand. For better backwards compatibility, I'd keep fill-color and add
an additional property, like

fill-elevation: background;

(If you write it like this, it smells like some kind of primary z-index
property. So, to follow that path, the z-index wouldn't be number, but a
list of numbers with decreasing priority.)

Paul



More information about the Mapcss mailing list