.. _rfc19:

===============================================================
  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_

.. _2100: https://github.com/mapserver/mapserver/issues/2100

Voting history
~~~~~~~~~~~~~~~~~

+1 Lime, Morissette, Woodbridge
