Skip to content

Commit

Permalink
BGDIINF_SB-3105 : adding layer group concept, with z-index calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
pakb committed Sep 8, 2023
1 parent deb235a commit 972a11b
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 2 deletions.
23 changes: 23 additions & 0 deletions src/api/layers/ExternalGroupOfLayers.class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import ExternalLayer from '@/api/layers/ExternalLayer.class'
import LayerTypes from '@/api/layers/LayerTypes.enum'

/**
* Description of a group of layers, that could be added altogether or separately, that stems from a getCapabilities XML parsing. (see https://www.mediamaps.ch/ogc/schemas-xsdoc/sld/1.2/capabilities_1_3_0_xsd.html#Layer)
*
* If the group of layer is added to the map, all layers being part of it should be added under this group's name "banner"
*/
export default class ExternalGroupOfLayers extends ExternalLayer {
/**
* @param {String} name Name of this layer to be shown to the user
* @param {String} hostname getCapabilities URL host name, so that it can be used in the ID generation
* @param {ExternalLayer[]} layers Description of the layers being part of this group (they will all be displayed at the same time, in contrast to an aggregate layer)
*/
constructor(name, hostname, ...layers) {
super(name, LayerTypes.GROUP, `${hostname}:${name.replaceAll(' ', '_')}`, null, 1, true)
this.layers = [...layers]
}

getID() {
return this.externalLayerId
}
}
1 change: 1 addition & 0 deletions src/api/layers/LayerTypes.enum.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ const LayerTypes = {
AGGREGATE: 'aggregate',
KML: 'kml',
VECTOR: 'vector',
GROUP: 'group',
}
export default LayerTypes
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@
:style-url="layerConfig.styleUrl"
:z-index="zIndex"
/>
<div v-if="layerConfig.type === LayerTypes.GROUP">
<open-layers-internal-layer
v-for="(layer, index) in layerConfig.layers"
:key="`${layer.getID()}-${index}`"
:layer-config="layer"
:z-index="zIndex + index"
/>
</div>
<!--
Aggregate layers are some kind of a edge case where two or more layers are joint together but only one of them
is visible depending on the map resolution.
Expand Down
5 changes: 3 additions & 2 deletions src/modules/map/components/openlayers/OpenLayersMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@
/>
<!-- Adding all other layers -->
<OpenLayersInternalLayer
v-for="(layer, index) in visibleLayers"
v-for="layer in visibleLayers"
:key="layer.getID()"
:layer-config="layer"
:preview-year="previewYear"
:current-map-resolution="resolution"
:z-index="index + startingZIndexForVisibleLayers"
:z-index="zIndexForVisibleLayer(layer)"
/>
<!-- Adding pinned location -->
<OpenLayersMarker
Expand Down Expand Up @@ -204,6 +204,7 @@ export default {
'isCurrentlyDrawing',
'backgroundLayers',
'isDesktopMode',
'zIndexForVisibleLayer',
]),
crossHairStyle() {
if (this.crossHair) {
Expand Down
51 changes: 51 additions & 0 deletions src/store/modules/__tests__/layers.store.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import AbstractLayer from '@/api/layers/AbstractLayer.class'
import ExternalGroupOfLayers from '@/api/layers/ExternalGroupOfLayers.class'
import ExternalWMTSLayer from '@/api/layers/ExternalWMTSLayer.class'
import GeoAdminWMSLayer from '@/api/layers/GeoAdminWMSLayer.class'
import GeoAdminWMTSLayer from '@/api/layers/GeoAdminWMTSLayer.class'
import LayerTimeConfig from '@/api/layers/LayerTimeConfig.class'
Expand Down Expand Up @@ -123,3 +125,52 @@ describe('Visible layers are filtered correctly by the store', () => {
expect(getVisibleLayers()).to.be.an('Array').empty
})
})

