Skip to content

Commit

Permalink
Merge pull request #304 from fschmenger/layer_opacity_control
Browse files Browse the repository at this point in the history
Layer opacity control
  • Loading branch information
JakobMiksch committed Nov 3, 2022
2 parents 6f444a8 + b74def0 commit c8b3b2d
Show file tree
Hide file tree
Showing 15 changed files with 224 additions and 22 deletions.
2 changes: 2 additions & 0 deletions app-starter/static/app-conf-projected.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"selectable": true,
"hoverable": true,
"hoverAttribute": "naam",
"opacityControl": true,
"style": {
"strokeColor": "white",
"strokeWidth": 2,
Expand All @@ -111,6 +112,7 @@
"tileGridRef": "dutch_rd",
"isBaseLayer": false,
"visible": false,
"opacityControl": true,
"crossOrigin": "anonymous"
},
{
Expand Down
7 changes: 5 additions & 2 deletions app-starter/static/app-conf-sidebar.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@
"isBaseLayer": false,
"visible": false,
"displayInLayerList": true,
"legend": true
"legend": true,
"opacityControl": true
},
{
"type": "IMAGEWMS",
Expand All @@ -176,7 +177,8 @@
"attribution": "Kindly provided by @ahocevar",
"isBaseLayer": false,
"visible": false,
"displayInLayerList": true
"displayInLayerList": true,
"opacityControl": true
},
{
"type": "VECTORTILE",
Expand All @@ -185,6 +187,7 @@
"format": "MVT",
"visible": false,
"attribution": "Kindly provided by @ahocevar",
"opacityControl": true,
"style": {
"strokeColor": "gray",
"strokeWidth": 1,
Expand Down
7 changes: 5 additions & 2 deletions app-starter/static/app-conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@
"isBaseLayer": false,
"visible": false,
"displayInLayerList": true,
"legend": true
"legend": true,
"opacityControl": true
},
{
"type": "IMAGEWMS",
Expand All @@ -170,7 +171,8 @@
"attribution": "Kindly provided by @ahocevar",
"isBaseLayer": false,
"visible": false,
"displayInLayerList": true
"displayInLayerList": true,
"opacityControl": true
},
{
"type": "VECTORTILE",
Expand All @@ -179,6 +181,7 @@
"format": "MVT",
"attribution": "Kindly provided by @ahocevar",
"visible": false,
"opacityControl": true,
"style": {
"strokeColor": "gray",
"strokeWidth": 1,
Expand Down
1 change: 1 addition & 0 deletions docs/map-layer-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The following properties can be applied to all map layer types
| visible | Boolean value, whether the layer should be initially visible. Defaults to `true`. | `"visible": false` |
| extent | Array containing the bounding extent for layer rendering. The layer will not be rendered outside of this extent. Per default the extent of the layer is not constrained. | `"extent": [600584.4677702306, 5906357.431606389, 1864172.5237905537, 7388769.588491274]` |
| opacity | Numeric value ranging from 0 to 1 describing the opaqueness of the layer. Defaults to `1.0`. | `"opacity": 0.5` |
| opacityControl | Boolean value, whether a slider control to customize the layers opacity should appear in the LayerList. Defaults to `false`. | `"opacityControl": true`|
| zIndex | Numeric value specifying the stack order of layers. Layers will be ordered by z-index and then by order of declaration. Defaults to `-1` for background layers and `0` for all other layers. | `"zIndex": 2` |
| displayInLayerList | Boolean value, whether the layer should appear in the LayerList. Ignored if the layer is a background layer - see option `isBaseLayer` | `"displayInLayerList": true` |
| supportsPermalink | Boolean value, whether the layers state should be considered in permanent links - see also [permalink](wegue-configuration?id=permalink). Defaults to `true`. | `"supportsPermalink": true` |
Expand Down
1 change: 1 addition & 0 deletions docs/module-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Module identifier: `wgu-layerlist`
| Property | Meaning | Example |
|----------------------|:---------:|---------|
| showLegends | Flag to enable/disable rendering of layer legend images in the LayerList. Defaults to `true`. | `"showLegends": false` |
| showOpacityControls | Flag to enable/disable rendering of slider controls to customize the layers opacity. Defaults to `true`. | `"showOpacityControls": false` |

## MeasureTool

Expand Down
15 changes: 13 additions & 2 deletions docs/wegue-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -540,11 +540,14 @@ Example configurations can be found in the `app-starter/static` directory. Below
"attribution": "Kindly provided by @ahocevar",
"isBaseLayer": false,
"visible": false,
"displayInLayerList": true
"displayInLayerList": true,
"legend": true,
"opacityControl": true
},
{
"type": "IMAGEWMS",
"lid": "ahocevar-imagewms",
"ratio": 1.5,
"format": "image/png",
"layers": "ne:ne_10m_populated_places",
"url": "https://ahocevar.com/geoserver/wms",
Expand All @@ -553,14 +556,17 @@ Example configurations can be found in the `app-starter/static` directory. Below
"attribution": "Kindly provided by @ahocevar",
"isBaseLayer": false,
"visible": false,
"displayInLayerList": true
"displayInLayerList": true,
"opacityControl": true
},
{
"type": "VECTORTILE",
"lid": "ahocevar-vectortyle",
"url": "https://ahocevar.com/geoserver/gwc/service/tms/1.0.0/ne:ne_10m_admin_0_countries@EPSG%3A900913@pbf/{z}/{x}/{-y}.pbf",
"format": "MVT",
"attribution": "Kindly provided by @ahocevar",
"visible": false,
"opacityControl": true,
"style": {
"strokeColor": "gray",
"strokeWidth": 1,
Expand Down Expand Up @@ -662,6 +668,11 @@ Example configurations can be found in the `app-starter/static` directory. Below
},
"wgu-localeswitcher": {
"target": "toolbar"
},
"sample-module": {
"target": "toolbar",
"win": "floating",
"icon": "star"
}
}
}
Expand Down
12 changes: 4 additions & 8 deletions src/components/layerlist/LayerList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
:key="layer.get('lid')"
:layer="layer"
:mapView="map.getView()"
:showDetails="showDetails(layer)"
:showLegends="showLegends"
:showOpacityControls="showOpacityControls"
/>
</v-list>
</template>
Expand All @@ -22,7 +23,8 @@
},
mixins: [Mapable],
props: {
showLegends: { type: Boolean, required: true }
showLegends: { type: Boolean, required: true },
showOpacityControls: { type: Boolean, required: true }
},
data () {
return {
Expand All @@ -36,12 +38,6 @@
*/
onMapBound () {
this.layers = this.map.getLayers().getArray();
},
/**
* Returns true, if the layer item should show an extension slider with layer details.
**/
showDetails (layer) {
return this.showLegends && !!layer.get('legend');
}
},
computed: {
Expand Down
39 changes: 36 additions & 3 deletions src/components/layerlist/LayerListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,17 @@
{{ layer.get('name') }}
</v-list-item-title>
</template>
<v-list-item>
<v-list-item
v-if="showOpacityControl"
class="overflow-visible"
>
<wgu-layeropacitycontrol
:layer="layer"
/>
</v-list-item>
<v-list-item
v-if="showLegend"
>
<!-- Remarks:
The legend image item is wrapped by an v-if block to avoid unneccesary image
requests when the layer item is not expanded.
Expand Down Expand Up @@ -53,11 +63,13 @@

<script>
import LayerLegendImage from './LayerLegendImage'
import LayerOpacityControl from './LayerOpacityControl'
export default {
name: 'wgu-layerlistitem',
components: {
'wgu-layerlegendimage': LayerLegendImage
'wgu-layerlegendimage': LayerLegendImage,
'wgu-layeropacitycontrol': LayerOpacityControl
},
data () {
return {
Expand All @@ -67,7 +79,8 @@ export default {
props: {
layer: { type: Object, required: true },
mapView: { type: Object, required: true },
showDetails: { type: Boolean, required: true }
showLegends: { type: Boolean, required: true },
showOpacityControls: { type: Boolean, required: true }
},
methods: {
/**
Expand All @@ -76,6 +89,26 @@ export default {
onItemClick () {
this.layer.setVisible(!this.layer.getVisible());
}
},
computed: {
/**
* Returns true, if the layer item should show an extension slider with layer details.
*/
showDetails () {
return this.showLegend || this.showOpacityControl;
},
/**
* Returns true, if the layer item should show a legend image.
*/
showLegend () {
return this.showLegends && !!this.layer.get('legend');
},
/**
* Returns true, if the layer item should show an opacity control.
*/
showOpacityControl () {
return this.showOpacityControls && !!this.layer.get('opacityControl');
}
}
};
</script>
4 changes: 3 additions & 1 deletion src/components/layerlist/LayerListWin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
>
<wgu-layerlist
:showLegends="showLegends"
:showOpacityControls="showOpacityControls"
/>
</wgu-module-card>

Expand All @@ -24,7 +25,8 @@
},
props: {
icon: { type: String, required: false, default: 'layers' },
showLegends: { type: Boolean, required: false, default: true }
showLegends: { type: Boolean, required: false, default: true },
showOpacityControls: { type: Boolean, required: false, default: true }
}
}
</script>
31 changes: 31 additions & 0 deletions src/components/layerlist/LayerOpacityControl.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<v-slider
color="secondary"
prepend-icon="opacity"
:value="layer.getOpacity()"
min="0"
max="1"
step="0.01"
thumb-label
hide-details
@input="onOpacitySliderInput"
>
</v-slider>
</template>

<script>
export default {
name: 'wgu-layeropacitycontrol',
props: {
layer: { type: Object, required: true }
},
methods: {
/**
* Handler for input on the opacity slider, updates the layer`s opacity.
*/
onOpacitySliderInput (value) {
this.layer.setOpacity(value);
}
}
}
</script>
1 change: 1 addition & 0 deletions src/factory/Layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export const LayerFactory = {
extent: lConf.extent,
visible: lConf.visible,
opacity: lConf.opacity,
opacityControl: lConf.opacityControl,
zIndex: lConf.zIndex,
confName: lConf.name,
confAttributions: lConf.attributions,
Expand Down
3 changes: 2 additions & 1 deletion test/unit/specs/components/layerlist/LayerList.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';

const moduleProps = {
'showLegends': true
'showLegends': true,
'showOpacityControls': true
};

describe('layerlist/LayerList.vue', () => {
Expand Down
63 changes: 60 additions & 3 deletions test/unit/specs/components/layerlist/LayerListItem.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const view = new View({
const moduleProps = {
'mapView': view,
'layer': osmLayer,
'showDetails': true
'showLegends': true,
'showOpacityControls': true
};

describe('layerlist/LayerListItem.vue', () => {
Expand All @@ -38,7 +39,8 @@ describe('layerlist/LayerListItem.vue', () => {
it('has correct props', () => {
expect(vm.mapView).to.equal(view);
expect(vm.layer).to.equal(osmLayer);
expect(vm.showDetails).to.equal(true)
expect(vm.showLegends).to.equal(true);
expect(vm.showOpacityControls).to.equal(true);
});

afterEach(() => {
Expand Down Expand Up @@ -81,8 +83,63 @@ describe('layerlist/LayerListItem.vue', () => {

it('onItemClick toggles layer visibility', () => {
expect(osmLayer.getVisible()).to.equal(true);
vm.onItemClick(osmLayer);
vm.onItemClick();
expect(osmLayer.getVisible()).to.equal(false);
});
});

describe('computed properties', () => {
let comp;
let vm;
beforeEach(() => {
comp = shallowMount(LayerListItem, {
propsData: moduleProps
});
vm = comp.vm;
});

it('has correct showLegend property for layer', () => {
expect(vm.showLegend).to.equal(false);

const osmLayer2 = new TileLayer({
source: new OSM(),
legend: true
});
comp.setProps({ layer: osmLayer2 });
expect(vm.showLegend).to.equal(true);
});

it('has correct showOpacityControl property for layer', () => {
expect(vm.showOpacityControl).to.equal(false);

const osmLayer2 = new TileLayer({
source: new OSM(),
opacityControl: true
});
comp.setProps({ layer: osmLayer2 });
expect(vm.showOpacityControl).to.equal(true);
});

it('has correct showDetails property for layer', () => {
expect(vm.showDetails).to.equal(false);

const osmLayer2 = new TileLayer({
source: new OSM(),
legend: true
});
comp.setProps({ layer: osmLayer2 });
expect(vm.showDetails).to.equal(true);

const osmLayer3 = new TileLayer({
source: new OSM(),
opacityControl: true
});
comp.setProps({ layer: osmLayer3 });
expect(vm.showDetails).to.equal(true);
});

afterEach(() => {
comp.destroy();
});
});
});
Loading

0 comments on commit c8b3b2d

Please sign in to comment.