Skip to content

Layer opacity control #304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Nov 3, 2022
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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this do?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can see this has been added in eef26a6. Quoted from map-layer-configuration.md:
Ratio 1 means image requests are the size of the map viewport, 2 means twice the width and height of the map viewport. Must be 1 or higher.
The whole purpose here is to sync the documentation example to the current app-conf.json, as I added new properties. Since this hasn`t been done for quite some time, some unrelated changes to this PR will pop up in the documentation file.

"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.
**/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
**/
*/

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by b74def0.

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.
**/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
**/
*/

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by b74def0.

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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
expect(vm.showOpacityControls).to.equal(true)
expect(vm.showOpacityControls).to.equal(true);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by b74def0.

});

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