To retrieve and display ECDIS data from a WMS server, you need to consider the presence of S-52 display settings. To pass along and apply these styling settings on the WMS server, you must make use of SLD and embed the settings in your request.

Working with S-52 display settings

Maritime ECDIS data is typically rendered according to the International Hydrographic Organisation (IHO) S-52 specification. It provides a detailed list of icons, line styles and other styling information to use for the visualization of buoys, lightmarks, and other maritime features.

The S-52 specification defines a set of parameters that you can use to optimize the displaying of maritime data for a specific environment. These parameters include color scheme settings, ship depth settings, several object filters, and other customizations.

In an end user application, where the client application renders the data, you provide these settings directly to the rendering engine.

In a client-server setup though, a remote server renders the data. You must pass these parameters from the client to the server, so that the server can render its images according to the client’s preferences.

The WMS protocol doesn’t offer out-of-the-box support for the modeling of S-52 parameters, making it impossible to use this type of customization in a default WMS client-server setup. For that reason, LuciadLightspeed defines a custom WMS extension for the exchange of S-52 settings between WMS clients and servers.

Embedding S-52 display settings in a WMS GetMap request using SLD

The WMS protocol allows embedding an SLD style in a GetMap request. You can use such an embedded SLD style to pass custom styling parameters to a WMS server, and tell the WMS server how to render its images. LuciadLightspeed products use this styling mechanism to support S-52 customization, through a custom S-52 SLD extension.

Embed S-52 display settings using the optional Maritime Standards component

If you have the optional Maritime Standards component available in your LuciadLightspeed installation, you can use its dedicated S-52 API and domain model to define S-52 display settings. This API allows you to customize the S-52 visualization using the TLcdS52DisplaySettings class.

To embed an object of this class in a valid WMS GetMap request:

  1. Create and configure an S-52 display settings object using TLcdS52DisplaySettings. In the samples of the Maritime Standards component, the display settings are configured through the user interface, using the S52DisplaySettingsCustomizer class.

  2. Once the configuration is complete, embed the S-52 display settings object in an S-52 symbolizer. The symbolizer is itself embedded in an SLD Feature Type Style.

    TLcdS52SLDSymbolizer symbolizer = new TLcdS52SLDSymbolizer();
    symbolizer.setDisplaySettings(displaySettings);
    
    TLcdSLDRule rule = new TLcdSLDRule();
    rule.addSymbolizer(symbolizer);
    
    TLcdSLDFeatureTypeStyle featureTypeStyle = new TLcdSLDFeatureTypeStyle();
    featureTypeStyle.addRule(rule);
    
    TLcdSLDUserStyle layerStyle = new TLcdSLDUserStyle();
    layerStyle.setDefault(true);
    layerStyle.addFeatureTypeStyle(featureTypeStyle);
  3. Create a Styled Layer Descriptor, and add an SLD Named Layer with a reference to the Feature Type Style for each layer that you want to include in your GetMap request.

    Program: Creating a Styled Layer Descriptor (from samples/wms/client/ecdis/gxy/MainPanel)
    TLcdSLDStyledLayerDescriptor styledLayerDescriptor = new TLcdSLDStyledLayerDescriptor();
    
    for (ALcdWMSNamedLayer aS52SLDLayer : aS52SLDLayers) {
      TLcdSLDNamedLayer layer = new TLcdSLDNamedLayer();
      layer.setName(aS52SLDLayer.getNamedLayerName());
      layer.addLayerStyle(layerStyle);
      styledLayerDescriptor.addLayer(layer);
    }
  4. Set the Styled Layer Descriptor on the ALcdWMSProxy object, using the setStyledLayerDescriptor() method, so that the WMS client includes the S-52 style in your GetMap requests.

Embed S-52 styling settings using the standard LuciadLightspeed API

If you don’t have the Maritime Standards component available, you must rely on a custom domain model to define the S-52 display settings and embed the settings in a GetMap request through an SLD extension. This domain model is defined by two XML Schemas:

  • The S-52 XSD Schema: defines an SLD-independent XML representation of S-52 display settings.

  • The SLD S-52 XSD Schema: defines a thin wrapper around the S-52 XSD Schema, allowing you to embed the S-52 display settings into an SLD symbolizer extension.

Both schemas are available as resources in the LuciadLightspeed distribution. You can find them in the samples\resources\samples\wms\client\ecdis folder of your LuciadLightspeed installation.

