Skip to content

Commit 3bd2453

Browse files
committed
Add LegendPrint plugin
1 parent b13f163 commit 3bd2453

File tree

6 files changed

+133
-1
lines changed

6 files changed

+133
-1
lines changed

js/appConfig.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import MapComparePlugin from 'qwc2/plugins/MapCompare';
2727
import MapCopyrightPlugin from 'qwc2/plugins/MapCopyright';
2828
import MapExportPlugin from 'qwc2/plugins/MapExport';
2929
import MapInfoTooltipPlugin from 'qwc2/plugins/MapInfoTooltip';
30+
import MapLegendPlugin from 'qwc2/plugins/MapLegend';
3031
import MapTipPlugin from 'qwc2/plugins/MapTip';
3132
import MeasurePlugin from 'qwc2/plugins/Measure';
3233
import NewsPopupPlugin from 'qwc2/plugins/NewsPopup';
@@ -51,6 +52,7 @@ import {renderHelp} from './Help';
5152
import CCCEditSupport from './plugins/CCCEditSupport';
5253
import {CCCInterfacePlugin, CCCAttributeCalculator} from './plugins/CCCInterface';
5354
import LandRegisterExtractPlugin from './plugins/LandRegisterExtract';
55+
import LegendPrintPlugin from './plugins/LegendPrint';
5456
import PlotOwnerInfo from './plugins/PlotOwnerInfo';
5557
import SoBottomBarPlugin from './plugins/SoBottomBar';
5658
import SoTopBarPlugin from './plugins/SoTopBar';
@@ -104,11 +106,13 @@ export default {
104106
MapComparePlugin: MapComparePlugin,
105107
HeightProfilePlugin: HeightProfilePlugin,
106108
MapInfoTooltipPlugin: MapInfoTooltipPlugin(),
109+
MapLegendPlugin: MapLegendPlugin,
107110
AuthenticationPlugin: AuthenticationPlugin,
108111
PlotInfoToolPlugin: PlotInfoToolPlugin,
109112
LandRegisterExtractPlugin: LandRegisterExtractPlugin,
110113
CCCInterfacePlugin: CCCInterfacePlugin,
111-
LoginUserPlugin: LoginUserPlugin
114+
LoginUserPlugin: LoginUserPlugin,
115+
LegendPrintPlugin: LegendPrintPlugin
112116
},
113117
cfg: {
114118
IdentifyPlugin: {

js/plugins/LegendPrint.jsx

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
* Copyright 2025 Sourcepole AG
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
import React from 'react';
10+
import {connect} from 'react-redux';
11+
12+
import PropTypes from 'prop-types';
13+
import {setCurrentTask} from 'qwc2/actions/task';
14+
import ResizeableWindow from 'qwc2/components/ResizeableWindow';
15+
import LayerUtils from 'qwc2/utils/LayerUtils';
16+
import LocaleUtils from 'qwc2/utils/LocaleUtils';
17+
import MapUtils from 'qwc2/utils/MapUtils';
18+
import MiscUtils from 'qwc2/utils/MiscUtils';
19+
20+
21+
class LegendPrint extends React.Component {
22+
static propTypes = {
23+
/** Whether to display a BBOX dependent legend. Can be `true|false|"theme"`, latter means only for theme layers. */
24+
bboxDependentLegend: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
25+
enabled: PropTypes.bool,
26+
/** Additional parameters to pass to the GetLegendGraphics request. */
27+
extraLegendParameters: PropTypes.string,
28+
layers: PropTypes.array,
29+
map: PropTypes.object,
30+
mapScale: PropTypes.number,
31+
/** Whether to display a scale dependent legend. Can be `true|false|"theme"`, latter means only for theme layers. */
32+
scaleDependentLegend: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
33+
setCurrentTask: PropTypes.func,
34+
/** Template location for the legend print functionality */
35+
templatePath: PropTypes.string
36+
};
37+
static defaultProps = {
38+
templatePath: ":/templates/legendprint.html"
39+
};
40+
render() {
41+
if (!this.props.enabled) {
42+
return null;
43+
}
44+
const setLegendPrintContents = (el) => {
45+
if (!el) {
46+
return;
47+
}
48+
el.addEventListener('load', () => {
49+
const container = el.contentWindow.document.getElementById("legendcontainer");
50+
if (container) {
51+
let body = '<p id="legendcontainerbody">';
52+
body += this.props.layers.map(layer => {
53+
if (!layer.visibility) {
54+
return "";
55+
} else if (layer.legendUrl) {
56+
return this.printLayerLegend(layer, layer);
57+
} else if (layer.color) {
58+
return '<div class="legend-entry"><span style="display: inline-block; width: 1em; height: 1em; box-shadow: inset 0 0 0 1000px ' + layer.color + '; margin: 0.25em; border: 1px solid black;">&nbsp;</span>' + (layer.title || layer.name) + '</div>';
59+
} else {
60+
return "";
61+
}
62+
}).join("");
63+
body += "</p>";
64+
container.innerHTML = body;
65+
} else {
66+
this.legendPrintWindow.document.body.innerHTML = "Broken template. An element with id=legendcontainer must exist.";
67+
}
68+
});
69+
};
70+
const printLegend = (ev) => {
71+
ev.target.parentElement.parentElement.getElementsByTagName('iframe')[0].contentWindow.print();
72+
};
73+
74+
return (
75+
<ResizeableWindow icon="print" initialHeight={0.75 * window.innerHeight}
76+
initialWidth={0.5 * window.innerWidth}
77+
onClose={() => this.props.setCurrentTask(null)}
78+
title={LocaleUtils.tr("layertree.printlegend")}
79+
>
80+
<div className="layertree-legend-print-body" role="body">
81+
<iframe ref={setLegendPrintContents} src={MiscUtils.resolveAssetsPath(this.props.templatePath)} />
82+
<div className="layertree-legend-print-body-buttonbar">
83+
<button onClick={printLegend}>{LocaleUtils.tr("layertree.printlegend")}</button>
84+
</div>
85+
</div>
86+
</ResizeableWindow>
87+
);
88+
}
89+
printLayerLegend = (layer, sublayer) => {
90+
let body = "";
91+
if (sublayer.sublayers) {
92+
if (sublayer.visibility) {
93+
body = '<div class="legend-group">' +
94+
'<h3 class="legend-group-title">' + (sublayer.title || sublayer.name) + '</h3>' +
95+
'<div class="legend-group-body">' +
96+
sublayer.sublayers.map(subsublayer => this.printLayerLegend(layer, subsublayer)).join("\n") +
97+
'</div>' +
98+
'</div>';
99+
}
100+
} else {
101+
if (sublayer.visibility && LayerUtils.layerScaleInRange(sublayer, this.props.mapScale)) {
102+
const request = LayerUtils.getLegendUrl(layer, {name: sublayer.name}, this.props.mapScale, this.props.map, this.props.bboxDependentLegend, this.props.scaleDependentLegend, this.props.extraLegendParameters);
103+
body = request ? '<div class="legend-entry"><img src="' + request + '" /></div>' : "";
104+
}
105+
}
106+
return body;
107+
};
108+
}
109+
110+
export default connect(state => ({
111+
enabled: state.task.id === "LegendPrint",
112+
layers: state.layers.flat,
113+
map: state.map,
114+
mapScale: MapUtils.computeForZoom(state.map.scales, state.map.zoom)
115+
}), {
116+
setCurrentTask: setCurrentTask
117+
})(LegendPrint);

static/config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
{"key": "RasterExport", "icon": "rasterexport"}
9494
]},
9595
{"key": "Print", "icon": "print"},
96+
{"key": "LegendPrint", "icon": "print"},
9697
{"key": "LandRegisterExtract", "icon": "print"},
9798
{"key": "Help", "icon": "info"},
9899
{"key": "Login", "icon": "login"}
@@ -202,6 +203,9 @@
202203
{
203204
"name": "Authentication"
204205
},
206+
{
207+
"name": "LegendPrint"
208+
},
205209
{
206210
"name": "LandRegisterExtract"
207211
},
@@ -310,6 +314,7 @@
310314
{"key": "RasterExport", "icon": "rasterexport"}
311315
]},
312316
{"key": "Print", "icon": "print"},
317+
{"key": "LegendPrint", "icon": "print"},
313318
{"key": "LandRegisterExtract", "icon": "print"},
314319
{"key": "Help", "icon": "info"},
315320
{"key": "Login", "icon": "login"}
@@ -435,6 +440,9 @@
435440
{
436441
"name": "Authentication"
437442
},
443+
{
444+
"name": "LegendPrint"
445+
},
438446
{
439447
"name": "LandRegisterExtract"
440448
},

static/translations/de-CH.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"appmenu": {
55
"items": {
66
"LandRegisterExtract": "Auszug Plan für das Grundbuch",
7+
"LegendPrint": "Legende drucken",
78
"Bookmark": "Lesezeichen",
89
"Compare3D": "Vergleichen",
910
"DateTime3D": "Datum und Zeit",

static/translations/en-US.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"appmenu": {
55
"items": {
66
"LandRegisterExtract": "Land Register Map Extract",
7+
"LegendPrint": "Print legend",
78
"Bookmark": "Bookmarks",
89
"Compare3D": "Compare",
910
"DateTime3D": "Date and Time",

static/translations/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
],
2121
"extra_strings": [
2222
"appmenu.items.LandRegisterExtract",
23+
"appmenu.items.LegendPrint",
2324
"search.coordinates"
2425
],
2526
"overrides": [

0 commit comments

Comments
 (0)