[GIS] How to use SLD to filter a WMS layer but without setting any styles

filtermapserveropenlayers-2sldstyle

I'm trying to filter (using OpenLayers) a WMS layer, served by MapServer.

I've got this working by building the appropriate OpenLayers.Filter rule(s) with an empty Polygon symbolizer (so no specific styles are set). I then construct an SLD from the rule(s) and pass that in the SLD_BODY parameter.

This has been working fine, however I've hit a snag. Originally, the map files for the various layers were setting STYLEITEM "AUTO", which was pretty ugly, but it worked.

I've now got rid of this and am manually setting the styles depending on the feature. e.g.

CLASSITEM "SomeField"
CLASSITEM "AnotherField"

CLASS
    EXPRESSION ("[SomeField]" eq "SomeValue" && "[AnotherField]" IN "val1,val2")

    STYLE
        COLOR 255 255 255
        OPACITY 25
    END #STYLE

    STYLE
        SYMBOL "hatch"
        COLOR 0 200 255
        ANGLE 45
        SIZE 2
        WIDTH 3
        GEOMTRANSFORM (buffer([shape],-1))
    END #STYLE

    STYLE
        OUTLINECOLOR 0 200 255
        WIDTH 1
    END #STYLE
END #CLASS

…Plus a good few more per layer.

Again, this all works fine. The layers look as I expect them too…until a filter is applied.

Then, the SLD_BODY gets generated with an appropriate filter and with no style data. However, my various styles defined (in the map files) then get ignored and every feature is just rendered in grey.

What am I doing wrong? It seems like the classes (or the expressions in the classes) are being ignored when using a filter.

The generated SLD document looks like:

<?xml version="1.0" encoding="UTF-8"?>
<sld:StyledLayerDescriptor xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
   <sld:NamedLayer>
      <sld:Name>MyLayerName</sld:Name>
      <sld:UserStyle>
         <sld:FeatureTypeStyle>
            <sld:Rule>
               <ogc:Filter>
                  <ogc:PropertyIsEqualTo matchCase="false">
                     <ogc:PropertyName>SomeField</ogc:PropertyName>
                     <ogc:Literal>SomeValue</ogc:Literal>
                  </ogc:PropertyIsEqualTo>
               </ogc:Filter>
               <sld:PolygonSymbolizer>
                  <sld:Fill />
                  <sld:Stroke />
               </sld:PolygonSymbolizer>
            </sld:Rule>
         </sld:FeatureTypeStyle>
      </sld:UserStyle>
   </sld:NamedLayer>
</sld:StyledLayerDescriptor>

And the appropriate part of the OpenLayers JS:

rule = new OpenLayers.Rule({
    filter:     layerFilter,
    symbolizer: {'Polygon': {
    }}
});

Side note:
If I manually change the <sld:Fill /> to <sld:Fill></sld:Fill>, it works. 😐

Although I could just use JS to replace it, that seems like a really hacky, messy way of doing it and would be a real last resort.

What's the proper way of doing this?

Screenshots attached to show what I mean regarding styling:

Styles working (No filters)

Styles working (No filters)
Styles broken (Filter active for the main feature in the image)

Styles broken (Filter active for the main feature in the image)

Best Answer

I don't think anything is broken (or at least working unexpectedly).

You can't style a WMS response directly in OpenLayers, because a WMS response is an image. For an WMS you can have the default style as configured on the server (in this instance in the map file), or you can modify the default style by passing an SLD to the server either in an SLD_BODY parameter or through an externally referenceable SLD (through an SLD parameter).

The SLD you are sending in the SLD_BODY parameter of your request is overwriting the style generated by MapServer for the polygon.

Related Question