qwc2 2025.4.3 → 2025.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2025.04.03",
3
+ "version": "2025.04.04",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
@@ -6,7 +6,7 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */import React from"react";import{connect}from"react-redux";import{TextEncoder,TextDecoder}from"@kayahr/text-encoding";import axios from"axios";import dayjs from"dayjs";import FileSaver from"file-saver";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{LayerRole}from"../actions/layers";import{setSnappingConfig}from"../actions/map";import Icon from"../components/Icon";import PrintSelection from"../components/PrintSelection";import SideBar from"../components/SideBar";import NumberInput from"../components/widgets/NumberInput";import Spinner from"../components/widgets/Spinner";import ConfigUtils from"../utils/ConfigUtils";import CoordinatesUtils from"../utils/CoordinatesUtils";import{explodeDxf,implodeDxf,mergeDxf}from"../utils/DxfUtils";import LayerUtils from"../utils/LayerUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import VectorLayerUtils from"../utils/VectorLayerUtils";import"./style/MapExport.css";import"@kayahr/text-encoding/encodings/windows-1252";/**
8
8
  * Allows exporting a selected portion of the map to a variety of formats.
9
- */var MapExport=/*#__PURE__*/function(_React$Component){function MapExport(props){var _this;_classCallCheck(this,MapExport);_this=_callSuper(this,MapExport,[props]);_defineProperty(_this,"state",{extents:[],exporting:false,availableFormats:[],selectedFormat:null,selectedFormatConfiguration:"",scale:null,pageSize:null,dpi:96});_defineProperty(_this,"changeFormat",function(ev){var _this$props$formatCon;var selectedFormat=ev.target.value;var selectedFormatConfiguration=((((_this$props$formatCon=_this.props.formatConfiguration)===null||_this$props$formatCon===void 0?void 0:_this$props$formatCon[selectedFormat])||[])[0]||{}).name;_this.setState({selectedFormat:selectedFormat,selectedFormatConfiguration:selectedFormatConfiguration})});_defineProperty(_this,"changeScale",function(value){_this.setState({scale:Math.max(1,parseInt(value,10)||0)})});_defineProperty(_this,"changeResolution",function(ev){_this.setState({dpi:parseInt(ev.target.value,10)||0})});_defineProperty(_this,"renderBody",function(){var _this$props$formatCon2;if(!_this.props.theme||!_this.state.selectedFormat){return null}var formatMap={"image/jpeg":"JPEG","image/png":"PNG","image/png; mode=16bit":"PNG 16bit","image/png; mode=8bit":"PNG 8bit","image/png; mode=1bit":"PNG 1bit","image/geotiff":"GeoTIFF","image/tiff":"GeoTIFF","application/dxf":"DXF","application/pdf":"GeoPDF"};var formatConfiguration=((_this$props$formatCon2=_this.props.formatConfiguration)===null||_this$props$formatCon2===void 0?void 0:_this$props$formatCon2[_this.state.selectedFormat.split(";")[0]])||[];var scaleChooser=null;if(!isEmpty(_this.props.allowedScales)){scaleChooser=/*#__PURE__*/React.createElement("select",{onChange:_this.changeScale,value:_this.state.scale||""},/*#__PURE__*/React.createElement("option",{hidden:true,value:_this.state.scale||""},_this.state.scale||""),_this.props.allowedScales.map(function(scale){return/*#__PURE__*/React.createElement("option",{key:scale,value:scale},"1 : ",scale)}))}else if(_this.props.allowedScales!==false){scaleChooser=/*#__PURE__*/React.createElement(NumberInput,{min:1,mobile:true,onChange:_this.changeScale,prefix:"1 : ",value:_this.state.scale||null})}return/*#__PURE__*/React.createElement("div",{className:"mapexport-body"},/*#__PURE__*/React.createElement("form",{action:"#",method:"POST",onSubmit:_this["export"],ref:function ref(el){_this.form=el}},/*#__PURE__*/React.createElement("table",{className:"options-table"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapexport.format")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:_this.changeFormat,value:_this.state.selectedFormat},_this.state.availableFormats.map(function(format){return/*#__PURE__*/React.createElement("option",{key:format,value:format},formatMap[format]||format)})))),formatConfiguration.length>1?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapexport.configuration")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({selectedFormatConfiguration:ev.target.value})},value:_this.state.selectedFormatConfiguration},formatConfiguration.map(function(config){return/*#__PURE__*/React.createElement("option",{key:config.name,value:config.name},config.name)})))):null,!isEmpty(_this.props.pageSizes)?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapexport.size")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({pageSize:ev.target.value||null})},value:_this.state.pageSize||""},/*#__PURE__*/React.createElement("option",{value:""},LocaleUtils.tr("mapexport.usersize")),_this.props.pageSizes.map(function(entry,idx){return/*#__PURE__*/React.createElement("option",{key:"size_"+idx,value:idx},entry.name)})))):null,scaleChooser&&_this.state.pageSize!==null?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapexport.scale")),/*#__PURE__*/React.createElement("td",null,scaleChooser)):null,_this.props.dpis?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapexport.resolution")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:_this.changeResolution,value:_this.state.dpi},_this.props.dpis.map(function(dpi){return/*#__PURE__*/React.createElement("option",{key:dpi+"dpi",value:dpi},dpi+" dpi")})))):null)),/*#__PURE__*/React.createElement("div",{className:"button-bar"},/*#__PURE__*/React.createElement("button",{className:"button",disabled:_this.state.exporting||isEmpty(_this.state.extents),type:"submit"},_this.state.exporting?/*#__PURE__*/React.createElement("span",{className:"mapexport-wait"},/*#__PURE__*/React.createElement(Spinner,null)," ",LocaleUtils.tr("mapexport.wait")):LocaleUtils.tr("mapexport.submit")))))});_defineProperty(_this,"renderPrintSelection",function(){if(_this.state.pageSize!==null){var pageSize=_this.props.pageSizes[_this.state.pageSize];var frame={width:pageSize.width,height:pageSize.height};return/*#__PURE__*/React.createElement(PrintSelection,{allowRotation:false,allowScaling:_this.props.allowedScales!==false,center:_this.props.map.center,fixedFrame:frame,geometryChanged:_this.geometryChanged,key:"PrintSelection",scale:_this.state.scale})}else{return/*#__PURE__*/React.createElement(PrintSelection,{allowRotation:false,geometryChanged:_this.geometryChanged,key:"PrintSelection"})}});_defineProperty(_this,"onShow",function(){var _this$props$formatCon3;var scale=Math.round(MapUtils.computeForZoom(_this.props.map.scales,_this.props.map.zoom)*_this.props.defaultScaleFactor);if(!isEmpty(_this.props.allowedScales)){var closestVal=Math.abs(scale-_this.props.allowedScales[0]);var closestIdx=0;for(var i=1;i<_this.props.allowedScales.length;++i){var currVal=Math.abs(scale-_this.props.allowedScales[i]);if(currVal<closestVal){closestVal=currVal;closestIdx=i}}scale=_this.props.allowedScales[closestIdx]}var availableFormats=_this.props.theme.availableFormats;if(!isEmpty(_this.props.allowedFormats)){availableFormats=availableFormats.filter(function(fmt){return _this.props.allowedFormats.includes(fmt)})}var selectedFormat=_this.props.defaultFormat&&availableFormats.includes(_this.props.defaultFormat)?_this.props.defaultFormat:availableFormats[0];var selectedFormatConfiguration=((((_this$props$formatCon3=_this.props.formatConfiguration)===null||_this$props$formatCon3===void 0?void 0:_this$props$formatCon3[selectedFormat])||[])[0]||{}).name;_this.setState({scale:scale,availableFormats:availableFormats,selectedFormat:selectedFormat,selectedFormatConfiguration:selectedFormatConfiguration});_this.props.setSnappingConfig(false,false)});_defineProperty(_this,"onHide",function(){_this.setState({extents:[],width:0,height:0,scale:null,pageSize:null})});_defineProperty(_this,"geometryChanged",function(center,extents,rotation,scale){_this.setState(function(state){return{extents:extents,scale:scale!==null&&scale!==void 0?scale:state.scale}})});_defineProperty(_this,"export",function(ev){var _this$props$formatCon4,_this$state$extents$a;ev.preventDefault();_this.setState({exporting:true});var format=_this.state.selectedFormat.split(";")[0];var formatConfiguration=(((_this$props$formatCon4=_this.props.formatConfiguration)===null||_this$props$formatCon4===void 0?void 0:_this$props$formatCon4[format])||[]).find(function(entry){return entry.name===_this.state.selectedFormatConfiguration});var version=_this.props.theme.version;var crs=_this.props.map.projection;var extent=(_this$state$extents$a=_this.state.extents.at(0))!==null&&_this$state$extents$a!==void 0?_this$state$extents$a:[0,0,0,0];var formattedExtent=CoordinatesUtils.getAxisOrder(crs).substring(0,2)==="ne"&&version==="1.3.0"?extent[1]+","+extent[0]+","+extent[3]+","+extent[2]:extent.join(",");var getPixelFromCoordinate=MapUtils.getHook(MapUtils.GET_PIXEL_FROM_COORDINATES_HOOK);var p1=getPixelFromCoordinate(extent.slice(0,2));var p2=getPixelFromCoordinate(extent.slice(2,4));var width=Math.round(Math.abs(p1[0]-p2[0])*_this.state.dpi/96);var height=Math.round(Math.abs(p1[1]-p2[1])*_this.state.dpi/96);var ext=format.split("/").pop();var timestamp=dayjs(new Date).format("YYYYMMDD_HHmmss");var fileName=_this.props.fileNameTemplate.replace("{theme}",_this.props.theme.id).replace("{timestamp}",timestamp)+"."+ext;var params={};// Base request params
9
+ */var MapExport=/*#__PURE__*/function(_React$Component){function MapExport(props){var _this;_classCallCheck(this,MapExport);_this=_callSuper(this,MapExport,[props]);_defineProperty(_this,"state",{extents:[],exporting:false,availableFormats:[],selectedFormat:null,selectedFormatConfiguration:"",scale:null,pageSize:null,dpi:96});_defineProperty(_this,"changeFormat",function(ev){var _this$props$formatCon;var selectedFormat=ev.target.value;var selectedFormatConfiguration=((((_this$props$formatCon=_this.props.formatConfiguration)===null||_this$props$formatCon===void 0?void 0:_this$props$formatCon[selectedFormat])||[])[0]||{}).name;_this.setState({selectedFormat:selectedFormat,selectedFormatConfiguration:selectedFormatConfiguration})});_defineProperty(_this,"changeScale",function(value){_this.setState({scale:Math.max(1,parseInt(value,10)||0)})});_defineProperty(_this,"changeResolution",function(ev){_this.setState({dpi:parseInt(ev.target.value,10)||0})});_defineProperty(_this,"renderBody",function(){var _this$props$formatCon2;if(!_this.props.theme||!_this.state.selectedFormat){return null}var formatMap={"image/jpeg":"JPEG","image/png":"PNG","image/png; mode=16bit":"PNG 16bit","image/png; mode=8bit":"PNG 8bit","image/png; mode=1bit":"PNG 1bit","image/geotiff":"GeoTIFF","image/tiff":"GeoTIFF","application/dxf":"DXF","application/pdf":"GeoPDF"};var formatConfiguration=((_this$props$formatCon2=_this.props.formatConfiguration)===null||_this$props$formatCon2===void 0?void 0:_this$props$formatCon2[_this.state.selectedFormat.split(";")[0]])||[];var scaleChooser=null;if(!isEmpty(_this.props.allowedScales)){scaleChooser=/*#__PURE__*/React.createElement("select",{onChange:_this.changeScale,value:_this.state.scale||""},/*#__PURE__*/React.createElement("option",{hidden:true,value:_this.state.scale||""},_this.state.scale||""),_this.props.allowedScales.map(function(scale){return/*#__PURE__*/React.createElement("option",{key:scale,value:scale},"1 : ",scale)}))}else if(_this.props.allowedScales!==false){scaleChooser=/*#__PURE__*/React.createElement(NumberInput,{min:1,mobile:true,onChange:_this.changeScale,prefix:"1 : ",value:_this.state.scale||null})}return/*#__PURE__*/React.createElement("div",{className:"mapexport-body"},/*#__PURE__*/React.createElement("form",{action:"#",method:"POST",onSubmit:_this["export"],ref:function ref(el){_this.form=el}},/*#__PURE__*/React.createElement("table",{className:"options-table"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapexport.format")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:_this.changeFormat,value:_this.state.selectedFormat},_this.state.availableFormats.map(function(format){return/*#__PURE__*/React.createElement("option",{key:format,value:format},formatMap[format]||format)})))),formatConfiguration.length>1?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapexport.configuration")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({selectedFormatConfiguration:ev.target.value})},value:_this.state.selectedFormatConfiguration},formatConfiguration.map(function(config){return/*#__PURE__*/React.createElement("option",{key:config.name,value:config.name},config.labelMsgId?LocaleUtils.tr(config.labelMsgId):config.name)})))):null,!isEmpty(_this.props.pageSizes)?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapexport.size")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({pageSize:ev.target.value||null})},value:_this.state.pageSize||""},/*#__PURE__*/React.createElement("option",{value:""},LocaleUtils.tr("mapexport.usersize")),_this.props.pageSizes.map(function(entry,idx){return/*#__PURE__*/React.createElement("option",{key:"size_"+idx,value:idx},entry.name)})))):null,scaleChooser&&_this.state.pageSize!==null?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapexport.scale")),/*#__PURE__*/React.createElement("td",null,scaleChooser)):null,_this.props.dpis?/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapexport.resolution")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:_this.changeResolution,value:_this.state.dpi},_this.props.dpis.map(function(dpi){return/*#__PURE__*/React.createElement("option",{key:dpi+"dpi",value:dpi},dpi+" dpi")})))):null)),/*#__PURE__*/React.createElement("div",{className:"button-bar"},/*#__PURE__*/React.createElement("button",{className:"button",disabled:_this.state.exporting||isEmpty(_this.state.extents),type:"submit"},_this.state.exporting?/*#__PURE__*/React.createElement("span",{className:"mapexport-wait"},/*#__PURE__*/React.createElement(Spinner,null)," ",LocaleUtils.tr("mapexport.wait")):LocaleUtils.tr("mapexport.submit")))))});_defineProperty(_this,"renderPrintSelection",function(){if(_this.state.pageSize!==null){var pageSize=_this.props.pageSizes[_this.state.pageSize];var frame={width:pageSize.width,height:pageSize.height};return/*#__PURE__*/React.createElement(PrintSelection,{allowRotation:false,allowScaling:_this.props.allowedScales!==false,center:_this.props.map.center,fixedFrame:frame,geometryChanged:_this.geometryChanged,key:"PrintSelection",scale:_this.state.scale})}else{return/*#__PURE__*/React.createElement(PrintSelection,{allowRotation:false,geometryChanged:_this.geometryChanged,key:"PrintSelection"})}});_defineProperty(_this,"onShow",function(){var _this$props$formatCon3;var scale=Math.round(MapUtils.computeForZoom(_this.props.map.scales,_this.props.map.zoom)*_this.props.defaultScaleFactor);if(!isEmpty(_this.props.allowedScales)){var closestVal=Math.abs(scale-_this.props.allowedScales[0]);var closestIdx=0;for(var i=1;i<_this.props.allowedScales.length;++i){var currVal=Math.abs(scale-_this.props.allowedScales[i]);if(currVal<closestVal){closestVal=currVal;closestIdx=i}}scale=_this.props.allowedScales[closestIdx]}var availableFormats=_this.props.theme.availableFormats;if(!isEmpty(_this.props.allowedFormats)){availableFormats=availableFormats.filter(function(fmt){return _this.props.allowedFormats.includes(fmt)})}var selectedFormat=_this.props.defaultFormat&&availableFormats.includes(_this.props.defaultFormat)?_this.props.defaultFormat:availableFormats[0];var selectedFormatConfiguration=((((_this$props$formatCon3=_this.props.formatConfiguration)===null||_this$props$formatCon3===void 0?void 0:_this$props$formatCon3[selectedFormat])||[])[0]||{}).name;_this.setState({scale:scale,availableFormats:availableFormats,selectedFormat:selectedFormat,selectedFormatConfiguration:selectedFormatConfiguration});_this.props.setSnappingConfig(false,false)});_defineProperty(_this,"onHide",function(){_this.setState({extents:[],width:0,height:0,scale:null,pageSize:null})});_defineProperty(_this,"geometryChanged",function(center,extents,rotation,scale){_this.setState(function(state){return{extents:extents,scale:scale!==null&&scale!==void 0?scale:state.scale}})});_defineProperty(_this,"export",function(ev){var _this$props$formatCon4,_this$state$extents$a;ev.preventDefault();_this.setState({exporting:true});var format=_this.state.selectedFormat.split(";")[0];var formatConfiguration=(((_this$props$formatCon4=_this.props.formatConfiguration)===null||_this$props$formatCon4===void 0?void 0:_this$props$formatCon4[format])||[]).find(function(entry){return entry.name===_this.state.selectedFormatConfiguration});var version=_this.props.theme.version;var crs=_this.props.map.projection;var extent=(_this$state$extents$a=_this.state.extents.at(0))!==null&&_this$state$extents$a!==void 0?_this$state$extents$a:[0,0,0,0];var formattedExtent=CoordinatesUtils.getAxisOrder(crs).substring(0,2)==="ne"&&version==="1.3.0"?extent[1]+","+extent[0]+","+extent[3]+","+extent[2]:extent.join(",");var getPixelFromCoordinate=MapUtils.getHook(MapUtils.GET_PIXEL_FROM_COORDINATES_HOOK);var p1=getPixelFromCoordinate(extent.slice(0,2));var p2=getPixelFromCoordinate(extent.slice(2,4));var width=Math.round(Math.abs(p1[0]-p2[0])*_this.state.dpi/96);var height=Math.round(Math.abs(p1[1]-p2[1])*_this.state.dpi/96);var ext=format.split("/").pop();var timestamp=dayjs(new Date).format("YYYYMMDD_HHmmss");var fileName=_this.props.fileNameTemplate.replace("{username}",ConfigUtils.getConfigProp("username",null,"")).replace("{tenant}",ConfigUtils.getConfigProp("tenant",null,"")).replace("{theme}",_this.props.theme.id).replace("{timestamp}",timestamp)+"."+ext;var params={};// Base request params
10
10
  params.SERVICE="WMS";params.VERSION=version;params.REQUEST="GetMap";params.FORMAT=_this.state.selectedFormat;params.DPI=_this.state.dpi;params.TRANSPARENT=true;params.TILED=false;params.CRS=_this.props.map.projection;params.BBOX=formattedExtent;params.WIDTH=width;params.HEIGHT=height;params.filename=fileName;// Dimension values
