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
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e09266a
read list of palettes from Thredds server layer metadata service
sixlighthouses Feb 8, 2024
33e4694
temp fix for using availablePalettes trait
sixlighthouses Feb 9, 2024
ad99869
use 2 new traits for Thredds Palettes in WebMapServiceCatalogItemTrai…
sixlighthouses Feb 23, 2024
f00d68a
Merge remote-tracking branch 'origin/main' into thredds-palettes
sixlighthouses Feb 23, 2024
7e2b20e
Merge remote-tracking branch 'origin/main' into thredds-palettes
sixlighthouses Mar 12, 2024
1db060e
merge main and update CHANGES
sixlighthouses Mar 12, 2024
9eefa33
Update lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts
sixlighthouses Mar 14, 2024
1a477f4
Update lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts
sixlighthouses Mar 14, 2024
1227d07
Update lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts
sixlighthouses Mar 14, 2024
ecabd69
fix prettier issue
sixlighthouses Mar 15, 2024
dc1a2b5
Merge remote-tracking branch 'origin/main' into thredds-palettes
sixlighthouses Mar 15, 2024
3e23262
remove superfluous anon function
sixlighthouses Mar 19, 2024
e9209ff
Merge remote-tracking branch 'origin/main' into thredds-palettes
sixlighthouses Mar 19, 2024
54b4420
if no palette URL is in the style abstract resolve and return [] rath…
sixlighthouses Mar 20, 2024
1d22d63
Merge remote-tracking branch 'origin/main' into thredds-palettes
sixlighthouses Mar 28, 2024
843ab42
remove thredds prefix from traits name, use the uri.clone method to g…
sixlighthouses Apr 2, 2024
086f24b
Merge remote-tracking branch 'origin/main' into thredds-palettes
sixlighthouses Apr 7, 2024
edc06b2
wip
sixlighthouses Apr 9, 2024
38c8c9d
Merge remote-tracking branch 'origin/main' into thredds-palettes
sixlighthouses Apr 9, 2024
a14d46e
move initial fetchPalettes into forceLoadMetadata
sixlighthouses Apr 10, 2024
0fd38b8
palettes correctly persisting after style change
sixlighthouses Apr 12, 2024
9f91a7d
wip
sixlighthouses Apr 12, 2024
41892d2
correct the check for undefined default style and remove console.logs
sixlighthouses Apr 14, 2024
722db12
run prettier
sixlighthouses Apr 14, 2024
2528d60
Merge remote-tracking branch 'origin/main' into thredds-palettes
sixlighthouses Apr 17, 2024
bacefe0
add CHANGES entry
sixlighthouses Apr 18, 2024
0dfd466
Merge branch 'main' into thredds-palettes
sixlighthouses May 7, 2024
283bda1
Merge branch 'main' into thredds-palettes
sixlighthouses May 7, 2024
f8d87f0
wip
sixlighthouses May 9, 2024
c07fb88
Merge remote-tracking branch 'origin/main' into thredds-palettes
sixlighthouses May 9, 2024
e8fc7b6
wip
sixlighthouses May 10, 2024
2ee6c8f
wip
sixlighthouses May 12, 2024
d8d11b6
correct the traits for new loadable stratum NCWMSGetMetaDataStratum
sixlighthouses May 13, 2024
2ddd71c
remove unused imports
sixlighthouses May 13, 2024
d06645c
Merge remote-tracking branch 'origin/main' into thredds-palettes
sixlighthouses May 13, 2024
545cf4b
wip
sixlighthouses May 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

#### next release (8.7.2)

- Add ability for users to select the palettes supplied by ncWMS servers for changing the visualisation of data.

- [The next improvement]

#### 8.7.1 - 2024-04-16

- Add ability for users to select Thredds palettes when available from Thredds servers for changing the visualisation of data.

- Fixed exception thrown from `objectArrayTrait` when a model has 0 strata and a `MergeStrategy` of `topStratum`.
- Upgraded to TerriajS Cesium 1.115.0
- Fix `PointStyleTraits.marker` bug where URLs were not being used.
- Fixed a bug with passing a relative baseUrl to Cesium >= 1.113.0 when `document.baseURI` is different to its `location`.
Expand Down
6 changes: 6 additions & 0 deletions lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ export type CapabilitiesDimension = string & {
readonly current?: boolean;
};

export type Palettes = {
palettes: ReadonlyArray<string>;
defaultPalette: string;
scaleRange: number[];
};

export type CapabilitiesExtent = string & {
readonly name: string;
readonly default?: string;
Expand Down
72 changes: 67 additions & 5 deletions lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import WebMapServiceCapabilities, {
getRectangleFromLayer
} from "./WebMapServiceCapabilities";
import WebMapServiceCatalogItem from "./WebMapServiceCatalogItem";
import { Complete } from "../../../Core/TypeModifiers";

const dateFormat = require("dateformat");

Expand Down Expand Up @@ -89,6 +90,69 @@ export default class WebMapServiceCapabilitiesStratum extends LoadableStratum(
) as this;
}

async fetchPalettes(
abstract: string,
legend:
| Complete<{
title?: string | undefined;
url?: string | undefined;
imageScaling?: number | undefined;
urlMimeType?: string | undefined;
items?:
| Complete<{
title?: string | undefined;
multipleTitles?: string[] | undefined;
maxMultipleTitlesShowed: number | undefined;
titleAbove?: string | undefined;
titleBelow?: string | undefined;
color?: string | undefined;
outlineColor?: string | undefined;
outlineWidth?: number | undefined;
multipleColors?: string[] | undefined;
imageUrl?: string | undefined;
marker?: string | undefined;
rotation: number | undefined;
addSpacingAbove?: boolean | undefined;
imageHeight: number | undefined;
imageWidth: number | undefined;
}>[]
| undefined;
backgroundColor?: string | undefined;
}>
| undefined
): Promise<StratumFromTraits<WebMapServiceAvailableStyleTraits>[]> {
const paletteResult: StratumFromTraits<WebMapServiceAvailableStyleTraits>[] =
[];

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

if (url) {
const paletteUrl = proxyCatalogItemUrl(this.catalogItem, url);
const response = await fetch(paletteUrl);
const data = await response.json();
const palettes = data.palettes;
palettes.forEach((palette: any) => {
paletteResult.push({
name: palette,
title: palette,
abstract: abstract,
legend: legend
});
});
}

return paletteResult;
}

@computed get metadataUrls() {
const metadataUrls: MetadataURL[] = [];

Expand Down Expand Up @@ -179,7 +243,6 @@ export default class WebMapServiceCapabilitiesStratum extends LoadableStratum(
(candidate) => candidate.name === style
);
}

// If no style is selected and this WMS doesn't support GetLegendGraphics - we must use the first style if none is explicitly specified.
// (If WMS supports GetLegendGraphics we can use it and omit style parameter to get the "default" style's legend)
if (!isDefined(layerStyle) && !this.catalogItem.supportsGetLegendGraphic)
Expand Down Expand Up @@ -222,6 +285,9 @@ export default class WebMapServiceCapabilitiesStratum extends LoadableStratum(
if (style) {
legendUri.setQuery("style", style);
}
if (this.isNcWMS && this.palette) {
legendUri.setQuery("palette", this.palette);
}
legendUrlMimeType = "image/png";
}

