The LuciadFusion Platform includes a few mechanisms for customizing the styling of a layer. Article How to customize the data styling focuses on styling options that are managed by the server. On the server, you can rely on Styled Layer Descriptor (SLD) style files, and plug in custom layer factories for styling. For some use cases, though, you may need to make styling customizable on the client side.

This article applies to the WMS service only.

The WMS service in LuciadFusion Platform allows clients to include an SLD in requests, providing you with options to customize the styling of the requested layers. For example, if a WMS offers a vector layer showing rivers, a client can retrieve a map showing this data in a custom color scheme. The SLD with the custom color scheme is passed along with the map request. The following SLD illustrates this for the usrivers layer offered by the Luciad sample WMS service:

Program: Defining a client-side SLD style
<StyledLayerDescriptor version="1.1.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
                       xmlns="http://www.opengis.net/sld" xmlns:se="http://www.opengis.net/se"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <NamedLayer>
    <se:Name>usrivers</se:Name>
    <UserStyle>
      <se:Name>myStyle</se:Name>
      <se:FeatureTypeStyle>
        <se:Name>myCustomFeatureTypeStyle</se:Name>
        <se:Rule>
          <se:LineSymbolizer>
            <se:Stroke>
              <se:SvgParameter name="stroke">%235555ff</se:SvgParameter>
              <se:SvgParameter name="stroke-width">6</se:SvgParameter>
            </se:Stroke>
          </se:LineSymbolizer>
          <se:LineSymbolizer>
            <se:Stroke>
              <se:SvgParameter name="stroke">%23add5ec</se:SvgParameter>
              <se:SvgParameter name="stroke-width">2</se:SvgParameter>
            </se:Stroke>
          </se:LineSymbolizer>
        </se:Rule>
      </se:FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

When the SLD is embedded in a WMS map request, the result looks like the map displayed at this URL:

https://sampleservices.luciad.com/wms?request=GetMap&LAYERS=usrivers&FORMAT=image/png&VERSION=1.3.0&BBOX=-80,38,-73,43.5&WIDTH=512&HEIGHT=512&STYLES=myStyle&CRS=CRS:84&SLD_BODY=<StyledLayerDescriptor%20version=%221.1.0%22%20xsi:schemaLocation=%22http://www.opengis.net/sld%20StyledLayerDescriptor.xsd%22%20xmlns=%22http://www.opengis.net/sld%22%20xmlns:se=%22http://www.opengis.net/se%22%20xmlns:xsi=%22http://www.w3.org/2001/XMLSchema-instance%22><NamedLayer><se:Name>usrivers</se:Name><UserStyle><se:Name>myStyle</se:Name><se:FeatureTypeStyle><se:Name>myCustomFeatureTypeStyle</se:Name><se:Rule><se:LineSymbolizer><se:Stroke><se:SvgParameter%20name=%22stroke%22>%235555ff</se:SvgParameter><se:SvgParameter%20name=%22stroke-width%22>6</se:SvgParameter></se:Stroke></se:LineSymbolizer><se:LineSymbolizer><se:Stroke><se:SvgParameter%20name=%22stroke%22>%23add5ec</se:SvgParameter><se:SvgParameter%20name=%22stroke-width%22>2</se:SvgParameter></se:Stroke></se:LineSymbolizer></se:Rule></se:FeatureTypeStyle></UserStyle></NamedLayer></StyledLayerDescriptor>

This approach relies on the standard OGC SLD styling options.

For some use cases, you may need to set up your own styling customization options. Our SLD implementation supports those by means of vendor-specific options that can be defined in an SLD symbolizer:

Program: Defining a client-side SLD style with vendor options
<StyledLayerDescriptor version="1.1.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
                       xmlns="http://www.opengis.net/sld" xmlns:se="http://www.opengis.net/se"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <NamedLayer>
    <se:Name>usrivers</se:Name>
    <UserStyle>
      <se:Name>myStyle</se:Name>
      <se:FeatureTypeStyle>
        <se:Name>myCustomFeatureTypeStyle</se:Name>
        <se:Rule>
          <se:LineSymbolizer>
            <se:VendorOption name="myStylingOption1">value1</se:VendorOption>
            <se:VendorOption name="myStylingOption2">value2</se:VendorOption>
          </se:LineSymbolizer>
        </se:Rule>
      </se:FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

To make use of this in the server, you need to plug in an ILcdSLDGXYLayerFactory service that recognizes your SLD style by its name and creates a custom layer based on the vendor options:

Program: Create a custom layer based on your SLD vendor options
@LcdService(service = ILcdSLDGXYLayerFactory.class)
public class ClientBasedStylingSnippets implements ILcdSLDGXYLayerFactory {

  // The key that matches with the <name> element in the SLD's Feature Type Style
  private static final String SLD_NAME = "myCustomFeatureTypeStyle";

  @Override
  public ILcdGXYLayer createGXYLayer(ILcdModel aModel, List<TLcdSLDFeatureTypeStyle> aSLDFeatureTypeStyles) {
    if (aSLDFeatureTypeStyles.size() != 1) {
      return null;
    }
    final TLcdSLDFeatureTypeStyle sld = aSLDFeatureTypeStyles.get(0);
    if (!SLD_NAME.equals(sld.getName())) {
      return null; // leave alone all normal SLD's and let some other factory handle it
    }

    TLcdSLDLineSymbolizer lineSymbolizer = (TLcdSLDLineSymbolizer) sld.getRule(0).getSymbolizer(0);
    List<TLcdSLDVendorOption> vendorOptions = lineSymbolizer.getVendorOptions();

    // Create the layer
    TLcdGXYLayer layer = TLcdGXYLayer.create(aModel);
    // ... take vendor options into account as required ...
    return layer;
  }
}