MS RFC 124: Improving SLD Support in MapServer

Last Updated

2019-06-26

Author

Jérome Boué

Contact

jbo-ads@laposte.net

Status

Draft

Version

TBD

Note

The present document is still a work in progress. Sections will be added over time when they are ready to be published. This aims at collecting comments and advices as early as possible.

Overview

The current implementation of SLD/SE in MapServer has many drawbacks. This RFC proposes to address some of them towards a better support. So far, the following issues have been identified:

  1. Arithmetic expressions: MapServer implementation of SLD doesn’t handle <Add>, <Sub>, <Mul>, <Div> operations or <Literal> or <PropertyName> elements in <SvgParameter> or in other elements expected to hold arithmetic expressions.

  2. WMS GetStyles request: A WMS GetStyles request returns a SLD file based only on Mapfile configuration even if a SLD or SLD_BODY parameter is present in the request.

  3. Style layering: When several styling rules apply to a feature, only the first one is taken into account, instead of appliyng them all by following the painters model as described in Symbology Encoding specification.

  4. Mark or ExternalGraphic in LineSymbolizer: MapServer implementation of SLD doesn’t handle <Mark> or <ExternalGraphic> elements in a <LineSymbolizer> element.

  5. LineSymbolizer and PolygonSymbolizer in Rule: MapServer implementation of SLD doesn’t handle both <LineSymbolizer> and <PolygonSymbolizer> in the same <Rule> element (which is more expressive than both <Fill> and <Stroke> in the same <PolygonSymbolizer>).

  6. UserLayer: MapServer implementation of SLD doesn’t handle <UserLayer> element.

The next sections of this RFC develop a description of each issue and the proposed solution.

Technical solution

1. Literal constants, variables and arithmetic expressions

Currently, MapServer only supports raw constants in <CssParameter> or <SvgParameter> tags, e.g.:

<SvgParameter name="stroke">#0000ff</SvgParameter>
<SvgParameter name="stroke-width">2.0</SvgParameter>

The objective is to support <Literal> and <PropertyName> as well as arithmetic expressions, e.g.:

<!-- Literal, PropertyName -->
<SvgParameter name="stroke"> <Literal>#0000ff</Literal> </SvgParameter>
<SvgParameter name="stroke-width"> <PropertyName>LINE_WIDTH</PropertyName> </SvgParameter>

<!-- Arithmetic expression -->
<SvgParameter name="stroke-width">
  <Mul>
    <PropertyName>CATEGORY</PropertyName>
    <Literal>3</Literal>
  </Mul>
</SvgParameter>

This RFC proposes to extent this syntax to the following tags:

Parent tag hierarchy

Target tags

<PolygonSymbolizer><Fill>

<SvgParameter name= »fill »>
<SvgParameter name= »fill-opacity »>
<PolygonSymbolizer><Stroke>
<LineSymbolizer><Stroke>

<SvgParameter name= »stroke »>
<SvgParameter name= »stroke-width »>
<SvgParameter name= »stroke-opacity »>
<PointSymbolizer><Graphic>


<Size>
<Opacity>
<Rotation>
<PointSymbolizer><Graphic><Displacement>

<DisplacementX>
<DisplacementY>
<PointSymbolizer><Graphic><Mark><Fill>
<SvgParameter name= »fill »>
<PointSymbolizer><Graphic><Mark><Stroke>

<SvgParameter name= »stroke »>
<SvgParameter name= »stroke-width »>
<TextSymbolizer>
<Rotation>
<TextSymbolizer><Font>
<SvgParameter name= »font-size »>
<TextSymbolizer><Fill>
<SvgParameter name= »fill »>
<TextSymbolizer><Halo><Fill>
<SvgParameter name= »fill »>

Adding arithmetic expression support to style and label properties involves the creation of a new field array, named exprBindings[], in styleObj and labelObj data structures. This field array stores expression strings converted from SLD syntax to MapFile syntax. It is handled in a way similar to existing bindings[] field array, used to store attribute names.

In addition, a new function is created to parse SLD arithmetic expressions and perform syntax conversion: msSLDParseOgcExpression().

A by-product effect is that adding support for arithmetic expressions in MapFile styles would be effortless.

2. WMS GetStyles request

WMS GetStyles request provides a SLD document based on MapFile contents. Currently this request doesn’t take into account an SLD document passed through SLD or SLD_BODY URL parameters. Moreover this translation lacks many basic styling features present in input MapFile.

This RFC proposes both to integrate input SLD document and enhance conversion from MapFile. The resulting SLD document generated by GetStyles request will be a combination of MapFile and SLD specified in the request, as close as possible to the actual styles being applied.

Enhancements concern the following items:

Description

MapFile

SLD (highlighted lines show enhancements)

SYMBOL (<PointSymbolizer>):
  • Both color and outline color are generated, including opacity (can be specified in input SLD)

  • ANGLE, OFFSET and global OPACITY are generated