11
11
  _this.props.layers.forEach(function(layer){if(layer.role===LayerRole.THEME){Object.entries(layer.dimensionValues||{}).forEach(function(_ref){var _ref2=_slicedToArray(_ref,2),key=_ref2[0],value=_ref2[1];if(value!==undefined){params[key]=value}})}});// Add parameters from custom format configuration
12
12
  if(formatConfiguration){var _formatConfiguration$;var keyCaseMap=Object.keys(params).reduce(function(res,key){return _objectSpread(_objectSpread({},res),{},_defineProperty({},key.toLowerCase(),key))},{});(formatConfiguration.extraQuery||"").split(/[?&]/).filter(Boolean).forEach(function(entry){var _entry$split=entry.split("="),_entry$split2=_slicedToArray(_entry$split,2),key=_entry$split2[0],value=_entry$split2[1];var caseKey=keyCaseMap[key.toLowerCase()]||key;params[caseKey]=value!==null&&value!==void 0?value:""});params.FORMAT_OPTIONS=(_formatConfiguration$=formatConfiguration.formatOptions)!==null&&_formatConfiguration$!==void 0?_formatConfiguration$:"";if(formatConfiguration.baseLayer){var layers=params[keyCaseMap.layers].split(",");if(!layers.includes(formatConfiguration.baseLayer)){params[keyCaseMap.layers]=[formatConfiguration.baseLayer].concat(_toConsumableArray(layers))}}}if(_this.state.selectedFormat==="application/dxf"){_this.dxfExport(params,fileName)}else{_this.genericExport(params,fileName,formatConfiguration)}});_defineProperty(_this,"genericExport",function(params,fileName,formatConfiguration){// Layer params
@@ -16,8 +16,9 @@ Object.keys(_this.props.theme.watermark||{}).forEach(function(key){params["WATER
16
16
  responses.forEach((response, idx) => {
17
17
  FileSaver.saveAs(new Blob([response.data], {type: "application/dxf"}), "orig_" + idx + "_" + fileName);
18
18
  });
19
- */_this.setState({exporting:false})})});_this.form=null;_this.state.dpi=(props.dpis||[])[0]||96;return _this}_inherits(MapExport,_React$Component);return _createClass(MapExport,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){if(this.state.pageSize===null&&prevState.pageSize!==null){this.setState({extents:[]})}}},{key:"render",value:function render(){var _this2=this;var minMaxTooltip=this.state.minimized?LocaleUtils.tr("print.maximize"):LocaleUtils.tr("print.minimize");var extraTitlebarContent=/*#__PURE__*/React.createElement(Icon,{className:"mapexport-minimize-maximize",icon:this.state.minimized?"chevron-down":"chevron-up",onClick:function onClick(){return _this2.setState(function(state){return{minimized:!state.minimized}})},title:minMaxTooltip});return/*#__PURE__*/React.createElement(SideBar,{extraClasses:"MapExport",extraTitlebarContent:extraTitlebarContent,icon:"rasterexport",id:"MapExport",key:"MapExport",onHide:this.onHide,onShow:this.onShow,side:this.props.side,title:LocaleUtils.tr("appmenu.items.MapExport"),width:"20em"},function(){return{body:_this2.state.minimized?null:_this2.renderBody(),extra:[_this2.renderPrintSelection()]}})}}])}(React.Component);_defineProperty(MapExport,"propTypes",{/** Whitelist of allowed export format mimetypes. If empty, supported formats are listed. */allowedFormats:PropTypes.arrayOf(PropTypes.string),/** List of scales at which to export the map. If empty, scale can be freely specified. If `false`, the map can only be exported at the current scale. */allowedScales:PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number),PropTypes.bool]),/** Default export format mimetype. If empty, first available format is used. */defaultFormat:PropTypes.string,/** The factor to apply to the map scale to determine the initial export map scale (if `allowedScales` is not `false`). */defaultScaleFactor:PropTypes.number,/** List of dpis at which to export the map. If empty, the default server dpi is used. */dpis:PropTypes.arrayOf(PropTypes.number),/** Whether to include external layers in the image. Requires QGIS Server 3.x! */exportExternalLayers:PropTypes.bool,/** Template for the name of the generated files when downloading. */fileNameTemplate:PropTypes.string,/** Custom export configuration per format.
19
+ */_this.setState({exporting:false})})});_this.form=null;_this.state.dpi=(props.dpis||[])[0]||96;return _this}_inherits(MapExport,_React$Component);return _createClass(MapExport,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){if(this.state.pageSize===null&&prevState.pageSize!==null){this.setState({extents:[]})}}},{key:"render",value:function render(){var _this2=this;var minMaxTooltip=this.state.minimized?LocaleUtils.tr("print.maximize"):LocaleUtils.tr("print.minimize");var extraTitlebarContent=/*#__PURE__*/React.createElement(Icon,{className:"mapexport-minimize-maximize",icon:this.state.minimized?"chevron-down":"chevron-up",onClick:function onClick(){return _this2.setState(function(state){return{minimized:!state.minimized}})},title:minMaxTooltip});return/*#__PURE__*/React.createElement(SideBar,{extraClasses:"MapExport",extraTitlebarContent:extraTitlebarContent,icon:"rasterexport",id:"MapExport",key:"MapExport",onHide:this.onHide,onShow:this.onShow,side:this.props.side,title:LocaleUtils.tr("appmenu.items.MapExport"),width:"20em"},function(){return{body:_this2.state.minimized?null:_this2.renderBody(),extra:[_this2.renderPrintSelection()]}})}}])}(React.Component);_defineProperty(MapExport,"propTypes",{/** Whitelist of allowed export format mimetypes. If empty, supported formats are listed. */allowedFormats:PropTypes.arrayOf(PropTypes.string),/** List of scales at which to export the map. If empty, scale can be freely specified. If `false`, the map can only be exported at the current scale. */allowedScales:PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number),PropTypes.bool]),/** Default export format mimetype. If empty, first available format is used. */defaultFormat:PropTypes.string,/** The factor to apply to the map scale to determine the initial export map scale (if `allowedScales` is not `false`). */defaultScaleFactor:PropTypes.number,/** List of dpis at which to export the map. If empty, the default server dpi is used. */dpis:PropTypes.arrayOf(PropTypes.number),/** Whether to include external layers in the image. Requires QGIS Server 3.x! */exportExternalLayers:PropTypes.bool,/** Template for the name of the generated files when downloading. Can contain the placeholders `{username}`, `{tenant}`, `{theme}`, `{timestamp}`. */fileNameTemplate:PropTypes.string,/** Custom export configuration per format.
20
20
  * If more than one configuration per format is provided, a selection combo will be displayed.
21
+ * `labelMsgId` is a translation string message id for the combo label. If not defined, `name` will be displayed.
21
22
  * `extraQuery` will be appended to the query string (replacing any existing parameters).
22
23
  * `formatOptions` will be passed as FORMAT_OPTIONS.
23
- * `baseLayer` will be appended to the LAYERS instead of the background layer. */formatConfiguration:PropTypes.shape({format:PropTypes.arrayOf(PropTypes.shape({name:PropTypes.string,extraQuery:PropTypes.string,formatOptions:PropTypes.string,baseLayer:PropTypes.string}))}),layers:PropTypes.array,map:PropTypes.object,/** List of image sizes to offer, in addition to the free-hand selection. The width and height are in millimeters. */pageSizes:PropTypes.arrayOf(PropTypes.shape({name:PropTypes.string,width:PropTypes.number,height:PropTypes.number})),setIdentifyEnabled:PropTypes.func,setSnappingConfig:PropTypes.func,/** The side of the application on which to display the sidebar. */side:PropTypes.string,theme:PropTypes.object});_defineProperty(MapExport,"defaultProps",{defaultScaleFactor:1,exportExternalLayers:true,fileNameTemplate:"{theme}_{timestamp}",side:"right",pageSizes:[]});var selector=function selector(state){return{theme:state.theme.current,map:state.map,layers:state.layers.flat}};export default connect(selector,{setSnappingConfig:setSnappingConfig})(MapExport);
24
+ * `baseLayer` will be appended to the LAYERS instead of the background layer. */formatConfiguration:PropTypes.shape({format:PropTypes.arrayOf(PropTypes.shape({name:PropTypes.string,labelMsgId:PropTypes.string,extraQuery:PropTypes.string,formatOptions:PropTypes.string,baseLayer:PropTypes.string}))}),layers:PropTypes.array,map:PropTypes.object,/** List of image sizes to offer, in addition to the free-hand selection. The width and height are in millimeters. */pageSizes:PropTypes.arrayOf(PropTypes.shape({name:PropTypes.string,width:PropTypes.number,height:PropTypes.number})),setIdentifyEnabled:PropTypes.func,setSnappingConfig:PropTypes.func,/** The side of the application on which to display the sidebar. */side:PropTypes.string,theme:PropTypes.object});_defineProperty(MapExport,"defaultProps",{defaultScaleFactor:1,exportExternalLayers:true,fileNameTemplate:"{theme}_{timestamp}",side:"right",pageSizes:[]});var selector=function selector(state){return{theme:state.theme.current,map:state.map,layers:state.layers.flat}};export default connect(selector,{setSnappingConfig:setSnappingConfig})(MapExport);
package/plugins/Print.js CHANGED
@@ -4,7 +4,7 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
- */import React from"react";import{connect}from"react-redux";import axios from"axios";import dayjs from"dayjs";import FileSaver from"file-saver";import formDataEntries from"formdata-json";import JSZip from"jszip";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{LayerRole,addLayerFeatures,clearLayer}from"../actions/layers";import{setSnappingConfig}from"../actions/map";import Icon from"../components/Icon";import PickFeature from"../components/PickFeature";import PrintSelection from"../components/PrintSelection";import ResizeableWindow from"../components/ResizeableWindow";import SideBar from"../components/SideBar";import EditableSelect from"../components/widgets/EditableSelect";import InputContainer from"../components/widgets/InputContainer";import NumberInput from"../components/widgets/NumberInput";import Spinner from"../components/widgets/Spinner";import ToggleSwitch from"../components/widgets/ToggleSwitch";import CoordinatesUtils from"../utils/CoordinatesUtils";import LayerUtils from"../utils/LayerUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import MiscUtils from"../utils/MiscUtils";import VectorLayerUtils from"../utils/VectorLayerUtils";import"./style/Print.css";/**
7
+ */import React from"react";import{connect}from"react-redux";import axios from"axios";import dayjs from"dayjs";import FileSaver from"file-saver";import formDataEntries from"formdata-json";import JSZip from"jszip";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{LayerRole,addLayerFeatures,clearLayer}from"../actions/layers";import{setSnappingConfig}from"../actions/map";import Icon from"../components/Icon";import PickFeature from"../components/PickFeature";import PrintSelection from"../components/PrintSelection";import ResizeableWindow from"../components/ResizeableWindow";import SideBar from"../components/SideBar";import EditableSelect from"../components/widgets/EditableSelect";import InputContainer from"../components/widgets/InputContainer";import NumberInput from"../components/widgets/NumberInput";import Spinner from"../components/widgets/Spinner";import ToggleSwitch from"../components/widgets/ToggleSwitch";import ConfigUtils from"../utils/ConfigUtils";import CoordinatesUtils from"../utils/CoordinatesUtils";import LayerUtils from"../utils/LayerUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import MiscUtils from"../utils/MiscUtils";import VectorLayerUtils from"../utils/VectorLayerUtils";import"./style/Print.css";/**
8
8
  * Invokes QGIS Server WMS GetPrint to print the map to PDF.
