Wednesday, 10 April 2013

MapGuide tidbits: FDO stylization expression functions

Believe it or not, these aren't the only expression functions that aren't documented.

You may have noticed these functions pop up when using the Expression Editor in Maestro or Studio/AutoCAD Map

  • ARGB
  • DECAP
  • FEATURECLASS
  • FEATUREID*
  • IF
  • LAYERID*
  • LOOKUP
  • MAPNAME*
  • RANGE
  • SESSION*
  • URLENCODE
* Denotes a MapGuide-specific FDO expression function (ie. Not supported/recognised in AutoCAD Map)

While some of these functions have been explained, others have not. Also there isn't really many solid examples, so it's understandable if you don't have much of an idea where and how such functions may prove useful.

So firstly, what are these functions? These functions are FDO Expression Functions that are only applicable during rendering and stylization of features. That means these functions can be used in any expression for:
  • A tooltip
  • A hyperlink
  • A feature label
  • Any styling/symbolization property that accepts FDO expressions
However, due to their scope you cannot use said functions in:
  • A layer filter (rendering/stylization doesn't happen at this stage)
  • Any part of a MgFeatureQueryOptions object (computed property or filter).
These functions are universally supported regardless of providers, as they are application-level functions provided by the FDO Expression Engine, so you don't have to worry about provided capabilities like regular FDO functions. Also unlike the custom aggregate functions, these functions are actual FDO functions so you can nest and chain these function calls with other FDO functions.

So like the other post, here's what each function in this list does.

ARGB

The ARGB function returns a 32-bit integer, which represents the color computed by this function. It's signature is:
  • ARGB(alpha, red, green, blue)
  • alpha, red, green, blue are numbers between 0 and 255 inclusive
Remarks: This function can be used in place of any layer style property that takes a color (eg. A border or fill)

DECAP

The DECAP function returns an auto-capitalized version of the input string. It's signature is:
  • DECAP(inputString)
  • inputString is a string
For example the expression DECAP('HELLO WORLD') will return the string "Hello World"

Remarks: This function I would imagine would primarily be used for normalizing string values for labelling.

FEATURECLASS

The FEATURECLASS function returns the fully qualified FDO class name that the currently stylized feature originates from. It takes no parameters.

Remarks: This function I would imagine is primarily used for tooltips or hyperlinks. Probably for displaying useful "debugging" information about a feature or maybe as part of some URL link you're building into the tooltip content.

FEATUREID

The FEATUREID function returns the base64 encoded key of the currently stylized feature. This is the same base64 key value that would be in a selection XML string if this feature was selected. It takes no parameters

Remarks: Probably the same use case as the FEATURECLASS expression function

IF

If you used excel, this function should be familiar to you. It's signature is:
  • IF(condition, trueExpr, falseExpr)
  • condition is a string representing the FDO condition to evaluate
  • trueExpr is the expression to return if the specified condition evaluates to true
  • falseExpr is the expression to return if the specified condition evaluates to false
Remarks: Obviously useful for binary expressions

LAYERID

The LAYERID function returns the unique id of the layer that the currently stylized feature belongs to. This unique id is the same value returned by MgLayerBase::GetObjectId() for that same layer. It takes no parameters

Remarks: Probably used for tooltips or hyperlinks, in conjunction with some server-side logic (invoked through a built tooltip content URL) that does something with the runtime layer (MgLayer) state.

LOOKUP

The LOOKUP function implements a lookup table where each key is associated with a single value. Its signature is:
  • LOOKUP(expr, defaultValue, key1, value1, ... keyN, valueN)
  • expr is the FDO expression that evaluates to a string or number
  • defaultValue is the value to return if none of the keys are equal to the given expression
  • key[1...n] is the value to compare the evaluated expression against for equality
  • value[1...n] is the value to return if the corresponding key is equal to the evaluated expression
For example, this expression:

LOOKUP(RTYPE, 'Unknown', 'AGR', 'Agriculture', 'MFG', 'Manufacturing', 'RES', 'Residential')

Will return the following values based on the value of the RTYPE attribute of the currently stylized feature:
  • RTYPE = 'AGR': Expression returns 'Agriculture'
  • RTYPE = 'MFG': Expression returns 'Manufacturing'
  • RTYPE = 'RES': Expression returns 'Residential'
  • RTYPE is NULL or does not match any of the above: Expression returns 'Unknown'

Remarks: A scenario where I can see this function being useful is for creating "legendless" themes. Read on to understand what I'm talking about.

MAPNAME

The MAPNAME function returns the name of the runtime map that the current stylized feature is part of. It takes no parameters.

Remarks: Once again, it's probably going to be mostly used for tooltips or hyperlinks. Either for "debugging" or building tooltip content URLs to server-side logic using the MapGuide API. 

RANGE

The RANGE function is similar to LOOKUP in that it's a function that can return one of many values based on a given expression. The difference is the expression is compared against a min/max range instead of a fixed value. It's signature is:
  • RANGE(expr, defaultValue, min1, max1, value1, ... minN, maxN, valueN)
  • expr is the FDO expression that evaluates to a number
  • defaultValue is the value to return if none of the expression does not fall within any of the specified range
  • min[1...n] defines the lower bound of a given range
  • max[1...n] defines the upper bound of a given range
  • value[1...n] defines the value to return if the evaluated expression lies within the respective min and max of this range
For example, the following expression:

RANGE(POPULATION, 4.0, 100000, 1000000, 6.0, 1000000, 10000000, 8.0)

Will return the following values based on the value of the POPULATION attribute of the currently stylized feature:
  • 100000 <= POPULATION < 1000000: Expression returns 6.0
  • 1000000 <= POPULATION < 10000000: Expresion returns 8.0
  • POPULATION is NULL or does not fit within any of the above ranges: Expression returns 4.0
Remarks: Same use case as LOOKUP. A way to create "legendless" themes.

SESSION

The SESSION function returns the current MapGuide id of the session that initiated this rendering/stylization operation. It takes no parameters

Remarks: Same use case as MAPNAME. Most likely used in conjunction with MAPNAME, seeing as most server-side logic require both the session id and the map name in order to do anything useful with the runtime map (MgMap)

URLENCODE

The URLENCODE function encodes the input string. It's signature is:
  • URLENCODE(inputStr)
  • inputStr is the string to URL encode
Remarks: Probably used to encode content when building URLs in the tooltip or for hyperlinks.

So there's the overview of these functions. How about some examples? I got some right here.

Example 1: A comprehensive tooltip

This example layer definition shows all of the above stylization functions in a tooltip so you can get an idea of what these functions are returning based on the Sheboygan parcels data.



Example 2: A "legendless" themed layer

This example layer definition shows how the normal Parcels layer from the Sheboygan dataset using the LOOKUP expression function to dynamically theme the parcels. Note how the legend does not show the individual theme rules. This is because the Layer Definition only has one rule, but that one rule uses the LOOKUP function to compute the fill based on the type (RTYPE) of the Parcel feature.



Maestro does not currently offer any assistance in creating "legendless" themes. It's something I've put into consideration.

Hopefully this post sheds greater light on what these functions are and how they work. These functions may provide layer stylization options that you didn't think was previously possible.

2 comments:

נמרוד כנען said...

LOOKUP: Can you give us a more comprehensive briefing. It's a very powerful feature that nobody I know uses.

Jackie Ng said...

Added examples for LOOKUP and RANGE functions