Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thredds palettes #7059

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open

Thredds palettes #7059

wants to merge 36 commits into from

Conversation

sixlighthouses
Copy link
Contributor

@sixlighthouses sixlighthouses commented Feb 23, 2024

What this PR does

Adds the functionality to allow users to make use of Thredds palettes for styling.

Test me

Browse to
url: http://ci.terria.io/thredds-palettes/

Add a thredds server -- example https://thredds.ereefs.aims.gov.au/thredds/wms/GBR4_H2p0_B3p1_Cq3P_Dhnd/monthly.nc?service=WMS&version=1.3.0&request=GetCapabilities

Add a layer

Select a style from the workbench control

You will now see the Palettes drop down

select a palette to see the layers style change n.b some layers will need to have the Color Scale Range edited to correctly use the palettes

Checklist

  • There are unit tests to verify my changes are correct or unit tests aren't applicable (if so, write quick reason why unit tests don't exist)
  • I've updated relevant documentation in doc/.
  • I've updated CHANGES.md with what I changed.
  • I've provided instructions in the PR description on how to test this PR.

@sixlighthouses
Copy link
Contributor Author

On first load of the Thredds server no style is selected, so no palettes are displayed
image

Once the user selects a style, we fetch the list of palettes associated with that style

image

@sppigot
Copy link
Contributor

sppigot commented Mar 8, 2024

Thanks @sixlighthouses - this is a really useful addition to the THREDDS WMS support! Please merge ASAP

@sixlighthouses sixlighthouses marked this pull request as ready for review March 11, 2024 23:45
lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts Outdated Show resolved Hide resolved
lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts Outdated Show resolved Hide resolved
// const paletteResult: StratumFromTraits<WebMapServiceAvailableLayerStylesTraits>[] =
// [];

async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this anonymous function get called?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That one is an IIFE -- I used it so I can call the async fetchPalettes without having to make the parent function async

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking that one up Lawrence, it was never getting called, removed that code block

lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts Outdated Show resolved Hide resolved
const extractedUrl = urls?.[0];

if (!extractedUrl) {
reject("No URL found in abstract");
Copy link
Contributor

@ljowen ljowen Mar 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless we also return here the fetch below will still execute and make a request to <ur>/undefined

Should No url in the abstract be treated as an error? My understanding is it's an option property for thredds wms's so it might instead be more appropriate to resolve([])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to resolve, thanks Lawrence

Copy link
Contributor

@nf-s nf-s left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are a few architectural issues with this PR.

The ncWMS GetMetadata with item=layerDetails (which is currently being extracted from the selected WMS style abstract) - actually has nothing to do with specific styles, it returns extra metadata for a given layer.

For example

The JSON response includes the following things related to palettes

{
  "scaleRange": [-50, 50],
  "palettes": [
    "default",
    "default-inv",
    "div-BrBG",
    ...
  ],
  "defaultPalette": "psu-viridis",
  "noPaletteStyles": ["contours"]
}

This means that the palettes should be visible if any style is selected that isn't in noPaletteStyles (styles that don't support palettes). The default palette should also be set to defaultPalette, and the default colorScaleMinimum and colorScaleMaximum should be set using scaleRange.

This GetMetadata JSON should be fetched in WebMapServiceCatalogItem.forceLoadMetadata - and should be in it's own LoadableStratum (eg something like NcMWSGetMetadataStratum). From that LoadableStratum, you can define values for threddsPalette and threddsPalettes (and also colorScaleMinimum and colorScaleMaximum).

  • You can also check the current layer there, and return undefined if the layer name is in noPaletteStyles.

The GetMetadata URL can be constructed using something like

this.uri.clone()
  .setSearch({
    service: "WMS",
    version: this.useWmsVersion130 ? "1.3.0" : "1.1.1",
    request: "GetMetadata",
    item: "layerDetails",
    layerName: this.layersArray[0],
  })
  .toString()

While WMS does support multiple layers, I think we should just fetch GetMetadata for the first layer at the moment.

How you have setup threddsPaletteDimensions works well!
So only minimal changes should be needed for that.

Finally, can you please add a supportsGetMetadata and supportsPalette traits? You can just copy supportsColorScaleRange. This will allow us to override the default behaviour - eg turn it off or on manually.

Also, sorry to nitpick, but all of this is ncWMS not THREDDs specific - so can you please rename the WebMapServiceCatalogItem traits to palette and availablePalettes (just to match the existing pattern with availableStyles etc) - and other thredds name properties/objects

