Skip to content

Commit

Permalink
Add LegendPrint plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
manisandro committed Jan 30, 2025
1 parent b13f163 commit 3bd2453
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 1 deletion.
6 changes: 5 additions & 1 deletion js/appConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import MapComparePlugin from 'qwc2/plugins/MapCompare';
import MapCopyrightPlugin from 'qwc2/plugins/MapCopyright';
import MapExportPlugin from 'qwc2/plugins/MapExport';
import MapInfoTooltipPlugin from 'qwc2/plugins/MapInfoTooltip';
import MapLegendPlugin from 'qwc2/plugins/MapLegend';
import MapTipPlugin from 'qwc2/plugins/MapTip';
import MeasurePlugin from 'qwc2/plugins/Measure';
import NewsPopupPlugin from 'qwc2/plugins/NewsPopup';
Expand All @@ -51,6 +52,7 @@ import {renderHelp} from './Help';
import CCCEditSupport from './plugins/CCCEditSupport';
import {CCCInterfacePlugin, CCCAttributeCalculator} from './plugins/CCCInterface';
import LandRegisterExtractPlugin from './plugins/LandRegisterExtract';
import LegendPrintPlugin from './plugins/LegendPrint';
import PlotOwnerInfo from './plugins/PlotOwnerInfo';
import SoBottomBarPlugin from './plugins/SoBottomBar';
import SoTopBarPlugin from './plugins/SoTopBar';
Expand Down Expand Up @@ -104,11 +106,13 @@ export default {
MapComparePlugin: MapComparePlugin,
HeightProfilePlugin: HeightProfilePlugin,
MapInfoTooltipPlugin: MapInfoTooltipPlugin(),
MapLegendPlugin: MapLegendPlugin,
AuthenticationPlugin: AuthenticationPlugin,
PlotInfoToolPlugin: PlotInfoToolPlugin,
LandRegisterExtractPlugin: LandRegisterExtractPlugin,
CCCInterfacePlugin: CCCInterfacePlugin,
LoginUserPlugin: LoginUserPlugin
LoginUserPlugin: LoginUserPlugin,
LegendPrintPlugin: LegendPrintPlugin
},
cfg: {
IdentifyPlugin: {
Expand Down
117 changes: 117 additions & 0 deletions js/plugins/LegendPrint.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* Copyright 2025 Sourcepole AG
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import {connect} from 'react-redux';

import PropTypes from 'prop-types';
import {setCurrentTask} from 'qwc2/actions/task';
import ResizeableWindow from 'qwc2/components/ResizeableWindow';
import LayerUtils from 'qwc2/utils/LayerUtils';
import LocaleUtils from 'qwc2/utils/LocaleUtils';
import MapUtils from 'qwc2/utils/MapUtils';
import MiscUtils from 'qwc2/utils/MiscUtils';


class LegendPrint extends React.Component {
static propTypes = {
/** Whether to display a BBOX dependent legend. Can be `true|false|"theme"`, latter means only for theme layers. */
bboxDependentLegend: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
enabled: PropTypes.bool,
/** Additional parameters to pass to the GetLegendGraphics request. */
extraLegendParameters: PropTypes.string,
layers: PropTypes.array,
map: PropTypes.object,
mapScale: PropTypes.number,
/** Whether to display a scale dependent legend. Can be `true|false|"theme"`, latter means only for theme layers. */
scaleDependentLegend: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
setCurrentTask: PropTypes.func,
/** Template location for the legend print functionality */
templatePath: PropTypes.string
};
static defaultProps = {
templatePath: ":/templates/legendprint.html"
};
render() {
if (!this.props.enabled) {
return null;
}
const setLegendPrintContents = (el) => {
if (!el) {
return;
}
el.addEventListener('load', () => {
const container = el.contentWindow.document.getElementById("legendcontainer");
if (container) {
let body = '<p id="legendcontainerbody">';
body += this.props.layers.map(layer => {
if (!layer.visibility) {
return "";
} else if (layer.legendUrl) {
return this.printLayerLegend(layer, layer);
} else if (layer.color) {
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>';
} else {
return "";
}
}).join("");
body += "</p>";
container.innerHTML = body;
} else {
this.legendPrintWindow.document.body.innerHTML = "Broken template. An element with id=legendcontainer must exist.";
}
});
};
const printLegend = (ev) => {
ev.target.parentElement.parentElement.getElementsByTagName('iframe')[0].contentWindow.print();
};

return (
<ResizeableWindow icon="print" initialHeight={0.75 * window.innerHeight}
initialWidth={0.5 * window.innerWidth}
onClose={() => this.props.setCurrentTask(null)}
title={LocaleUtils.tr("layertree.printlegend")}
>
<div className="layertree-legend-print-body" role="body">
<iframe ref={setLegendPrintContents} src={MiscUtils.resolveAssetsPath(this.props.templatePath)} />
<div className="layertree-legend-print-body-buttonbar">
<button onClick={printLegend}>{LocaleUtils.tr("layertree.printlegend")}</button>
</div>
</div>
</ResizeableWindow>
);
}
printLayerLegend = (layer, sublayer) => {
let body = "";
if (sublayer.sublayers) {
if (sublayer.visibility) {
body = '<div class="legend-group">' +
'<h3 class="legend-group-title">' + (sublayer.title || sublayer.name) + '</h3>' +
'<div class="legend-group-body">' +
sublayer.sublayers.map(subsublayer => this.printLayerLegend(layer, subsublayer)).join("\n") +
'</div>' +
'</div>';
}
} else {
if (sublayer.visibility && LayerUtils.layerScaleInRange(sublayer, this.props.mapScale)) {
const request = LayerUtils.getLegendUrl(layer, {name: sublayer.name}, this.props.mapScale, this.props.map, this.props.bboxDependentLegend, this.props.scaleDependentLegend, this.props.extraLegendParameters);
body = request ? '<div class="legend-entry"><img src="' + request + '" /></div>' : "";
}
}
return body;
};
}

export default connect(state => ({
enabled: state.task.id === "LegendPrint",
layers: state.layers.flat,
map: state.map,
mapScale: MapUtils.computeForZoom(state.map.scales, state.map.zoom)
}), {
setCurrentTask: setCurrentTask
})(LegendPrint);
8 changes: 8 additions & 0 deletions static/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
{"key": "RasterExport", "icon": "rasterexport"}
]},
{"key": "Print", "icon": "print"},
{"key": "LegendPrint", "icon": "print"},
{"key": "LandRegisterExtract", "icon": "print"},
{"key": "Help", "icon": "info"},
{"key": "Login", "icon": "login"}
Expand Down Expand Up @@ -202,6 +203,9 @@
{
"name": "Authentication"
},
{
"name": "LegendPrint"
},
{
"name": "LandRegisterExtract"
},
Expand Down Expand Up @@ -310,6 +314,7 @@
{"key": "RasterExport", "icon": "rasterexport"}
]},
{"key": "Print", "icon": "print"},
{"key": "LegendPrint", "icon": "print"},
{"key": "LandRegisterExtract", "icon": "print"},
{"key": "Help", "icon": "info"},
{"key": "Login", "icon": "login"}
Expand Down Expand Up @@ -435,6 +440,9 @@
{
"name": "Authentication"
},
{
"name": "LegendPrint"
},
{
"name": "LandRegisterExtract"
},
Expand Down
1 change: 1 addition & 0 deletions static/translations/de-CH.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"appmenu": {
"items": {
"LandRegisterExtract": "Auszug Plan für das Grundbuch",
"LegendPrint": "Legende drucken",
"Bookmark": "Lesezeichen",
"Compare3D": "Vergleichen",
"DateTime3D": "Datum und Zeit",
Expand Down
1 change: 1 addition & 0 deletions static/translations/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"appmenu": {
"items": {
"LandRegisterExtract": "Land Register Map Extract",
"LegendPrint": "Print legend",
"Bookmark": "Bookmarks",
"Compare3D": "Compare",
"DateTime3D": "Date and Time",
Expand Down
1 change: 1 addition & 0 deletions static/translations/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
],
"extra_strings": [
"appmenu.items.LandRegisterExtract",
"appmenu.items.LegendPrint",
"search.coordinates"
],
"overrides": [
Expand Down

0 comments on commit 3bd2453

Please sign in to comment.