Skip to content

Commit

Permalink
Merge pull request #303 from fschmenger/layer_legends
Browse files Browse the repository at this point in the history
Layer legends
  • Loading branch information
fschmenger committed Oct 31, 2022
2 parents 76fa530 + 4d9132e commit 6f444a8
Show file tree
Hide file tree
Showing 14 changed files with 547 additions and 56 deletions.
3 changes: 2 additions & 1 deletion app-starter/static/app-conf-sidebar.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@
"attribution": "Kindly provided by @ahocevar",
"isBaseLayer": false,
"visible": false,
"displayInLayerList": true
"displayInLayerList": true,
"legend": true
},
{
"type": "IMAGEWMS",
Expand Down
3 changes: 2 additions & 1 deletion app-starter/static/app-conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@
"attribution": "Kindly provided by @ahocevar",
"isBaseLayer": false,
"visible": false,
"displayInLayerList": true
"displayInLayerList": true,
"legend": true
},
{
"type": "IMAGEWMS",
Expand Down
3 changes: 3 additions & 0 deletions docs/map-layer-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ The following properties can be applied to all map layer types
| 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` |
| attributions | Text or HTML string to be displayed as source attribution in the map. This setting will override the layer attributions declared in the language packs. | `"attributions": "<a href='https://www.pdok.nl' target='_blank'>PDOK</a> by Dutch Kadaster",` |
| previewImage | URL to a preview image for layers to be displayed in the background layer selection control. This option has no effect if the layer is not a background layer - see option `isBaseLayer` | `"previewImage": "static/icon/my-layer-preview.png"` |
| legend | Boolean value, whether a layer legend image should be displayed in the LayerList. Defaults to `false`. | `"legend": true`|
| legendUrl | URL to a legend image. This value is required to produce a legend, if the layer is not a WMS layer. The URL may contain format placeholders corresponding to the parameters `language`, `scale` or any of the additional options given among `legendOptions`. A placeholder is delimited by `{{` and `}}` – i.e. `{{VAR_NAME}}`. | `"legendUrl": "static/icon/my-layer-legend-{{LANGUAGE}}.png"`
| legendOptions | An object, containing additional parameters to request the legend image. Supported options may be vendor specific, e.g. see [GeoServer Docs](https://docs.geoserver.org/latest/en/user/services/wms/get_legend_graphic/index.html) for the options supported for WMS layers in GeoServer. | `"legendOptions": {"transparent": true, "width": 14 }`



Expand Down
4 changes: 3 additions & 1 deletion docs/module-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ Module identifier: `wgu-infoclick`

Module identifier: `wgu-layerlist`

No additional config options besides the general ones.
| Property | Meaning | Example |
|----------------------|:---------:|---------|
| showLegends | Flag to enable/disable rendering of layer legend images in the LayerList. Defaults to `true`. | `"showLegends": false` |

## MeasureTool

Expand Down
20 changes: 20 additions & 0 deletions docs/wegue-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ This describes the Wegue application configuration, which is modelled as JSON do
| tileGridDefs | Array of tile grid definition objects | See [tileGridDefs](wegue-configuration?id=tilegriddefs) |
| viewAnimation | Configuration object for view animations | See [viewAnimation](wegue-configuration?id=viewAnimation) |
| sidebar | Configuration object for the application sidebar. | See [sidebar](wegue-configuration?id=sidebar) |
| legend | Configuration object containing application wide parameters for layer legends. | See [legend](wegue-configuration?id=legend) |

### colorTheme

Expand Down Expand Up @@ -246,6 +247,25 @@ Below is an example for such a configuration object:
}
```
### legend
Wegue supports rendering of layer legend images, which will be displayed in the [LayerList module](module-configuration?id=LayerList). The optional property `legend` in the main Wegue configuration provides sensible defaults to legend request parameters for all layers in the application. This can be useful e.g. for parameters like fonts, font-sizes and other common options, which you want to share between all legends.
Supported options may be vendor specific, e.g. see [GeoServer Docs](https://docs.geoserver.org/latest/en/user/services/wms/get_legend_graphic/index.html) for the options supported for WMS layers in GeoServer.
Example:
```json
"legend": {
"transparent": true,
"width": 14,
"height": 16,
}
```

Alternatively you can specify legend request parameters on a per layer basis, by assigning a layers `legendOptions` attribute - see [mapLayers](layer-configuration?id=General).
Settings for the individual layers are merged with the application wide option, while the specific layer setting takes precedence.

For information on how to enable and customize legends for specific layers, see the documentation of [mapLayers](layer-configuration?id=General).

### viewAnimation

Expand Down
62 changes: 62 additions & 0 deletions src/components/layerlist/LayerLegendImage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<!-- Remarks:
As we need none of the responsive functionality of v-img, we use a simple
HTML img to stop the component from flickering when the image is re-requested.
-->
<img v-if="legendURL" :src="legendURL">
</template>

<script>
import LayerLegend from '../../util/LayerLegend';
/**
* Module for one legend element.
*/
export default {
name: 'wgu-layerlegendimage',
props: {
mapView: { type: Object, required: true },
layer: { type: Object, required: true }
},
data () {
return {
resolution: this.mapView.getResolution(),
viewResolutionChanged: undefined
}
},
/**
* Register for an event to update the legend on resolution change.
*/
created () {
const viewResolutionChanged = function (event) {
this.resolution = event.target.getResolution();
}.bind(this);
this.mapView.on('change:resolution', viewResolutionChanged);
this.viewResolutionChanged = viewResolutionChanged;
},
/**
* Unregister the event fired on resolution change.
*/
destroyed () {
if (this.viewResolutionChanged) {
this.mapView.un('change:resolution', this.viewResolutionChanged);
}
},
computed: {
/**
* Returns a URL to the layers legend image.
*/
legendURL () {
const options = {
language: this.$i18n.locale,
...this.layer.get('legendOptions')
};
return LayerLegend.getUrl(
this.layer, this.resolution, options, this.layer.get('legendUrl'));
}
}
}
</script>
45 changes: 18 additions & 27 deletions src/components/layerlist/LayerList.vue
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
<template>

<v-list>
<v-list-item class="wgu-layerlist-item"
v-for="layer in displayedLayers"
:key="layer.lid"
@click="onItemClick(layer)">
<v-list-item-action>
<v-checkbox
color="secondary"
hide-details
:input-value="layer.getVisible()"
/>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
{{ layer.get('name') }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>

<v-list expand>
<wgu-layerlistitem
v-for="layer in displayedLayers"
:key="layer.get('lid')"
:layer="layer"
:mapView="map.getView()"
:showDetails="showDetails(layer)"
/>
</v-list>
</template>

<script>
import { Mapable } from '../../mixins/Mapable';
import LayerListItem from './LayerListItem'
export default {
name: 'wgu-layerlist',
components: {
'wgu-layerlistitem': LayerListItem
},
mixins: [Mapable],
props: {
showLegends: { type: Boolean, required: true }
},
data () {
return {
Expand All @@ -44,13 +38,10 @@
this.layers = this.map.getLayers().getArray();
},
/**
* Handler for click on item in layer list:
* Toggles the corresponding layer visibility.
*
* @param {Object} layer Layer object
*/
onItemClick (layer) {
layer.setVisible(!layer.getVisible());
* 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
81 changes: 81 additions & 0 deletions src/components/layerlist/LayerListItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<template>
<!-- Show layer details -->
<v-list-group
v-if="showDetails"
v-model="open"
class="text--primary"
>
<template v-slot:activator>
<v-list-item-action>
<v-checkbox
color="secondary"
hide-details
:input-value="layer.getVisible()"
@click.capture.stop="onItemClick()"
/>
</v-list-item-action>
<v-list-item-title>
{{ layer.get('name') }}
</v-list-item-title>
</template>
<v-list-item>
<!-- Remarks:
The legend image item is wrapped by an v-if block to avoid unneccesary image
requests when the layer item is not expanded.
-->
<wgu-layerlegendimage v-if="open"
:layer="layer"
:mapView="mapView"
/>
</v-list-item>
</v-list-group>

<!-- Simple layer entry -->
<v-list-item
v-else
class="wgu-layerlist-item"
>
<v-list-item-action>
<v-checkbox
color="secondary"
hide-details
:input-value="layer.getVisible()"
@click.capture.stop="onItemClick(layer)"
/>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
{{ layer.get('name') }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>

<script>
import LayerLegendImage from './LayerLegendImage'
export default {
name: 'wgu-layerlistitem',
components: {
'wgu-layerlegendimage': LayerLegendImage
},
data () {
return {
open: false
}
},
props: {
layer: { type: Object, required: true },
mapView: { type: Object, required: true },
showDetails: { type: Boolean, required: true }
},
methods: {
/**
* Handler for click on layer item, toggles the layer`s visibility.
*/
onItemClick () {
this.layer.setVisible(!this.layer.getVisible());
}
}
};
</script>
7 changes: 5 additions & 2 deletions src/components/layerlist/LayerListWin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
class="wgu-layerlist"
:icon="icon"
>
<wgu-layerlist />
<wgu-layerlist
:showLegends="showLegends"
/>
</wgu-module-card>

</template>
Expand All @@ -21,7 +23,8 @@
'wgu-layerlist': LayerList
},
props: {
icon: { type: String, required: false, default: 'layers' }
icon: { type: String, required: false, default: 'layers' },
showLegends: { type: Boolean, required: false, default: true }
}
}
</script>
5 changes: 4 additions & 1 deletion src/factory/Layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,10 @@ export const LayerFactory = {
opacity: lConf.opacity,
zIndex: lConf.zIndex,
confName: lConf.name,
confAttributions: lConf.attributions
confAttributions: lConf.attributions,
legend: lConf.legend,
legendUrl: lConf.legendUrl,
legendOptions: lConf.legendOptions
};
},

Expand Down
Loading

0 comments on commit 6f444a8

Please sign in to comment.