Please let me know if you need any further info/clarification - thanks!

@@ -671,6 +738,7 @@ class WebMapServiceCatalogItem
);
styles[layerIndex] = newStyle;
this.setTrait(stratumId, "styles", styles.join(","));
this.fetchPalettes();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a condition here to fetchPalettes is only called if the server supports it?

Currently, if you select a style for a non-THREDDs WMS - this causes an uncaught error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry this comment doesn't make sense with all the other changes I have suggested

Copy link
Contributor Author

@sixlighthouses sixlighthouses left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added traits for

  • colorScaleMinimum
  • colorScaleMaximum
  • defaultPalette
  • noPaletteStyles

added checks for current style is included in noPaletteStyles

Copy link
Contributor Author

@sixlighthouses sixlighthouses left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo

  • GetLegendGraphic failing when not using default
  • GetLegendGraphic being reset when changing styles

@sixlighthouses
Copy link
Contributor Author

Ready for re-review

Copy link
Contributor

@nf-s nf-s left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sixlighthouses this is definitely a good step forward. There are still a few architectural issues with this PR.

It is important to follow the Terria model layer patterns that I mentioned previously.

If you are unsure how to apply the Terria model layer patterns, there is some documentation here:

Please let me know if you want any further info, we can setup a meeting to discuss this.

description:
"Used to store the palettes available for a layer. This is a non-standard property supported by THREDDS servers. This property is ignored unless WebMapServiceCatalogItem's isThredds is true. The default value is ['default']."
})
palettes?: string[] = [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please rename this to availablePalettes (just to match the existing pattern with availableStyles etc)

Comment on lines 654 to 676
this.setTrait(CommonStrata.user, "palettes", data.palettes);
this.setTrait(
CommonStrata.user,
"colorScaleMinimum",
data.scaleRange[0]
);
this.setTrait(
CommonStrata.user,
"colorScaleMaximum",
data.scaleRange[1]
);
this.setTrait(
CommonStrata.user,
"defaultPalette",
data.defaultPalette
);
this.setTrait(
CommonStrata.user,
"noPaletteStyles",
data.noPaletteStyles
);
this.setTrait(CommonStrata.user, "showPalettes", true);
resolve(data.palettes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user stratum should only be used for user-driven changes to traits. The current fetchPalettes implementation makes changes to the user stratum - this means that when a share-link is generated, the palettes will be included.

Can you please move the fetchPalettes logic into a new LoadableStratum (you can call it NcMWSGetMetadataStratum) ?

Comment on lines +770 to +789

runInAction(() => {
const styles = this.styleSelectableDimensions.map(
(style) => style.selectedId || ""
);
styles[layerIndex] = newStyle;
this.setTrait(stratumId, "styles", styles.join(","));
styles[layerIndex] = newStyle ? newStyle : "";

if (this.isNcWMS && this.palette) {
const currentStyle = newStyle.split("/")[0];
const currentPalette = this.palette;
const newStyles = currentStyle + "/" + currentPalette;
this.setTrait(stratumId, "styles", newStyles);
if (this.noPaletteStyles.includes(newStyle)) {
this.setTrait(stratumId, "showPalettes", false);
} else {
this.setTrait(stratumId, "showPalettes", true);
}
} else {
this.setTrait(stratumId, "styles", styles.join(","));
}
Copy link
Contributor

@nf-s nf-s May 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, I think you should keep styles and palette separate. After creating the NcWMSLoadableStratum, you can change showPalette there without explicitly calling setTrait.

Comment on lines 229 to 231
if (this.palettes.length === 0) {
this.fetchPalettes();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be loaded after GetCapabilitiesStratum

Comment on lines 709 to 716
//if (this.stylesArray[0]) {
runInAction(() => {
this.setTrait(stratumId, "palette", newPalette);
const currentStyle = this.stylesArray[0]
? this.stylesArray[0]
: "default";
const newStyles = currentStyle.split("/")[0] + "/" + newPalette;
this.setTrait(stratumId, "styles", newStyles);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are some issues with updating styles like this - you should keep palette and styles separate.

With the current implementation, palette is not used unless the user makes changes - for example - if palette was defined in a catalog JSON file, it wouldn't be used.

You can apply the palette to the styles parameter here instead. You should only apply the palette to the first style - as this maps to the first layers style.

parameters.styles = this.styles ?? "";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants