MS RFC 72: Layer and Label-Level Geomtransforms

Author:Steve Lime
Contact:sdlime at

1. Overview

MapServer 6.0 introduced the concept of geometry expressions within a styleObj-geomtransform. For example, one could write:

  GEOMTRANSFORM (buffer([shape], -5)

This would cause a buffer operation to be run on the shape before being rendered with a given style.

This is useful for certain cartographic effects but is limited in a couple of ways:

  1. it operates in pixel space (e.g. once a feature is converted from map to image coordinates)
  2. the resulting shape can only be used with a single style so it is not efficient to, say, create a complex rendering of a buffered feature
  3. it is not possible to query transformed features
  4. the resulting shape cannot be used in any labeling operations

2. The proposed solution

This RFC proposes to extend GEOMTRANSFORMS to both the layer and label contexts. Basically the same keyword and syntax would become valid in other objects.

For a layer the tranformation would be applied to geometries as they are read from a datasource and before any drawing or query operations. As a result it would be much more efficient to perform complex rendering of a transformed shape. In addition the resulting shape would also be queryable in a consistent manner since the transformation would be independent of the map being drawn (e.g. scale, bounding box, etc...).

For a label the transformation would be applied ahead label point computation, in pixel coordinates much like the current style implementation. This will allow for effects like labeling the inside edge of a polygon or perhaps creating a curved labels within a polygon.

These operations are computationaly intensive so users would need to understand the performance impact but as tiling becomes the norm this is less an issue.

3. Implementation Details

For layers I propose adding a check to the functions msLayerGetShape() and msLayerNextShape() to conditionally apply the GEOMSTRANFORM before returning the shape. The resulting shape would contain all the attributes of the parent. (Note: one potential issue is that certain operations might affect the bounding box used to select candidate shapes via msLayerWhichShapes()).

For labels the check and transformation would be applied within the msLayerDrawShape() function.

Small changes to the logical expression grammar (mapparser.y) and expression tokenizer would need to be made.

3.1 Files affected

The following files will be modified/created by this RFC:

mapfile.c (layer/label read/write)
mapdraw.c (update msDrawShape())
maplayer.c (update msLayerGetShape(), msLayerNextShape(), msLayerWhichItems() and msLayerGetTokens())
maplexer.l (add additional GEOS operators, in trunk only buffer and difference are currently implemented)
mapparser.y (extend the grammar)

3.2 MapScript Issues

These are just expressionObj’s so functions to get/set them already exist.

3.3 Security Issues

Care must be take to avoid memory leaks associated with the production of the transformed shapes. It would make sense to allow runtime substitution like is done with layer filters and class expressions. Simlarly, validation patterns would be required.

3.4 Backwards Compatibilty Issues

This change provides a new functionality with no backwards compatibility issues being considered.

4. Bug ID

None assigned. See related ticket #3871.

5. Voting history