9
9
  *
10
10
  * Uses the print layouts defined in the QGIS project.
@@ -14,9 +14,9 @@ if(label.startsWith("__")){return null}var opts=_objectSpread({rows:1,name:label
14
14
  var printParams=LayerUtils.collectPrintParams(_this.props.layers,_this.props.theme,_this.state.scale,mapCrs,_this.props.printExternalLayers);Object.entries(printParams).forEach(function(_ref3){var _ref4=_slicedToArray(_ref3,2),key=_ref4[0],value=_ref4[1];formData[key]=value});formData[mapName+":LAYERS"]=printParams.LAYERS;formData[mapName+":STYLES"]=printParams.STYLES;formData[mapName+":FILTER"]=printParams.FILTER;formData[mapName+":FILTER_GEOM"]=printParams.FILTER_GEOM;// Add highlight params
15
15
  var printDpi=parseInt(_this.state.dpi,10)||0;var highlightParams=VectorLayerUtils.createPrintHighlighParams(_this.props.layers,mapCrs,_this.state.scale,printDpi,_this.props.scaleFactor);formData[mapName+":HIGHLIGHT_GEOM"]=highlightParams.geoms.join(";");formData[mapName+":HIGHLIGHT_SYMBOL"]=highlightParams.styles.join(";");formData[mapName+":HIGHLIGHT_LABELSTRING"]=highlightParams.labels.join(";");formData[mapName+":HIGHLIGHT_LABELCOLOR"]=highlightParams.labelFillColors.join(";");formData[mapName+":HIGHLIGHT_LABELBUFFERCOLOR"]=highlightParams.labelOutlineColors.join(";");formData[mapName+":HIGHLIGHT_LABELBUFFERSIZE"]=highlightParams.labelOutlineSizes.join(";");formData[mapName+":HIGHLIGHT_LABELSIZE"]=highlightParams.labelSizes.join(";");formData[mapName+":HIGHLIGHT_LABEL_DISTANCE"]=highlightParams.labelDist.join(";");formData[mapName+":HIGHLIGHT_LABEL_ROTATION"]=highlightParams.labelRotations.join(";");// Add dimension values
16
16
  _this.props.layers.forEach(function(layer){if(layer.role===LayerRole.THEME){Object.entries(layer.dimensionValues||{}).forEach(function(_ref5){var _ref6=_slicedToArray(_ref5,2),key=_ref6[0],value=_ref6[1];if(value!==undefined){formData[key]=value}})}});// Add extra print parameters
17
- var extraOptions=Object.fromEntries((_this.props.theme.extraPrintParameters||"").split("&").filter(Boolean).map(function(entry){return entry.split("=")}));Object.entries(extraOptions).forEach(function(_ref7){var _ref8=_slicedToArray(_ref7,2),key=_ref8[0],value=_ref8[1];formData[key]=value});var pages=[formData];if(_this.state.printSeriesEnabled){pages=_this.state.extents.map(function(extent,index){var fd=structuredClone(formData);fd.name=(index+1).toString().padStart(2,"0");fd[_this.state.layout.map.name+":extent"]=_this.formatExtent(extent);return fd})}var timestamp=dayjs(new Date).format("YYYYMMDD_HHmmss");var fileName=_this.props.fileNameTemplate.replace("{theme}",_this.props.theme.id).replace("{timestamp}",timestamp);// batch print all pages
17
+ var extraOptions=Object.fromEntries((_this.props.theme.extraPrintParameters||"").split("&").filter(Boolean).map(function(entry){return entry.split("=")}));Object.entries(extraOptions).forEach(function(_ref7){var _ref8=_slicedToArray(_ref7,2),key=_ref8[0],value=_ref8[1];formData[key]=value});var pages=[formData];if(_this.state.printSeriesEnabled){pages=_this.state.extents.map(function(extent,index){var fd=structuredClone(formData);fd.name=(index+1).toString().padStart(2,"0");fd[_this.state.layout.map.name+":extent"]=_this.formatExtent(extent);return fd})}var timestamp=dayjs(new Date).format("YYYYMMDD_HHmmss");var fileName=_this.props.fileNameTemplate.replace("{username}",ConfigUtils.getConfigProp("username",null,"")).replace("{tenant}",ConfigUtils.getConfigProp("tenant",null,"")).replace("{theme}",_this.props.theme.id).replace("{timestamp}",timestamp);// batch print all pages
18
18
  _this.batchPrint(pages,fileName)["catch"](function(e){_this.setState({outputLoaded:true,printOutputVisible:false});if(e.response){/* eslint-disable-next-line */console.warn(new TextDecoder().decode(e.response.data))}/* eslint-disable-next-line */alert("Print failed")})["finally"](function(){_this.setState({printing:false})})});_this.printForm=null;_this.state.grid=props.gridInitiallyEnabled;_this.state.dpi=props.defaultDpi;_this.state.selectedFormat=props.formats[0];return _this}_inherits(Print,_React$Component);return _createClass(Print,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){if(prevProps.theme!==this.props.theme){if(this.props.theme&&!isEmpty(this.props.theme.print)){var layouts=this.props.theme.print.filter(function(l){return l.map}).sort(function(a,b){return a.name.localeCompare(b.name,undefined,{numeric:true})});var layout=layouts.find(function(l){return l["default"]})||layouts[0];this.setState({layout:layout,atlasFeatures:[]})}else{this.setState({layout:null,atlasFeatures:[]})}}if(this.state.atlasFeatures!==prevState.atlasFeatures){if(!isEmpty(this.state.atlasFeatures)){var layer={id:"print-pick-selection",role:LayerRole.SELECTION,skipPrint:true};this.props.addLayerFeatures(layer,this.state.atlasFeatures,true)}else if(!isEmpty(prevState.atlasFeatures)){this.props.clearLayer("print-pick-selection")}}if(this.state.printSeriesEnabled&&this.state.selectedFormat!=="application/pdf"){this.setState({selectedFormat:"application/pdf"})}}},{key:"render",value:function render(){var _this2=this;var minMaxTooltip=this.state.minimized?LocaleUtils.tr("print.maximize"):LocaleUtils.tr("print.minimize");var extraTitlebarContent=/*#__PURE__*/React.createElement(Icon,{className:"print-minimize-maximize",icon:this.state.minimized?"chevron-down":"chevron-up",onClick:function onClick(){return _this2.setState(function(state){return{minimized:!state.minimized}})},title:minMaxTooltip});return[/*#__PURE__*/React.createElement(SideBar,{extraTitlebarContent:extraTitlebarContent,icon:"print",id:"Print",key:"Print",onHide:this.onHide,onShow:this.onShow,side:this.props.side,title:LocaleUtils.tr("appmenu.items.Print"),width:"20em"},function(){return{body:_this2.state.minimized?null:_this2.renderBody(),extra:[_this2.renderPrintSelection()]}}),this.renderPrintOutputWindow(),this.props.active&&this.state.layout&&this.state.layout.atlasCoverageLayer&&!this.state.printSeriesEnabled?/*#__PURE__*/React.createElement(PickFeature,{featurePicked:this.selectAtlasFeature,key:"FeaturePicker",layer:this.state.layout.atlasCoverageLayer}):null]}},{key:"batchPrint",value:function(){var _batchPrint=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(pages,fileName){var _this3=this;var promises,docs,files,file,fileURL,_iterator,_step,_file;return _regeneratorRuntime().wrap(function _callee$(_context){while(1)switch(_context.prev=_context.next){case 0:// Print pages on server
19
19
  promises=pages.map(function(formData){return _this3.printRequest(formData)});// Collect printing results
20
20
  _context.next=3;return Promise.all(promises);case 3:docs=_context.sent;_context.next=6;return this.collectFiles(docs,fileName);case 6:files=_context.sent;// Download or display files
21
- if(this.props.inlinePrintOutput&&files.length===1){file=files.pop();fileURL=URL.createObjectURL(file.content);this.setState({pdfData:file,pdfDataUrl:fileURL,outputLoaded:true})}else{_iterator=_createForOfIteratorHelper(files);try{for(_iterator.s();!(_step=_iterator.n()).done;){_file=_step.value;FileSaver.saveAs(_file.content,_file.fileName)}}catch(err){_iterator.e(err)}finally{_iterator.f()}}case 8:case"end":return _context.stop()}},_callee,this)}));function batchPrint(_x,_x2){return _batchPrint.apply(this,arguments)}return batchPrint}()},{key:"printRequest",value:function(){var _printRequest=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(formData){var data,config,response,contentType;return _regeneratorRuntime().wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:data=Object.entries(formData).map(function(pair){return pair.map(function(entry){return encodeURIComponent(entry).replace(/%20/g,"+")}).join("=")}).join("&");config={headers:{"Content-Type":"application/x-www-form-urlencoded"},responseType:"arraybuffer"};_context2.next=4;return axios.post(this.props.theme.printUrl,data,config);case 4:response=_context2.sent;contentType=response.headers["content-type"];return _context2.abrupt("return",{name:formData.name,data:response.data,contentType:contentType});case 7:case"end":return _context2.stop()}},_callee2,this)}));function printRequest(_x3){return _printRequest.apply(this,arguments)}return printRequest}()},{key:"collectFiles",value:function(){var _collectFiles=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(docs,fileName){var _this4=this;var data,content,_data,_content;return _regeneratorRuntime().wrap(function _callee3$(_context3){while(1)switch(_context3.prev=_context3.next){case 0:if(!(docs.length>1&&this.state.downloadMode==="onepdf")){_context3.next=6;break}_context3.next=3;return this.collectOnePdf(docs);case 3:data=_context3.sent;content=new Blob([data],{type:"application/pdf"});return _context3.abrupt("return",[{content:content,fileName:fileName+".pdf"}]);case 6:if(!(docs.length>1&&this.state.downloadMode==="onezip")){_context3.next=12;break}_context3.next=9;return this.collectOneZip(docs,fileName);case 9:_data=_context3.sent;_content=new Blob([_data],{type:"application/zip"});return _context3.abrupt("return",[{content:_content,fileName:fileName+".zip"}]);case 12:return _context3.abrupt("return",docs.map(function(doc){var content=new Blob([doc.data],{type:doc.contentType});var ext=_this4.state.selectedFormat.split(";")[0].split("/").pop();var appendix=doc.name?"_"+doc.name:"";return{content:content,fileName:fileName+appendix+"."+ext}}));case 13:case"end":return _context3.stop()}},_callee3,this)}));function collectFiles(_x4,_x5){return _collectFiles.apply(this,arguments)}return collectFiles}()},{key:"collectOnePdf",value:function(){var _collectOnePdf=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4(docs){var _yield$import,PDFDocument,mergedDoc,_iterator2,_step2,doc,pdfBytes,copiedPages,_iterator3,_step3,page;return _regeneratorRuntime().wrap(function _callee4$(_context4){while(1)switch(_context4.prev=_context4.next){case 0:_context4.next=2;return import("pdf-lib");case 2:_yield$import=_context4.sent;PDFDocument=_yield$import.PDFDocument;_context4.next=6;return PDFDocument.create();case 6:mergedDoc=_context4.sent;_iterator2=_createForOfIteratorHelper(docs);_context4.prev=8;_iterator2.s();case 10:if((_step2=_iterator2.n()).done){_context4.next=22;break}doc=_step2.value;_context4.next=14;return PDFDocument.load(doc.data);case 14:pdfBytes=_context4.sent;_context4.next=17;return mergedDoc.copyPages(pdfBytes,pdfBytes.getPageIndices());case 17:copiedPages=_context4.sent;_iterator3=_createForOfIteratorHelper(copiedPages);try{for(_iterator3.s();!(_step3=_iterator3.n()).done;){page=_step3.value;mergedDoc.addPage(page)}}catch(err){_iterator3.e(err)}finally{_iterator3.f()}case 20:_context4.next=10;break;case 22:_context4.next=27;break;case 24:_context4.prev=24;_context4.t0=_context4["catch"](8);_iterator2.e(_context4.t0);case 27:_context4.prev=27;_iterator2.f();return _context4.finish(27);case 30:_context4.next=32;return mergedDoc.save();case 32:return _context4.abrupt("return",_context4.sent);case 33:case"end":return _context4.stop()}},_callee4,null,[[8,24,27,30]])}));function collectOnePdf(_x6){return _collectOnePdf.apply(this,arguments)}return collectOnePdf}()},{key:"collectOneZip",value:function(){var _collectOneZip=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee5(docs,fileName){var mergedDoc,_iterator4,_step4,doc,file,ext,appendix;return _regeneratorRuntime().wrap(function _callee5$(_context5){while(1)switch(_context5.prev=_context5.next){case 0:mergedDoc=new JSZip;_iterator4=_createForOfIteratorHelper(docs);try{for(_iterator4.s();!(_step4=_iterator4.n()).done;){doc=_step4.value;file=new Blob([doc.data],{type:doc.contentType});ext=this.state.selectedFormat.split(";")[0].split("/").pop();appendix=doc.name?"_"+doc.name:"";mergedDoc.file(fileName+appendix+"."+ext,file)}}catch(err){_iterator4.e(err)}finally{_iterator4.f()}_context5.next=5;return mergedDoc.generateAsync({type:"arraybuffer"});case 5:return _context5.abrupt("return",_context5.sent);case 6:case"end":return _context5.stop()}},_callee5,this)}));function collectOneZip(_x7,_x8){return _collectOneZip.apply(this,arguments)}return collectOneZip}()}])}(React.Component);_defineProperty(Print,"propTypes",{active:PropTypes.bool,addLayerFeatures:PropTypes.func,/** Whether to allow GeoPDF export. Requires QGIS Server 3.32 or newer. */allowGeoPdfExport:PropTypes.bool,clearLayer:PropTypes.func,/** The default print dpi. */defaultDpi:PropTypes.number,/** The factor to apply to the map scale to determine the initial print map scale. */defaultScaleFactor:PropTypes.number,/** Show an option to print a series of extents. */displayPrintSeries:PropTypes.bool,/** Whether to display the printing rotation control. */displayRotation:PropTypes.bool,/** Template for the name of the generated files when downloading. */fileNameTemplate:PropTypes.string,/** Export layout format mimetypes. If format is not supported by QGIS Server, print will fail. */formats:PropTypes.arrayOf(PropTypes.string),/** Whether the grid is enabled by default. */gridInitiallyEnabled:PropTypes.bool,/** Whether to hide form fields which contain autopopulated values (i.e. search result label). */hideAutopopulatedFields:PropTypes.bool,/** Whether to display the print output in an inline dialog instead triggering a download. */inlinePrintOutput:PropTypes.bool,layers:PropTypes.array,map:PropTypes.object,/** Whether to print external layers. Requires QGIS Server 3.x! */printExternalLayers:PropTypes.bool,/** Scale factor to apply to line widths, font sizes, ... of redlining drawings passed to GetPrint. */scaleFactor:PropTypes.number,setIdentifyEnabled:PropTypes.func,setSnappingConfig:PropTypes.func,/** The side of the application on which to display the sidebar. */side:PropTypes.string,theme:PropTypes.object});_defineProperty(Print,"defaultProps",{defaultDpi:300,defaultScaleFactor:0.5,displayPrintSeries:false,displayRotation:true,fileNameTemplate:"{theme}_{timestamp}",gridInitiallyEnabled:false,formats:["application/pdf","image/jpeg","image/png","image/svg"],inlinePrintOutput:false,printExternalLayers:true,scaleFactor:1.9,// Experimentally determined...
21
+ if(this.props.inlinePrintOutput&&files.length===1){file=files.pop();fileURL=URL.createObjectURL(file.content);this.setState({pdfData:file,pdfDataUrl:fileURL,outputLoaded:true})}else{_iterator=_createForOfIteratorHelper(files);try{for(_iterator.s();!(_step=_iterator.n()).done;){_file=_step.value;FileSaver.saveAs(_file.content,_file.fileName)}}catch(err){_iterator.e(err)}finally{_iterator.f()}}case 8:case"end":return _context.stop()}},_callee,this)}));function batchPrint(_x,_x2){return _batchPrint.apply(this,arguments)}return batchPrint}()},{key:"printRequest",value:function(){var _printRequest=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(formData){var data,config,response,contentType;return _regeneratorRuntime().wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:data=Object.entries(formData).map(function(pair){return pair.map(function(entry){return encodeURIComponent(entry).replace(/%20/g,"+")}).join("=")}).join("&");config={headers:{"Content-Type":"application/x-www-form-urlencoded"},responseType:"arraybuffer"};_context2.next=4;return axios.post(this.props.theme.printUrl,data,config);case 4:response=_context2.sent;contentType=response.headers["content-type"];return _context2.abrupt("return",{name:formData.name,data:response.data,contentType:contentType});case 7:case"end":return _context2.stop()}},_callee2,this)}));function printRequest(_x3){return _printRequest.apply(this,arguments)}return printRequest}()},{key:"collectFiles",value:function(){var _collectFiles=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(docs,fileName){var _this4=this;var data,content,_data,_content;return _regeneratorRuntime().wrap(function _callee3$(_context3){while(1)switch(_context3.prev=_context3.next){case 0:if(!(docs.length>1&&this.state.downloadMode==="onepdf")){_context3.next=6;break}_context3.next=3;return this.collectOnePdf(docs);case 3:data=_context3.sent;content=new Blob([data],{type:"application/pdf"});return _context3.abrupt("return",[{content:content,fileName:fileName+".pdf"}]);case 6:if(!(docs.length>1&&this.state.downloadMode==="onezip")){_context3.next=12;break}_context3.next=9;return this.collectOneZip(docs,fileName);case 9:_data=_context3.sent;_content=new Blob([_data],{type:"application/zip"});return _context3.abrupt("return",[{content:_content,fileName:fileName+".zip"}]);case 12:return _context3.abrupt("return",docs.map(function(doc){var content=new Blob([doc.data],{type:doc.contentType});var ext=_this4.state.selectedFormat.split(";")[0].split("/").pop();var appendix=doc.name?"_"+doc.name:"";return{content:content,fileName:fileName+appendix+"."+ext}}));case 13:case"end":return _context3.stop()}},_callee3,this)}));function collectFiles(_x4,_x5){return _collectFiles.apply(this,arguments)}return collectFiles}()},{key:"collectOnePdf",value:function(){var _collectOnePdf=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4(docs){var _yield$import,PDFDocument,mergedDoc,_iterator2,_step2,doc,pdfBytes,copiedPages,_iterator3,_step3,page;return _regeneratorRuntime().wrap(function _callee4$(_context4){while(1)switch(_context4.prev=_context4.next){case 0:_context4.next=2;return import("pdf-lib");case 2:_yield$import=_context4.sent;PDFDocument=_yield$import.PDFDocument;_context4.next=6;return PDFDocument.create();case 6:mergedDoc=_context4.sent;_iterator2=_createForOfIteratorHelper(docs);_context4.prev=8;_iterator2.s();case 10:if((_step2=_iterator2.n()).done){_context4.next=22;break}doc=_step2.value;_context4.next=14;return PDFDocument.load(doc.data);case 14:pdfBytes=_context4.sent;_context4.next=17;return mergedDoc.copyPages(pdfBytes,pdfBytes.getPageIndices());case 17:copiedPages=_context4.sent;_iterator3=_createForOfIteratorHelper(copiedPages);try{for(_iterator3.s();!(_step3=_iterator3.n()).done;){page=_step3.value;mergedDoc.addPage(page)}}catch(err){_iterator3.e(err)}finally{_iterator3.f()}case 20:_context4.next=10;break;case 22:_context4.next=27;break;case 24:_context4.prev=24;_context4.t0=_context4["catch"](8);_iterator2.e(_context4.t0);case 27:_context4.prev=27;_iterator2.f();return _context4.finish(27);case 30:_context4.next=32;return mergedDoc.save();case 32:return _context4.abrupt("return",_context4.sent);case 33:case"end":return _context4.stop()}},_callee4,null,[[8,24,27,30]])}));function collectOnePdf(_x6){return _collectOnePdf.apply(this,arguments)}return collectOnePdf}()},{key:"collectOneZip",value:function(){var _collectOneZip=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee5(docs,fileName){var mergedDoc,_iterator4,_step4,doc,file,ext,appendix;return _regeneratorRuntime().wrap(function _callee5$(_context5){while(1)switch(_context5.prev=_context5.next){case 0:mergedDoc=new JSZip;_iterator4=_createForOfIteratorHelper(docs);try{for(_iterator4.s();!(_step4=_iterator4.n()).done;){doc=_step4.value;file=new Blob([doc.data],{type:doc.contentType});ext=this.state.selectedFormat.split(";")[0].split("/").pop();appendix=doc.name?"_"+doc.name:"";mergedDoc.file(fileName+appendix+"."+ext,file)}}catch(err){_iterator4.e(err)}finally{_iterator4.f()}_context5.next=5;return mergedDoc.generateAsync({type:"arraybuffer"});case 5:return _context5.abrupt("return",_context5.sent);case 6:case"end":return _context5.stop()}},_callee5,this)}));function collectOneZip(_x7,_x8){return _collectOneZip.apply(this,arguments)}return collectOneZip}()}])}(React.Component);_defineProperty(Print,"propTypes",{active:PropTypes.bool,addLayerFeatures:PropTypes.func,/** Whether to allow GeoPDF export. Requires QGIS Server 3.32 or newer. */allowGeoPdfExport:PropTypes.bool,clearLayer:PropTypes.func,/** The default print dpi. */defaultDpi:PropTypes.number,/** The factor to apply to the map scale to determine the initial print map scale. */defaultScaleFactor:PropTypes.number,/** Show an option to print a series of extents. */displayPrintSeries:PropTypes.bool,/** Whether to display the printing rotation control. */displayRotation:PropTypes.bool,/** Template for the name of the generated files when downloading. Can contain the placeholders `{username}`, `{tenant}`, `{theme}`, `{timestamp}`. */fileNameTemplate:PropTypes.string,/** Export layout format mimetypes. If format is not supported by QGIS Server, print will fail. */formats:PropTypes.arrayOf(PropTypes.string),/** Whether the grid is enabled by default. */gridInitiallyEnabled:PropTypes.bool,/** Whether to hide form fields which contain autopopulated values (i.e. search result label). */hideAutopopulatedFields:PropTypes.bool,/** Whether to display the print output in an inline dialog instead triggering a download. */inlinePrintOutput:PropTypes.bool,layers:PropTypes.array,map:PropTypes.object,/** Whether to print external layers. Requires QGIS Server 3.x! */printExternalLayers:PropTypes.bool,/** Scale factor to apply to line widths, font sizes, ... of redlining drawings passed to GetPrint. */scaleFactor:PropTypes.number,setIdentifyEnabled:PropTypes.func,setSnappingConfig:PropTypes.func,/** The side of the application on which to display the sidebar. */side:PropTypes.string,theme:PropTypes.object});_defineProperty(Print,"defaultProps",{defaultDpi:300,defaultScaleFactor:0.5,displayPrintSeries:false,displayRotation:true,fileNameTemplate:"{theme}_{timestamp}",gridInitiallyEnabled:false,formats:["application/pdf","image/jpeg","image/png","image/svg"],inlinePrintOutput:false,printExternalLayers:true,scaleFactor:1.9,// Experimentally determined...
22
22
  side:"right"});var selector=function selector(state){return{active:state.task.id==="Print",theme:state.theme.current,map:state.map,layers:state.layers.flat}};export default connect(selector,{addLayerFeatures:addLayerFeatures,clearLayer:clearLayer,setSnappingConfig:setSnappingConfig})(Print);
