LayerChooser: Support multiple service IDs per entry
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 50
- Forks
- 8
- Avg merge
- 18h 24m
- Merged PRs (30d)
- 11
Description
Description
Currently, each entry in the LayerChooser maps to exactly one (technical) service, because LayerConfiguration in src/core/types/layer.ts references a single id: string.
The goal of this feature is to let two (or more) services appear as a single entry in the LayerChooser and be toggled on/off together. To achieve this, the id parameter should accept string[] in addition to string. When an array is given, the entry is rendered once in the UI (name, legend, availability), while internally the visibility of all referenced OpenLayers layers is controlled in sync.
Agreed behavior for this feature:
- Entry identity (internal key): Use a synthetic key derived from joining the IDs with the separator
'|'(which should not occur in a service id, avoiding collision with the comma-separated WMSLAYERSparam). - Zoom availability: A merged entry is considered available if at least one of its layers is available at the current zoom level.
- Legends: If multiple layers of a merged entry provide a legend image, the images are stacked vertically in the legend view.
Affected areas
| File | What needs to change |
|---|---|
src/core/types/layer.ts |
Widen LayerConfiguration.id from string to string | string[]; update TSDoc and document the merged-entry behavior |
src/plugins/layerChooser/utils/getBackgroundsAndMasks.ts |
Resolve rawLayerList.getLayerWhere({ id }) for each ID in the array; log per missing sub-ID |
src/plugins/layerChooser/store.ts |
Update activeBackgroundId/activeMaskIds, disabledBackgrounds/disabledMasks, visibleMaskIds, masksSeparatedByType, the watch handlers and setActiveMaskIdsVisibility to match every sub-ID against layer.get('id') while keying entries via the synthetic key |
src/plugins/layerChooser/store.ts (updateActiveAndAvailableLayersByZoom, areLayersActive) |
Treat a merged entry as available if at least one sub-layer is available at the current zoom |
src/plugins/layerChooser/utils/areLayersActive.ts |
Support entries with multiple IDs when evaluating zoom/availability |
src/plugins/layerChooser/utils/prepareLegends.ts |
Collect a legend URL per sub-ID so a merged entry can hold multiple legend images |
src/plugins/layerChooser/types.ts |
Extend LayerLegend to carry multiple images (e.g. url: string → list of { name, url }) for stacked rendering |
src/plugins/layerChooser/components/LayerLegend.ce.vue |
Render multiple legend images stacked vertically |
src/plugins/layerChooser/components/LayerSelection.ce.vue |
Use the synthetic key for :key, v-model values, disabledMasks[...], legend/options button conditions; hide the options button for merged entries |
src/core/utils/checkServiceAvailability.ts |
Iterate the availability check over all sub-IDs of a merged entry |
src/core/utils/map/setupStyling.ts |
Verify the register.find((l) => l.id === layer.id) lookup handles merged entries (an array ID resolves to multiple raw layers) or explicitly excludes them |
Recommendation on entry identity
Introduce a central helper (e.g. normalizeLayerIds(id: string | string[]): string[]) plus a getLayerKey(id) that joins the IDs with '|'. This key is used wherever the entry must be uniquely referenced in the store (activeMaskIds, activeBackgroundId, disabledMasks, openedLegendId, etc.), while the individual IDs are used for all OpenLayers matching via layer.get('id'). Keeping normalization in one place avoids scattering Array.isArray checks across the codebase.
Out of scope
options.layers(WMS sub-layer selection) for merged entries: Not supported whenidis an array. The options button is hidden for such entries; single-ID entries keep the existing behavior.- Markers on merged entries: The markers feature (
configuration.markers,src/core/utils/map/setupMarkers.ts) only supports single-ID layers. A mergedLayerChooserentry (id: string[]) cannot be used as a marker layer;MarkerLayer.idremains a singlestring. - GFI / Filter / Attributions on merged entries: Feature queries via combined entries (
src/plugins/filter,src/plugins/attributions, GFI) are not part of this issue. - Mixing layer types in one entry: Combining
backgroundandmaskor other ids in a single entry is excluded; all sub-IDs share the sametype. - Automatic merging by heuristic: No automatic grouping; merging is only done explicitly via
id: string[].
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/core/types/layer.ts and trace LayerChooser state through src/plugins/layerChooser/store.ts, using the listed utility and component files as the implementation map. Define the shared identity and ID normalization behavior, then verify merged entries render once, synchronize all referenced layers, report availability correctly, stack legends, and preserve the stated out-of-scope behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100