Skip to content

https://github.com/Unidata/tds/issues/682 #175

Description

@387809109

Software version

  • EDAL Java 1.5.3.1, as bundled with THREDDS Data Server 5.8
  • The same relevant capability-template and style-selection logic is present in the current edal-java source

Environment

  • THREDDS Data Server 5.8
  • Deployment: official docker.io/unidata/thredds-docker:5.8 image
  • Container runtime: Podman
  • Host operating system: Linux
  • Java and Tomcat versions: those bundled with the official TDS 5.8 image

Description

When a WMS layer has a configured default palette, the GetCapabilities response advertises palette-based styles with a /default suffix.

For example:

<Style>
    <Name>default-scalar/default</Name>
    <Title>default-scalar/default</Title>
    <LegendURL width="110" height="264">
        <Format>image/png</Format>
        <OnlineResource
            xlink:type="simple"
            xlink:href="...?REQUEST=GetLegendGraphic&amp;PALETTE=default&amp;LAYERS=dcm&amp;STYLES=default-scalar/default"/>
    </LegendURL>
</Style>

The /default suffix is treated as an explicitly requested palette name. Consequently, it selects EDAL's built-in default palette rather than the default palette configured for the layer through PlottingStyleParameters.

For example, a layer configured to use seq-Greys produces the following results:

STYLES=default-scalar/default

Uses EDAL's built-in yellow-to-blue default palette.

STYLES=default-scalar

Correctly uses the layer-configured seq-Greys palette.

This means the automatically generated LegendURL does not represent the layer's configured default styling.

Steps to reproduce

  1. Configure a WMS layer so its default PlottingStyleParameters palette is seq-Greys.

    In THREDDS, this can be reproduced with:

    <datasetPath pathSpec="path/to/dataset/*.nc*">
        <pathDefaults>
            <defaultColorScaleRange>0 1</defaultColorScaleRange>
            <defaultPaletteName>seq-Greys</defaultPaletteName>
        </pathDefaults>
    </datasetPath>
  2. Restart the application.

  3. Request GetCapabilities:

    ?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities
    
  4. Find the default-scalar/default style and open its advertised LegendURL.

  5. Compare it with a request where the suffix is removed:

    ?REQUEST=GetLegendGraphic&LAYERS=<layer-name>&STYLES=default-scalar
    

Actual behaviour

The generated LegendURL includes:

STYLES=default-scalar/default

The default suffix is interpreted as an explicit request for EDAL's built-in default palette, overriding the palette supplied by the layer's default PlottingStyleParameters.

As a result, the generated legend can use different colours from a GetMap request that relies on the layer's configured defaults.

Expected behaviour

An advertised style described as using the "default palette" should use the default palette configured for that layer when one exists.

The generated LegendURL should produce the same palette as a request that omits an explicit palette suffix.

Apparent cause

The GetCapabilities templates append every advertised palette name to the style, including the special default palette:

https://github.com/Reading-eScience-Centre/edal-java/blob/master/wms/src/main/resources/templates/capabilities-1.3.0.vm#L264-L280

<Name>$style/$paletteName</Name>
...
<OnlineResource
    xlink:type="simple"
    xlink:href="$baseUrl?REQUEST=GetLegendGraphic&amp;PALETTE=$paletteName&amp;LAYERS=$layerName&amp;STYLES=$style/$paletteName"/>

GetMapStyleParams gives the style suffix precedence over the layer-configured palette:

https://github.com/Reading-eScience-Centre/edal-java/blob/master/wms/src/main/java/uk/ac/rdg/resc/edal/wms/GetMapStyleParams.java#L392-L405

if (styleParts.length > 1) {
    paletteName = styleParts[1];
} else if (defaults.getPalette() != null
        && !"".equals(defaults.getPalette())) {
    paletteName = defaults.getPalette();
} else {
    paletteName = ColourPalette.DEFAULT_PALETTE_NAME;
}

Therefore, default-scalar/default never reaches the configured-default branch.

Proposed solution

For the special advertised palette named default, generate a style without a palette suffix:

<Name>$style</Name>
<Title>$style</Title>

and generate its legend URL using:

STYLES=$style

For explicitly named palettes, retain the existing behaviour:

STYLES=$style/$paletteName

Conceptually, the Velocity template could use:

#if($paletteName.equalsIgnoreCase("default"))
    <Name>$style</Name>
    <Title>$style</Title>
    ...
    <OnlineResource
        xlink:type="simple"
        xlink:href="$baseUrl?REQUEST=GetLegendGraphic&amp;LAYERS=$layerName&amp;STYLES=$style"/>
#else
    <Name>$style/$paletteName</Name>
    <Title>$style/$paletteName</Title>
    ...
    <OnlineResource
        xlink:type="simple"
        xlink:href="$baseUrl?REQUEST=GetLegendGraphic&amp;PALETTE=$paletteName&amp;LAYERS=$layerName&amp;STYLES=$style/$paletteName"/>
#end

The equivalent change should be applied to both:

capabilities-1.3.0.vm
capabilities-1.1.1.vm

Regression tests could verify that:

  • a layer-configured palette is used by the advertised default style;
  • the generated LegendURL produces the same palette as the corresponding default GetMap request;
  • explicitly named palette styles continue to use their requested palette;
  • layers without a configured palette continue to fall back to EDAL's built-in default palette.

An alternative, if changing advertised style names is considered incompatible, would be to preserve /default but interpret that special suffix as the layer-configured default palette when one exists. However, this would change the meaning of explicitly requesting /default, so handling the special case in the capability templates may be clearer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions