From 3b68dd97d36e1c9246399bdee835057f41585cd3 Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Wed, 11 Dec 2024 12:41:02 +0100 Subject: [PATCH 01/32] Add support for dashboard.json --- src/components/general/DashboardDisplay.vue | 62 ++++------ src/components/general/DashboardItems.vue | 65 +++++++++++ src/lib/component-settings/types.ts | 73 ++++++++++++ src/lib/dashboard/types.ts | 24 ++++ src/lib/topology/dashboard.ts | 118 +++++++++----------- src/lib/topology/nodes.ts | 2 +- src/stores/componentSettings.ts | 29 +++++ src/stores/dashboards.ts | 27 +++++ src/views/DashboardView.vue | 16 +-- 9 files changed, 304 insertions(+), 112 deletions(-) create mode 100644 src/components/general/DashboardItems.vue create mode 100644 src/lib/component-settings/types.ts create mode 100644 src/lib/dashboard/types.ts create mode 100644 src/stores/componentSettings.ts create mode 100644 src/stores/dashboards.ts diff --git a/src/components/general/DashboardDisplay.vue b/src/components/general/DashboardDisplay.vue index fd8ab6710..449eb3ea2 100644 --- a/src/components/general/DashboardDisplay.vue +++ b/src/components/general/DashboardDisplay.vue @@ -1,39 +1,27 @@ @@ -19,7 +16,6 @@ From e0789c8f058f67eb9630bbc02abf19440da75edc Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Fri, 13 Dec 2024 11:57:44 +0100 Subject: [PATCH 13/32] Add support for overlayer layers based on locationSets --- .../SpatialDisplayComponent.vue | 6 +++ src/components/wms/OverlayControl.vue | 2 +- src/components/wms/OverlayLayer.vue | 41 +++++++++++++++++++ src/lib/topology/locations.ts | 37 ++++++++++++++--- 4 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 src/components/wms/OverlayLayer.vue diff --git a/src/components/spatialdisplay/SpatialDisplayComponent.vue b/src/components/spatialdisplay/SpatialDisplayComponent.vue index dd4b4bb14..447ce2e22 100644 --- a/src/components/spatialdisplay/SpatialDisplayComponent.vue +++ b/src/components/spatialdisplay/SpatialDisplayComponent.vue @@ -41,6 +41,11 @@ v-if="workflowsStore.isSelectingCoordinate" v-model:coordinate="workflowsStore.coordinate" /> +
@@ -172,6 +177,7 @@ import { TimeSeriesData } from '@/lib/timeseries/types/SeriesData' import CoordinateSelectorLayer from '@/components/wms/CoordinateSelectorLayer.vue' import CoordinateSelectorControl from '@/components/map/CoordinateSelectorControl.vue' import type { MapSettings, OverlayLocation } from '@/lib/topology/componentSettings' +import OverlayLayer from '@/components/wms/OverlayLayer.vue' interface ElevationWithUnitSymbol { units?: string diff --git a/src/components/wms/OverlayControl.vue b/src/components/wms/OverlayControl.vue index 11fcaea91..d5cbddf7f 100644 --- a/src/components/wms/OverlayControl.vue +++ b/src/components/wms/OverlayControl.vue @@ -61,7 +61,7 @@ watchEffect(() => { selectedIds.value = getVisibleOverlayIds(props.settings?.overlays ?? []) }) -const selectedOverlays = defineModel() +const selectedOverlays = defineModel('selectedOverlays') watchEffect(() => { selectedOverlays.value = getOverlocationsByIds(selectedIds.value) }) diff --git a/src/components/wms/OverlayLayer.vue b/src/components/wms/OverlayLayer.vue new file mode 100644 index 000000000..40a35d96e --- /dev/null +++ b/src/components/wms/OverlayLayer.vue @@ -0,0 +1,41 @@ + + + diff --git a/src/lib/topology/locations.ts b/src/lib/topology/locations.ts index f3e75a39d..58110e084 100644 --- a/src/lib/topology/locations.ts +++ b/src/lib/topology/locations.ts @@ -71,9 +71,36 @@ async function fetchLocationsAsGeoJsonForSingleFilterId( includeIconNames: true, showThresholds: true, } - // TODO: Remove cast to any when fews-pi-requests supports GeoJSON response in LocationResponse - // type. - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const response = (await provider.getLocations(filter)) as any - return response as FeatureCollection + const response = await provider.getLocations(filter) + if (!isFeatureCollection(response)) { + throw new Error('Expected GeoJSON FeatureCollection') + } + return response +} + +function isFeatureCollection( + geojson: FeatureCollection | unknown, +): geojson is FeatureCollection { + return ( + (geojson as FeatureCollection).type === + 'FeatureCollection' + ) +} + +export async function fetchLocationSetAsGeoJson( + baseUrl: string, + locationSetId: string, +): Promise> { + const provider = new PiWebserviceProvider(baseUrl, { + transformRequestFn: createTransformRequestFn(), + }) + const filter = { + documentFormat: DocumentFormat.GEO_JSON, + locationSetId: locationSetId, + } + const response = await provider.getLocations(filter) + if (!isFeatureCollection(response)) { + throw new Error('Expected GeoJSON FeatureCollection') + } + return response } From 321de9ceff118af9b5d213d414eaf60f994dbf6e Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Mon, 16 Dec 2024 14:43:58 +0100 Subject: [PATCH 14/32] Make overlay selection menu more compact --- src/components/wms/OverlayControl.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/wms/OverlayControl.vue b/src/components/wms/OverlayControl.vue index d5cbddf7f..41f7859da 100644 --- a/src/components/wms/OverlayControl.vue +++ b/src/components/wms/OverlayControl.vue @@ -10,6 +10,7 @@ v-model:selected="selectedIds" select-strategy="leaf" class="pb-0" + density="compact" > @@ -32,7 +34,7 @@ > From 5b52d30a882380b023dc3ab878c85d061108ef2d Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Mon, 16 Dec 2024 14:51:04 +0100 Subject: [PATCH 15/32] Use getLayer and getSource id to remain active on basemap change --- src/components/wms/OverlayLayer.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/wms/OverlayLayer.vue b/src/components/wms/OverlayLayer.vue index 40a35d96e..6a11397f4 100644 --- a/src/components/wms/OverlayLayer.vue +++ b/src/components/wms/OverlayLayer.vue @@ -23,6 +23,7 @@ import type { OverlayLocation } from '@/lib/topology/componentSettings' import { fetchLocationSetAsGeoJson } from '@/lib/topology' import { configManager } from '@/services/application-config' import { asyncComputed } from '@vueuse/core' +import { getLayerId, getSourceId } from '@/lib/map' interface Props { overlay: OverlayLocation @@ -30,8 +31,8 @@ interface Props { const props = defineProps() -const sourceId = `overlay-source-${props.overlay.id}` -const layerId = `overlay-layer-${props.overlay.id}` +const sourceId = getSourceId(`overlay-${props.overlay.id}`) +const layerId = getLayerId(`overlay-${props.overlay.id}`) const baseUrl = configManager.get('VITE_FEWS_WEBSERVICES_URL') const geojson = asyncComputed( From 61a4ee50d3aabb89cafde7212f0806a2f8469fdc Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Tue, 17 Dec 2024 09:04:41 +0100 Subject: [PATCH 16/32] Use topologyNode name as dashboard tab title --- src/components/general/DashboardItems.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/general/DashboardItems.vue b/src/components/general/DashboardItems.vue index 6cd283547..3f8bbd756 100644 --- a/src/components/general/DashboardItems.vue +++ b/src/components/general/DashboardItems.vue @@ -7,7 +7,11 @@ class="flex-0-0 w-100" density="compact" > - + {{ item.title }} @@ -66,7 +70,7 @@ const componentItems = computed(() => { const topologyNode = topologyNodesStore.getNodeById(item.topologyNodeId) const component = componentTypeToComponentMap[componentName] const componentProps = getComponentPropsForNode(componentName, topologyNode) - const title = componentTypeToTitleMap[componentName] + const title = topologyNode?.name ?? componentTypeToTitleMap[componentName] const icon = componentTypeToIconMap[componentName] const settings = getComponentSettingsForItem(item) return { From eab95ec2da5533e4c8af55cdddea70594b9a9a60 Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Tue, 17 Dec 2024 10:33:40 +0100 Subject: [PATCH 17/32] Use topologyNode iconId if available for dasbboard tab --- src/components/general/DashboardItems.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/general/DashboardItems.vue b/src/components/general/DashboardItems.vue index 3f8bbd756..8cbaf182f 100644 --- a/src/components/general/DashboardItems.vue +++ b/src/components/general/DashboardItems.vue @@ -71,7 +71,7 @@ const componentItems = computed(() => { const component = componentTypeToComponentMap[componentName] const componentProps = getComponentPropsForNode(componentName, topologyNode) const title = topologyNode?.name ?? componentTypeToTitleMap[componentName] - const icon = componentTypeToIconMap[componentName] + const icon = topologyNode?.iconId ?? componentTypeToIconMap[componentName] const settings = getComponentSettingsForItem(item) return { title, From 0702c0a9f0e341e81c45a159cb3a72c53dd81f28 Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Tue, 17 Dec 2024 15:30:20 +0100 Subject: [PATCH 18/32] Add overlays to component settings store --- .../SpatialDisplayComponent.vue | 9 +-- src/components/wms/OverlayControl.vue | 67 +++++-------------- src/lib/topology/componentSettings.ts | 29 ++------ src/stores/componentSettings.ts | 33 +++++++-- 4 files changed, 54 insertions(+), 84 deletions(-) diff --git a/src/components/spatialdisplay/SpatialDisplayComponent.vue b/src/components/spatialdisplay/SpatialDisplayComponent.vue index 447ce2e22..0b08c1b54 100644 --- a/src/components/spatialdisplay/SpatialDisplayComponent.vue +++ b/src/components/spatialdisplay/SpatialDisplayComponent.vue @@ -42,7 +42,7 @@ v-model:coordinate="workflowsStore.coordinate" /> @@ -90,7 +90,7 @@ :selectedLocationId="props.locationId" @changeLocationId="onLocationChange" /> - :settings="settings" v-model:selectedOverlays="selectedOverlays" /> @@ -176,8 +176,9 @@ import { useWorkflowsStore } from '@/stores/workflows' import { TimeSeriesData } from '@/lib/timeseries/types/SeriesData' import CoordinateSelectorLayer from '@/components/wms/CoordinateSelectorLayer.vue' import CoordinateSelectorControl from '@/components/map/CoordinateSelectorControl.vue' -import type { MapSettings, OverlayLocation } from '@/lib/topology/componentSettings' +import type { MapSettings } from '@/lib/topology/componentSettings' import OverlayLayer from '@/components/wms/OverlayLayer.vue' +import { useComponentSettingsStore } from '@/stores/componentSettings' interface ElevationWithUnitSymbol { units?: string @@ -245,6 +246,7 @@ const showLayer = ref(true) const layerKind = ref(LayerKind.Static) const colourScalesStore = useColourScalesStore() +const componentSettingsStore = useComponentSettingsStore() const workflowsStore = useWorkflowsStore() const showLocationsLayer = ref(true) @@ -376,7 +378,6 @@ const showLocationSearchControl = computed(() => { return !(props.settings?.locationSearchEnabled === false) }) -const selectedOverlays = ref([]) watch( () => props.layerCapabilities, diff --git a/src/components/wms/OverlayControl.vue b/src/components/wms/OverlayControl.vue index 41f7859da..fa7c838f4 100644 --- a/src/components/wms/OverlayControl.vue +++ b/src/components/wms/OverlayControl.vue @@ -1,5 +1,5 @@
@@ -147,6 +145,7 @@ import LocationsLayer from '@/components/wms/LocationsLayer.vue' import SelectedCoordinateLayer from '@/components/wms/SelectedCoordinateLayer.vue' import InformationPanel from '@/components/wms/InformationPanel.vue' import OverlayControl from '@/components/wms/OverlayControl.vue' +import BaseMapControl from '@/components/wms/BaseMapControl.vue' import ElevationSlider from '@/components/wms/ElevationSlider.vue' import DateTimeSlider from '@/components/general/DateTimeSlider.vue' import BoundingBoxControl from '@/components/map/BoundingBoxControl.vue' @@ -378,7 +377,6 @@ const showLocationSearchControl = computed(() => { return !(props.settings?.locationSearchEnabled === false) }) - watch( () => props.layerCapabilities, (layer) => { diff --git a/src/components/wms/BaseMapControl.vue b/src/components/wms/BaseMapControl.vue new file mode 100644 index 000000000..f98e8647a --- /dev/null +++ b/src/components/wms/BaseMapControl.vue @@ -0,0 +1,28 @@ + + + diff --git a/src/services/useBaseLayers/index.ts b/src/services/useBaseLayers/index.ts deleted file mode 100644 index 424c6e4e5..000000000 --- a/src/services/useBaseLayers/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -import type { MaybeRefOrGetter, ShallowRef } from 'vue' -import { shallowRef, toValue, watchEffect } from 'vue' -import Basemaps from '@/assets/base-layers.json' -import { MglDefaults } from '@indoorequal/vue-maplibre-gl' -import { useDark } from '@vueuse/core' -import { StyleSpecification } from 'maplibre-gl' - -export interface UseBaseLayersReturn { - baseLayerStyle: ShallowRef - baseLayers: ShallowRef<(string | object)[]> -} - -export function useBaseLayers( - layerId: MaybeRefOrGetter, -): UseBaseLayersReturn { - const baseLayerStyle = shallowRef( - MglDefaults.style ?? '', - ) - const baseLayers = shallowRef<(string | object)[]>(Basemaps.baseLayers) - - const isDark = useDark() - - watchEffect(() => { - const _layerId = toValue(layerId) - const layerDefinition = Basemaps.baseLayers.find( - (layer: any) => layer.id === _layerId, - ) - if (layerDefinition?.automatic) { - if (isDark.value === true) { - const themedLayer = Basemaps.baseLayers.find( - (layer: any) => layer.id === layerDefinition.automatic.dark, - ) - if (themedLayer?.style) baseLayerStyle.value = themedLayer?.style - } else { - const themedLayer = Basemaps.baseLayers.find( - (layer: any) => layer.id === layerDefinition.automatic.light, - ) - if (themedLayer?.style) baseLayerStyle.value = themedLayer?.style - } - } else if (layerDefinition?.style) { - baseLayerStyle.value = layerDefinition?.style - } - }) - - return { - baseLayerStyle, - baseLayers, - } -} diff --git a/src/stores/componentSettings.ts b/src/stores/componentSettings.ts index 3c9ba5100..ba9c3c2ac 100644 --- a/src/stores/componentSettings.ts +++ b/src/stores/componentSettings.ts @@ -1,23 +1,31 @@ import { getResourcesStaticUrl } from '@/lib/fews-config' import { defineStore } from 'pinia' +import DefaultBaseMaps from '@/assets/DefaultBaseMaps.json' import type { + BaseMap, ComponentSettings, ComponentSettingsResponse, Declarations, OverlayLocation, } from '@/lib/topology/componentSettings' +import { useDark } from '@vueuse/core' interface State { settings: ComponentSettings[] declarations?: Declarations selectedOverlayIds: string[] - selectedBaseMapId?: string + selectedBaseMapId: string +} + +function isKeyOfDefaultStyle(key: string): key is keyof typeof DefaultBaseMaps { + return key in DefaultBaseMaps } export const useComponentSettingsStore = defineStore('componentSettings', { state: (): State => ({ settings: [], selectedOverlayIds: [], + selectedBaseMapId: 'automatic', }), getters: { overlays: (state) => state.declarations?.overlays?.locations ?? [], @@ -26,9 +34,33 @@ export const useComponentSettingsStore = defineStore('componentSettings', { .map((id) => this.overlays.find((o) => o.id === id)) .filter((o) => o !== undefined) }, - basemaps: (state) => { - return state.declarations?.baseMaps + baseMaps: (state) => { + const defaultBaseMaps: BaseMap[] = Object.values(DefaultBaseMaps) + const baseMaps = state.declarations?.baseMaps ?? [] + return [ + ...defaultBaseMaps, + ...baseMaps, + ] + }, + selectedBaseMap(): BaseMap { + if (this.selectedBaseMapId === 'automatic') { + const isDark = useDark() + return DefaultBaseMaps[isDark.value ? 'dark' : 'light'] + } + if (isKeyOfDefaultStyle(this.selectedBaseMapId)) { + return DefaultBaseMaps[this.selectedBaseMapId] + } + // FIXME: What to do if the selected base map is not found? + // Could happen when persisting the selected base map + return this.baseMaps.find((b) => b.id === this.selectedBaseMapId) ?? this.baseMaps[0] }, + selectedStyle(): string { + const style = this.selectedBaseMap.style + if (style.startsWith('/')) { + return getResourcesStaticUrl(style.slice(1)) + } + return style + } }, actions: { async fetchState() { From 6fcf0adfba50d0a27ec09d39c448d83675a53c87 Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Tue, 17 Dec 2024 13:32:52 +0100 Subject: [PATCH 22/32] Get dashboard after empty check --- src/stores/dashboards.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/dashboards.ts b/src/stores/dashboards.ts index e7a58e413..e07492d18 100644 --- a/src/stores/dashboards.ts +++ b/src/stores/dashboards.ts @@ -12,9 +12,9 @@ export const useDashboardsStore = defineStore('dashboards', { }), actions: { async fetchState() { - const url = getResourcesStaticUrl('dashboards.json') if (this.dashboards.length > 0) return + const url = getResourcesStaticUrl('dashboards.json') const response = await fetch(url) const data: DashboardsResponse = await response.json() this.dashboards = data.dashboards From 9501cab4dd157259c132be1804027f46c9b2ce28 Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Tue, 17 Dec 2024 13:33:47 +0100 Subject: [PATCH 23/32] Disable tasks as it breaks the topology tree --- src/lib/topology/displayTabs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/topology/displayTabs.ts b/src/lib/topology/displayTabs.ts index 938e778da..5d5d59091 100644 --- a/src/lib/topology/displayTabs.ts +++ b/src/lib/topology/displayTabs.ts @@ -88,7 +88,7 @@ export function displayTabsForNode( break case 'tasks': // HACK - tab.active = true + tab.active = false tab.to.params = { ...params } break } From cc589ff9cd2a78c8d5c3e78fe96a954190799ca4 Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Tue, 17 Dec 2024 13:34:32 +0100 Subject: [PATCH 24/32] Linting --- src/components/spatialdisplay/SpatialDisplay.vue | 4 +++- src/lib/dashboard/types.ts | 2 +- src/stores/componentSettings.ts | 12 ++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/spatialdisplay/SpatialDisplay.vue b/src/components/spatialdisplay/SpatialDisplay.vue index 7e9f29708..9f8b290d6 100644 --- a/src/components/spatialdisplay/SpatialDisplay.vue +++ b/src/components/spatialdisplay/SpatialDisplay.vue @@ -153,7 +153,9 @@ const filter = computed(() => { }) const showChartPanel = computed(() => { - return filter.value !== undefined && !(props.settings?.chartPanelEnabled === false) + return ( + filter.value !== undefined && !(props.settings?.chartPanelEnabled === false) + ) }) const elevationChartFilter = computed(() => { diff --git a/src/lib/dashboard/types.ts b/src/lib/dashboard/types.ts index 869bc4e1a..d6dcd8583 100644 --- a/src/lib/dashboard/types.ts +++ b/src/lib/dashboard/types.ts @@ -1,4 +1,4 @@ -import { ComponentType } from "@/lib/topology/component" +import { ComponentType } from '@/lib/topology/component' export interface DashboardsResponse { dashboards: Dashboard[] diff --git a/src/stores/componentSettings.ts b/src/stores/componentSettings.ts index ba9c3c2ac..ed126ab2a 100644 --- a/src/stores/componentSettings.ts +++ b/src/stores/componentSettings.ts @@ -37,10 +37,7 @@ export const useComponentSettingsStore = defineStore('componentSettings', { baseMaps: (state) => { const defaultBaseMaps: BaseMap[] = Object.values(DefaultBaseMaps) const baseMaps = state.declarations?.baseMaps ?? [] - return [ - ...defaultBaseMaps, - ...baseMaps, - ] + return [...defaultBaseMaps, ...baseMaps] }, selectedBaseMap(): BaseMap { if (this.selectedBaseMapId === 'automatic') { @@ -52,7 +49,10 @@ export const useComponentSettingsStore = defineStore('componentSettings', { } // FIXME: What to do if the selected base map is not found? // Could happen when persisting the selected base map - return this.baseMaps.find((b) => b.id === this.selectedBaseMapId) ?? this.baseMaps[0] + return ( + this.baseMaps.find((b) => b.id === this.selectedBaseMapId) ?? + this.baseMaps[0] + ) }, selectedStyle(): string { const style = this.selectedBaseMap.style @@ -60,7 +60,7 @@ export const useComponentSettingsStore = defineStore('componentSettings', { return getResourcesStaticUrl(style.slice(1)) } return style - } + }, }, actions: { async fetchState() { From a39c840785e02e0ffaf44b9bd32b3e21f42aa0e1 Mon Sep 17 00:00:00 2001 From: hvangeffen Date: Wed, 11 Dec 2024 13:55:13 +0100 Subject: [PATCH 25/32] Scope current colour scales to spatialdisplay instance --- .../SpatialDisplayComponent.vue | 125 +++++------------- src/components/wms/InformationPanel.vue | 84 +++++++----- src/services/useColourScales/index.ts | 56 ++++++++ src/services/useWms/index.ts | 10 +- src/stores/colourScales.ts | 115 ++++++++++------ 5 files changed, 225 insertions(+), 165 deletions(-) create mode 100644 src/services/useColourScales/index.ts diff --git a/src/components/spatialdisplay/SpatialDisplayComponent.vue b/src/components/spatialdisplay/SpatialDisplayComponent.vue index be491ec18..379120e92 100644 --- a/src/components/spatialdisplay/SpatialDisplayComponent.vue +++ b/src/components/spatialdisplay/SpatialDisplayComponent.vue @@ -13,18 +13,18 @@ :streamlineOptions="layerCapabilities?.animatedVectors" @doubleclick="onCoordinateClick" /> -
+
() const isLoading = ref(false) let debouncedSetLayerOptions!: () => void -const legendLayerName = ref(props.layerName) const legendLayerStyles = ref() const userSettings = useUserSettingsStore() @@ -246,6 +238,9 @@ const layerKind = ref(LayerKind.Static) const colourScalesStore = useColourScalesStore() const componentSettingsStore = useComponentSettingsStore() +const currentColourScale = ref() +const currentColourScaleIds = ref([]) + const workflowsStore = useWorkflowsStore() const showLocationsLayer = ref(true) @@ -263,73 +258,22 @@ watchEffect(() => { watch( legendLayerStyles, - () => { - const styles = legendLayerStyles.value + (styles) => { if (styles === undefined) { - colourScalesStore.currentIds = [] - colourScalesStore.currentIndex = 0 + currentColourScaleIds.value = [] return } - legendLayerName.value = props.layerName - colourScalesStore.currentIds = styles.map(styleToId) - colourScalesStore.currentIndex = 0 - - styles.forEach(async (style) => { - const styleId = styleToId(style) - - if (!(styleId in colourScalesStore.scales)) { - const initialLegendGraphic = await fetchWmsLegend( - baseUrl, - legendLayerName.value, - userSettings.useDisplayUnits, - undefined, - style, - ) - - const legend = initialLegendGraphic.legend - const newColourScale = reactive({ - title: getLegendTitle( - props.layerCapabilities?.title ?? '', - initialLegendGraphic, - ), - style: style, - colourMap: legend, - range: legendToRange(legend), - initialRange: legendToRange(legend), - useGradients: !legend.some((entry) => entry.colorSmoothing === false), - }) - colourScalesStore.scales[styleId] = newColourScale - - const range = computed(() => { - const newRange = rangeToString(newColourScale.range) - const initialRange = rangeToString(newColourScale.initialRange) - - return newRange !== initialRange ? newRange : undefined - }) - - const newLegendGraphic = useWmsLegend( - baseUrl, - legendLayerName, - () => userSettings.useDisplayUnits, - range, - style, - () => - props.layerCapabilities - ? (props.layerCapabilities.styles ?? [style]) - : undefined, - ) - - watch(newLegendGraphic, () => { - if (newLegendGraphic.value?.legend === undefined) return - colourScalesStore.scales[styleId].title = getLegendTitle( - props.layerCapabilities?.title ?? '', - newLegendGraphic.value, - ) - colourScalesStore.scales[styleId].colourMap = - newLegendGraphic.value.legend - }) - } + currentColourScaleIds.value = styles.map(styleToId) + + styles.forEach((style) => { + colourScalesStore.addScale( + style, + props.layerName, + () => props.layerCapabilities?.title, + () => userSettings.useDisplayUnits, + () => props.layerCapabilities?.styles ?? [], + ) }) }, { immediate: true }, @@ -383,7 +327,6 @@ watch( const _forecastTime = layer?.keywordList?.[0].forecastTime forecastTime.value = _forecastTime ? new Date(_forecastTime) : undefined - legendLayerName.value = props.layerName legendLayerStyles.value = props.layerCapabilities?.styles if (legendLayerStyles.value === undefined && props.layerName) { legendLayerStyles.value = [ @@ -414,7 +357,7 @@ watch(currentElevation, () => { }) watch( - [() => colourScalesStore.currentScale?.range, () => userSettings.useDisplayUnits], + [() => currentColourScale.value?.range, () => userSettings.useDisplayUnits], () => { setLayerOptions() }, @@ -462,10 +405,10 @@ function setLayerOptions(): void { ? convertBoundingBoxToLngLatBounds(props.layerCapabilities.boundingBox) : undefined, elevation: currentElevation.value, - colorScaleRange: colourScalesStore.currentScale?.range - ? rangeToString(colourScalesStore.currentScale?.range) + colorScaleRange: currentColourScale.value?.range + ? rangeToString(currentColourScale.value?.range) : undefined, - style: colourScalesStore.currentScale?.style.name, + style: currentColourScale.value?.style.name, useDisplayUnits: userSettings.useDisplayUnits, } } else { diff --git a/src/components/wms/InformationPanel.vue b/src/components/wms/InformationPanel.vue index 32d2c26c4..07edfe160 100644 --- a/src/components/wms/InformationPanel.vue +++ b/src/components/wms/InformationPanel.vue @@ -36,14 +36,11 @@ prepend-icon="mdi-clock-time-four-outline" > - + @@ -62,14 +59,12 @@
-