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&PALETTE=default&LAYERS=dcm&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.
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
-
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>
-
Restart the application.
-
Request GetCapabilities:
?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities
-
Find the default-scalar/default style and open its advertised LegendURL.
-
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&PALETTE=$paletteName&LAYERS=$layerName&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:
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&LAYERS=$layerName&STYLES=$style"/>
#else
<Name>$style/$paletteName</Name>
<Title>$style/$paletteName</Title>
...
<OnlineResource
xlink:type="simple"
xlink:href="$baseUrl?REQUEST=GetLegendGraphic&PALETTE=$paletteName&LAYERS=$layerName&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.
Software version
edal-javasourceEnvironment
docker.io/unidata/thredds-docker:5.8imageDescription
When a WMS layer has a configured default palette, the GetCapabilities response advertises palette-based styles with a
/defaultsuffix.For example:
The
/defaultsuffix is treated as an explicitly requested palette name. Consequently, it selects EDAL's built-indefaultpalette rather than the default palette configured for the layer throughPlottingStyleParameters.For example, a layer configured to use
seq-Greysproduces the following results:Uses EDAL's built-in yellow-to-blue default palette.
Correctly uses the layer-configured
seq-Greyspalette.This means the automatically generated LegendURL does not represent the layer's configured default styling.
Steps to reproduce
Configure a WMS layer so its default
PlottingStyleParameterspalette isseq-Greys.In THREDDS, this can be reproduced with:
Restart the application.
Request GetCapabilities:
Find the
default-scalar/defaultstyle and open its advertised LegendURL.Compare it with a request where the suffix is removed:
Actual behaviour
The generated LegendURL includes:
The
defaultsuffix is interpreted as an explicit request for EDAL's built-in default palette, overriding the palette supplied by the layer's defaultPlottingStyleParameters.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
defaultpalette:https://github.com/Reading-eScience-Centre/edal-java/blob/master/wms/src/main/resources/templates/capabilities-1.3.0.vm#L264-L280
GetMapStyleParamsgives 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
Therefore,
default-scalar/defaultnever reaches the configured-default branch.Proposed solution
For the special advertised palette named
default, generate a style without a palette suffix:and generate its legend URL using:
For explicitly named palettes, retain the existing behaviour:
Conceptually, the Velocity template could use:
The equivalent change should be applied to both:
Regression tests could verify that:
An alternative, if changing advertised style names is considered incompatible, would be to preserve
/defaultbut 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.