4

I would like to use inline SLD to style polygon served by GeoServer.

Here is working example in MapServer:

without defined style:

http://gis.ibbeck.de/include/mapserver/mapserv.exe?map=/daten/mapfiles/world/World.map&LAYERS=COUNTRY&FORMAT=image%2Fpng&VERSION=1.1.1&TRANSPARENT=TRUE&SERVICE=WMS&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&SRS=EPSG%3A4326&BBOX=-52,-90,76,38&WIDTH=256&HEIGHT=256

with SLD_BODY parameter:

http://gis.ibbeck.de/include/mapserver/mapserv.exe?map=/daten/mapfiles/world/World.map&LAYERS=COUNTRY&FORMAT=image%2Fpng&VERSION=1.1.1&TRANSPARENT=TRUE&SLD_BODY=%3CStyledLayerDescriptor+version%3D%221.1.0%22%3E%3CNamedLayer%3E%3CName%3ECountry%3C%2FName%3E%3CUserStyle%3E%3CIsDefault%3E1%3C%2FIsDefault%3E%3CFeatureTypeStyle%3E%3CRule%3E%3CPolygonSymbolizer%3E%3CFill%3E%3CCssParameter+name%3D%22fill%22%3E%23FF0000%3C%2FCssParameter%3E%3C%2FFill%3E%3C%2FPolygonSymbolizer%3E%3C%2FRule%3E%3C%2FFeatureTypeStyle%3E%3C%2FUserStyle%3E%3C%2FNamedLayer%3E%3C%2FStyledLayerDescriptor%3E%0A&SERVICE=WMS&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&SRS=EPSG%3A4326&BBOX=-52,-90,76,38&WIDTH=256&HEIGHT=256

Here is unencoded SLD_BODY parameter:

<StyledLayerDescriptor version="1.1.0">
 <NamedLayer>
  <Name>Country</Name>
  <UserStyle>
   <IsDefault>1</IsDefault>
    <FeatureTypeStyle>
     <Rule>
      <PolygonSymbolizer>
       <Fill>
        <CssParameter name="fill">#FF0000</CssParameter>
       </Fill>
      </PolygonSymbolizer>
     </Rule>
    </FeatureTypeStyle>
   </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

According to documentation, the same SLD should work for GeoServer serving WMS:

GeoServer DOcumentation

Library mode occurs when map layers and styles are specified using the layers and styles WMS parameters, and additional styling is supplied externally...The styles in the external style document take precedence over the catalog styles during rendering. Style lookup in library mode operates as follows:

  • For each layer in the layers list, the applied style is either a named style specified in the styles list (if present), or the layer default style

  • For a named style, if the external style document has a <NamedLayer>...<UserStyle> with matching layer name and style name, then it is used. Otherwise, the style name is searched for in the catalog. If it is not found there, an error occurs.

  • For a default style, the external style document is searched to find a <NamedLayer> element with the layer name. If it contains a <UserStyle> with the <IsDefault> element having the value 1 then that style is used. Otherwise, the default server style for the layer (which must exist) is used.

But I can't get it working (i.e. all polygons should be red but remain unchanged):

http://ihp-wins.unesco.org/geoserver/geonode/wms?service=WMS&version=1.1.1&request=GetMap&layers=DRIN_GWBs&bbox=6586968.00981259%2C4614357.59391692%2C6647685.57959369%2C4705644.12428735&width=510&height=768&srs=EPSG%3A3908&format=image%2Fpng&SLD_BODY=%3CStyledLayerDescriptor+version%3D%221.1.0%22%3E%3CNamedLayer%3E%3CName%3EDRIN_GWBs%3C%2FName%3E%3CUserStyle%3E%3CIsDefault%3E1%3C%2FIsDefault%3E%3CFeatureTypeStyle%3E%3CRule%3E%3CPolygonSymbolizer%3E%3CFill%3E%3CCssParameter+name%3D%22fill%22%3E%23FF0000%3C%2FCssParameter%3E%3C%2FFill%3E%3C%2FPolygonSymbolizer%3E%3C%2FRule%3E%3C%2FFeatureTypeStyle%3E%3C%2FUserStyle%3E%3C%2FNamedLayer%3E%3C%2FStyledLayerDescriptor%3E

Here is that unencoded SLD parameter:

<StyledLayerDescriptor version="1.1.0">
 <NamedLayer>
  <Name>DRIN_GWBs</Name>
   <UserStyle>
    <IsDefault>1</IsDefault>
    <FeatureTypeStyle>
     <Rule>
      <PolygonSymbolizer>
       <Fill>
        <CssParameter name="fill">#FF0000</CssParameter>
       </Fill>
      </PolygonSymbolizer>
     </Rule>
    </FeatureTypeStyle>
   </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

SLD is supported by this service (as per GetCapabilities):

<UserDefinedSymbolization SupportSLD="1" UserLayer="1" UserStyle="1" RemoteWFS="1"/>

And GetStyles as well:

http://ihp-wins.unesco.org/geoserver/geonode/wms?service=WMS&version=1.1.1&request=GetStyles&layers=DRIN_GWBs

There are no errors but polygons are not changing color either.

= = = = Edit 2021.02.18

@Ian-Turton solution does work. But there are a few quirks that I will try to explain to those lost as I am:

Here is working url for another service with inline SLD_BODY parameter:

https://hotspots.dea.ga.gov.au/geoserver/public/wms?srs=EPSG%3A3857&format=image%2Fpng&service=WMS&version=1.1.1&request=GetMap&layers=DigitalEarthAustraliaWaterbodies&bbox=15262945.80798399%2C-3443946.7464169003%2C15341217.324948017%2C-3365675.229452882&width=256&height=256&SLD_BODY=%3CStyledLayerDescriptor%20version%3D%221.0.0%22%20xmlns%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%22%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%20xmlns%3Agml%3D%22http%3A%2F%2Fwww.opengis.net%2Fgml%22%20xsi%3AschemaLocation%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%20http%3A%2F%2Fschemas.opengis.net%2Fsld%2F1.0.0%2FStyledLayerDescriptor.xsd%22%3E%3CNamedLayer%3E%3CName%3Epublic:DigitalEarthAustraliaWaterbodies%3C%2FName%3E%3CUserStyle%3E%3CFeatureTypeStyle%3E%3CRule%3E%3CPolygonSymbolizer%3E%3CFill%3E%3CCssParameter%20name%3D%22fill%22%3E%23ff0000%3C%2FCssParameter%3E%3C%2FFill%3E%3C%2FPolygonSymbolizer%3E%3C%2FRule%3E%3C%2FFeatureTypeStyle%3E%3C%2FUserStyle%3E%3C%2FNamedLayer%3E%3C%2FStyledLayerDescriptor%3E

And SLD part, unencoded:

<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
 <NamedLayer>
  <Name>public:DigitalEarthAustraliaWaterbodies</Name>
  <UserStyle>
    <FeatureTypeStyle>
     <Rule>
      <PolygonSymbolizer>
       <Fill>
        <CssParameter name="fill">#FF0000</CssParameter>
       </Fill>
      </PolygonSymbolizer>
     </Rule>
    </FeatureTypeStyle>
  </UserStyle>
 </NamedLayer>
</StyledLayerDescriptor>

So <Name> is indeed layer name but must have 'workspace prefix' included, as Ian indicated in his comment (ie geoserver/public/wms). It's not something that is listed in GetCapabilities and can only be 'deducted' from service url. That requirement was not obvious to me.

I would also like to point that this solution may be 'undocumented feature' of Geoserver since, in my opinion, it does not match official documentation. That is, it is neither the second dot option (ie. where SLD supposed to have "matching layer name AND style name" - since only layer name is provided) nor the third dot point (ie. "contains a <UserStyle> with the <IsDefault> element having the value 1" - no <IsDefault> element is present in SLD).

6
  • your GeoServer URL returns an error saying the layer is unknown so I can't test but this answer gis.stackexchange.com/a/246185/79 suggests that you need a styles parameter which matches the name of the style in the SLD
    – Ian Turton
    Commented Feb 12, 2021 at 10:20
  • All URLs above work for me. I tried all the combinations as per Geoserver doco. Presented version is the third dot point option and works in Mapserver. The second dot point combination didn't work either. Any further thoughts?
    – edaus
    Commented Feb 12, 2021 at 12:54
  • Ask GeoServer to send SLD in the format that it likes with GetStyles and compare it with what you have now.
    – user30184
    Commented Feb 13, 2021 at 12:04
  • Good tip! Unfortunately, still not working, even if I only change colours in SLD. Could you have a go? Maybe I missed something obvious. Thanks!
    – edaus
    Commented Feb 16, 2021 at 0:13
  • 1
    Nope, it is the layer name - but it needs the workspace prefix included, which you can skip in the layers param as you are hitting the workspace end point geoserver/**public**/wms so use public:DigitalEarthAustraliaWaterbodies and it does work
    – Ian Turton
    Commented Feb 17, 2021 at 11:14