describe('Layer z-index are calculated correctly in the store', () => {
const getZIndex = (layer) => store.getters.zIndexForVisibleLayer(layer)

beforeEach(async () => {
await resetStore()
await store.dispatch('setLayerConfig', [bgLayer, firstLayer, secondLayer])
// setting up the background layer
await store.dispatch('setBackground', bgLayer)
})

it('gives a z-index of -1 if the given layer is not valid', () => {
expect(getZIndex(null)).to.eq(-1)
expect(getZIndex(undefined)).to.eq(-1)
expect(getZIndex({})).to.eq(-1)
expect(getZIndex('')).to.eq(-1)
expect(getZIndex(0)).to.eq(-1)
expect(getZIndex(true)).to.eq(-1)
})

it('counts the BG layer', async () => {
await store.dispatch('addLayer', firstLayer)
expect(getZIndex(firstLayer)).to.eq(1) // BG layer takes the 0 spot
})

it('counts two non group layer correctly', async () => {
await store.dispatch('addLayer', firstLayer)
await store.dispatch('addLayer', secondLayer)
expect(getZIndex(firstLayer)).to.eq(1)
expect(getZIndex(secondLayer)).to.eq(2)
})

it('counts a group layers correctly', async () => {
const groupLayer = new ExternalGroupOfLayers(
'group',
'group',
new ExternalWMTSLayer('', 1.0, true, '...', 'layer1', []),
new ExternalWMTSLayer('', 1.0, true, '...', 'layer2', []),
new ExternalWMTSLayer('', 1.0, true, '...', 'layer3', []),
new ExternalWMTSLayer('', 1.0, true, '...', 'layer4', [])
)
await store.dispatch('addLayer', firstLayer)
await store.dispatch('addLayer', groupLayer)
await store.dispatch('addLayer', secondLayer)
expect(getZIndex(firstLayer)).to.eq(1)
expect(getZIndex(groupLayer)).to.eq(2)
expect(getZIndex(secondLayer)).to.eq(6)
})
})
39 changes: 39 additions & 0 deletions src/store/modules/layers.store.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import AbstractLayer from '@/api/layers/AbstractLayer.class'
import ExternalGroupOfLayers from '@/api/layers/ExternalGroupOfLayers.class'
import LayerTypes from '@/api/layers/LayerTypes.enum'
import { ActiveLayerConfig } from '@/utils/layerUtils'
import log from '@/utils/logging'
Expand Down Expand Up @@ -121,6 +122,44 @@ const getters = {
const layer = state.activeLayers.find((layer) => layer.getID() === layerId)
return layer?.isExternal || (layer?.type === LayerTypes.KML && !layer?.adminId)
},
/**
* Returns the z-index of a visible layer, taking into account the background layer(s) and/or
* if one of them is a group of layer (and thus all sub-layers are counted in the index)
*
* If the layer is not part of the visible layers (or is null or invalid), this will return -1 as a result
*
* @param {AbstractLayer} layerIdOrObject
* @returns {Number}
*/
zIndexForVisibleLayer: (state, getters) => (layerIdOrObject) => {
let lookupId
if (layerIdOrObject instanceof AbstractLayer) {
lookupId = layerIdOrObject.getID()
} else {
lookupId = layerIdOrObject
}
const matchingLayer = getters.visibleLayers.find((layer) => layer.getID() === lookupId)
if (!matchingLayer) {
return -1
}
// we start by counting the background layer
let bgZIndex = state.currentBackgroundLayer ? 1 : 0
// we now count layers, checking if there are sub-layers (if the layer is a group of layer)
return (
getters.visibleLayers
// only keeping visible layer below the one that we want the z-index of
.slice(0, getters.visibleLayers.indexOf(matchingLayer))
// transforming layers into "z-indexes" by counting layers for groups, or 1 for normal layers
.map((layer) => {
if (layer instanceof ExternalGroupOfLayers) {
return layer.layers.length
}
return 1
})
// sum of all "z-index", and setting the initial value to the background's z-index
.reduce((a, b) => a + b, bgZIndex)
)
},
}

const actions = {
Expand Down

0 comments on commit 972a11b

Please sign in to comment.