artemp/mapnik — Issue #828: All values should become expressions
Author: artemp
Created: 2011-10-11 16:38:10+00:00
State: open
Labels: Symbolizers

To allow for less complex styles, every symbolizer attribute should become an expression. There are some properties that already have a notion of being an expression, e.g. the polygon-pattern-file and text-name has token replacement and the marker-width is an expression too.

## How to implement

When rendering, create a pseudo-stylesheet for each layer that contains only the rules for that layer. This is already happening in [https://github.com/mapnik/mapnik2/blob/f3061554c97e80520da45870d86ae7ed6cc5c7ee/include/mapnik/feature_style_processor.hpp#L262-297 apply_to_layer()]. Instead of just creating a new set, we clone each rule and pre-evaluate it; i.e. evaluate all expressions as much as possible, leaving the parts that reference feature-specific values intact. In some cases, this might already yield a constant value, in other cases we still have an expression. This is an optional step and should be implemented last to improve performance should the following changes turn out to slow down rendering dramatically.

Every attribute of a symbolizer becomes an expression. The renderer passes the feature to the attribute getter of a symbolizer to obtain the actual value. In case the value is static, the expression object just returns that value, otherwise it evaluates the expression taking the current feature into account. In addition to the feature's attributes, the scale denominator is also an available attribute.

As a next step, we'd add ''value gradients'': a function that transforms a float in the range of 0.0 to 1.0 to an actual value, e.g. you could create a color gradient from #000 to #FFF and using an expression, calculate a value between 0 and 1 (e.g. by using statistics about the datasource) and resolve that value to a color. This could come in two flavors, a gradient() function that returns continuous values and a levels() that returns only discrete values.

Related tickets: #816, #827, #704, #810