= !MapGuide RFC 32 – Expression Functions to Support Theming = This page contains an change request (RFC) for the !MapGuide Open Source project. More !MapGuide RFCs can be found on the [wiki:MapGuideRfcs RFCs] page. == Status == ||RFC Template Version||1.0|| ||Submission Date||September 5, 2007|| ||Last Modified||Ben Trumbore [[Timestamp]]|| ||Author||Ben Trumbore|| ||RFC Status||adopted|| ||Implementation Status||completed|| ||Proposed Milestone||2.0|| ||Assigned PSC guide(s)||Tom|| ||'''Voting History'''|||| ||+1||Tom, Jason, Bruce, Andy, Paul || ||+0|||| ||-0|||| ||-1|||| ||Abstained||Bob, Haris|| == Overview == The new !MapGuide symbolizations support expressions as values for almost all display attributes (color, size, etc.). This RFC proposes some functions that, when implemented for the expression engine, will make it easier to specify a display attribute theme using an expression. == Motivation == Currently, the best way to specify a style theme for a !MapGuide layer is by creating a series of style rules. Each rule contains a filter that selects a subset of the layer’s features, and a symbolization that will be applied to those features. Rules are processed in order, and each feature is stylized by only one rule – the first whose filter describes the feature.[[BR]] Because !MapGuide symbolizations allow expressions as values for their display attributes, it is also possible to specify some types of theming independent of the style rules. For example, a line’s thickness in points could be taken from a feature property that contains the number of lanes of a highway, or a hydrant’s output capacity might be depicted by setting a symbol’s X an Y sizes to a numerical expression based on a capacity property. Even when used in combination, however, these theming mechanisms suffer from several limitations:[[BR]] * Using many style rules to implement large themes is inefficient. Each style rule contains its own complete symbolization, so having many rules creates large layer definitions. A large number of rules also increases the number of selection operations needed to determine which features will be stylized using which rules.[[BR]] * Defining a “multivariate” theme using only rules can require a large number of rules with complicated filters and unique symbolizations. For instance, theming a point layer so that four symbol sizes, five symbol shapes and six symbol colors are selected based on different feature properties would require 120 style rules.[[BR]] * Currently, symbolization parameter expressions are limited to basic arithmetic operations and simple mathematical functions. These are insufficient for specifying the typical themes that are implemented using rules.[[BR]] These problems can be overcome by augmenting the expression engine with several theming-specific functions. These functions will accept parameters that encapsulate the definition of a theme for one display attribute (color, line thickness, etc.). They will need to work for multiple data types (string, real, integer, boolean, color, date-time). Since these function-based themes can be specified for multiple display attributes within a single symbolization, they can provide multivariate theming using a single style rule. == Proposed Solution == Three theming functions are proposed. Except where noted, each parameter can be a constant or expression that evaluates to a string or numerical value. The first function is quite simple: '''If('Condition', !TrueValue, !FalseValue)''' The ‘Condition’ parameter is a string containing any expression that evaluates to a Boolean value (essentially, a filter). Typically, this might be a single comparison such as 'population > 1000', where ‘population’ is a feature property of the layer. ‘!TrueValue’ and ‘!FalseValue’ are expressions that are evaluated and returned when the condition is true or false, respectively. Both expressions must evaluate to the same data type (string or number). This example could be used to rotate an upward-facing arrow symbol to indicate rising or falling populations: If('pop2005 > pop2000', 0.0, 180.0) By recursively using more ‘If’ functions for ‘!TrueValue’ and ‘!FalseValue’, it is possible to specify any set of discrete theme categories. However, since such expressions would be inefficient to evaluate, the following two functions are also proposed: '''Lookup(Expression, !DefaultValue, Key1, Value1, … KeyN, ValueN)''' This function implements a lookup table where each key is associated with a single value. ‘Expression’ is an expression that evaluates to a key (string or number). This key is compared to the remaining constant ‘Key#’ parameters to select the constant ‘Value#’ parameter that is to be returned. If the requested key is not found, ‘!DefaultValue’ is returned. The ‘Expression’ and all ‘Key’ parameters must have the same data type, as must the ‘!DefaultValue’ and all ‘Value#’ parameters. The number of key-value pairs is not fixed. This example could be used to assign colors to parcels based on their zoning type: Lookup(zoning, 0xff888888, 'Industrial', 0xffff0000, 'Commercial', 0xff00ff00, 'Residential', 0xff0000ff) In the last function, the ‘Expression’ key is compared to a set of ranges, where a key matches a range if MIN <= KEY < MAX: '''Range(Expression, !DefaultValue, Min1, Max1, Value1, … MinN, MaxN, ValueN)''' Ranges are specified by the ‘Min#’ and ‘Max#’ parameters, and each has an associated ‘Value#’ parameter. If the requested key does not match any of the provided ranges, ‘!DefaultValue’ is returned. If ranges overlap, the first range that matches the key will be selected. The ‘Expression’ and all ‘Min’ and `Max’ parameters must have the same data type, as must the ‘!DefaultValue’ and all ‘Value#’ parameters. The number of range-value sets is not fixed. This example could be used to specify symbol size depending on city populations: Range(population, 4.0, 100000, 1000000, 6.0, 1000000, 10000000, 8.0) == Implications == Layer definitions that use expressions containing theming functions will be stylized correctly only on !MapGuide servers from a release that implements those functions. == Test Plan == A new unit test will be required to exercise the theming functions. It should operate on fixed test feature data and exercise a set of theming functions. These functions should span the range of capabilities and data types supported by the implementation. == Funding/Resources == Supplied by Autodesk.