GeoServer – Variable Substitution with Environment Variables in SLD

geoserverleafletsld

I'm posting this as a new question as a follow-up to this one Geoserver SLD: Dynamic Variable Substitution

I am struggling to get SLD variable substitution to work where I have an environment variable representing an attribute table column heading. The layer is rendered via Leaflet from GeoServer. Example is here https://www.climatejust.org.uk/map-dev/ (two map layers: 'Social Heat Vulnerability Index' and 'Sensitivity').

Here my two layers in Leaflet, one with an attribute column named ZH_VULN_IN and other SENS_IND.

var ZH_VULN_IN = L.tileLayer.wms(cj_server, {
    layers: 'cj18:FINAL_SSVI_FLOOD_HEAT_04022014',
    env: 'att:ZH_VULN_IN',
    tiles: true,
    format: 'image/png',
    transparent: true
})
var SENS_IND = L.tileLayer.wms(cj_server, {
    layers: 'FINAL_SSVI_FLOOD_HEAT_04022014',
    env: 'att:SENS_IND',
    tiles: true,
    format: 'image/png',
    transparent: true
  })

The Geoserver log file seems to get the correct env variable passed and I can see this changing when I select either of the two layers but the map does not render.

Log output:

Elevation = []
Env = {ATT=ZH_VULN_IN}
Exceptions = SE_XML
FeatureId = null
FeatureVersion = null
Filter = null
Format = image/png
FormatOptions = {}
Get = true
Height = 256
Interpolations = []
Layers = [org.geoserver.wms.MapLayerInfo@832dfcaf]
MaxFeatures = null
Palette = null
RawKvp = {FORMAT=image/png, TILES=true, STYLES=, WIDTH=256, ENV=att:ZH_VULN_IN, HEIGHT=256, LAYERS=cj18:FINAL_SSVI_FLOOD_HEAT_04022014, REQUEST=GetMap, SRS=EPSG:3857, BBOX=-313086.06785608194,7200979.560689886,0,7514065.628545967, VERSION=1.1.1, SERVICE=WMS, TRANSPARENT=true}

This is my sld file:

<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:se="http://www.opengis.net/se" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" xmlns:ogc="http://www.opengis.net/ogc" version="1.1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <NamedLayer>
    <se:Name>FINAL_SSVI_FLOOD_HEAT_04022014</se:Name>
    <UserStyle>
      <se:Name>FINAL_SSVI_FLOOD_HEAT_04022014</se:Name>
      <se:FeatureTypeStyle>
        <se:Rule>
          <se:Name>-3 - 0</se:Name>
          <se:Description>
            <se:Title>-3 - 0</se:Title>
          </se:Description>
          <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
            <ogc:And>
              <ogc:PropertyIsGreaterThanOrEqualTo>
                <!--ogc:PropertyName>ZH_VULN_IN</ogc:PropertyName-->
                <!-- replace about line with next three lines -->
                <ogc:Function name="env">
                  <ogc:Literal>att</ogc:Literal>
                </ogc:Function>
                <ogc:Literal>-3</ogc:Literal>
              </ogc:PropertyIsGreaterThanOrEqualTo>
              <ogc:PropertyIsLessThanOrEqualTo>
                <!--ogc:PropertyName>ZH_VULN_IN</ogc:PropertyName-->
                <!-- replace about line with next three lines -->
                <ogc:Function name="env">
                  <ogc:Literal>att</ogc:Literal>
                </ogc:Function>
                <ogc:Literal>0</ogc:Literal>
              </ogc:PropertyIsLessThanOrEqualTo>
            </ogc:And>
          </ogc:Filter>
          <se:PolygonSymbolizer>
            <se:Fill>
              <se:SvgParameter name="fill">#404040</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#232323</se:SvgParameter>
              <se:SvgParameter name="stroke-width">1</se:SvgParameter>
              <se:SvgParameter name="stroke-linejoin">bevel</se:SvgParameter>
            </se:Stroke>
          </se:PolygonSymbolizer>
        </se:Rule>
        <se:Rule>
          <se:Name>> 0 - 6.8</se:Name>
          <se:Description>
            <se:Title>> 0 - 7</se:Title>
          </se:Description>
          <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
            <ogc:And>
              <ogc:PropertyIsGreaterThan>
                <!--ogc:PropertyName>ZH_VULN_IN</ogc:PropertyName-->
                <!-- replace about line with next three lines -->
                <ogc:Function name="env"> 
                  <ogc:Literal>att</ogc:Literal>
                </ogc:Function>
                <ogc:Literal>0</ogc:Literal>
              </ogc:PropertyIsGreaterThan>
              <ogc:PropertyIsLessThanOrEqualTo>
                <!--ogc:PropertyName>ZH_VULN_IN</ogc:PropertyName-->
                <!-- replace about line with next three lines -->
                <ogc:Function name="env"> 
                  <ogc:Literal>att</ogc:Literal>
                </ogc:Function>
                <ogc:Literal>7</ogc:Literal>
              </ogc:PropertyIsLessThanOrEqualTo>
            </ogc:And>
          </ogc:Filter>
          <se:PolygonSymbolizer>
            <se:Fill>
              <se:SvgParameter name="fill">#ca0020</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#232323</se:SvgParameter>
              <se:SvgParameter name="stroke-width">1</se:SvgParameter>
              <se:SvgParameter name="stroke-linejoin">bevel</se:SvgParameter>
            </se:Stroke>
          </se:PolygonSymbolizer>
        </se:Rule>
      </se:FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

If I uncomment these lines in the SLD file

<!–ogc:PropertyName>ZH_VULN_IN</ogc:PropertyName–>

and then comment out the next three lines the map renders fine using data from the ZH_VULN_IN column but that's not what I want. I want this to change based on the selected map layer. I have tried various approaches based on the previous questions asked about this but with no positive outcome.

Am I missing something obvious?

Best Answer

What you are expanding there is the value of the env variable, ZH_VULN_IN, which is then compared, as a static string, to 7 (not very meaningful).

What you want to do instead:

  <ogc:PropertyIsLessThanOrEqualTo>
    <ogc:Functionn name="property">
      <ogc:Function name="env"> 
        <ogc:Literal>att</ogc:Literal>
      </ogc:Function>
    </ogc:Function>
    <ogc:Literal>7</ogc:Literal>
  </ogc:PropertyIsLessThanOrEqualTo>

The "property" function allows for dynamic property lookup, which would be otherwise unsupported in SLD.

Related Question