Skip to content

Commit 840a0e3

Browse files
feat(WMS Style Selector): Add WMS Style Selector (#3346)
* Add WMS Style Selector * Update shared styling for settings menus * Minor review changes * JSDoc fixes and small comments
1 parent 47bb03a commit 840a0e3

File tree

12 files changed

+466
-42
lines changed

12 files changed

+466
-42
lines changed

packages/geoview-core/public/locales/en/translation.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@
266266
"mosaicOperationBlend": "Blend",
267267
"mosaicOperationSum": "Sum",
268268
"orderAscending": "Oldest to Newest",
269-
"orderDescending": "Newest to Oldest"
269+
"orderDescending": "Newest to Oldest",
270+
"selectWmsStyle": "Select WMS style"
270271
}
271272
},
272273
"details": {

packages/geoview-core/public/locales/fr/translation.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@
266266
"mosaicOperationBlend": "Mélange",
267267
"mosaicOperationSum": "Somme",
268268
"orderAscending": "Plus ancien au plus récent",
269-
"orderDescending": "Plus récent au plus ancien"
269+
"orderDescending": "Plus récent au plus ancien",
270+
"selectWmsStyle": "Sélectionner le style WMS"
270271
}
271272
},
272273
"details": {

packages/geoview-core/src/api/config/validation-classes/raster-validation-classes/ogc-wms-layer-entry-config.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,14 @@ export class OgcWmsLayerEntryConfig extends AbstractBaseLayerEntryConfig {
175175
* If styles are not yet cached, the method reads them from the layer metadata
176176
* and initializes the internal style list. The styles correspond to named
177177
* style definitions advertised by the WMS service (from the `Style` section of the metadata).
178-
* @returns {string[] | undefined} The list of available style names, or `undefined` if none are defined.
178+
*
179+
* @returns The list of available style names, or `undefined` if none are defined.
179180
*/
180181
getStyles(): string[] | undefined {
181182
// If no styles defined
182183
if (!this.#styles) {
183184
// Read styles from the metadata
184-
const styles = this.getLayerMetadata()?.Style;
185+
const styles = this.getStylesMetadata();
185186

186187
// Update internal styles list
187188
if (styles?.length || 0 > 1) {
@@ -193,6 +194,17 @@ export class OgcWmsLayerEntryConfig extends AbstractBaseLayerEntryConfig {
193194
return this.#styles;
194195
}
195196

197+
/**
198+
* Retrieves the full style metadata objects available for this layer.
199+
* Returns the complete `TypeMetadataWMSCapabilityLayerStyle` objects from the layer metadata,
200+
* which include style names, legend URLs, and other style-related information.
201+
*
202+
* @returns The list of available style metadata objects, or `undefined` if none are defined.
203+
*/
204+
getStylesMetadata(): TypeMetadataWMSCapabilityLayerStyle[] | undefined {
205+
return this.getLayerMetadata()?.Style;
206+
}
207+
196208
/**
197209
* Determines the style to apply for this layer.
198210
* Retrieves the list of available styles from the layer config/metadata and returns

packages/geoview-core/src/api/event-processors/event-processor-children/legend-event-processor.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
TypeLayerControls,
77
TypeLayerStatus,
88
TypeMetadataEsriRasterFunctionInfos,
9+
TypeMetadataWMSCapabilityLayerStyle,
910
TypeMosaicMethod,
1011
TypeMosaicRule,
1112
} from '@/api/types/layer-schema-types';
@@ -14,6 +15,7 @@ import type { TypeLegendLayer, TypeLegendLayerItem, TypeLegendItem } from '@/cor
1415
import { MapViewer } from '@/geo/map/map-viewer';
1516
import { GeoUtilities } from '@/geo/utils/utilities';
1617
import type { ConfigBaseClass } from '@/api/config/validation-classes/config-base-class';
18+
import { OgcWmsLayerEntryConfig } from '@/api/config/validation-classes/raster-validation-classes/ogc-wms-layer-entry-config';
1719
import type {
1820
ILayerState,
1921
LegendQueryStatus,
@@ -240,6 +242,7 @@ export class LegendEventProcessor extends AbstractEventProcessor {
240242

241243
/**
242244
* Gets the active raster function for a layer.
245+
*
243246
* @param mapId - The map identifier.
244247
* @param layerPath - The layer path.
245248
* @returns The active raster function identifier.
@@ -250,6 +253,7 @@ export class LegendEventProcessor extends AbstractEventProcessor {
250253

251254
/**
252255
* Sets the active raster function for a layer.
256+
*
253257
* @param mapId - The map identifier.
254258
* @param layerPath - The layer path.
255259
* @param rasterFunctionId - The raster function identifier to set.
@@ -260,6 +264,7 @@ export class LegendEventProcessor extends AbstractEventProcessor {
260264

261265
/**
262266
* Updates the active raster function for a layer in the store.
267+
*
263268
* @param mapId - The map identifier.
264269
* @param layerPath - The layer path.
265270
* @param rasterFunctionId - The raster function identifier to set.
@@ -279,6 +284,7 @@ export class LegendEventProcessor extends AbstractEventProcessor {
279284

280285
/**
281286
* Gets the allowed mosaic methods for a layer.
287+
*
282288
* @param mapId - The map identifier.
283289
* @param layerPath - The layer path.
284290
* @returns The allowed mosaic methods or undefined.
@@ -293,6 +299,7 @@ export class LegendEventProcessor extends AbstractEventProcessor {
293299

294300
/**
295301
* Gets the active mosaic rule for a layer.
302+
*
296303
* @param mapId - The map identifier.
297304
* @param layerPath - The layer path.
298305
* @returns The active mosaic rule or undefined.
@@ -303,6 +310,7 @@ export class LegendEventProcessor extends AbstractEventProcessor {
303310

304311
/**
305312
* Sets the active mosaic rule for a layer.
313+
*
306314
* @param mapId - The map identifier.
307315
* @param layerPath - The layer path.
308316
* @param mosaicRule - The mosaic rule to set.
@@ -313,6 +321,7 @@ export class LegendEventProcessor extends AbstractEventProcessor {
313321

314322
/**
315323
* Updates the mosaicRule for a layer by merging new properties.
324+
*
316325
* @param mapId - The map id.
317326
* @param layerPath - The layer path.
318327
* @param partialMosaicRule - An object with one or more mosaicRule properties to update.
@@ -334,6 +343,7 @@ export class LegendEventProcessor extends AbstractEventProcessor {
334343

335344
/**
336345
* Updates the active mosaic rule for a layer in the store.
346+
*
337347
* @param mapId - The map identifier.
338348
* @param layerPath - The layer path.
339349
* @param mosaicRule - The mosaic rule to set.
@@ -347,8 +357,49 @@ export class LegendEventProcessor extends AbstractEventProcessor {
347357
}
348358
}
349359

360+
/**
361+
* Gets the active WMS style for a layer.
362+
*
363+
* @param mapId - The map identifier.
364+
* @param layerPath - The layer path.
365+
* @returns The active WMS style name.
366+
*/
367+
static getLayerWmsStyle(mapId: string, layerPath: string): string | undefined {
368+
return LegendEventProcessor.getLegendLayerInfo(mapId, layerPath)?.wmsStyle;
369+
}
370+
371+
/**
372+
* Sets the active WMS style for a layer.
373+
*
374+
* @param mapId - The map identifier.
375+
* @param layerPath - The layer path.
376+
* @param wmsStyleName - The WMS style name to set.
377+
*/
378+
static setLayerWmsStyle(mapId: string, layerPath: string, wmsStyleName: string | undefined): void {
379+
if (!wmsStyleName) return;
380+
MapEventProcessor.getMapViewerLayerAPI(mapId).setLayerWmsStyle(layerPath, wmsStyleName);
381+
}
382+
383+
/**
384+
* Updates the active WMS style for a layer in the store.
385+
*
386+
* @param mapId - The map identifier.
387+
* @param layerPath - The layer path.
388+
* @param wmsStyleName - The WMS style name to set.
389+
*/
390+
static setLayerWmsStyleInStore(mapId: string, layerPath: string, wmsStyleName: string | undefined): void {
391+
const layers = LegendEventProcessor.getLayerState(mapId).legendLayers;
392+
const layer = this.findLayerByPath(layers, layerPath);
393+
394+
if (layer) {
395+
layer.wmsStyle = wmsStyleName;
396+
this.getLayerState(mapId).setterActions.setLegendLayers(layers);
397+
}
398+
}
399+
350400
/**
351401
* Gets the raster function previews for the ESRI image layer.
402+
*
352403
* @param mapId - The map identifier.
353404
* @param layerPath - The layer path.
354405
* @returns The raster function previews.
@@ -360,8 +411,28 @@ export class LegendEventProcessor extends AbstractEventProcessor {
360411
return geoviewLayer.getRasterFunctionPreviews();
361412
}
362413

414+
/**
415+
* Retrieves the layer's available WMS styles.
416+
*
417+
* @param mapId - The unique identifier of the map instance.
418+
* @param layerPath - The path to the layer.
419+
* @returns The available WMS style names, or `undefined` if not available.
420+
*/
421+
static getLayerWmsStyles(mapId: string, layerPath: string): TypeMetadataWMSCapabilityLayerStyle[] | undefined {
422+
// Get the layer config
423+
const layerConfig = MapEventProcessor.getMapViewerLayerAPI(mapId).getLayerEntryConfigIfExists(layerPath);
424+
425+
// Check if it's a WMS layer config
426+
if (layerConfig && layerConfig instanceof OgcWmsLayerEntryConfig) {
427+
return layerConfig.getStylesMetadata();
428+
}
429+
430+
return undefined;
431+
}
432+
363433
/**
364434
* Gets the available settings for a layer.
435+
*
365436
* @param mapId - The map identifier.
366437
* @param layerPath - The layer path.
367438
* @returns Array of available setting types.
@@ -384,6 +455,12 @@ export class LegendEventProcessor extends AbstractEventProcessor {
384455
settings.push('mosaicRule');
385456
}
386457

458+
// Check if multiple WMS styles are available
459+
const styles = this.getLayerWmsStyles(mapId, layerPath);
460+
if (styles && styles.length > 1) {
461+
settings.push('wmsStyles');
462+
}
463+
387464
// Add other layer types with settings here
388465
return settings;
389466
}

packages/geoview-core/src/core/components/layers/right-panel/layer-settings/layer-settings-style.ts

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ export const getSxClasses = (theme: Theme): SxStyles => ({
1515
},
1616
},
1717

18-
rasterFunctionMenu: {
18+
// Shared styles for setting selector submenus (raster function, WMS style, etc.)
19+
settingSelectorMenu: {
1920
'& .MuiPaper-root': {
2021
padding: '8px',
2122
maxHeight: '400px',
22-
paddingRight: '16px', // Extra padding for scrollbar space
23+
paddingRight: '16px',
2324
// Custom scrollbar styling
2425
'&::-webkit-scrollbar': {
2526
width: '8px',
@@ -40,7 +41,7 @@ export const getSxClasses = (theme: Theme): SxStyles => ({
4041
},
4142
},
4243

43-
rasterFunctionMenuItem: {
44+
settingSelectorMenuItem: {
4445
border: '1px solid',
4546
borderColor: 'divider',
4647
borderRadius: 2,
@@ -53,7 +54,20 @@ export const getSxClasses = (theme: Theme): SxStyles => ({
5354
borderColor: 'primary.main',
5455
},
5556
},
56-
previewImageContainer: {
57+
58+
settingSelectorListItemText: {
59+
'& .MuiListItemText-primary': {
60+
fontWeight: 600,
61+
},
62+
},
63+
64+
settingSelectorPreviewIcon: {
65+
width: 100,
66+
height: 100,
67+
},
68+
69+
// ESRI Image Raster Function specific styles
70+
rasterFunctionPreviewImageContainer: {
5771
width: 100,
5872
height: 100,
5973
border: '2px solid',
@@ -65,19 +79,47 @@ export const getSxClasses = (theme: Theme): SxStyles => ({
6579
overflow: 'hidden',
6680
marginRight: '16px',
6781
},
68-
previewImage: {
82+
83+
rasterFunctionPreviewImage: {
6984
width: '100%',
7085
height: '100%',
7186
objectFit: 'cover',
7287
},
73-
previewIcon: {
88+
89+
// WMS Style specific styles
90+
wmsStyleMenuItem: {
91+
border: '1px solid',
92+
borderColor: 'divider',
93+
borderRadius: 2,
94+
margin: '4px 0',
95+
padding: '12px',
96+
alignItems: 'center',
97+
'&:hover': {
98+
borderColor: 'primary.main',
99+
},
100+
'&.Mui-selected': {
101+
borderColor: 'primary.main',
102+
},
103+
},
104+
105+
wmsStylePreviewImageContainer: {
74106
width: 100,
75-
height: 100,
107+
minHeight: 100,
108+
maxHeight: 200, // Cap maximum height to handle tall legend images
109+
border: '2px solid',
110+
borderColor: 'divider',
111+
borderRadius: 2,
112+
display: 'flex',
113+
alignItems: 'center',
114+
justifyContent: 'center',
115+
overflow: 'hidden',
116+
marginRight: '16px',
76117
},
77118

78-
rasterFunctionListItemText: {
79-
'& .MuiListItemText-primary': {
80-
fontWeight: 600,
81-
},
119+
wmsStylePreviewImage: {
120+
width: '100%',
121+
height: 'auto', // Preserve aspect ratio
122+
maxHeight: '200px',
123+
objectFit: 'contain', // Show full image without cropping
82124
},
83125
});

0 commit comments

Comments
 (0)