[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