The following steps describe how to use these XML Schemas to embed S-52 display settings into a valid WMS GetMap request. The complete source code is available in the samples/wms/client/ecdis sample folder.

  1. Create the S-52 data model: you can automatically create the S-52 data model from the XSD Schema using the TLcdXMLDataModelBuilder.

    Program: Setting up the S-52 data model
    String namespace = "http://www.luciad.com/ecdis/s52/1.0";
    String schemaLocation = getClass().getClassLoader()
                                      .getResource("samples/wms/client/ecdis/s52.xsd")
                                      .toString();
    
    TLcdDataModelBuilder dataModelBuilder = new TLcdDataModelBuilder(namespace);
    
    // Initialize the model using the XML Schema information
    TLcdXMLDataModelBuilder xmlDataModelBuilder = new TLcdXMLDataModelBuilder();
    xmlDataModelBuilder.buildDataModel(dataModelBuilder, namespace, schemaLocation);
    
    TLcdDataModel dataModel = dataModelBuilder.createDataModel();

    For the S-52 display settings, you can either use the default TLcdDataObject, or you can create a custom class extending TLcdDataObject that allows you to add functionality to the object. The sample adds support for property change events.

  2. Create the S-52 - SLD data model: the SLD wrapper data model can be created in a similar way to the S-52 data model.

    Program: Creating an S-52- SLD wrapper data model
    String namespace = "http://www.luciad.com/ecdis/s52-sld/1.0";
    String schemaLocation = getClass().getClassLoader()
                                      .getResource("com/luciad/format/s52/s52-sld.xsd")
                                      .toString();
    
    TLcdDataModelBuilder dataModelBuilder = new TLcdDataModelBuilder(namespace);
    
    // Initialize the model using the XML Schema information
    TLcdXMLDataModelBuilder xmlDataModelBuilder =
        new TLcdXMLDataModelBuilder(TLcdSEDataTypes.getDataModel(),
                                    S52DataTypes.getDataModel());
    xmlDataModelBuilder.setEntityResolver(new TLcdXMLEntityResolver());
    xmlDataModelBuilder.buildDataModel(dataModelBuilder, schemaLocation);
    
    // Configure the Java instance class for the Symbolizer type
    dataModelBuilder.typeBuilder("S52SymbolizerType")
                    .instanceClass(S52SLDDataTypes.S52Symbolizer.class);
    
    TLcdDataModel dataModel = dataModelBuilder.createDataModel();

    On the Java side, you need to create an S-52 extension of the ALcdSLDSymbolizer class, encapsulating the S-52 display settings.

    Program: A custom S-52 SLD symbolizer (from samples/wms/client/ecdis/gxy/s52/S52SLDDataTypes)
    public static class S52Symbolizer extends ALcdSLDSymbolizer {
    
      public S52Symbolizer() {
        super(S52_SYMBOLIZER_TYPE);
      }
    
      public S52Symbolizer(TLcdDataType aType) {
        super(aType);
      }
    
      public S52DataTypes.S52DisplaySettings getDisplaySettings() {
        return (S52DataTypes.S52DisplaySettings) getValue(DISPLAY_SETTINGS_STRING);
      }
    
      public void setDisplaySettings(S52DataTypes.S52DisplaySettings aDisplaySettings) {
        setValue(DISPLAY_SETTINGS_STRING, aDisplaySettings);
      }
    
    }
  3. Create and configure an S-52 display settings object: once you have set up the data models, you can create an S-52 display settings object and configure its settings using the data model API. In the sample, the display settings are configured through the user interface, using the S52DisplaySettingsCustomizer class.

  4. Once the configuration is complete, embed the S-52 display settings object in an S-52 symbolizer, which is itself embedded in an SLD Feature Type Style.

    Program: Embedding S-52 display settings in an SLD Feature Type Style (from samples/wms/client/ecdis/gxy/MainPanel)
    S52SLDDataTypes.S52Symbolizer symbolizer = new S52SLDDataTypes.S52Symbolizer();
    symbolizer.setDisplaySettings(aDisplaySettings);
    
    TLcdSLDRule rule = new TLcdSLDRule();
    rule.addSymbolizer(symbolizer);
    
    TLcdSLDFeatureTypeStyle featureTypeStyle = new TLcdSLDFeatureTypeStyle();
    featureTypeStyle.addRule(rule);
    
    TLcdSLDUserStyle layerStyle = new TLcdSLDUserStyle();
    layerStyle.setDefault(true);
    layerStyle.addFeatureTypeStyle(featureTypeStyle);
  5. Create a Styled Layer Descriptor, and add an SLD Named Layer with a reference to the Feature Type Style for each layer you want to include in your GetMap request. This is shown in Program: Creating a Styled Layer Descriptor.

  6. Set the Styled Layer Descriptor on the ALcdWMSProxy object, using the setStyledLayerDescriptor() method, so that the WMS client includes the S-52 style in your GetMap requests.

Detecting which layers support S-52/SLD styling

A WMS server may serve a mixed set of layers: some layers contain ECDIS data, others containing different sorts of data. To allow WMS clients to discover which layers support S-52/SLD styling, LuciadFusion WMS servers include the ‘S52-SLD’ keyword in the layer description. Such a layer description is provided for each layer in the GetCapabilities request. Program: Detection of WMS layers supporting the S-52/SLD styling extension shows how to detect whether a WMS layer supports S-52/SLD styling.

Program: Detection of WMS layers supporting the S-52/SLD styling extension (from samples/wms/client/ecdis/gxy/MainPanel)
private static boolean isS52SLDLayer(ALcdWMSNamedLayer aLayer) {
  for (int i = 0; i < aLayer.getKeywordCount(); i++) {
    if (aLayer.getKeyword(i).equals("S52-SLD")) {
      return true;
    }
  }
  return false;
}

Note that ECDIS layers that have been fused to raster tiles on a LuciadFusion server don’t support S-52 styling. Once the S-57 data has been fused, you can no longer adjust its styling. These layers are visible as ECDIS data on WMS clients, but they don’t include the S52-SLD keyword in their keyword list.