LAYER
  TYPE POINT
  STYLE
    COLOR 0 0 255
    OUTLINECOLOR 255 0 0
    OPACITY 50
    SYMBOL "star"
    SIZE 20
    ANGLE 180
    OFFSET 2 2
  END
END
<se:PointSymbolizer>
  <se:Graphic>
    <se:Mark>
      <se:WellKnownName>star</se:WellKnownName>
      <se:Stroke>
        <se:SvgParameter name="stroke">#ff0000</se:SvgParameter>
        <se:SvgParameter name="stroke-opacity">1</se:SvgParameter>
        <se:SvgParameter name="stroke-width">1</se:SvgParameter>
      </se:Stroke>
      <se:Fill>
        <se:SvgParameter name="fill">#0000ff</se:SvgParameter>
        <se:SvgParameter name="fill-opacity">0.10</se:SvgParameter>
      </se:Fill>
    </se:Mark>
    <se:Size>20</se:Size>
    <se:Rotation>180</se:Rotation>
    <se:Displacement>
      <se:DisplacementX>2</se:DisplacementX>
      <se:DisplacementY>2</se:DisplacementY>
    </se:Displacement>
    <se:Opacity>0.5</se:Opacity>
  </se:Graphic>
</se:PointSymbolizer>
POLYGON (<PolygonSymbolizer>):
  • Outline opacity is generated

LAYER
  TYPE POLYGON
  CLASS
    STYLE
     WIDTH 1
      OPACITY 50
      COLOR 0 255 255
      OUTLINECOLOR 255 0 255
    END
  END
END
<se:PolygonSymbolizer>
  <se:Fill>
    <se:SvgParameter name="fill">#00ffff</se:SvgParameter>
    <se:SvgParameter name="fill-opacity">0.50</se:SvgParameter>
  </se:Fill>
  <se:Stroke>
    <se:SvgParameter name="stroke">#ff00ff</se:SvgParameter>
    <se:SvgParameter name="stroke-width">1.00</se:SvgParameter>
    <se:SvgParameter name="stroke-opacity">0.50</se:SvgParameter>
  </se:Stroke>
</se:PolygonSymbolizer>
LABEL (<TextSymbolizer>):
  • Outline color, aka Halo, is generated

LAYER
  CLASS
    LABEL
      TEXT "[name]"
      COLOR 255 255 255
      OUTLINECOLOR 0 255 0
      OUTLINEWIDTH 2
      TYPE TRUETYPE
      FONT vera-bold
      SIZE 12
      OFFSET 2 20
      ANGLE 15
    END
  END
END
<se:TextSymbolizer>
  <se:Label>
    <se:PropertyName>name</se:PropertyName>
  </se:Label>
  <se:Font>
    <se:SvgParameter name="font-family">vera</se:SvgParameter>
    <se:SvgParameter name="font-weight">bold</se:SvgParameter>
    <se:SvgParameter name="font-size">12</se:SvgParameter>
  </se:Font>
  <se:Fill>
    <se:SvgParameter name="fill">#ffffff</se:SvgParameter>
  </se:Fill>
  <se:LabelPlacement>
    <se:PointPlacement>
      <se:Displacement>
        <se:DisplacementX>2</se:DisplacementX>
        <se:DisplacementY>20</se:DisplacementY>
      </se:Displacement>
    </se:PointPlacement>
    <se:AnchorPoint>
      <se:AnchorPointX>0.5</se:AnchorPointX>
      <se:AnchorPointY>0.5</se:AnchorPointY>
    </se:AnchorPoint>
    <se:Rotation>15</se:Rotation>
  </se:LabelPlacement>
  <se:Halo>
    <se:Radius>2</se:Radius>
    <se:Fill>
      <se:SvgParameter name="fill">#00ff00</se:SvgParameter>
    </se:Fill>
  </se:Halo>
</se:TextSymbolizer>

3. Style layering

Note

Work in progress

4. Mark or ExternalGraphic in LineSymbolizer

Note

Work in progress

5. LineSymbolizer and PolygonSymbolizer in Rule

Note

Work in progress

6. UserLayer

Note

Work in progress

Testing

The msautotest/sld suite will be created and populated with test cases focusing on these new or improved features.

Moreover the msautotest/{gdal,misc,query,renderers,wxs} test suites will be run during development in order to make sure that no regression occurs.

Documentation

Mapserver SLD documentation page will be updated according to the proposed features described in this RFC.

Backwards compatibility issues

No compatibility issues are expected. The goal is to provide a better SLD support without changing any other existing behaviour.

Affected Files

  • mapcopy.c

  • mapfile.c

  • maplayer.c

  • mapogcsld.c

  • mapogcsld.h

  • mapserver.h

  • maputil.c

Note

Work in progress

Voting history