@@ -4,8 +4,8 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
- */import React from"react";import{Line}from"react-chartjs-2";import{connect}from"react-redux";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{v1 as uuidv1}from"uuid";import{LayerRole}from"../actions/layers";import{setCurrentTask}from"../actions/task";import Icon from"../components/Icon";import ResizeableWindow from"../components/ResizeableWindow";import ButtonBar from"../components/widgets/ButtonBar";import TextInput from"../components/widgets/TextInput";import IdentifyUtils from"../utils/IdentifyUtils";import LayerUtils from"../utils/LayerUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import"./style/ValueTool.css";/**
7
+ */import React from"react";import{Line}from"react-chartjs-2";import{connect}from"react-redux";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{v1 as uuidv1}from"uuid";import{LayerRole}from"../actions/layers";import{setCurrentTask}from"../actions/task";import Icon from"../components/Icon";import ResizeableWindow from"../components/ResizeableWindow";import ButtonBar from"../components/widgets/ButtonBar";import NumberInput from"../components/widgets/NumberInput";import TextInput from"../components/widgets/TextInput";import IdentifyUtils from"../utils/IdentifyUtils";import LayerUtils from"../utils/LayerUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import"./style/ValueTool.css";/**
8
8
  * Displays raster band values of active raster layers at the hovered mouse position,
9
9
  * queried via GetFeatureInfo.
10
- */var ValueTool=/*#__PURE__*/function(_React$Component){function ValueTool(props){var _this;_classCallCheck(this,ValueTool);_this=_callSuper(this,ValueTool,[props]);_defineProperty(_this,"renderTableTab",function(){if(isEmpty(_this.state.values)){return/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement("i",null,LocaleUtils.tr("valuetool.nodata")))}return/*#__PURE__*/React.createElement("table",{className:"valuetool-table"},/*#__PURE__*/React.createElement("tbody",null,Object.entries(_this.state.values).map(function(_ref){var _ref2=_slicedToArray(_ref,2),key=_ref2[0],data=_ref2[1];var bandvals=Object.entries(data.values);if(_this.state.selectedBands[key]){var activeBands=_this.state.selectedBands[key].split(",").map(function(x){return parseInt(x.trim(),10)-1});bandvals=bandvals.filter(function(_,i){return activeBands.includes(i)})}return[/*#__PURE__*/React.createElement("tr",{key:key},/*#__PURE__*/React.createElement("th",{colSpan:"2"},data.layertitle)),bandvals.map(function(_ref3){var _ref4=_slicedToArray(_ref3,2),bandname=_ref4[0],bandval=_ref4[1];return/*#__PURE__*/React.createElement("tr",{key:key+"_"+bandname},/*#__PURE__*/React.createElement("td",null,bandname),/*#__PURE__*/React.createElement("td",null,bandval))})]})))});_defineProperty(_this,"renderGraphTab",function(){var values=Object.values(_this.state.values).map(function(x){return Object.values(x.values)}).flat().filter(function(x){return x});var data={labels:values.map(function(_,i){return String(i)}),datasets:[{data:values,borderColor:"rgb(255,0,0)",borderWidth:2}]};var options={responsive:true,maintainAspectRatio:false,animation:{duration:0}};return/*#__PURE__*/React.createElement("div",{className:"valuetool-chart-container"},/*#__PURE__*/React.createElement(Line,{data:data,options:options}))});_defineProperty(_this,"renderOptionsTab",function(){var options=_this.state.showLayers==="selected"||_this.state.showBands==="selected"?[/*#__PURE__*/React.createElement("hr",{key:"sep"}),/*#__PURE__*/React.createElement("div",{key:"label"},LocaleUtils.tr("valuetool.selectlayersbands")),/*#__PURE__*/React.createElement("table",{className:"valuetool-table-selection",key:"table"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("th",null,LocaleUtils.tr("valuetool.layer")),_this.state.showBands==="selected"?/*#__PURE__*/React.createElement("th",null,LocaleUtils.tr("valuetool.bands")):null),_this.props.layers.map(function(layer){var sublayers=LayerUtils.getSublayerNames(layer,true,function(sublayer){return sublayer.geometryType===null});return sublayers.map(function(sublayer){var key=layer.url+"#"+sublayer;return/*#__PURE__*/React.createElement("tr",{key:key},/*#__PURE__*/React.createElement("td",null,_this.state.showLayers==="selected"?/*#__PURE__*/React.createElement(Icon,{icon:_this.state.selectedLayers.includes(key)?"checked":"unchecked",onClick:function onClick(){return _this.toggleSelectedLayer(key)}}):null,sublayer),_this.state.showBands==="selected"?/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement(TextInput,{onChange:function onChange(value){return _this.setLayerBands(key,value)},placeholder:LocaleUtils.tr("valuetool.all"),value:_this.state.selectedBands[key]||""})):null)})})))]:null;return/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement("table",{className:"valuetool-table-options"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("valuetool.showlayers"),":"),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({showLayers:ev.target.value})},value:_this.state.showLayers},/*#__PURE__*/React.createElement("option",{value:"visible"},LocaleUtils.tr("valuetool.visiblelayers")),/*#__PURE__*/React.createElement("option",{value:"all"},LocaleUtils.tr("valuetool.alllayers")),/*#__PURE__*/React.createElement("option",{value:"selected"},LocaleUtils.tr("valuetool.selectedlayers"))))),/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("valuetool.showbands"),":"),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({showBands:ev.target.value})},value:_this.state.showBands},/*#__PURE__*/React.createElement("option",{value:"all"},LocaleUtils.tr("valuetool.allbands")),/*#__PURE__*/React.createElement("option",{value:"selected"},LocaleUtils.tr("valuetool.selectedbands"))))))),options)});_defineProperty(_this,"toggleSelectedLayer",function(key){_this.setState(function(state){return{selectedLayers:state.selectedLayers.includes(key)?state.selectedLayers.filter(function(x){return x!==key}):[].concat(_toConsumableArray(state.selectedLayers),[key])}})});_defineProperty(_this,"setLayerBands",function(key,bands){_this.setState(function(state){return{selectedBands:_objectSpread(_objectSpread({},state.selectedBands),{},_defineProperty({},key,_toConsumableArray(new Set(bands.split(",").map(function(x){return parseInt(x.trim(),10)||0}).sort().filter(function(x){return x}))).join(", ")))}})});_defineProperty(_this,"onWindowClose",function(){_this.props.setCurrentTask(null)});_defineProperty(_this,"scheduleQueryValues",function(ev){var coordinate=ev.coordinate;clearTimeout(_this.queryTimeout);_this.queryTimeout=setTimeout(function(){return _this.queryValues(coordinate)},100)});_defineProperty(_this,"queryValues",function(coordinate){var options={info_format:"text/xml",feature_count:5,with_geometry:false,with_htmlcontent:false};var reqId=uuidv1();_this.reqId=reqId;var newValues={};_this.props.layers.forEach(function(layer){var layerActive=null;if(_this.state.showLayers==="all"){layerActive=function layerActive(){return true}}else if(_this.state.showLayers==="selected"){layerActive=function layerActive(sublayer){return _this.state.selectedLayers.includes(layer.url+"#"+sublayer.name)}}else if(_this.state.showLayers==="visible"){layerActive=function layerActive(sublayer){return sublayer.visibility}}var queryLayers=LayerUtils.getSublayerNames(layer,true,function(sublayer){return layerActive(sublayer)&&sublayer.geometryType===null});if(isEmpty(queryLayers)){return}// Preserve previous result rows, but with empty values, to prevent "flickering"
11
- queryLayers.forEach(function(sublayername){var key=layer.url+"#"+sublayername;if(_this.state.values[key]){newValues[key]=_objectSpread(_objectSpread({},_this.state.values[key]),{},{values:Object.fromEntries(Object.keys(_this.state.values[key].values).map(function(k){return[k,""]}))})}});var request=IdentifyUtils.buildRequest(layer,queryLayers.join(","),coordinate,_this.props.map,options);IdentifyUtils.sendRequest(request,function(response){if(_this.reqId===reqId){var result=IdentifyUtils.parseXmlResponse(response||"",_this.props.map.projection);_this.setState(function(state){return{values:_objectSpread(_objectSpread({},state.values),Object.entries(result).reduce(function(res,_ref5){var _ref6=_slicedToArray(_ref5,2),sublayername=_ref6[0],features=_ref6[1];var key=layer.url+"#"+sublayername;res[key]={layertitle:features[0].layertitle,values:features[0].properties};return res},{}))}})}})});_this.setState({values:newValues})});_this.queryTimeout=null;_this.reqId=null;_this.state=ValueTool.defaultState;return _this}_inherits(ValueTool,_React$Component);return _createClass(ValueTool,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){if(this.props.enabled&&!prevProps.enabled){MapUtils.getHook(MapUtils.GET_MAP).on("pointermove",this.scheduleQueryValues)}else if(!this.props.enabled&&prevProps.enabled){MapUtils.getHook(MapUtils.GET_MAP).un("pointermove",this.scheduleQueryValues);clearTimeout(this.queryTimeout);this.queryTimeout=null;this.setState(ValueTool.defaultState)}}},{key:"render",value:function render(){var _this2=this;if(!this.props.enabled){return null}var buttons=[{key:"Table",label:LocaleUtils.tr("valuetool.table")},{key:"Graph",label:LocaleUtils.tr("valuetool.graph")},{key:"Options",label:LocaleUtils.tr("valuetool.options")}];var tab=null;if(this.state.activeTab==="Table"){tab=this.renderTableTab()}else if(this.state.activeTab==="Graph"){tab=this.renderGraphTab()}else if(this.state.activeTab==="Options"){tab=this.renderOptionsTab()}return/*#__PURE__*/React.createElement(ResizeableWindow,{dockable:this.props.geometry.side,icon:"info-sign",initialHeight:this.props.geometry.initialHeight,initialWidth:this.props.geometry.initialWidth,initialX:this.props.geometry.initialX,initialY:this.props.geometry.initialY,initiallyDocked:this.props.geometry.initiallyDocked,onClose:this.onWindowClose,title:LocaleUtils.tr("valuetool.title")},/*#__PURE__*/React.createElement("div",{className:"valuetool-body",role:"body"},/*#__PURE__*/React.createElement(ButtonBar,{active:this.state.activeTab,buttons:buttons,onClick:function onClick(key){return _this2.setState({activeTab:key})}}),tab))}}])}(React.Component);_defineProperty(ValueTool,"propTypes",{/** The number of decimal places to display for elevation values. */enabled:PropTypes.bool,/** Default window geometry with size, position and docking status. Positive position values (including '0') are related to top (InitialY) and left (InitialX), negative values (including '-0') to bottom (InitialY) and right (InitialX). */geometry:PropTypes.shape({initialWidth:PropTypes.number,initialHeight:PropTypes.number,initialX:PropTypes.number,initialY:PropTypes.number,initiallyDocked:PropTypes.bool,side:PropTypes.string}),layers:PropTypes.array,map:PropTypes.object,setCurrentTask:PropTypes.func});_defineProperty(ValueTool,"defaultProps",{geometry:{initialWidth:240,initialHeight:320,initialX:0,initialY:0,initiallyDocked:false,side:"left"}});_defineProperty(ValueTool,"defaultState",{activeTab:"Table",showLayers:"visible",showBands:"all",selectedLayers:[],selectedBands:{},values:{}});export default connect(function(state){return{enabled:state.task.id==="ValueTool",layers:state.layers.flat.filter(function(layer){return(layer.role===LayerRole.THEME||layer.role===LayerRole.USERLAYER)&&(layer.infoFormats||[]).includes("text/xml")}),map:state.map}},{setCurrentTask:setCurrentTask})(ValueTool);
10
+ */var ValueTool=/*#__PURE__*/function(_React$Component){function ValueTool(props){var _this;_classCallCheck(this,ValueTool);_this=_callSuper(this,ValueTool,[props]);_defineProperty(_this,"renderTableTab",function(){if(isEmpty(_this.state.values)){return/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement("i",null,LocaleUtils.tr("valuetool.nodata")))}return/*#__PURE__*/React.createElement("table",{className:"valuetool-table"},/*#__PURE__*/React.createElement("tbody",null,Object.entries(_this.state.values).map(function(_ref){var _ref2=_slicedToArray(_ref,2),key=_ref2[0],data=_ref2[1];var bandvals=Object.entries(data.values);if(_this.state.selectedBands[key]){var activeBands=_this.state.selectedBands[key].split(",").map(function(x){return parseInt(x.trim(),10)-1});bandvals=bandvals.filter(function(_,i){return activeBands.includes(i)})}return[/*#__PURE__*/React.createElement("tr",{key:key},/*#__PURE__*/React.createElement("th",{colSpan:"2"},data.layertitle)),bandvals.map(function(_ref3){var _ref4=_slicedToArray(_ref3,2),bandname=_ref4[0],bandval=_ref4[1];return/*#__PURE__*/React.createElement("tr",{key:key+"_"+bandname},/*#__PURE__*/React.createElement("td",null,bandname),/*#__PURE__*/React.createElement("td",null,bandval))})]})))});_defineProperty(_this,"renderGraphTab",function(){var values=Object.values(_this.state.values).map(function(x){return Object.values(x.values)}).flat().filter(function(x){return x});var data={labels:values.map(function(_,i){return String(i)}),datasets:[{data:values,borderColor:"rgb(255,0,0)",borderWidth:2}]};var yAxisConfig={};if(_this.state.graphMinY){yAxisConfig.min=_this.state.graphMinY}if(_this.state.graphMaxY){yAxisConfig.max=_this.state.graphMaxY}var options={responsive:true,maintainAspectRatio:false,animation:{duration:0},scales:{y:yAxisConfig}};return/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement("div",{className:"valuetool-chart-options"},/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("valuetool.ymin"),": "),/*#__PURE__*/React.createElement(NumberInput,{onChange:function onChange(value){return _this.setState({graphMinY:value})},value:_this.state.graphMinY}),/*#__PURE__*/React.createElement("span",{style:{marginLeft:"0.5em"}}),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("valuetool.ymax"),": "),/*#__PURE__*/React.createElement(NumberInput,{onChange:function onChange(value){return _this.setState({graphMaxY:value})},value:_this.state.graphMaxY})),/*#__PURE__*/React.createElement("div",{className:"valuetool-chart-container"},/*#__PURE__*/React.createElement(Line,{data:data,options:options})))});_defineProperty(_this,"renderOptionsTab",function(){var options=_this.state.showLayers==="selected"||_this.state.showBands==="selected"?[/*#__PURE__*/React.createElement("hr",{key:"sep"}),/*#__PURE__*/React.createElement("div",{key:"label"},LocaleUtils.tr("valuetool.selectlayersbands")),/*#__PURE__*/React.createElement("table",{className:"valuetool-table-selection",key:"table"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("th",null,LocaleUtils.tr("valuetool.layer")),_this.state.showBands==="selected"?/*#__PURE__*/React.createElement("th",null,LocaleUtils.tr("valuetool.bands")):null),_this.props.layers.map(function(layer){var sublayers=LayerUtils.getSublayerNames(layer,true,function(sublayer){return sublayer.geometryType===null});return sublayers.map(function(sublayer){var key=layer.url+"#"+sublayer;return/*#__PURE__*/React.createElement("tr",{key:key},/*#__PURE__*/React.createElement("td",null,_this.state.showLayers==="selected"?/*#__PURE__*/React.createElement(Icon,{icon:_this.state.selectedLayers.includes(key)?"checked":"unchecked",onClick:function onClick(){return _this.toggleSelectedLayer(key)}}):null,sublayer),_this.state.showBands==="selected"?/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement(TextInput,{onChange:function onChange(value){return _this.setLayerBands(key,value)},placeholder:LocaleUtils.tr("valuetool.all"),value:_this.state.selectedBands[key]||""})):null)})})))]:null;return/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement("table",{className:"valuetool-table-options"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("valuetool.showlayers"),":"),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({showLayers:ev.target.value})},value:_this.state.showLayers},/*#__PURE__*/React.createElement("option",{value:"visible"},LocaleUtils.tr("valuetool.visiblelayers")),/*#__PURE__*/React.createElement("option",{value:"all"},LocaleUtils.tr("valuetool.alllayers")),/*#__PURE__*/React.createElement("option",{value:"selected"},LocaleUtils.tr("valuetool.selectedlayers"))))),/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("valuetool.showbands"),":"),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({showBands:ev.target.value})},value:_this.state.showBands},/*#__PURE__*/React.createElement("option",{value:"all"},LocaleUtils.tr("valuetool.allbands")),/*#__PURE__*/React.createElement("option",{value:"selected"},LocaleUtils.tr("valuetool.selectedbands"))))))),options)});_defineProperty(_this,"toggleSelectedLayer",function(key){_this.setState(function(state){return{selectedLayers:state.selectedLayers.includes(key)?state.selectedLayers.filter(function(x){return x!==key}):[].concat(_toConsumableArray(state.selectedLayers),[key])}})});_defineProperty(_this,"setLayerBands",function(key,bands){_this.setState(function(state){return{selectedBands:_objectSpread(_objectSpread({},state.selectedBands),{},_defineProperty({},key,_toConsumableArray(new Set(bands.split(",").map(function(x){return parseInt(x.trim(),10)||0}).sort().filter(function(x){return x}))).join(", ")))}})});_defineProperty(_this,"onWindowClose",function(){_this.props.setCurrentTask(null)});_defineProperty(_this,"scheduleQueryValues",function(ev){var coordinate=ev.coordinate;clearTimeout(_this.queryTimeout);_this.queryTimeout=setTimeout(function(){return _this.queryValues(coordinate)},100)});_defineProperty(_this,"queryValues",function(coordinate){var options={info_format:"text/xml",feature_count:5,with_geometry:false,with_htmlcontent:false};var reqId=uuidv1();_this.reqId=reqId;var newValues={};_this.props.layers.forEach(function(layer){var layerActive=null;if(_this.state.showLayers==="all"){layerActive=function layerActive(){return true}}else if(_this.state.showLayers==="selected"){layerActive=function layerActive(sublayer){return _this.state.selectedLayers.includes(layer.url+"#"+sublayer.name)}}else if(_this.state.showLayers==="visible"){layerActive=function layerActive(sublayer){return sublayer.visibility}}var queryLayers=LayerUtils.getSublayerNames(layer,true,function(sublayer){return layerActive(sublayer)&&sublayer.geometryType===null});if(isEmpty(queryLayers)){return}// Preserve previous result rows, but with empty values, to prevent "flickering"
11
+ queryLayers.forEach(function(sublayername){var key=layer.url+"#"+sublayername;if(_this.state.values[key]){newValues[key]=_objectSpread(_objectSpread({},_this.state.values[key]),{},{values:Object.fromEntries(Object.keys(_this.state.values[key].values).map(function(k){return[k,""]}))})}});var request=IdentifyUtils.buildRequest(layer,queryLayers.join(","),coordinate,_this.props.map,options);IdentifyUtils.sendRequest(request,function(response){if(_this.reqId===reqId){var result=IdentifyUtils.parseXmlResponse(response||"",_this.props.map.projection);_this.setState(function(state){return{values:_objectSpread(_objectSpread({},state.values),Object.entries(result).reduce(function(res,_ref5){var _ref6=_slicedToArray(_ref5,2),sublayername=_ref6[0],features=_ref6[1];var key=layer.url+"#"+sublayername;res[key]={layertitle:features[0].layertitle,values:features[0].properties};return res},{}))}})}})});_this.setState({values:newValues})});_this.queryTimeout=null;_this.reqId=null;_this.state=ValueTool.defaultState;return _this}_inherits(ValueTool,_React$Component);return _createClass(ValueTool,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){if(this.props.enabled&&!prevProps.enabled){MapUtils.getHook(MapUtils.GET_MAP).on("pointermove",this.scheduleQueryValues)}else if(!this.props.enabled&&prevProps.enabled){MapUtils.getHook(MapUtils.GET_MAP).un("pointermove",this.scheduleQueryValues);clearTimeout(this.queryTimeout);this.queryTimeout=null;this.setState(ValueTool.defaultState)}}},{key:"render",value:function render(){var _this2=this;if(!this.props.enabled){return null}var buttons=[{key:"Table",label:LocaleUtils.tr("valuetool.table")},{key:"Graph",label:LocaleUtils.tr("valuetool.graph")},{key:"Options",label:LocaleUtils.tr("valuetool.options")}];var tab=null;if(this.state.activeTab==="Table"){tab=this.renderTableTab()}else if(this.state.activeTab==="Graph"){tab=this.renderGraphTab()}else if(this.state.activeTab==="Options"){tab=this.renderOptionsTab()}return/*#__PURE__*/React.createElement(ResizeableWindow,{dockable:this.props.geometry.side,icon:"info-sign",initialHeight:this.props.geometry.initialHeight,initialWidth:this.props.geometry.initialWidth,initialX:this.props.geometry.initialX,initialY:this.props.geometry.initialY,initiallyDocked:this.props.geometry.initiallyDocked,onClose:this.onWindowClose,title:LocaleUtils.tr("valuetool.title")},/*#__PURE__*/React.createElement("div",{className:"valuetool-body",role:"body"},/*#__PURE__*/React.createElement(ButtonBar,{active:this.state.activeTab,buttons:buttons,onClick:function onClick(key){return _this2.setState({activeTab:key})}}),tab))}}])}(React.Component);_defineProperty(ValueTool,"propTypes",{/** The number of decimal places to display for elevation values. */enabled:PropTypes.bool,/** Default window geometry with size, position and docking status. Positive position values (including '0') are related to top (InitialY) and left (InitialX), negative values (including '-0') to bottom (InitialY) and right (InitialX). */geometry:PropTypes.shape({initialWidth:PropTypes.number,initialHeight:PropTypes.number,initialX:PropTypes.number,initialY:PropTypes.number,initiallyDocked:PropTypes.bool,side:PropTypes.string}),layers:PropTypes.array,map:PropTypes.object,setCurrentTask:PropTypes.func});_defineProperty(ValueTool,"defaultProps",{geometry:{initialWidth:240,initialHeight:320,initialX:0,initialY:0,initiallyDocked:false,side:"left"}});_defineProperty(ValueTool,"defaultState",{activeTab:"Table",showLayers:"visible",showBands:"all",selectedLayers:[],selectedBands:{},values:{},graphMinY:null,graphMaxY:null});export default connect(function(state){return{enabled:state.task.id==="ValueTool",layers:state.layers.flat.filter(function(layer){return(layer.role===LayerRole.THEME||layer.role===LayerRole.USERLAYER)&&(layer.infoFormats||[]).includes("text/xml")}),map:state.map}},{setCurrentTask:setCurrentTask})(ValueTool);
package/plugins/View3D.js CHANGED
@@ -6,6 +6,26 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */import React from"react";import{connect,Provider}from"react-redux";import PropTypes from"prop-types";import{createSelector}from"reselect";import*as displayExports from"../actions/display";import{setView3dMode,View3DMode}from"../actions/display";import{setCurrentTask}from"../actions/task";import*as themeExports from"../actions/theme";import PluginsContainer from"../components/PluginsContainer";import ResizeableWindow from"../components/ResizeableWindow";import StandardApp from"../components/StandardApp";import View3DSwitcher from"../components/map3d/View3DSwitcher";import map3dReducer from"../components/map3d/slices/map3d";import ReducerIndex from"../reducers/index";import searchProvidersSelector from"../selectors/searchproviders";import{createStore}from"../stores/StandardStore";import LocaleUtils from"../utils/LocaleUtils";import{UrlParams}from"../utils/PermaLinkUtils";/**
8
8
  * Displays a 3D map view.
9
+ *
10
+ * To add a 3D View to a theme, add the following configuration block to a theme item in `themesConfig.json`:
11
+ * ```
12
+ * "map3d": {
13
+ * "dtm": {"url": "<url_to_dtm.tif>", "crs": "<dtm_epsg_code>},
14
+ * "basemaps": [
15
+ * {"name": "<name_of_background_layer>", "visibility": true},
16
+ * {"name": "<name_of_background_layer>"},
17
+ * ...
18
+ * ],
19
+ * "tiles3d": [
20
+ * {"name": "<name>", "url": "<url_to_tileset.json>", "title": "<title>", "colorAttr": "<tile_batch_attr>"}
21
+ * ]
22
+ * }
23
+ * ```
24
+ * Where:
25
+ *
26
+ * - The DTM should be a cloud optimized GeoTIFF.
27
+ * - The background layer names refer to the names of the entries defined in `backgroundLayers` in the `themesConfig.json`.
28
+ * - The optional `colorAttr` is the name of an attribute stored in the tileset batch table which stores the batch color, as a 0xRRGGBB integer.
9
29
  */var View3D=/*#__PURE__*/function(_React$Component){function View3D(props){var _this;_classCallCheck(this,View3D);_this=_callSuper(this,View3D,[props]);_defineProperty(_this,"state",{componentLoaded:false,windowDetached:false});_defineProperty(_this,"render3DWindow",function(){if(_this.props.display.view3dMode>View3DMode.DISABLED){var extraControls=[{icon:"sync",callback:_this.setViewToExtent,title:LocaleUtils.tr("map3d.syncview")}];if(!_this.state.windowDetached){extraControls.push({icon:"maximize",callback:function callback(){return _this.props.setView3dMode(View3DMode.FULLSCREEN)},title:LocaleUtils.tr("window.maximize")})}var Map3D=_this.map3dComponent;return/*#__PURE__*/React.createElement(ResizeableWindow,{extraControls:extraControls,fullscreen:_this.props.display.view3dMode===View3DMode.FULLSCREEN,icon:"map3d",initialHeight:_this.props.geometry.initialHeight,initialWidth:_this.props.geometry.initialWidth,initialX:_this.props.geometry.initialX,initialY:_this.props.geometry.initialY,initiallyDocked:_this.props.geometry.initiallyDocked,key:"View3DWindow",maximizeable:false,onClose:_this.onClose,onExternalWindowResized:_this.redrawScene,onGeometryChanged:_this.onGeometryChanged,splitScreenWhenDocked:true,splitTopAndBottomBar:true,title:LocaleUtils.tr("map3d.title")},_this.state.componentLoaded?/*#__PURE__*/React.createElement(Provider,{role:"body",store:_this.store},/*#__PURE__*/React.createElement(Map3D,{innerRef:_this.setRef,onMapInitialized:_this.setupMap,options:_this.props.options,searchProviders:_this.props.searchProviders,theme:_this.props.theme}),_this.props.view3dMode===View3DMode.FULLSCREEN?/*#__PURE__*/React.createElement(PluginsContainer,{plugins:_this.props.plugins,pluginsAppConfig:{},pluginsConfig:_this.props.pluginsConfig}):null):null)}return null});_defineProperty(_this,"onClose",function(){_this.props.setView3dMode(View3DMode.DISABLED);UrlParams.updateParams({v3d:undefined})});_defineProperty(_this,"onGeometryChanged",function(geometry){if(geometry.maximized&&_this.props.display.view3dMode!==View3DMode.FULLSCREEN){_this.props.setView3dMode(View3DMode.FULLSCREEN)}_this.setState({windowDetached:geometry.detached})});_defineProperty(_this,"setRef",function(ref){_this.map3dComponentRef=ref});_defineProperty(_this,"setViewToExtent",function(){if(_this.map3dComponentRef){_this.map3dComponentRef.setViewToExtent(_this.props.mapBBox.bounds,_this.props.mapBBox.rotation)}});_defineProperty(_this,"setupMap",function(){if(_this.map3dComponentRef&&_this.restoreOnComponentLoad){_this.restoreOnComponentLoad=false;var state3d=_objectSpread({},_this.props.startupState.map3d);if(_this.props.startupParams.v3d){var values=_this.props.startupParams.v3d.split(",").map(parseFloat).filter(function(x){return!isNaN(x)});if(values.length===6){state3d.center=[values[0],values[1],values[2]];state3d.cameraPos=[values[3],values[4],values[5]]}}_this.map3dComponentRef.restore3dState(state3d);if(!_this.props.startupParams.v3d){_this.setViewToExtent()}}else{_this.setViewToExtent()}});_defineProperty(_this,"redrawScene",function(ev){if(_this.map3dComponentRef){_this.map3dComponentRef.redrawScene(ev)}});_this.map3dComponent=null;_this.map3dComponentRef=null;// Subset of 2d reducers
10
30
  var _ReducerIndex$reducer=ReducerIndex.reducers,task=_ReducerIndex$reducer.task,windows=_ReducerIndex$reducer.windows;// Reducer for syncronization with parent store
11
31
  var forwardReducer=function forwardReducer(key,forwardActions,syncAction){return function(){var state=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var action=arguments.length>1?arguments[1]:undefined;if(forwardActions.includes(action.type)){// Forward to parent store
@@ -57,4 +57,14 @@ table.valuetool-table-options td > select {
57
57
 
58
58
  table.valuetool-table-options td:first-child {
59
59
  white-space: nowrap;
60
+ }
61
+
62
+ div.valuetool-chart-options {
63
+ display: flex;
64
+ align-items: center;
65
+ }
66
+
67
+ div.valuetool-chart-options > div.number-input {
68
+ flex: 1 1 auto;
69
+ margin-left: 0.25em;
60
70
  }
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "Няма",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "Žádná",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "Ebenen",
689
689
  "table": "Tabelle",
690
690
  "title": "Value Tool",
691
- "visiblelayers": "Sichtbare Ebenen"
691
+ "visiblelayers": "Sichtbare Ebenen",
692
+ "ymax": "Min Y",
693
+ "ymin": "Max Y"
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "Keine",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "Ebenen",
689
689
  "table": "Tabelle",
690
690
  "title": "Value Tool",
691
- "visiblelayers": "Sichtbare Ebenen"
691
+ "visiblelayers": "Sichtbare Ebenen",
692
+ "ymax": "Min Y",
693
+ "ymin": "Max Y"
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "Keine",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "Show layers",
689
689
  "table": "Table",
690
690
  "title": "Value Tool",
691
- "visiblelayers": "Visible"
691
+ "visiblelayers": "Visible",
692
+ "ymax": "Max Y",
693
+ "ymin": "Min Y"
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "None",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "Couches",
689
689
  "table": "Tableau",
690
690
  "title": "Value Tool",
691
- "visiblelayers": "Couches visibles"
691
+ "visiblelayers": "Couches visibles",
692
+ "ymax": "Min Y",
693
+ "ymin": "Max Y"
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "Aucune",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "Livelli",
689
689
  "table": "Tabelle",
690
690
  "title": "Value Tool",
691
- "visiblelayers": "Livelli visibili"
691
+ "visiblelayers": "Livelli visibili",
692
+ "ymax": "Min Y",
693
+ "ymin": "Max Y"
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "Nessuno",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "無し",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "Geen",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "Nenhum",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "Niciunul",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "",
@@ -688,7 +688,9 @@
688
688
  "showlayers": "",
689
689
  "table": "",
690
690
  "title": "",
691
- "visiblelayers": ""
691
+ "visiblelayers": "",
692
+ "ymax": "",
693
+ "ymin": ""
692
694
  },
693
695
  "vectorlayerpicker": {
694
696
  "none": "Yok",
@@ -591,6 +591,8 @@
591
591
  "valuetool.table",
592
592
  "valuetool.title",
593
593
  "valuetool.visiblelayers",
594
+ "valuetool.ymax",
595
+ "valuetool.ymin",
594
596
  "vectorlayerpicker.none",
595
597
  "vectorlayerpicker.prompt",
596
598
  "window.close",