1 Answer 1

2

After some experimenting and turning GeoServer's logging level up to GEOTOOLS_DEVELOPER it turns out that GeoServer didn't understand your SLD as it didn't contain any schema locations. So changing your SLD to start with the following worked.

<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc"
                   xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml"
                   xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">



curl -v --output img.png "http://localhost:8080/geoserver/topp/wms?service=WMS&version=1.1.0&request=GetMap&layers=topp%3Astates&bbox=-124.73142200000001%2C24.955967%2C-66.969849%2C49.371735&width=768&height=330&srs=EPSG%3A4326&styles=&format=image%2Fpng&SLD_BODY=%3CStyledLayerDescriptor%20version%3D%221.0.0%22%20xmlns%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%22%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%20xmlns%3Agml%3D%22http%3A%2F%2Fwww.opengis.net%2Fgml%22%20xsi%3AschemaLocation%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%20http%3A%2F%2Fschemas.opengis.net%2Fsld%2F1.0.0%2FStyledLayerDescriptor.xsd%22%3E%3CNamedLayer%3E%3CName%3Etopp:states%3C%2FName%3E%3CUserStyle%3E%3CFeatureTypeStyle%3E%3CRule%3E%3CPolygonSymbolizer%3E%3CFill%3E%3CCssParameter+name%3D%22fill%22%3E%23FF0000%3C%2FCssParameter%3E%3C%2FFill%3E%3C%2FPolygonSymbolizer%3E%3C%2FRule%3E%3C%2FFeatureTypeStyle%3E%3C%2FUserStyle%3E%3C%2FNamedLayer%3E%3C%2FStyledLayerDescriptor%3E"

returns this:

enter image description here

Changing the name in the NamedLayer to geonode:DRIN_GWBs gives me the following command line:

curl -v --output img.png "http://ihp-wins.unesco.org/geoserver/geonode/wms?service=WMS&version=1.1.1&request=GetMap&layers=DRIN_GWBs&bbox=6586968.00981259%2C4614357.59391692%2C6647685.57959369%2C4705644.12428735&width=510&height=768&srs=EPSG%3A3908&format=image%2Fpng&&SLD_BODY=%3CStyledLayerDescriptor%20version%3D%221.0.0%22%20xmlns%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%22%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%20xmlns%3Agml%3D%22http%3A%2F%2Fwww.opengis.net%2Fgml%22%20xsi%3AschemaLocation%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%20http%3A%2F%2Fschemas.opengis.net%2Fsld%2F1.0.0%2FStyledLayerDescriptor.xsd%22%3E%3CNamedLayer%3E%3CName%3Egeonode:DRIN_GWBs%3C%2FName%3E%3CUserStyle%3E%3CFeatureTypeStyle%3E%3CRule%3E%3CPolygonSymbolizer%3E%3CFill%3E%3CCssParameter%20name%3D%22fill%22%3E%23FF0000%3C%2FCssParameter%3E%3C%2FFill%3E%3C%2FPolygonSymbolizer%3E%3C%2FRule%3E%3C%2FFeatureTypeStyle%3E%3C%2FUserStyle%3E%3C%2FNamedLayer%3E%3C%2FStyledLayerDescriptor%3E"

and this result:

enter image description here

1
  • Thanks a million @Ian-Turton! Your efforts much appreciated! As it turns out, <NamedLayer><Name> in SLD part refers to "style" and not to the actual layer name! That is, in GetCap layer is named: <Layer queryable="1" opaque="0"><Name>DRIN_GWBs</Name>... then further down there is <Style><Name>geonode:DRIN_GWBs</Name>. So, in general terms, this approach is not what's listed in Geoserver documentation and it I trouble getting it work with another service... I provided more details in edits to my question if you don't mind having another look.
    – edaus
    Commented Feb 17, 2021 at 9:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.