Expand Down Expand Up @@ -361,10 +427,6 @@ export default class WebMapServiceCapabilitiesStratum extends LoadableStratum(
const result: StratumFromTraits<WebMapServiceAvailableLayerStylesTraits>[] =
[];

if (!this.capabilities) {
return result;
}

const capabilitiesLayers = this.capabilitiesLayers;
for (const layerTuple of capabilitiesLayers) {
const layerName = layerTuple[0];
Expand Down
131 changes: 125 additions & 6 deletions lib/Models/Catalog/Ows/WebMapServiceCatalogItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ import {
} from "../../../Table/tableFeatureInfoContext";
import WebMapServiceCatalogItemTraits, {
SUPPORTED_CRS_3857,
SUPPORTED_CRS_4326
SUPPORTED_CRS_4326,
WebMapServiceAvailableLayerStylesTraits
} from "../../../Traits/TraitsClasses/WebMapServiceCatalogItemTraits";
import CommonStrata from "../../Definition/CommonStrata";
import CreateModel from "../../Definition/CreateModel";
Expand Down Expand Up @@ -225,12 +226,16 @@ class WebMapServiceCatalogItem
}

protected async forceLoadMetadata(): Promise<void> {
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

if (
this.strata.get(GetCapabilitiesMixin.getCapabilitiesStratumName) !==
undefined
)
return;
const stratum = await WebMapServiceCapabilitiesStratum.load(this);

runInAction(() => {
this.strata.set(GetCapabilitiesMixin.getCapabilitiesStratumName, stratum);
});
Expand Down Expand Up @@ -380,6 +385,7 @@ class WebMapServiceCatalogItem
if (time) {
uri.addQuery("time", time);
}

return uri.toString();
}

Expand Down Expand Up @@ -518,8 +524,6 @@ class WebMapServiceCatalogItem
return undefined;
}

console.log(`Creating new ImageryProvider for time ${time}`);

// Set dimensionParameters
const dimensionParameters = formatDimensionsForOws(this.dimensions);
if (time !== undefined) {
Expand Down Expand Up @@ -619,6 +623,104 @@ class WebMapServiceCatalogItem
}
);

fetchPalettes(): Promise<string[]> {
return new Promise((resolve, reject) => {
if (!this.isThredds) {
resolve([]);
}

if (this.palettes.length > 0) {
resolve([...this.palettes]);
}

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

if (!extractedUrl) {
resolve([]);
}
const proxiedUrl = proxyCatalogItemUrl(this, extractedUrl!);

fetch(proxiedUrl, { method: "GET" })
.then((response) => response.json())
.then((data) => {
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) ?

})
.catch((error) => {
reject(error);
});
});
}

@computed
get paletteDimensions(): SelectableDimensionEnum[] {
if (!this.isNcWMS || !this.showPalettes) {
return [];
}

const options: { name: string; id: string }[] = [];

this.palettes.map((palette) => {
options.push({
name: palette,
id: palette
});
});

return [
{
name: "Palettes",
id: `${this.uniqueId}-palettes`,
options,
selectedId: this.palette,
setDimensionValue: (
stratumId: string,
newPalette: string | undefined
) => {
//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 ?? "";

});
//}
}
}
];
}

@computed
get styleSelectableDimensions(): SelectableDimensionEnum[] {
return this.availableStyles.map((layer, layerIndex) => {
Expand Down Expand Up @@ -665,12 +767,26 @@ class WebMapServiceCatalogItem
newStyle: string | undefined
) => {
if (!newStyle) return;

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(","));
}
Comment on lines +748 to +767
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.

});
},
// There is no way of finding out default style if no style has been selected :(
Expand Down Expand Up @@ -755,10 +871,13 @@ class WebMapServiceCatalogItem
return super.selectableDimensions;
}

const paletteDimensions = this.showPalettes ? this.paletteDimensions : [];

return filterOutUndefined([
...super.selectableDimensions,
...this.wmsDimensionSelectableDimensions,
...this.styleSelectableDimensions
...this.styleSelectableDimensions,
...paletteDimensions
]);
}

Expand Down
1 change: 1 addition & 0 deletions lib/ReactViews/Analytics/ParameterEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const ParameterEditor = createReactClass({
renderEditor() {
for (let i = 0; i < ParameterEditor.parameterTypeConverters.length; ++i) {
const converter = ParameterEditor.parameterTypeConverters[i];

const editor = converter.parameterTypeToDiv(
this.props.parameter.type,
this
Expand Down
2 changes: 1 addition & 1 deletion lib/ReactViews/Workbench/Controls/Legend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import LegendOwnerTraits from "../../../Traits/TraitsClasses/LegendOwnerTraits";
import LegendTraits, {
LegendItemTraits
} from "../../../Traits/TraitsClasses/LegendTraits";
import Styles from "./legend.scss";
import Styles, { legend } from "./legend.scss";

/* A lookup map for displayable mime types */
const DISPLAYABLE_MIME_TYPES = [
Expand Down