MS RFC 19: Style & Label attribute binding

Date:2006/06/07
Author:Steve Lime
Contact:steve.lime at DNR.STATE.MN.US
Status:Passed (in process)
Version:MapServer 5.0

Description: Presently MapServer supports binding of label and style properties for a few select attributes (e.g. angle). However, it is cumbersome to add new bindings which leads to unnecessarily complex structures and code that is difficult to maintain. This RFC presents ideas to bring a bit of order to that chaos and make expansion of this capability easier to achieve.

C Structural Changes

A new structure called attributeBindingObj would be added:

typedef struct {
  char *item;
  char index;
} attributeBindingObj;

Several new enumerations would then define what properties could be bound:

#define MS_STYLE_BINDING_LENGTH ...
#define MS_STYLE_BINDING_ENUM { MS_STYLE_BINDING_SIZE, MS_STYLE_BINDING_ANGLE, ... };

#define MS_LABEL_BINDING_LENGTH ...
#define MS_LABEL_BINDING_ENUM { MS_LABEL_BINDING_SIZE, MS_LABEL_BINDING_ANGLE, ... };

Several elements would be removed from layerObj and styleObj. For example, angleitem, angleitemindex and similar members would be removed. styleObj's and labelObj's would each take on 2 new members:

char hasBindings;
attributeBindingObj bindings[MS_STYLE_BINDING_LENGTH];

Mapfile/MapScript Changes

Options like SIZEITEM and ANGLEITEM would go away. Instead a more logical syntax such as:

STYLE
  SIZE [mySizeItem]
  ANGLE [myAngleItem]
  COLOR 255 0 0
  SYMBOL 'square'
END

Square brackets have been used in MapServer templates and expressions to bind to attributes so they are a natural choice to denote attribute bindings in this case.

Similarly MapScript would loose the ability to set/get the xxxITEM properties. Instead the style and label objects would get setBinding and deleteBinding methods:

(in Perl)
$style->setBinding($mapscript::MS_STYLE_BINDING_SIZE, 'mySizeItem');
$style->deleteBinding($mapscript::MS_STYLE_BINDING_COLOR);

Files Affected

  • map.h => structure changes, enum and define additions
  • maputil.c => add msStyleBindAttributes();
void msStyleBindAttributes(shapeObj *shape, styleObj *style)
{
  if(style->bindings[MS_STYLE_BINDING_SIZE].item)
    style->size = atoi(shape->values[style->bindings[MS_STYLE_BINDING_SIZE].index]);
  if(style->bindings[MS_STYLE_BINDING_ANGLE].item)
    style->angle = atoi(shape->values[style->bindings[MS_STYLE_BINDING_ANGLE].index]);
  ...
}
  • maplabel.c => add msLabelBindAttributes();
  • maplayer.c => fix msWhichItems() to populate the binding indexes
  • mapdraw.c => remove references to the xxxITEM properties, if a style or label has bindings then call msStyleBindAttributes or msLabelBindAttributes
  • mapfile.c => fix parsing to hangle strings in addition to numbers for all supported bindings (symbols already allow this), if a binding is defined flip the hasBindings flag, remove all references to xxxITEM properties, alter style and label writing code to honor bindings as part of output
  • mapcopy.c => fix style and labeling copying
  • maplexer.l/mapfile.h => remove xxxITEM defines and lexer references, and to define a new raw type (similar to MS_STRING) called MS_BINDING
  • mapscript/swiginc/style.i => add setBinding and deleteBinding methods (similar for PHP/MapScript)

Testing

  • Python suite: need tests to set and delete bindings
  • MsAutoTest suite: a mapfile testing various bindings would be developed (DNR tests have one example for labels)

Backwards compatibility issues

This does affect a number of parameters, however they are lightly used so this is probably worth the risk. The primary risk is breaking mapfiles as opposed to scripts. Given that this will definitely break some stuff I think it is most appropriate as a 5.0 change.

Bug ID

2100

Voting history

+1 Lime, Morissette, Woodbridge