qwc2 2025.4.14 → 2025.4.22

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.
Files changed (44) hide show
  1. package/components/AttributeTableWidget.js +1 -1
  2. package/components/AutoEditForm.js +1 -1
  3. package/components/EditUploadField.js +2 -2
  4. package/components/QtDesignerForm.js +1 -1
  5. package/components/WindowManager.js +1 -1
  6. package/components/map3d/ExportObjects3D.js +6 -3
  7. package/components/map3d/Identify3D.js +4 -4
  8. package/components/map3d/Map3D.js +9 -8
  9. package/components/map3d/Measure3D.js +7 -5
  10. package/components/map3d/style/Map3D.css +9 -0
  11. package/components/map3d/style/SearchField3D.css +4 -3
  12. package/components/map3d/utils/Tiles3DStyle.js +11 -1
  13. package/package.json +4 -3
  14. package/plugins/Bookmark.js +1 -1
  15. package/plugins/HeightProfile.js +9 -8
  16. package/plugins/MapInfoTooltip.js +5 -3
  17. package/plugins/View3D.js +29 -4
  18. package/reducers/layers.js +2 -1
  19. package/scripts/dist.sh +7 -1
  20. package/static/translations/bg-BG.json +1 -0
  21. package/static/translations/ca-ES.json +1 -0
  22. package/static/translations/cs-CZ.json +1 -0
  23. package/static/translations/de-CH.json +1 -0
  24. package/static/translations/de-DE.json +1 -0
  25. package/static/translations/en-US.json +1 -0
  26. package/static/translations/es-ES.json +1 -0
  27. package/static/translations/fi-FI.json +1 -0
  28. package/static/translations/fr-FR.json +1 -0
  29. package/static/translations/hu-HU.json +1 -0
  30. package/static/translations/it-IT.json +1 -0
  31. package/static/translations/ja-JP.json +1 -0
  32. package/static/translations/nl-NL.json +1 -0
  33. package/static/translations/no-NO.json +1 -0
  34. package/static/translations/pl-PL.json +1 -0
  35. package/static/translations/pt-BR.json +1 -0
  36. package/static/translations/pt-PT.json +1 -0
  37. package/static/translations/ro-RO.json +1 -0
  38. package/static/translations/ru-RU.json +1 -0
  39. package/static/translations/sv-SE.json +1 -0
  40. package/static/translations/tr-TR.json +1 -0
  41. package/static/translations/tsconfig.json +1 -0
  42. package/utils/EditingInterface.js +4 -1
  43. package/utils/ElevationInterface.js +25 -0
  44. package/utils/ServiceLayerUtils.js +2 -2
@@ -1,15 +1,17 @@
1
- function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}function _classCallCheck(a,n){if(!(a instanceof n))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var o=r[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,_toPropertyKey(o.key),o)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _callSuper(t,o,e){return o=_getPrototypeOf(o),_possibleConstructorReturn(t,_isNativeReflectConstruct()?Reflect.construct(o,e||[],_getPrototypeOf(t).constructor):o.apply(t,e))}function _possibleConstructorReturn(t,e){if(e&&("object"==_typeof(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return _assertThisInitialized(t)}function _assertThisInitialized(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _isNativeReflectConstruct(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(_isNativeReflectConstruct=function _isNativeReflectConstruct(){return!!t})()}function _getPrototypeOf(t){return _getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},_getPrototypeOf(t)}function _inherits(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&_setPrototypeOf(t,e)}function _setPrototypeOf(t,e){return _setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},_setPrototypeOf(t,e)}function _defineProperty(e,r,t){return(r=_toPropertyKey(r))in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+""}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(t)}/**
1
+ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}function _toConsumableArray(r){return _arrayWithoutHoles(r)||_iterableToArray(r)||_unsupportedIterableToArray(r)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0}}function _iterableToArray(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _arrayWithoutHoles(r){if(Array.isArray(r))return _arrayLikeToArray(r)}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}function _classCallCheck(a,n){if(!(a instanceof n))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var o=r[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,_toPropertyKey(o.key),o)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _callSuper(t,o,e){return o=_getPrototypeOf(o),_possibleConstructorReturn(t,_isNativeReflectConstruct()?Reflect.construct(o,e||[],_getPrototypeOf(t).constructor):o.apply(t,e))}function _possibleConstructorReturn(t,e){if(e&&("object"==_typeof(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return _assertThisInitialized(t)}function _assertThisInitialized(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _isNativeReflectConstruct(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(_isNativeReflectConstruct=function _isNativeReflectConstruct(){return!!t})()}function _getPrototypeOf(t){return _getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},_getPrototypeOf(t)}function _inherits(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&_setPrototypeOf(t,e)}function _setPrototypeOf(t,e){return _setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},_setPrototypeOf(t,e)}function _defineProperty(e,r,t){return(r=_toPropertyKey(r))in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+""}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(t)}/**
2
2
  * Copyright 2024 Sourcepole AG
3
3
  * All rights reserved.
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 ColorLayer from"@giro3d/giro3d/core/layer/ColorLayer";import Shape from"@giro3d/giro3d/entities/Shape";import DrawTool,{conditions}from"@giro3d/giro3d/interactions/DrawTool.js";import VectorSource from"@giro3d/giro3d/sources/VectorSource";import ol from"openlayers";import pointInPolygon from"point-in-polygon";import PropTypes from"prop-types";import{CurvePath,LineCurve,Vector2,Vector3}from"three";import ConfigUtils from"../../utils/ConfigUtils";import CoordinatesUtils from"../../utils/CoordinatesUtils";import LocaleUtils from"../../utils/LocaleUtils";import MeasureUtils from"../../utils/MeasureUtils";import TaskBar from"../TaskBar";import ButtonBar from"../widgets/ButtonBar";import CopyButton from"../widgets/CopyButton";import HeightProfile3D from"./HeightProfile3D";import"../../plugins/style/Measure.css";var Measure3D=/*#__PURE__*/function(_React$Component){function Measure3D(props){var _this;_classCallCheck(this,Measure3D);_this=_callSuper(this,Measure3D,[props]);_defineProperty(_this,"state",{mode:null,result:null,lenUnit:"metric",areaUnit:"metric",elevUnit:"absolute"});_defineProperty(_this,"onShow",function(mode){_this.setState({mode:mode!==null&&mode!==void 0?mode:"Point"});_this.abortController=new AbortController;_this.measureTool=new DrawTool({instance:_this.props.sceneContext.scene});_this.drawLayer=new ColorLayer({source:new VectorSource({data:[],format:new ol.format.GeoJSON,style:_this.featureStyleFunction})});_this.props.sceneContext.map.addLayer(_this.drawLayer)});_defineProperty(_this,"onHide",function(){_this.clearResult();_this.setState({mode:null});_this.abortController.abort();_this.abortController=null;_this.measureTool.dispose();_this.measureTool=null;_this.props.sceneContext.map.removeLayer(_this.drawLayer,{dispose:true});_this.drawLayer=null});_defineProperty(_this,"renderModeSwitcher",function(){var buttons=[{key:"Point",label:LocaleUtils.tr("measureComponent.pointLabel")},{key:"LineString",label:LocaleUtils.tr("measureComponent.lengthLabel")},{key:"Polygon",label:LocaleUtils.tr("measureComponent.areaLabel")}];return/*#__PURE__*/React.createElement(ButtonBar,{active:_this.state.mode,buttons:buttons,onClick:function onClick(mode){return _this.setState({mode:mode,result:null})}})});_defineProperty(_this,"renderResult",function(){if(!_this.state.result){return null}var text="";var unitSelector=null;if(_this.state.mode==="Point"){text=CoordinatesUtils.getFormattedCoordinate(_this.state.result.pos.slice(0,2),_this.props.sceneContext.mapCrs);var prec=ConfigUtils.getConfigProp("measurementPrecision");text+=", "+(_this.state.result.ground>0&&_this.state.elevUnit==="ground"?_this.state.result.ground:_this.state.result.pos[2]).toFixed(prec);if(_this.state.result.ground>0){unitSelector=/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({elevUnit:ev.target.value})},value:_this.state.elevUnit},/*#__PURE__*/React.createElement("option",{value:"ground"},LocaleUtils.tr("measureComponent.ground")),/*#__PURE__*/React.createElement("option",{value:"absolute"},LocaleUtils.tr("measureComponent.absolute")))}else{unitSelector=/*#__PURE__*/React.createElement("span",{className:"measure-unit-label"},LocaleUtils.tr("measureComponent.absolute"))}}else if(_this.state.mode==="LineString"){text=MeasureUtils.formatMeasurement(_this.state.result.length,false,_this.state.lenUnit);unitSelector=/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({lenUnit:ev.target.value})},value:_this.state.lenUnit},/*#__PURE__*/React.createElement("option",{value:"metric"},LocaleUtils.tr("measureComponent.metric")),/*#__PURE__*/React.createElement("option",{value:"imperial"},LocaleUtils.tr("measureComponent.imperial")),/*#__PURE__*/React.createElement("option",{value:"m"},"m"),/*#__PURE__*/React.createElement("option",{value:"km"},"km"),/*#__PURE__*/React.createElement("option",{value:"ft"},"ft"),/*#__PURE__*/React.createElement("option",{value:"mi"},"mi"))}else if(_this.state.mode==="Polygon"){text=MeasureUtils.formatMeasurement(_this.state.result,true,_this.state.areaUnit);unitSelector=/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({areaUnit:ev.target.value})},value:_this.state.areaUnit},/*#__PURE__*/React.createElement("option",{value:"metric"},LocaleUtils.tr("measureComponent.metric")),/*#__PURE__*/React.createElement("option",{value:"imperial"},LocaleUtils.tr("measureComponent.imperial")),/*#__PURE__*/React.createElement("option",{value:"sqm"},"m\xB2"),/*#__PURE__*/React.createElement("option",{value:"ha"},"ha"),/*#__PURE__*/React.createElement("option",{value:"sqkm"},"km\xB2"),/*#__PURE__*/React.createElement("option",{value:"sqft"},"ft\xB2"),/*#__PURE__*/React.createElement("option",{value:"acre"},"acre"),/*#__PURE__*/React.createElement("option",{value:"sqmi"},"mi\xB2"))}return/*#__PURE__*/React.createElement("div",{className:"controlgroup"},/*#__PURE__*/React.createElement("input",{className:"measure-result",readOnly:true,type:"text",value:text}),unitSelector,/*#__PURE__*/React.createElement(CopyButton,{text:text}))});_defineProperty(_this,"featureStyleFunction",function(){return[new ol.style.Style({fill:new ol.style.Fill({color:[41,120,180,0.5]})}),new ol.style.Style({stroke:new ol.style.Stroke({color:[255,255,255],width:4})}),new ol.style.Style({stroke:new ol.style.Stroke({color:[41,120,180],width:1.5})})]});_defineProperty(_this,"clearResult",function(){_this.drawLayer.source.clear();_this.measurementObjects.forEach(function(object){_this.props.sceneContext.scene.remove(object)});_this.measurementObjects=[];_this.setState({result:null})});_defineProperty(_this,"restart",function(){if(_this.abortController){_this.abortController.abort()}_this.abortController=new AbortController;var pick=_this.state.mode==="Point"?null// default pick
8
- :function(e){return _this.props.sceneContext.scene.pickObjectsAt(e,{sortByDistance:true,where:[_this.props.sceneContext.getMap()]})};var options={signal:_this.abortController.signal,endCondition:conditions.doubleClick,pick:pick};if(_this.state.mode==="Point"){_this.measureTool.createPoint(options).then(_this.measurePoint)["catch"](function(){})}else if(_this.state.mode==="LineString"){_this.measureTool.createLineString(options).then(_this.measureLine)["catch"](function(){})}else if(_this.state.mode==="Polygon"){_this.measureTool.createPolygon(options).then(_this.measureArea)["catch"](function(){})}else if(_this.state.mode==="Height"){_this.measureTool.createVerticalMeasure(options).then(_this.measureHeight)["catch"](function(){})}});_defineProperty(_this,"measurePoint",function(point){if(point===null){_this.restart();return}_this.clearResult();var pos=point.points[0];// Measure point above terrain
9
- _this.props.sceneContext.getTerrainHeightFromDTM([pos.x,pos.y]).then(function(elevation){var ground=pos.z-elevation>0.3?pos.z-elevation:0;var elevationLabelFormatter=function elevationLabelFormatter(options){if(options.index===0){return MeasureUtils.formatMeasurement(elevation,false,LocaleUtils.tr("measureComponent.absolute"))}else if(ground>0&&_this.state.elevUnit==="ground"){return MeasureUtils.formatMeasurement(pos.z-elevation,false,LocaleUtils.tr("measureComponent.ground"))}else{return MeasureUtils.formatMeasurement(pos.z,false,LocaleUtils.tr("measureComponent.absolute"))}};var shape=null;if(ground>0){// Add line
7
+ */import React from"react";import ColorLayer from"@giro3d/giro3d/core/layer/ColorLayer";import Shape from"@giro3d/giro3d/entities/Shape";import DrawTool,{conditions}from"@giro3d/giro3d/interactions/DrawTool.js";import VectorSource from"@giro3d/giro3d/sources/VectorSource";import ol from"openlayers";import pointInPolygon from"point-in-polygon";import PropTypes from"prop-types";import{CurvePath,LineCurve,Vector2,Vector3}from"three";import ConfigUtils from"../../utils/ConfigUtils";import CoordinatesUtils from"../../utils/CoordinatesUtils";import LocaleUtils from"../../utils/LocaleUtils";import MeasureUtils from"../../utils/MeasureUtils";import TaskBar from"../TaskBar";import ButtonBar from"../widgets/ButtonBar";import CopyButton from"../widgets/CopyButton";import HeightProfile3D from"./HeightProfile3D";import"../../plugins/style/Measure.css";var Measure3D=/*#__PURE__*/function(_React$Component){function Measure3D(props){var _this;_classCallCheck(this,Measure3D);_this=_callSuper(this,Measure3D,[props]);_defineProperty(_this,"state",{mode:null,result:null,lenUnit:"metric",areaUnit:"metric",elevUnit:"absolute"});_defineProperty(_this,"onShow",function(mode){_this.setState({mode:mode!==null&&mode!==void 0?mode:"Point"});_this.abortController=new AbortController;_this.measureTool=new DrawTool({instance:_this.props.sceneContext.scene});_this.drawLayer=new ColorLayer({source:new VectorSource({data:[],format:new ol.format.GeoJSON,style:_this.featureStyleFunction})});_this.props.sceneContext.map.addLayer(_this.drawLayer)});_defineProperty(_this,"onHide",function(){_this.clearResult();_this.setState({mode:null});_this.abortController.abort();_this.abortController=null;_this.measureTool.dispose();_this.measureTool=null;_this.props.sceneContext.map.removeLayer(_this.drawLayer,{dispose:true});_this.drawLayer=null});_defineProperty(_this,"renderModeSwitcher",function(){var buttons=[{key:"Point",label:LocaleUtils.tr("measureComponent.pointLabel")},{key:"HeightDiff",label:LocaleUtils.tr("measureComponent.heightDiffLabel")},{key:"LineString",label:LocaleUtils.tr("measureComponent.lengthLabel")},{key:"Polygon",label:LocaleUtils.tr("measureComponent.areaLabel")}];return/*#__PURE__*/React.createElement(ButtonBar,{active:_this.state.mode,buttons:buttons,onClick:function onClick(mode){return _this.setState({mode:mode,result:null})}})});_defineProperty(_this,"renderResult",function(){if(!_this.state.result){return null}var text="";var unitSelector=null;if(_this.state.mode==="Point"){text=CoordinatesUtils.getFormattedCoordinate(_this.state.result.pos.slice(0,2),_this.props.sceneContext.mapCrs);var prec=ConfigUtils.getConfigProp("measurementPrecision");text+=", "+(_this.state.result.ground>0&&_this.state.elevUnit==="ground"?_this.state.result.ground:_this.state.result.pos[2]).toFixed(prec);if(_this.state.result.ground>0){unitSelector=/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({elevUnit:ev.target.value})},value:_this.state.elevUnit},/*#__PURE__*/React.createElement("option",{value:"ground"},LocaleUtils.tr("measureComponent.ground")),/*#__PURE__*/React.createElement("option",{value:"absolute"},LocaleUtils.tr("measureComponent.absolute")))}else{unitSelector=/*#__PURE__*/React.createElement("span",{className:"measure-unit-label"},LocaleUtils.tr("measureComponent.absolute"))}}else if(_this.state.mode==="HeightDiff"){text=(_this.state.result||[]).length===2?MeasureUtils.formatMeasurement(Math.abs(_this.state.result[1].z-_this.state.result[0].z),false,_this.state.lenUnit):"";unitSelector=/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({lenUnit:ev.target.value})},value:_this.state.lenUnit},/*#__PURE__*/React.createElement("option",{value:"metric"},LocaleUtils.tr("measureComponent.metric")),/*#__PURE__*/React.createElement("option",{value:"imperial"},LocaleUtils.tr("measureComponent.imperial")),/*#__PURE__*/React.createElement("option",{value:"m"},"m"),/*#__PURE__*/React.createElement("option",{value:"km"},"km"),/*#__PURE__*/React.createElement("option",{value:"ft"},"ft"),/*#__PURE__*/React.createElement("option",{value:"mi"},"mi"))}else if(_this.state.mode==="LineString"){text=MeasureUtils.formatMeasurement(_this.state.result.length,false,_this.state.lenUnit);unitSelector=/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({lenUnit:ev.target.value})},value:_this.state.lenUnit},/*#__PURE__*/React.createElement("option",{value:"metric"},LocaleUtils.tr("measureComponent.metric")),/*#__PURE__*/React.createElement("option",{value:"imperial"},LocaleUtils.tr("measureComponent.imperial")),/*#__PURE__*/React.createElement("option",{value:"m"},"m"),/*#__PURE__*/React.createElement("option",{value:"km"},"km"),/*#__PURE__*/React.createElement("option",{value:"ft"},"ft"),/*#__PURE__*/React.createElement("option",{value:"mi"},"mi"))}else if(_this.state.mode==="Polygon"){text=MeasureUtils.formatMeasurement(_this.state.result,true,_this.state.areaUnit);unitSelector=/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setState({areaUnit:ev.target.value})},value:_this.state.areaUnit},/*#__PURE__*/React.createElement("option",{value:"metric"},LocaleUtils.tr("measureComponent.metric")),/*#__PURE__*/React.createElement("option",{value:"imperial"},LocaleUtils.tr("measureComponent.imperial")),/*#__PURE__*/React.createElement("option",{value:"sqm"},"m\xB2"),/*#__PURE__*/React.createElement("option",{value:"ha"},"ha"),/*#__PURE__*/React.createElement("option",{value:"sqkm"},"km\xB2"),/*#__PURE__*/React.createElement("option",{value:"sqft"},"ft\xB2"),/*#__PURE__*/React.createElement("option",{value:"acre"},"acre"),/*#__PURE__*/React.createElement("option",{value:"sqmi"},"mi\xB2"))}return/*#__PURE__*/React.createElement("div",{className:"controlgroup"},/*#__PURE__*/React.createElement("input",{className:"measure-result",readOnly:true,type:"text",value:text}),unitSelector,/*#__PURE__*/React.createElement(CopyButton,{text:text}))});_defineProperty(_this,"featureStyleFunction",function(){return[new ol.style.Style({fill:new ol.style.Fill({color:[41,120,180,0.5]})}),new ol.style.Style({stroke:new ol.style.Stroke({color:[255,255,255],width:4})}),new ol.style.Style({stroke:new ol.style.Stroke({color:[41,120,180],width:1.5})})]});_defineProperty(_this,"clearResult",function(){_this.drawLayer.source.clear();_this.measurementObjects.forEach(function(object){_this.props.sceneContext.scene.remove(object)});_this.measurementObjects=[];_this.setState({result:null})});_defineProperty(_this,"restart",function(){if(_this.abortController){_this.abortController.abort()}_this.abortController=new AbortController;var terrainPick=function terrainPick(e){return _this.props.sceneContext.scene.pickObjectsAt(e,{sortByDistance:true,where:[_this.props.sceneContext.getMap()]})};var options={signal:_this.abortController.signal,endCondition:conditions.doubleClick,pick:null// default pick
8
+ };if(_this.state.mode==="Point"){_this.measureTool.createPoint(options).then(_this.measurePoint)["catch"](function(){})}else if(_this.state.mode==="LineString"){options.pick=terrainPick;_this.measureTool.createLineString(options).then(_this.measureLine)["catch"](function(){})}else if(_this.state.mode==="Polygon"){options.pick=terrainPick;_this.measureTool.createPolygon(options).then(_this.measureArea)["catch"](function(){})}else if(_this.state.mode==="HeightDiff"){_this.measureTool.createPoint(options).then(_this.measureHeightDiff)["catch"](function(){})}});_defineProperty(_this,"measurePoint",function(point){if(point===null){_this.restart();return}_this.clearResult();var pos=point.points[0];// Measure point above terrain
9
+ _this.props.sceneContext.getTerrainHeightFromDTM([pos.x,pos.y]).then(function(elevation){var ground=pos.z-elevation>0.3?pos.z-elevation:0;var elevationLabelFormatter=function elevationLabelFormatter(options){if(options.index===0){return MeasureUtils.formatMeasurement(elevation,false,"m")+" "+LocaleUtils.tr("measureComponent.absolute")}else if(ground>0&&_this.state.elevUnit==="ground"){return MeasureUtils.formatMeasurement(pos.z-elevation,false,"m")+" "+LocaleUtils.tr("measureComponent.ground")}else{return MeasureUtils.formatMeasurement(pos.z,false,LocaleUtils.tr("measureComponent.absolute"))}};var shape=null;if(ground>0){// Add line
10
10
  shape=new Shape({showVertexLabels:true,showLine:true,showVertices:true,vertexLabelFormatter:elevationLabelFormatter});shape.setPoints([new Vector3(pos.x,pos.y,elevation),pos])}else{// Add point
11
11
  shape=new Shape({showVertexLabels:true,showLine:false,showVertices:true,vertexLabelFormatter:elevationLabelFormatter});shape.setPoints([new Vector3(pos.x,pos.y,pos.z)])}_this.props.sceneContext.scene.add(shape);_this.measurementObjects.push(shape);_this.props.sceneContext.scene.remove(point);_this.setState({result:{pos:[pos.x,pos.y,pos.z],ground:ground}});// Setup for next measurement
12
- _this.restart()})});_defineProperty(_this,"measureLine",function(lineString){if(lineString===null){_this.restart();return}_this.clearResult();var features=new ol.format.GeoJSON().readFeatures(lineString.toGeoJSON(),{dataProjection:"EPSG:4326",featureProjection:_this.props.sceneContext.mapCrs});_this.drawLayer.source.addFeatures(features);_this.props.sceneContext.scene.remove(lineString);// Compute 2d length and nSamples spaced points
12
+ _this.restart()})});_defineProperty(_this,"measureHeightDiff",function(point){if(point===null){_this.restart();return}if((_this.state.result||[]).length>=2){_this.clearResult()}var pos=point.points[0];if((_this.state.result||[]).length===1){// Add line if two points drawn
13
+ var points=[_this.state.result[0],pos];if(points[0].z>points[1].z){points.reverse()}var line=new Shape({showVertexLabels:true,vertexLabelFormatter:function vertexLabelFormatter(options){return options.index===2?MeasureUtils.formatMeasurement(points[1].z-points[0].z,false,_this.state.lenUnit):null},showLine:true});line.setPoints([new Vector3(points[0].x,points[0].y,points[0].z),new Vector3(points[1].x,points[1].y,points[0].z),new Vector3(points[1].x,points[1].y,points[1].z)]);_this.props.sceneContext.scene.add(line);_this.measurementObjects.push(line)}else{// Add first drawn point
14
+ var shape=new Shape({showVertices:true});shape.setPoints([new Vector3(pos.x,pos.y,pos.z)]);_this.props.sceneContext.scene.add(shape);_this.measurementObjects.push(shape)}_this.props.sceneContext.scene.remove(point);_this.setState(function(state){return{result:[].concat(_toConsumableArray(state.result||[]),[{x:pos.x,y:pos.y,z:pos.z}])}});_this.restart()});_defineProperty(_this,"measureLine",function(lineString){if(lineString===null){_this.restart();return}_this.clearResult();var features=new ol.format.GeoJSON().readFeatures(lineString.toGeoJSON(),{dataProjection:"EPSG:4326",featureProjection:_this.props.sceneContext.mapCrs});_this.drawLayer.source.addFeatures(features);_this.props.sceneContext.scene.remove(lineString);// Compute 2d length and nSamples spaced points
13
15
  var path=new CurvePath;var len2d=0;for(var i=0;i<lineString.points.length-1;i++){var v0=lineString.points[i];var v1=lineString.points[i+1];var line=new LineCurve(new Vector2(v0.x,v0.y),new Vector2(v1.x,v1.y));path.add(line);len2d+=Math.sqrt((v1.x-v0.x)*(v1.x-v0.x)+(v1.y-v0.y)*(v1.y-v0.y))}var nSamples=Math.min(_this.props.maxSampleCount,Math.round(len2d/_this.props.minMeasureLength));var points=path.getSpacedPoints(nSamples-1).map(function(p){return[p.x,p.y]});_this.props.sceneContext.getTerrainHeightFromDTM(points).then(function(elevations){var line3d=points.map(function(p,i){return[p[0],p[1],elevations[i],0]});var len3d=0;for(var _i=1;_i<nSamples;++_i){var dx=line3d[_i][0]-line3d[_i-1][0];var dy=line3d[_i][1]-line3d[_i-1][1];var dz=line3d[_i][2]-line3d[_i-1][2];len3d+=Math.sqrt(dx*dx+dy*dy+dz*dz);line3d[_i][3]=len3d;// Also store incremental length for height profie
14
16
  }_this.setState({result:{length:len3d,profile:line3d}});// Setup for next measurement
15
17
  _this.restart()})});_defineProperty(_this,"measureArea",function(polygon){if(polygon===null){_this.restart();return}_this.clearResult();var features=new ol.format.GeoJSON().readFeatures(polygon.toGeoJSON(),{dataProjection:"EPSG:4326",featureProjection:_this.props.sceneContext.mapCrs});_this.drawLayer.source.addFeatures(features);_this.props.sceneContext.scene.remove(polygon);// Compute boundingbox of polygon, divide boundingbox into quads,
@@ -39,4 +39,13 @@ div.map3d-inspector {
39
39
 
40
40
  div.map3d-inspector input {
41
41
  color: black!important;
42
+ }
43
+
44
+ span.map3d-tile-batch-label {
45
+ background-color: rgba(41, 120, 180, 0.75);
46
+ border: 1px solid white;
47
+ color: white;
48
+ font-weight: bold;
49
+ padding: 0.25em 0.5em;
50
+ border-radius: 8px;
42
51
  }
@@ -1,7 +1,8 @@
1
1
  span.map3d-search-pin-label {
2
- -webkit-text-stroke: 0.8px black;
3
- text-stroke: 0.8px black;
2
+ background-color: rgba(41, 120, 180, 0.75);
3
+ border: 1px solid white;
4
4
  color: white;
5
5
  font-weight: bold;
6
- font-size: 16px;
6
+ padding: 0.25em 0.5em;
7
+ border-radius: 8px;
7
8
  }
@@ -1 +1,11 @@
1
- function _toConsumableArray(r){return _arrayWithoutHoles(r)||_iterableToArray(r)||_unsupportedIterableToArray(r)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0}}function _iterableToArray(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _arrayWithoutHoles(r){if(Array.isArray(r))return _arrayLikeToArray(r)}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}import{Float32BufferAttribute}from"three";var Tiles3DStyle={getBatchColor:function getBatchColor(group,batchId){var _group$batchTable$get;var colorAttr=group.userData.batchColorAttr;if(!colorAttr){return 16777215}return(_group$batchTable$get=group.batchTable.getDataFromId(batchId)[colorAttr])!==null&&_group$batchTable$get!==void 0?_group$batchTable$get:16777215},applyDeclarativeStyle:function applyDeclarativeStyle(group,tilesetConfig){group.userData.batchColorAttr=tilesetConfig.colorAttr;var batchColorCache={};var batchColor=function batchColor(batchId){if(!batchColorCache[batchId]){var color=Tiles3DStyle.getBatchColor(group,batchId);var r=(color>>16&255)/255;var g=(color>>8&255)/255;var b=(color&255)/255;batchColorCache[batchId]=[r,g,b]}return batchColorCache[batchId]};group.traverse(function(c){if(c.geometry){if(tilesetConfig.colorAttr){var batchidAttr=c.geometry.getAttribute("_batchid");var colors=[];batchidAttr.array.forEach(function(batchId){colors.push.apply(colors,_toConsumableArray(batchColor(batchId)))});c.geometry.setAttribute("color",new Float32BufferAttribute(colors,3));c.material.vertexColors=true}}})}};export default Tiles3DStyle;
1
+ function _toConsumableArray(r){return _arrayWithoutHoles(r)||_iterableToArray(r)||_unsupportedIterableToArray(r)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0}}function _iterableToArray(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _arrayWithoutHoles(r){if(Array.isArray(r))return _arrayLikeToArray(r)}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}/**
2
+ * Copyright 2025 Sourcepole AG
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */import isEmpty from"lodash.isempty";import parseCssColor from"parse-css-color";import{Float32BufferAttribute,Group,Vector3}from"three";import{CSS2DObject}from"three/addons/renderers/CSS2DRenderer";function createLabelObject(entry){var labelEl=document.createElement("span");labelEl.innerText=entry.label;labelEl.className="map3d-tile-batch-label";var label=new CSS2DObject(labelEl);label.position.copy(entry.pos);label.updateMatrixWorld();return label}function batchColor(batchId,batchAttr,config){var _config$tilesetStyle$,_config$tilesetStyle;if(((_config$tilesetStyle$=(_config$tilesetStyle=config.tilesetStyle)===null||_config$tilesetStyle===void 0||(_config$tilesetStyle=_config$tilesetStyle[batchId])===null||_config$tilesetStyle===void 0?void 0:_config$tilesetStyle.color)!==null&&_config$tilesetStyle$!==void 0?_config$tilesetStyle$:null)!==null){var color=parseCssColor(config.tilesetStyle[batchId].color);return[].concat(_toConsumableArray(color.values.map(function(c){return c/255})),[color.alpha])}else if(batchAttr[config.colorAttr]){var _batchAttr$config$alp;var _color=batchAttr[config.colorAttr];var alpha=config.alphaAttr?(_batchAttr$config$alp=batchAttr[config.alphaAttr])!==null&&_batchAttr$config$alp!==void 0?_batchAttr$config$alp:255:255;var r=(_color>>16&255)/255;var g=(_color>>8&255)/255;var b=(_color&255)/255;return[r,g,b,alpha/255]}else{return null}}function batchLabel(batchId,batchAttr,config){var _config$tilesetStyle$2,_config$tilesetStyle2;if(((_config$tilesetStyle$2=(_config$tilesetStyle2=config.tilesetStyle)===null||_config$tilesetStyle2===void 0||(_config$tilesetStyle2=_config$tilesetStyle2[batchId])===null||_config$tilesetStyle2===void 0?void 0:_config$tilesetStyle2.label)!==null&&_config$tilesetStyle$2!==void 0?_config$tilesetStyle$2:null)!==null){return config.tilesetStyle[batchId].label}else if(config.labelAttr){return batchAttr[config.labelAttr]}else{return null}}var Tiles3DStyle={handleModelLoad:function handleModelLoad(group,config){var _config$idAttr;var batchColorCache={};var batchLabelCache={};var labels={};var idAttr=(_config$idAttr=config.idAttr)!==null&&_config$idAttr!==void 0?_config$idAttr:"id";group.traverse(function(c){if(c.geometry){var batchidxAttr=c.geometry.getAttribute("_batchid");var batchPosAttr=c.geometry.getAttribute("position");var rgbaColors=[];var rgbColors=[];var haveColor=false;var haveAlpha=false;batchidxAttr.array.forEach(function(batchIdx,idx){var batchAttr=group.batchTable.getDataFromId(batchIdx);var batchId=String(batchAttr[idAttr]);// Handle color
8
+ var color=batchColorCache[batchIdx];if(color===undefined){color=batchColorCache[batchIdx]=batchColor(batchId,batchAttr,config)}if(color){haveColor=true;haveAlpha|=color[3]<1;rgbaColors.push.apply(rgbaColors,_toConsumableArray(color));rgbColors.push.apply(rgbColors,_toConsumableArray(color.slice(0,3)))}else{rgbaColors.push.apply(rgbaColors,[1,1,1,1]);rgbColors.push.apply(rgbColors,[1,1,1])}// Handle label
9
+ var label=batchLabelCache[batchIdx];if(label===undefined){label=batchLabelCache[batchIdx]=batchLabel(batchId,batchAttr,config)}if(label){var pos=batchPosAttr.array.slice(3*idx,3*idx+3);var entry=labels[batchIdx];if(!entry){entry=labels[batchIdx]={label:label,pos:pos,count:1,matrix:c.matrixWorld}}else{entry.pos[0]+=pos[0];entry.pos[1]+=pos[1];entry.pos[2]=Math.max(entry.pos[2],pos[2]);++entry.count}}});if(haveColor){if(haveAlpha){c.geometry.setAttribute("color",new Float32BufferAttribute(rgbaColors,4))}else{// Discard alpha
10
+ var count=rgbaColors.length/4;var bufAttr=new Float32BufferAttribute(count*3,3);for(var i=0,j=0;i<count;++i){bufAttr.array[j++]=rgbaColors[4*i];bufAttr.array[j++]=rgbaColors[4*i+1];bufAttr.array[j++]=rgbaColors[4*i+2]}c.geometry.setAttribute("color",bufAttr)}c.material.vertexColors=true;c.material.transparent=haveAlpha}}});if(!isEmpty(labels)){var tileLabels=[];var labelObjects=new Group;Object.values(labels).forEach(function(entry){var pos=new Vector3(entry.pos[0]/entry.count,entry.pos[1]/entry.count,entry.pos[2]+10).applyMatrix4(entry.matrix);tileLabels.push({pos:pos,label:entry.label});labelObjects.add(createLabelObject(tileLabels[tileLabels.length-1]))});group.userData.tileLabels=tileLabels;group.add(labelObjects)}},handleTileVisibilityChange:function handleTileVisibilityChange(group,visible){// Re-add labels
11
+ if(visible&&group.userData.tileLabels){var labelObjects=new Group;group.userData.tileLabels.forEach(function(entry){labelObjects.add(createLabelObject(entry))});group.add(labelObjects)}}};export default Tiles3DStyle;
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2025.04.14",
3
+ "version": "2025.04.22",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
7
- "repository": "git@github.com:qgis/qwc2.git",
7
+ "repository": "git+ssh://git@github.com/qgis/qwc2.git",
8
8
  "homepage": "https://https://qwc-services.github.io/",
9
9
  "bugs": {
10
10
  "url": "https://github.com/qgis/qwc2/issues"
@@ -17,7 +17,7 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "@furkot/webfonts-generator": "^2.0.2",
20
- "@giro3d/giro3d": "^0.42.2",
20
+ "@giro3d/giro3d": "^0.42.4",
21
21
  "@kayahr/text-encoding": "^2.0.0",
22
22
  "@loaders.gl/core": "^4.3.3",
23
23
  "@loaders.gl/shapefile": "^4.3.3",
@@ -55,6 +55,7 @@
55
55
  "ol-ext": "^4.0.24",
56
56
  "ol-mapbox-style": "^12.3.5",
57
57
  "painterro": "^1.2.87",
58
+ "parse-css-color": "^0.2.1",
58
59
  "path-browserify": "^1.0.1",
59
60
  "pdf-lib": "^1.17.1",
60
61
  "pdfjs-dist": "^4.9.155",
@@ -10,4 +10,4 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
10
10
  * Bookmarks are only allowed for authenticated users.
11
11
  *
12
12
  * Requires `permalinkServiceUrl` to point to a `qwc-permalink-service`.
13
- */var Bookmark=/*#__PURE__*/function(_React$Component){function Bookmark(){var _this;_classCallCheck(this,Bookmark);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,Bookmark,[].concat(args));_defineProperty(_this,"state",{bookmarks:[],currentBookmark:null,description:"",saving:false});_defineProperty(_this,"open",function(bookmarkkey,newtab){var url=location.href.split("?")[0]+"?bk="+bookmarkkey;if(newtab){window.open(url,"_blank")}else{location.href=url}});_defineProperty(_this,"zoomToBookmarkExtent",function(bookmarkkey){resolveBookmark(bookmarkkey,function(params){if("c"in params&&"s"in params){var _params$crs;var scale=parseFloat(params.s);var zoom=MapUtils.computeZoom(_this.props.mapScales,scale);var center=params.c.split(/[;,]/g).map(function(x){return parseFloat(x)});_this.props.zoomToPoint(center,zoom,(_params$crs=params.crs)!==null&&_params$crs!==void 0?_params$crs:_this.props.mapCrs)}else if("e"in params){var _params$crs2;var bounds=params.e.split(",").map(function(n){return parseFloat(n)});_this.props.zoomToExtent(bounds,(_params$crs2=params.crs)!==null&&_params$crs2!==void 0?_params$crs2:_this.props.mapCrs)}})});_defineProperty(_this,"toggleCurrentBookmark",function(bookmark){if(_this.state.currentBookmark===bookmark.key){_this.setState({currentBookmark:null,description:""})}else{_this.setState({currentBookmark:bookmark.key,description:bookmark.description})}});_defineProperty(_this,"addBookmark",function(){createBookmark(_this.state.description,function(success){if(!success){/* eslint-disable-next-line */alert(LocaleUtils.tr("bookmark.addfailed"))}_this.refresh()});_this.setState({description:"",currentBookmark:null})});_defineProperty(_this,"updateBookmark",function(bookmark){_this.setState({saving:true});updateBookmark(bookmark.key,_this.state.description,function(success){if(!success){/* eslint-disable-next-line */alert(LocaleUtils.tr("bookmark.savefailed"))}_this.setState({saving:false,description:"",currentBookmark:null});_this.refresh()})});_defineProperty(_this,"removeBookmark",function(bookmark){removeBookmark(bookmark.key,function(success){if(!success){/* eslint-disable-next-line */alert(LocaleUtils.tr("bookmark.removefailed"))}_this.refresh()})});_defineProperty(_this,"refresh",function(){getUserBookmarks(ConfigUtils.getConfigProp("username"),function(bookmarks){_this.setState({bookmarks:bookmarks})})});return _this}_inherits(Bookmark,_React$Component);return _createClass(Bookmark,[{key:"componentDidMount",value:function componentDidMount(){this.refresh()}},{key:"render",value:function render(){var _this2=this;var openTitle=LocaleUtils.tr("bookmark.open");var openTabTitle=LocaleUtils.tr("bookmark.openTab");var zoomTitle=LocaleUtils.tr("bookmark.zoomToExtent");var username=ConfigUtils.getConfigProp("username");var placeholder=LocaleUtils.tr("bookmark.description");var addBookmarkTitle=LocaleUtils.tr("bookmark.add");var updateTitle=LocaleUtils.tr("bookmark.update");var removeTitle=LocaleUtils.tr("bookmark.remove");var lastUpdateTitle=LocaleUtils.tr("bookmark.lastUpdate");var currentBookmark=this.state.bookmarks.find(function(bookmark){return bookmark.key===_this2.state.currentBookmark});return/*#__PURE__*/React.createElement(SideBar,{icon:"bookmark",id:"Bookmark",side:this.props.side,title:LocaleUtils.tr("appmenu.items.Bookmark"),width:"20em"},!username?/*#__PURE__*/React.createElement("div",{className:"bookmark-body",role:"body"},LocaleUtils.tr("bookmark.notloggedin")):/*#__PURE__*/React.createElement("div",{className:"bookmark-body",role:"body"},/*#__PURE__*/React.createElement("h4",null,LocaleUtils.tr("bookmark.manage")),/*#__PURE__*/React.createElement("div",{className:"bookmark-create"},/*#__PURE__*/React.createElement("input",{onChange:function onChange(ev){return _this2.setState({description:ev.target.value})},onKeyDown:function onKeyDown(ev){if(ev.key==="Enter"&&_this2.state.description!==""){_this2.addBookmark()}},placeholder:placeholder,type:"text",value:this.state.description})),/*#__PURE__*/React.createElement("div",{className:"bookmark-actions controlgroup"},/*#__PURE__*/React.createElement("button",{className:"button",disabled:!currentBookmark,onClick:function onClick(){return _this2.open(currentBookmark.key,false)},title:openTitle},/*#__PURE__*/React.createElement(Icon,{icon:"folder-open"})),/*#__PURE__*/React.createElement("button",{className:"button",disabled:!currentBookmark,onClick:function onClick(){return _this2.open(currentBookmark.key,true)},title:openTabTitle},/*#__PURE__*/React.createElement(Icon,{icon:"open_link"})),this.props.mapCrs&&this.props.mapScales?/*#__PURE__*/React.createElement("button",{className:"button",disabled:!currentBookmark,onClick:function onClick(){return _this2.zoomToBookmarkExtent(currentBookmark.key)},title:zoomTitle},/*#__PURE__*/React.createElement(Icon,{icon:"zoom"})):null,/*#__PURE__*/React.createElement("span",{className:"bookmark-actions-spacer"}),/*#__PURE__*/React.createElement("button",{className:"button",disabled:!this.state.description,onClick:this.addBookmark,title:addBookmarkTitle},/*#__PURE__*/React.createElement(Icon,{icon:"plus"})),/*#__PURE__*/React.createElement("button",{className:"button",disabled:!currentBookmark||!this.state.description,onClick:function onClick(){return _this2.updateBookmark(currentBookmark)},title:updateTitle},this.state.saving?/*#__PURE__*/React.createElement(Spinner,null):/*#__PURE__*/React.createElement(Icon,{icon:"save"})),/*#__PURE__*/React.createElement("button",{className:"button",disabled:!currentBookmark,onClick:function onClick(){return _this2.removeBookmark(currentBookmark)},title:removeTitle},/*#__PURE__*/React.createElement(Icon,{icon:"trash"}))),/*#__PURE__*/React.createElement("div",{className:"bookmark-list"},this.state.bookmarks.map(function(bookmark){var itemclasses=classnames({"bookmark-list-item":true,"bookmark-list-item-active":_this2.state.currentBookmark===bookmark.key});return/*#__PURE__*/React.createElement("div",{className:itemclasses,key:bookmark.key,onClick:function onClick(){return _this2.toggleCurrentBookmark(bookmark)},title:lastUpdateTitle+": "+bookmark.date},bookmark.description)}),isEmpty(this.state.bookmarks)?/*#__PURE__*/React.createElement("div",{className:"bookmark-list-item-empty"},LocaleUtils.tr("bookmark.nobookmarks")):null)))}}])}(React.Component);_defineProperty(Bookmark,"availableIn3D",true);_defineProperty(Bookmark,"propTypes",{mapCrs:PropTypes.string,mapScales:PropTypes.array,/** The side of the application on which to display the sidebar. */side:PropTypes.string,zoomToExtent:PropTypes.func,zoomToPoint:PropTypes.func});_defineProperty(Bookmark,"defaultProps",{side:"right"});var selector=function selector(state){var _state$map,_state$map2;return{mapCrs:(_state$map=state.map)===null||_state$map===void 0?void 0:_state$map.projection,mapScales:(_state$map2=state.map)===null||_state$map2===void 0?void 0:_state$map2.scales}};export default connect(selector,{zoomToExtent:zoomToExtent,zoomToPoint:zoomToPoint})(Bookmark);
13
+ */var Bookmark=/*#__PURE__*/function(_React$Component){function Bookmark(){var _this;_classCallCheck(this,Bookmark);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,Bookmark,[].concat(args));_defineProperty(_this,"state",{bookmarks:[],currentBookmark:null,description:"",saving:false});_defineProperty(_this,"open",function(bookmarkkey,newtab){var url=location.href.split("?")[0]+"?bk="+bookmarkkey;if(newtab){window.open(url,"_blank")}else{location.href=url}});_defineProperty(_this,"zoomToBookmarkExtent",function(bookmarkkey){resolveBookmark(bookmarkkey,function(params){if("c"in params&&"s"in params){var _params$crs;var scale=parseFloat(params.s);var zoom=MapUtils.computeZoom(_this.props.mapScales,scale);var center=params.c.split(/[;,]/g).map(function(x){return parseFloat(x)});_this.props.zoomToPoint(center,zoom,(_params$crs=params.crs)!==null&&_params$crs!==void 0?_params$crs:_this.props.mapCrs)}else if("e"in params){var _params$crs2;var bounds=params.e.split(",").map(function(n){return parseFloat(n)});_this.props.zoomToExtent(bounds,(_params$crs2=params.crs)!==null&&_params$crs2!==void 0?_params$crs2:_this.props.mapCrs)}})});_defineProperty(_this,"toggleCurrentBookmark",function(bookmark){if(_this.state.currentBookmark===bookmark.key){_this.setState({currentBookmark:null,description:""})}else{_this.setState({currentBookmark:bookmark.key,description:bookmark.description})}});_defineProperty(_this,"addBookmark",function(){createBookmark(_this.state.description,function(success){if(!success){/* eslint-disable-next-line */alert(LocaleUtils.tr("bookmark.addfailed"))}_this.refresh()});_this.setState({description:"",currentBookmark:null})});_defineProperty(_this,"updateBookmark",function(bookmark){_this.setState({saving:true});updateBookmark(bookmark.key,_this.state.description,function(success){if(!success){/* eslint-disable-next-line */alert(LocaleUtils.tr("bookmark.savefailed"))}_this.setState({saving:false,description:"",currentBookmark:null});_this.refresh()})});_defineProperty(_this,"removeBookmark",function(bookmark){removeBookmark(bookmark.key,function(success){if(!success){/* eslint-disable-next-line */alert(LocaleUtils.tr("bookmark.removefailed"))}_this.refresh()})});_defineProperty(_this,"refresh",function(){getUserBookmarks(ConfigUtils.getConfigProp("username"),function(bookmarks){_this.setState({bookmarks:bookmarks})})});return _this}_inherits(Bookmark,_React$Component);return _createClass(Bookmark,[{key:"componentDidMount",value:function componentDidMount(){this.refresh()}},{key:"render",value:function render(){var _this2=this;var openTitle=LocaleUtils.tr("bookmark.open");var openTabTitle=LocaleUtils.tr("bookmark.openTab");var zoomTitle=LocaleUtils.tr("bookmark.zoomToExtent");var username=ConfigUtils.getConfigProp("username");var placeholder=LocaleUtils.tr("bookmark.description");var addBookmarkTitle=LocaleUtils.tr("bookmark.add");var updateTitle=LocaleUtils.tr("bookmark.update");var removeTitle=LocaleUtils.tr("bookmark.remove");var lastUpdateTitle=LocaleUtils.tr("bookmark.lastUpdate");var currentBookmark=this.state.bookmarks.find(function(bookmark){return bookmark.key===_this2.state.currentBookmark});return/*#__PURE__*/React.createElement(SideBar,{icon:"bookmark",id:"Bookmark",side:this.props.side,title:LocaleUtils.tr("appmenu.items.Bookmark"),width:"20em"},!username?/*#__PURE__*/React.createElement("div",{className:"bookmark-body",role:"body"},LocaleUtils.tr("bookmark.notloggedin")):/*#__PURE__*/React.createElement("div",{className:"bookmark-body",role:"body"},/*#__PURE__*/React.createElement("h4",null,LocaleUtils.tr("bookmark.manage")),/*#__PURE__*/React.createElement("div",{className:"bookmark-create"},/*#__PURE__*/React.createElement("input",{onChange:function onChange(ev){return _this2.setState({description:ev.target.value})},onKeyDown:function onKeyDown(ev){if(ev.key==="Enter"&&_this2.state.description!==""){_this2.addBookmark()}},placeholder:placeholder,type:"text",value:this.state.description})),/*#__PURE__*/React.createElement("div",{className:"bookmark-actions controlgroup"},/*#__PURE__*/React.createElement("button",{className:"button",disabled:!currentBookmark,onClick:function onClick(){return _this2.open(currentBookmark.key,false)},title:openTitle},/*#__PURE__*/React.createElement(Icon,{icon:"folder-open"})),/*#__PURE__*/React.createElement("button",{className:"button",disabled:!currentBookmark,onClick:function onClick(){return _this2.open(currentBookmark.key,true)},title:openTabTitle},/*#__PURE__*/React.createElement(Icon,{icon:"open_link"})),this.props.mapCrs&&this.props.mapScales?/*#__PURE__*/React.createElement("button",{className:"button",disabled:!currentBookmark,onClick:function onClick(){return _this2.zoomToBookmarkExtent(currentBookmark.key)},title:zoomTitle},/*#__PURE__*/React.createElement(Icon,{icon:"zoom"})):null,/*#__PURE__*/React.createElement("span",{className:"bookmark-actions-spacer"}),/*#__PURE__*/React.createElement("button",{className:"button",disabled:!this.state.description,onClick:this.addBookmark,title:addBookmarkTitle},/*#__PURE__*/React.createElement(Icon,{icon:"plus"})),/*#__PURE__*/React.createElement("button",{className:"button",disabled:!currentBookmark||!this.state.description,onClick:function onClick(){return _this2.updateBookmark(currentBookmark)},title:updateTitle},this.state.saving?/*#__PURE__*/React.createElement(Spinner,null):/*#__PURE__*/React.createElement(Icon,{icon:"save"})),/*#__PURE__*/React.createElement("button",{className:"button",disabled:!currentBookmark,onClick:function onClick(){return _this2.removeBookmark(currentBookmark)},title:removeTitle},/*#__PURE__*/React.createElement(Icon,{icon:"trash"}))),/*#__PURE__*/React.createElement("div",{className:"bookmark-list"},this.state.bookmarks.map(function(bookmark){var itemclasses=classnames({"bookmark-list-item":true,"bookmark-list-item-active":_this2.state.currentBookmark===bookmark.key});return/*#__PURE__*/React.createElement("div",{className:itemclasses,key:bookmark.key,onClick:function onClick(){return _this2.toggleCurrentBookmark(bookmark)},onDoubleClick:function onDoubleClick(){return _this2.open(bookmark.key,false)},title:lastUpdateTitle+": "+bookmark.date},bookmark.description)}),isEmpty(this.state.bookmarks)?/*#__PURE__*/React.createElement("div",{className:"bookmark-list-item-empty"},LocaleUtils.tr("bookmark.nobookmarks")):null)))}}])}(React.Component);_defineProperty(Bookmark,"availableIn3D",true);_defineProperty(Bookmark,"propTypes",{mapCrs:PropTypes.string,mapScales:PropTypes.array,/** The side of the application on which to display the sidebar. */side:PropTypes.string,zoomToExtent:PropTypes.func,zoomToPoint:PropTypes.func});_defineProperty(Bookmark,"defaultProps",{side:"right"});var selector=function selector(state){var _state$map,_state$map2;return{mapCrs:(_state$map=state.map)===null||_state$map===void 0?void 0:_state$map.projection,mapScales:(_state$map2=state.map)===null||_state$map2===void 0?void 0:_state$map2.scales}};export default connect(selector,{zoomToExtent:zoomToExtent,zoomToPoint:zoomToPoint})(Bookmark);
@@ -4,23 +4,24 @@ 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 ReactDOM from"react-dom";import{connect}from"react-redux";import axios from"axios";import{Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Filler,BubbleController}from"chart.js";import FileSaver from"file-saver";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{addMarker,removeMarker}from"../actions/layers";import{changeMeasurementState}from"../actions/measurement";import ResizeableWindow from"../components/ResizeableWindow";import Spinner from"../components/widgets/Spinner";import ConfigUtils from"../utils/ConfigUtils";import LayerUtils from"../utils/LayerUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import MeasureUtils from"../utils/MeasureUtils";import MiscUtils from"../utils/MiscUtils";import VectorLayerUtils from"../utils/VectorLayerUtils";import"./style/HeightProfile.css";ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Filler,BubbleController);var HeightProfilePrintDialog_=/*#__PURE__*/function(_React$PureComponent){function HeightProfilePrintDialog_(props){var _this;_classCallCheck(this,HeightProfilePrintDialog_);_this=_callSuper(this,HeightProfilePrintDialog_,[props]);_defineProperty(_this,"state",{initialized:false,imageUrl:""});_defineProperty(_this,"closePrintWindow",function(){_this.externalWindow.close()});_defineProperty(_this,"setWindowContent",function(){_this.externalWindow.addEventListener("beforeunload",_this.props.onClose,false);var container=_this.externalWindow.document.getElementById("heightprofilecontainer");if(container){var printBtn=_this.externalWindow.document.createElement("div");printBtn.id="print";printBtn.style.marginBottom="1em";printBtn.innerHTML="<style type=\"text/css\">@media print{ #print { display: none; }}</style>"+"<button onClick=\"(function(){window.print();})()\">"+LocaleUtils.tr("heightprofile.print")+"</button>";container.appendChild(printBtn);_this.imageEl=_this.externalWindow.document.createElement("div");_this.imageEl.id="map";_this.imageEl.innerHTML=LocaleUtils.tr("heightprofile.loadingimage");container.appendChild(_this.imageEl);_this.portalEl=_this.externalWindow.document.createElement("div");_this.portalEl.id="profile";container.appendChild(_this.portalEl);_this.setState({initialized:true});_this.externalWindow.document.body.style.overflowX="hidden"}else{_this.externalWindow.document.body.innerHTML="Broken template. An element with id=heightprofilecontainer must exist."}});_defineProperty(_this,"refreshImage",function(){var measurement=_this.props.measurement;var layer={type:"vector",opacity:255,features:[{type:"Feature",geometry:{coordinates:measurement.coordinates,type:"LineString"},styleOptions:{strokeColor:[255,0,0,1],strokeWidth:4},properties:{segment_labels:measurement.segment_lengths.map(function(length){return MeasureUtils.formatMeasurement(length,false,measurement.lenUnit)})}}]};var mapCrs=_this.props.map.projection;var scale=Math.round(MapUtils.computeForZoom(_this.props.map.scales,_this.props.map.zoom));var exportParams=LayerUtils.collectPrintParams(_this.props.layers,_this.props.theme,scale,mapCrs,true,false);var highlightParams=VectorLayerUtils.createPrintHighlighParams([layer],mapCrs);var imageParams=_objectSpread({SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetMap",TRANSPARENT:"true",TILED:"false",CRS:_this.props.map.projection,BBOX:_this.props.map.bbox.bounds,WIDTH:_this.props.map.size.width,HEIGHT:_this.props.map.size.height,HIGHLIGHT_GEOM:highlightParams.geoms.join(";"),HIGHLIGHT_SYMBOL:highlightParams.styles.join(";"),HIGHLIGHT_LABELSTRING:highlightParams.labels.join(";"),HIGHLIGHT_LABELCOLOR:highlightParams.labelFillColors.join(";"),HIGHLIGHT_LABELBUFFERCOLOR:highlightParams.labelOutlineColors.join(";"),HIGHLIGHT_LABELBUFFERSIZE:highlightParams.labelOutlineSizes.join(";"),HIGHLIGHT_LABELSIZE:highlightParams.labelSizes.join(";"),HIGHLIGHT_LABEL_DISTANCE:highlightParams.labelDist.join(";"),HIGHLIGHT_LABEL_ROTATION:highlightParams.labelRotations.join(";"),csrf_token:MiscUtils.getCsrfToken()},exportParams);var baseUrl=_this.props.theme.url.split("?")[0];var query=Object.entries(imageParams).map(function(_ref){var _ref2=_slicedToArray(_ref,2),k=_ref2[0],v=_ref2[1];return"".concat(encodeURIComponent(k),"=").concat(encodeURIComponent(v))}).join("&");var src=baseUrl+"?"+query;if(src===_this.state.imageUrl){return}_this.setState({imageUrl:src});var options={headers:{"content-type":"application/x-www-form-urlencoded"},responseType:"blob"};axios.post(baseUrl,query,options).then(function(response){var reader=new FileReader;reader.readAsDataURL(response.data);reader.onload=function(){_this.imageEl.innerHTML="<img src=\"".concat(reader.result,"\" style=\"width: 100%\" />")}})["catch"](function(){// Fall back to GET
7
+ */import React from"react";import{Line}from"react-chartjs-2";import ReactDOM from"react-dom";import{connect}from"react-redux";import axios from"axios";import{Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Filler,BubbleController}from"chart.js";import FileSaver from"file-saver";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{v1 as uuidv1}from"uuid";import{addMarker,removeMarker}from"../actions/layers";import{changeMeasurementState}from"../actions/measurement";import ResizeableWindow from"../components/ResizeableWindow";import Spinner from"../components/widgets/Spinner";import{getElevationInterface}from"../utils/ElevationInterface";import LayerUtils from"../utils/LayerUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import MeasureUtils from"../utils/MeasureUtils";import MiscUtils from"../utils/MiscUtils";import VectorLayerUtils from"../utils/VectorLayerUtils";import"./style/HeightProfile.css";ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Filler,BubbleController);var HeightProfilePrintDialog_=/*#__PURE__*/function(_React$PureComponent){function HeightProfilePrintDialog_(props){var _this;_classCallCheck(this,HeightProfilePrintDialog_);_this=_callSuper(this,HeightProfilePrintDialog_,[props]);_defineProperty(_this,"state",{initialized:false,imageUrl:""});_defineProperty(_this,"closePrintWindow",function(){_this.externalWindow.close()});_defineProperty(_this,"setWindowContent",function(){_this.externalWindow.addEventListener("beforeunload",_this.props.onClose,false);var container=_this.externalWindow.document.getElementById("heightprofilecontainer");if(container){var printBtn=_this.externalWindow.document.createElement("div");printBtn.id="print";printBtn.style.marginBottom="1em";printBtn.innerHTML="<style type=\"text/css\">@media print{ #print { display: none; }}</style>"+"<button onClick=\"(function(){window.print();})()\">"+LocaleUtils.tr("heightprofile.print")+"</button>";container.appendChild(printBtn);_this.imageEl=_this.externalWindow.document.createElement("div");_this.imageEl.id="map";_this.imageEl.innerHTML=LocaleUtils.tr("heightprofile.loadingimage");container.appendChild(_this.imageEl);_this.portalEl=_this.externalWindow.document.createElement("div");_this.portalEl.id="profile";container.appendChild(_this.portalEl);_this.setState({initialized:true});_this.externalWindow.document.body.style.overflowX="hidden"}else{_this.externalWindow.document.body.innerHTML="Broken template. An element with id=heightprofilecontainer must exist."}});_defineProperty(_this,"refreshImage",function(){var measurement=_this.props.measurement;var layer={type:"vector",opacity:255,features:[{type:"Feature",geometry:{coordinates:measurement.coordinates,type:"LineString"},styleOptions:{strokeColor:[255,0,0,1],strokeWidth:4},properties:{segment_labels:measurement.segment_lengths.map(function(length){return MeasureUtils.formatMeasurement(length,false,measurement.lenUnit)})}}]};var mapCrs=_this.props.map.projection;var scale=Math.round(MapUtils.computeForZoom(_this.props.map.scales,_this.props.map.zoom));var exportParams=LayerUtils.collectPrintParams(_this.props.layers,_this.props.theme,scale,mapCrs,true,false);var highlightParams=VectorLayerUtils.createPrintHighlighParams([layer],mapCrs);var imageParams=_objectSpread({SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetMap",TRANSPARENT:"true",TILED:"false",CRS:_this.props.map.projection,BBOX:_this.props.map.bbox.bounds,WIDTH:_this.props.map.size.width,HEIGHT:_this.props.map.size.height,HIGHLIGHT_GEOM:highlightParams.geoms.join(";"),HIGHLIGHT_SYMBOL:highlightParams.styles.join(";"),HIGHLIGHT_LABELSTRING:highlightParams.labels.join(";"),HIGHLIGHT_LABELCOLOR:highlightParams.labelFillColors.join(";"),HIGHLIGHT_LABELBUFFERCOLOR:highlightParams.labelOutlineColors.join(";"),HIGHLIGHT_LABELBUFFERSIZE:highlightParams.labelOutlineSizes.join(";"),HIGHLIGHT_LABELSIZE:highlightParams.labelSizes.join(";"),HIGHLIGHT_LABEL_DISTANCE:highlightParams.labelDist.join(";"),HIGHLIGHT_LABEL_ROTATION:highlightParams.labelRotations.join(";"),csrf_token:MiscUtils.getCsrfToken()},exportParams);var baseUrl=_this.props.theme.url.split("?")[0];var query=Object.entries(imageParams).map(function(_ref){var _ref2=_slicedToArray(_ref,2),k=_ref2[0],v=_ref2[1];return"".concat(encodeURIComponent(k),"=").concat(encodeURIComponent(v))}).join("&");var src=baseUrl+"?"+query;if(src===_this.state.imageUrl){return}_this.setState({imageUrl:src});var options={headers:{"content-type":"application/x-www-form-urlencoded"},responseType:"blob"};axios.post(baseUrl,query,options).then(function(response){var reader=new FileReader;reader.readAsDataURL(response.data);reader.onload=function(){_this.imageEl.innerHTML="<img src=\"".concat(reader.result,"\" style=\"width: 100%\" />")}})["catch"](function(){// Fall back to GET
8
8
  _this.imageEl.innerHTML="<img src=\"".concat(src,"\" style=\"width: 100%\" />")})});_defineProperty(_this,"windowResized",function(){if(_this.chart){_this.chart.resize()}});_this.externalWindow=null;_this.chart=null;_this.portalEl=null;_this.imageEl=null;return _this}_inherits(HeightProfilePrintDialog_,_React$PureComponent);return _createClass(HeightProfilePrintDialog_,[{key:"componentDidMount",value:function componentDidMount(){var templatePath=MiscUtils.resolveAssetsPath(this.props.templatePath);this.externalWindow=window.open(templatePath,LocaleUtils.tr("heightprofile.title"),"toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes");this.externalWindow.addEventListener("load",this.setWindowContent,false);this.externalWindow.addEventListener("resize",this.windowResized,false);window.addEventListener("beforeunload",this.closePrintWindow)}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){if(this.props.layers!==prevProps.layers||this.props.map.bbox!==prevProps.map.bbox||this.state.initialized&&!prevState.initialized){this.refreshImage()}}},{key:"componentWillUnmount",value:function componentWillUnmount(){this.closePrintWindow();window.removeEventListener("beforeunload",this.closePrintWindow)}},{key:"render",value:function render(){var _this2=this;if(!this.state.initialized){return null}return/*#__PURE__*/ReactDOM.createPortal(this.props.children(function(el){_this2.chart=el},false),this.portalEl)}}])}(React.PureComponent);_defineProperty(HeightProfilePrintDialog_,"propTypes",{children:PropTypes.func,layers:PropTypes.array,map:PropTypes.object,measurement:PropTypes.object,onClose:PropTypes.func,templatePath:PropTypes.string,theme:PropTypes.object});var HeightProfilePrintDialog=connect(function(state){return{layers:state.layers.flat,map:state.map,theme:state.theme.current}},{})(HeightProfilePrintDialog_);/**
9
9
  * Displays a height profile along a measured line.
10
10
  *
11
11
  * Triggered automatically when a line is measured via the `Measure` plugin.
12
12
  *
13
- * Requires `elevationServiceUrl` in `config.json` to point to a `qwc-elevation-service`.
13
+ * Requires `elevationServiceUrl` in `config.json` to point to a `qwc-elevation-service`,
14
+ * or a custom elevation interface to be exposed in `window.QWC2ElevationInterface`, see
15
+ * [ElevationInterface.js](https://github.com/qgis/qwc2/blob/master/utils/ElevationInterface.js).
14
16
  *
15
17
  * The print height profile functionality requires a template located by default at `assets/templates/heightprofileprint.html`
16
18
  * with containing a container element with `id=heightprofilecontainer`.
17
- */var HeightProfile=/*#__PURE__*/function(_React$Component){function HeightProfile(props){var _this3;_classCallCheck(this,HeightProfile);_this3=_callSuper(this,HeightProfile,[props]);_defineProperty(_this3,"state",{data:{},isloading:false,drawnodes:true,printdialog:false});_defineProperty(_this3,"onClose",function(){_this3.setState({data:{},isloading:false});_this3.props.changeMeasurementState(_objectSpread(_objectSpread({},_this3.props.measurement),{},{pickPositionCallback:null}))});_defineProperty(_this3,"renderHeightProfile",function(saveRef,interactive){if(_this3.props.measurement.drawing){return null}if(_this3.state.data.error){return/*#__PURE__*/React.createElement("div",{className:"height-profile-error",role:"body"},LocaleUtils.tr("heightprofile.error")+": "+_this3.state.data.error)}var distanceStr=LocaleUtils.tr("heightprofile.distance");var heightStr=LocaleUtils.tr("heightprofile.height");var aslStr=LocaleUtils.tr("heightprofile.asl");var data={labels:_this3.state.data.x,datasets:[{data:_this3.state.data.y,fill:true,backgroundColor:"rgba(255,0,0,0.5)",borderColor:"rgb(255,0,0)",borderWidth:2,pointRadius:0,order:1},{type:"bubble",data:_this3.state.data.nodes,backgroundColor:"rgb(255, 255, 255)",borderColor:"rgb(255, 0, 0)",borderWidth:2,radius:5,hoverRadius:0,hoverBorderWidth:2,order:0,hidden:!_this3.state.drawnodes}]};// Approx 10 ticks
19
+ */var HeightProfile=/*#__PURE__*/function(_React$Component){function HeightProfile(props){var _this3;_classCallCheck(this,HeightProfile);_this3=_callSuper(this,HeightProfile,[props]);_defineProperty(_this3,"state",{data:{},reqId:null,drawnodes:true,printdialog:false});_defineProperty(_this3,"onClose",function(){_this3.setState({data:{},isloading:false});_this3.props.changeMeasurementState(_objectSpread(_objectSpread({},_this3.props.measurement),{},{pickPositionCallback:null}))});_defineProperty(_this3,"renderHeightProfile",function(saveRef,interactive){if(_this3.props.measurement.drawing){return null}if(_this3.state.data.error){return/*#__PURE__*/React.createElement("div",{className:"height-profile-error",role:"body"},LocaleUtils.tr("heightprofile.error")+": "+_this3.state.data.error)}var distanceStr=LocaleUtils.tr("heightprofile.distance");var heightStr=LocaleUtils.tr("heightprofile.height");var aslStr=LocaleUtils.tr("heightprofile.asl");var data={labels:_this3.state.data.x,datasets:[{data:_this3.state.data.y,fill:true,backgroundColor:"rgba(255,0,0,0.5)",borderColor:"rgb(255,0,0)",borderWidth:2,pointRadius:0,order:1},{type:"bubble",data:_this3.state.data.nodes,backgroundColor:"rgb(255, 255, 255)",borderColor:"rgb(255, 0, 0)",borderWidth:2,radius:5,hoverRadius:0,hoverBorderWidth:2,order:0,hidden:!_this3.state.drawnodes}]};// Approx 10 ticks
18
20
  var stepSizeFact=Math.pow(10,Math.ceil(Math.log10(_this3.state.data.totLength/10)));var stepSize=Math.round(_this3.state.data.totLength/stepSizeFact)*stepSizeFact/10;var prec=_this3.props.heightProfilePrecision;var options={responsive:true,maintainAspectRatio:false,animation:{duration:0},plugins:{legend:{display:false},tooltip:{enabled:interactive,intersect:false,displayColors:false,bodyFont:{weight:"bold"},callbacks:{title:function title(ctx){return distanceStr+": "+MeasureUtils.formatMeasurement(ctx[0].parsed.x,false,"metric")},label:function label(ctx){return heightStr+": "+ctx.parsed.y.toFixed(prec)+" m "+aslStr}}}},scales:{x:{type:"linear",ticks:{stepSize:stepSize,font:{size:10},callback:function callback(value){return value}},title:{display:true,text:distanceStr+" [m]",padding:0},max:Math.ceil(_this3.state.data.totLength)},y:{ticks:{font:{size:10},callback:function callback(value){return value.toFixed(prec)}},title:{display:true,text:heightStr+" [m "+aslStr+"]"},max:Math.ceil(_this3.state.data.maxY)}},onHover:interactive?function(evt,activeEls,chart){var chartArea=chart.chartArea;var chartX=Math.min(Math.max(evt.x-chartArea.left),chartArea.width);_this3.updateMarker(chartX/chartArea.width*_this3.state.data.totLength)}:undefined};return/*#__PURE__*/React.createElement("div",{className:"height-profile-chart-container",role:"body",style:{position:"relative"}},/*#__PURE__*/React.createElement(Line,{data:data,options:options,ref:saveRef}))});_defineProperty(_this3,"resizeChart",function(){if(_this3.chart){_this3.chart.resize()}});_defineProperty(_this3,"updateMarker",function(x){var segmentLengths=_this3.props.measurement.segment_lengths;var coo=_this3.props.measurement.coordinates;if(isEmpty(segmentLengths)||isEmpty(coo)){return}var i=0;var runl=0;while(i<segmentLengths.length-1&&x>runl+segmentLengths[i]){runl+=segmentLengths[i++]}var lambda=(x-runl)/segmentLengths[i];var p=[coo[i][0]+lambda*(coo[i+1][0]-coo[i][0]),coo[i][1]+lambda*(coo[i+1][1]-coo[i][1])];_this3.props.addMarker("heightprofile",p,"",_this3.props.projection,1000001);// 1000001: one higher than the zIndex in MeasurementSupport...
19
21
  });_defineProperty(_this3,"showTooltip",function(idx){if(!_this3.chart){return}var chartArea=_this3.chart.chartArea;_this3.chart.tooltip.setActiveElements([{datasetIndex:0,index:idx}],{x:(chartArea.left+chartArea.right)/2,y:(chartArea.top+chartArea.bottom)/2});_this3.chart.update()});_defineProperty(_this3,"clearMarkerAndTooltip",function(){_this3.props.removeMarker("heightprofile");if(_this3.chart){_this3.chart.tooltip.setActiveElements([],{x:0,y:0})}});_defineProperty(_this3,"pickPositionCallback",function(pos){if(!pos||!_this3.state.data){_this3.clearMarkerAndTooltip();return}// Find sample index
20
22
  var segmentLengths=_this3.props.measurement.segment_lengths;var coo=_this3.props.measurement.coordinates;var x=0;for(var iSegment=0;iSegment<coo.length-1;++iSegment){if(_this3.pointOnSegment(pos,coo[iSegment],coo[iSegment+1])){var len=MeasureUtils.computeSegmentLengths([pos,coo[iSegment]],_this3.props.projection,_this3.props.measurement.geodesic)[0];x+=len;break}else{x+=segmentLengths[iSegment]}}var k=Math.min(1,x/_this3.state.data.totLength);var idx=Math.min(_this3.state.data.y.length-1,Math.floor(k*_this3.props.samples));_this3.showTooltip(idx)});_defineProperty(_this3,"pointOnSegment",function(q,p1,p2){var tol=1E-3;// Determine whether points lie on same line: cross-product (P2-P1) x (Q - P1) zero?
21
23
  var cross=(p2[0]-p1[0])*(q[1]-p1[1])-(q[0]-p1[0])*(p2[1]-p1[1]);if(Math.abs(cross)>tol){return false}// Determine if coordinates lie within segment coordinates
22
- if(Math.abs(p1[0]-p2[0])>tol){return p1[0]<=q[0]&&q[0]<=p2[0]||p2[0]<=q[0]&&q[0]<=p1[0]}else{return p1[1]<=q[1]&&q[1]<=p2[1]||p2[1]<=q[1]&&q[1]<=p1[1]}});_defineProperty(_this3,"exportProfile",function(){if(!_this3.state.data.x){return}var csv="";csv+="index"+"\t"+"distance"+"\t"+"elevation"+"\n";_this3.state.data.x.forEach(function(x,idx){var sample={x:x,y:_this3.state.data.y[idx]};var prec=_this3.props.heightProfilePrecision;var distance=Math.round(sample.x*Math.pow(10,prec))/Math.pow(10,prec);var height=Math.round(sample.y*Math.pow(10,prec))/Math.pow(10,prec);csv+=String(idx).replace("\"","\"\"")+"\t"+String(distance)+"\t"+String(height)+"\n"});FileSaver.saveAs(new Blob([csv],{type:"text/plain;charset=utf-8"}),"heightprofile.csv")});_this3.chart=null;_this3.profilePrintWindow=null;return _this3}_inherits(HeightProfile,_React$Component);return _createClass(HeightProfile,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){if(this.props.measurement.coordinates!==prevProps.measurement.coordinates){if(this.props.measurement.drawing===false&&this.props.measurement.geomType==="LineString"&&!isEmpty(this.props.measurement.coordinates)){this.queryElevations(this.props.measurement.coordinates,this.props.measurement.segment_lengths,this.props.projection)}else if(!isEmpty(this.state.data)){this.setState({data:{}});this.props.changeMeasurementState(_objectSpread(_objectSpread({},this.props.measurement),{},{pickPositionCallback:null}))}}}},{key:"queryElevations",value:function queryElevations(coordinates,distances,projection){var _this4=this;var serviceUrl=(ConfigUtils.getConfigProp("elevationServiceUrl")||"").replace(/\/$/,"");var totLength=this.props.measurement.length;if(serviceUrl){this.setState({isloading:true});axios.post(serviceUrl+"/getheightprofile",{coordinates:coordinates,distances:distances,projection:projection,samples:this.props.samples}).then(function(response){if(_this4.state.isloading!==true){// Since aborted
23
- return}// Compute x-axis distances and get node points
24
- var nodes=[];var cumDist=distances[0];var distIdx=0;var y=response.data.elevations;var x=y.map(function(entry,idx,a){var dist=(idx/(a.length-1)*totLength).toFixed(0);if(dist>=cumDist){nodes.push({x:dist,y:y[idx]});cumDist+=distances[++distIdx]}return dist});// First and last node
25
- nodes.unshift({x:x[0],y:y[0]});nodes.push({x:x[x.length-1],y:y[y.length-1]});var data={x:x,y:response.data.elevations,maxY:Math.max.apply(Math,_toConsumableArray(response.data.elevations)),totLength:totLength,nodes:nodes};_this4.setState({isloading:false,data:data});_this4.props.changeMeasurementState(_objectSpread(_objectSpread({},_this4.props.measurement),{},{pickPositionCallback:_this4.pickPositionCallback}))})["catch"](function(e){_this4.setState({isloading:false,data:{error:String(e)}});// eslint-disable-next-line
26
- console.log("Query failed: "+e)})}}},{key:"render",value:function render(){var _this5=this;if(isEmpty(this.state.data)&&!this.state.isloading){return null}var extraControls=[{icon:"circle",active:this.state.drawnodes,callback:function callback(){return _this5.setState(function(state){return{drawnodes:!state.drawnodes}})},title:LocaleUtils.tr("heightprofile.drawnodes")},{icon:"export",callback:this.exportProfile,title:LocaleUtils.tr("heightprofile.export")},{icon:"print",active:this.state.printdialog,callback:function callback(){return _this5.setState(function(state){return{printdialog:!state.printdialog}})},title:LocaleUtils.tr("heightprofile.print")}];return[/*#__PURE__*/React.createElement(ResizeableWindow,{dockable:"bottom",extraControls:extraControls,icon:"line",initialHeight:this.props.height,initialWidth:600,initiallyDocked:true,key:"ProfileDialog",onClose:this.onClose,onExternalWindowResized:this.resizeChart,splitScreenWhenDocked:true,title:LocaleUtils.tr("heightprofile.title"),usePortal:false},this.state.isloading?/*#__PURE__*/React.createElement("div",{className:"height-profile-loading-indicator",role:"body"},/*#__PURE__*/React.createElement(Spinner,{className:"spinner"})," ",LocaleUtils.tr("heightprofile.loading")):this.renderHeightProfile(function(el){_this5.chart=el},true)),this.state.printdialog?/*#__PURE__*/React.createElement(HeightProfilePrintDialog,{key:"ProfilePrintDialog",measurement:this.props.measurement,onClose:function onClose(){return _this5.setState({printdialog:false})},templatePath:this.props.templatePath},this.renderHeightProfile):null]}}])}(React.Component);_defineProperty(HeightProfile,"propTypes",{addMarker:PropTypes.func,changeMeasurementState:PropTypes.func,/** The height of the height profile widget in pixels. */height:PropTypes.number,/** The precision of displayed and exported values (0: no decimals, 1: 1 decimal position, etc). */heightProfilePrecision:PropTypes.number,measurement:PropTypes.object,projection:PropTypes.string,removeMarker:PropTypes.func,/** The number of elevation samples to query. */samples:PropTypes.number,/** Template location for the height profile print functionality */templatePath:PropTypes.string});_defineProperty(HeightProfile,"defaultProps",{samples:500,heightProfilePrecision:0,height:150,templatePath:":/templates/heightprofileprint.html"});export default connect(function(state){return{measurement:state.measurement,projection:state.map.projection}},{addMarker:addMarker,changeMeasurementState:changeMeasurementState,removeMarker:removeMarker})(HeightProfile);
24
+ if(Math.abs(p1[0]-p2[0])>tol){return p1[0]<=q[0]&&q[0]<=p2[0]||p2[0]<=q[0]&&q[0]<=p1[0]}else{return p1[1]<=q[1]&&q[1]<=p2[1]||p2[1]<=q[1]&&q[1]<=p1[1]}});_defineProperty(_this3,"exportProfile",function(){if(!_this3.state.data.x){return}var csv="";csv+="index"+"\t"+"distance"+"\t"+"elevation"+"\n";_this3.state.data.x.forEach(function(x,idx){var sample={x:x,y:_this3.state.data.y[idx]};var prec=_this3.props.heightProfilePrecision;var distance=Math.round(sample.x*Math.pow(10,prec))/Math.pow(10,prec);var height=Math.round(sample.y*Math.pow(10,prec))/Math.pow(10,prec);csv+=String(idx).replace("\"","\"\"")+"\t"+String(distance)+"\t"+String(height)+"\n"});FileSaver.saveAs(new Blob([csv],{type:"text/plain;charset=utf-8"}),"heightprofile.csv")});_this3.chart=null;_this3.profilePrintWindow=null;return _this3}_inherits(HeightProfile,_React$Component);return _createClass(HeightProfile,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){if(this.props.measurement.coordinates!==prevProps.measurement.coordinates){if(this.props.measurement.drawing===false&&this.props.measurement.geomType==="LineString"&&!isEmpty(this.props.measurement.coordinates)){this.queryElevations(this.props.measurement.coordinates,this.props.measurement.segment_lengths,this.props.projection)}else if(!isEmpty(this.state.data)){this.setState({data:{}});this.props.changeMeasurementState(_objectSpread(_objectSpread({},this.props.measurement),{},{pickPositionCallback:null}))}}}},{key:"queryElevations",value:function queryElevations(coordinates,distances,projection){var _this4=this;var reqId=uuidv1();this.setState({reqId:reqId});var totLength=this.props.measurement.length;getElevationInterface().getProfile(coordinates,distances,projection,this.props.samples).then(function(elevations){// Request changed
25
+ if(_this4.state.reqId!==reqId){return}// Compute x-axis distances and get node points
26
+ var nodes=[];var cumDist=distances[0];var distIdx=0;var y=elevations;var x=y.map(function(entry,idx,a){var dist=(idx/(a.length-1)*totLength).toFixed(0);if(dist>=cumDist){nodes.push({x:dist,y:y[idx]});cumDist+=distances[++distIdx]}return dist});// First and last node
27
+ nodes.unshift({x:x[0],y:y[0]});nodes.push({x:x[x.length-1],y:y[y.length-1]});var data={x:x,y:elevations,maxY:Math.max.apply(Math,_toConsumableArray(elevations)),totLength:totLength,nodes:nodes};_this4.setState({reqId:null,data:data});_this4.props.changeMeasurementState(_objectSpread(_objectSpread({},_this4.props.measurement),{},{pickPositionCallback:_this4.pickPositionCallback}))})["catch"](function(error){_this4.setState({reqId:null,data:error?{error:error}:{}})})}},{key:"render",value:function render(){var _this5=this;if(isEmpty(this.state.data)&&!this.state.isloading){return null}var extraControls=[{icon:"circle",active:this.state.drawnodes,callback:function callback(){return _this5.setState(function(state){return{drawnodes:!state.drawnodes}})},title:LocaleUtils.tr("heightprofile.drawnodes")},{icon:"export",callback:this.exportProfile,title:LocaleUtils.tr("heightprofile.export")},{icon:"print",active:this.state.printdialog,callback:function callback(){return _this5.setState(function(state){return{printdialog:!state.printdialog}})},title:LocaleUtils.tr("heightprofile.print")}];return[/*#__PURE__*/React.createElement(ResizeableWindow,{dockable:"bottom",extraControls:extraControls,icon:"line",initialHeight:this.props.height,initialWidth:600,initiallyDocked:true,key:"ProfileDialog",onClose:this.onClose,onExternalWindowResized:this.resizeChart,splitScreenWhenDocked:true,title:LocaleUtils.tr("heightprofile.title"),usePortal:false},this.state.isloading?/*#__PURE__*/React.createElement("div",{className:"height-profile-loading-indicator",role:"body"},/*#__PURE__*/React.createElement(Spinner,{className:"spinner"})," ",LocaleUtils.tr("heightprofile.loading")):this.renderHeightProfile(function(el){_this5.chart=el},true)),this.state.printdialog?/*#__PURE__*/React.createElement(HeightProfilePrintDialog,{key:"ProfilePrintDialog",measurement:this.props.measurement,onClose:function onClose(){return _this5.setState({printdialog:false})},templatePath:this.props.templatePath},this.renderHeightProfile):null]}}])}(React.Component);_defineProperty(HeightProfile,"propTypes",{addMarker:PropTypes.func,changeMeasurementState:PropTypes.func,/** The height of the height profile widget in pixels. */height:PropTypes.number,/** The precision of displayed and exported values (0: no decimals, 1: 1 decimal position, etc). */heightProfilePrecision:PropTypes.number,measurement:PropTypes.object,projection:PropTypes.string,removeMarker:PropTypes.func,/** The number of elevation samples to query. */samples:PropTypes.number,/** Template location for the height profile print functionality */templatePath:PropTypes.string});_defineProperty(HeightProfile,"defaultProps",{samples:500,heightProfilePrecision:0,height:150,templatePath:":/templates/heightprofileprint.html"});export default connect(function(state){return{measurement:state.measurement,projection:state.map.projection}},{addMarker:addMarker,changeMeasurementState:changeMeasurementState,removeMarker:removeMarker})(HeightProfile);
@@ -4,13 +4,15 @@ 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 PropTypes from"prop-types";import{setCurrentTask}from"../actions/task";import Icon from"../components/Icon";import CopyButton from"../components/widgets/CopyButton";import ConfigUtils from"../utils/ConfigUtils";import CoordinatesUtils from"../utils/CoordinatesUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import"./style/MapInfoTooltip.css";/**
7
+ */import React from"react";import{connect}from"react-redux";import axios from"axios";import PropTypes from"prop-types";import{setCurrentTask}from"../actions/task";import Icon from"../components/Icon";import CopyButton from"../components/widgets/CopyButton";import ConfigUtils from"../utils/ConfigUtils";import CoordinatesUtils from"../utils/CoordinatesUtils";import{getElevationInterface}from"../utils/ElevationInterface";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import"./style/MapInfoTooltip.css";/**
8
8
  * Provides map context information when right-clicking on the map.
9
9
  *
10
10
  * Displays the coordinates at the picked position by default.
11
11
  *
12
12
  * If `elevationServiceUrl` in `config.json` to points to a `qwc-elevation-service`,
13
- * the height at the picked position is also displayed.
13
+ * or a custom elevation interface is exposed in `window.QWC2ElevationInterface` (see
14
+ * [ElevationInterface.js](https://github.com/qgis/qwc2/blob/master/utils/ElevationInterface.js)), the
15
+ * height at the picked position is also displayed.
14
16
  *
15
17
  * If `mapInfoService` in `config.json` points to a `qwc-mapinfo-service`, additional
16
18
  * custom information according to the `qwc-mapinfo-service` configuration is returned.
@@ -29,4 +31,4 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
29
31
  * render() { return ...; }
30
32
  * };
31
33
  * ```
32
- */var MapInfoTooltip=/*#__PURE__*/function(_React$Component){function MapInfoTooltip(){var _this;_classCallCheck(this,MapInfoTooltip);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,MapInfoTooltip,[].concat(args));_defineProperty(_this,"state",{point:null,elevation:null,extraInfo:null});_defineProperty(_this,"clear",function(){_this.setState({point:null,height:null,extraInfo:null})});return _this}_inherits(MapInfoTooltip,_React$Component);return _createClass(MapInfoTooltip,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this2=this;if(!this.props.enabled&&this.state.point){this.clear();return}var newPoint=this.props.map.click;if(!newPoint||newPoint.button!==2){if(this.state.point){this.clear()}}else{var oldPoint=prevProps.map.click;if(!oldPoint||oldPoint.pixel[0]!==newPoint.pixel[0]||oldPoint.pixel[1]!==newPoint.pixel[1]){this.setState({point:newPoint,elevation:null});var serviceParams={pos:newPoint.coordinate.join(","),crs:this.props.map.projection};var elevationService=(ConfigUtils.getConfigProp("elevationServiceUrl")||"").replace(/\/$/,"");var elevationPrecision=prevProps.elevationPrecision;if(elevationService){axios.get(elevationService+"/getelevation",{params:serviceParams}).then(function(response){_this2.setState({elevation:Math.round(response.data.elevation*Math.pow(10,elevationPrecision))/Math.pow(10,elevationPrecision)})})["catch"](function(){})}var mapInfoService=ConfigUtils.getConfigProp("mapInfoService");if(mapInfoService){axios.get(mapInfoService,{params:serviceParams}).then(function(response){_this2.setState({extraInfo:response.data.results})})["catch"](function(){})}}}}},{key:"render",value:function render(){var _this3=this;if(!this.state.point){return null}var info=[];var projections=[this.props.map.displayCrs];if(!projections.includes(this.props.map.projection)){projections.push(this.props.map.projection)}if(this.props.includeWGS84&&!projections.includes("EPSG:4326")){projections.push("EPSG:4326")}projections.map(function(crs){var coo=CoordinatesUtils.reproject(_this3.state.point.coordinate,_this3.props.map.projection,crs);var decimals=CoordinatesUtils.getPrecision(crs);info.push([(CoordinatesUtils.getAvailableCRS()[crs]||{label:crs}).label,coo.map(function(x){return LocaleUtils.toLocaleFixed(x,decimals)}).join(", ")])});if(this.state.elevation){info.push([LocaleUtils.tr("mapinfotooltip.elevation"),this.state.elevation+" m"])}if(this.state.extraInfo){info.push.apply(info,_toConsumableArray(this.state.extraInfo))}var title=LocaleUtils.tr("mapinfotooltip.title");var pixel=MapUtils.getHook(MapUtils.GET_PIXEL_FROM_COORDINATES_HOOK)(this.state.point.coordinate);var style={left:this.props.mapMargins.left+pixel[0]+"px",top:this.props.mapMargins.top+pixel[1]+"px"};var text=info.map(function(entry){return entry.join(": ")}).join("\n");var routingButtons=null;if(ConfigUtils.havePlugin("Routing")){var prec=CoordinatesUtils.getPrecision(this.props.map.displayCrs);var pos=CoordinatesUtils.reproject(this.state.point.coordinate,this.props.map.projection,this.props.map.displayCrs);var point={text:pos.map(function(x){return x.toFixed(prec)}).join(", ")+" ("+this.props.map.displayCrs+")",pos:_toConsumableArray(pos),crs:this.props.map.displayCrs};routingButtons=/*#__PURE__*/React.createElement("table",{className:"mapinfotooltip-body-routing"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("b",null,LocaleUtils.tr("routing.route"),":")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("div",{className:"controlgroup"},/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this3.props.setCurrentTask("Routing",null,null,{from:point})}},LocaleUtils.tr("routing.fromhere")),/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this3.props.setCurrentTask("Routing",null,null,{to:point})}},LocaleUtils.tr("routing.tohere")),/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this3.props.setCurrentTask("Routing",null,null,{via:point})}},LocaleUtils.tr("routing.addviapoint"))))),/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("b",null,LocaleUtils.tr("routing.reachability"),":")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("div",{className:"controlgroup"},/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this3.props.setCurrentTask("Routing",null,null,{isocenter:point})}},LocaleUtils.tr("routing.isocenter")),/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this3.props.setCurrentTask("Routing",null,null,{isoextracenter:point})}},LocaleUtils.tr("routing.isoextracenter")))))))}return/*#__PURE__*/React.createElement("div",{className:"mapinfotooltip",style:style},/*#__PURE__*/React.createElement("div",{className:"mapinfotooltip-window"},/*#__PURE__*/React.createElement("div",{className:"mapinfotooltip-titlebar"},/*#__PURE__*/React.createElement("span",{className:"mapinfotooltip-title"},title),/*#__PURE__*/React.createElement(CopyButton,{buttonClass:"mapinfotooltip-button",text:text}),/*#__PURE__*/React.createElement(Icon,{className:"mapinfotooltip-button",icon:"remove",onClick:this.clear})),/*#__PURE__*/React.createElement("div",{className:"mapinfotooltip-body"},/*#__PURE__*/React.createElement("table",null,/*#__PURE__*/React.createElement("tbody",null,info.map(function(entry,index){return/*#__PURE__*/React.createElement("tr",{key:"row"+index},/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("b",null,entry[0],":")),/*#__PURE__*/React.createElement("td",null,entry[1]))}))),routingButtons,this.props.plugins.map(function(Plugin,idx){return/*#__PURE__*/React.createElement(Plugin,{closePopup:_this3.clear,key:idx,point:_this3.state.point,projection:_this3.props.map.projection})}))))}}])}(React.Component);_defineProperty(MapInfoTooltip,"propTypes",{/** The number of decimal places to display for elevation values. */elevationPrecision:PropTypes.number,enabled:PropTypes.bool,includeWGS84:PropTypes.bool,map:PropTypes.object,mapMargins:PropTypes.object,/** Additional plugin components for the map info tooltip. */plugins:PropTypes.array,setCurrentTask:PropTypes.func});_defineProperty(MapInfoTooltip,"defaultProps",{elevationPrecision:0,includeWGS84:true,plugins:[]});export default(function(plugins){return connect(function(state){return{mapMargins:state.windows.mapMargins,enabled:state.task.identifyEnabled,map:state.map,plugins:plugins}},{setCurrentTask:setCurrentTask})(MapInfoTooltip)});
34
+ */var MapInfoTooltip=/*#__PURE__*/function(_React$Component){function MapInfoTooltip(){var _this;_classCallCheck(this,MapInfoTooltip);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,MapInfoTooltip,[].concat(args));_defineProperty(_this,"state",{point:null,elevation:null,extraInfo:null});_defineProperty(_this,"clear",function(){_this.setState({point:null,height:null,extraInfo:null})});return _this}_inherits(MapInfoTooltip,_React$Component);return _createClass(MapInfoTooltip,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this2=this;if(!this.props.enabled&&this.state.point){this.clear();return}var newPoint=this.props.map.click;if(!newPoint||newPoint.button!==2){if(this.state.point){this.clear()}}else{var oldPoint=prevProps.map.click;if(!oldPoint||oldPoint.pixel[0]!==newPoint.pixel[0]||oldPoint.pixel[1]!==newPoint.pixel[1]){this.setState({point:newPoint,elevation:null});var pos=newPoint.coordinate;var crs=this.props.map.projection;getElevationInterface().getElevation(pos,crs).then(function(elevation){var elevationPrecision=_this2.props.elevationPrecision;_this2.setState({elevation:Math.round(elevation*Math.pow(10,elevationPrecision))/Math.pow(10,elevationPrecision)})})["catch"](function(){});var mapInfoService=ConfigUtils.getConfigProp("mapInfoService");if(mapInfoService){axios.get(mapInfoService,{params:{pos:pos.join(","),crs:crs}}).then(function(response){_this2.setState({extraInfo:response.data.results})})["catch"](function(){})}}}}},{key:"render",value:function render(){var _this3=this;if(!this.state.point){return null}var info=[];var projections=[this.props.map.displayCrs];if(!projections.includes(this.props.map.projection)){projections.push(this.props.map.projection)}if(this.props.includeWGS84&&!projections.includes("EPSG:4326")){projections.push("EPSG:4326")}projections.map(function(crs){var coo=CoordinatesUtils.reproject(_this3.state.point.coordinate,_this3.props.map.projection,crs);var decimals=CoordinatesUtils.getPrecision(crs);info.push([(CoordinatesUtils.getAvailableCRS()[crs]||{label:crs}).label,coo.map(function(x){return LocaleUtils.toLocaleFixed(x,decimals)}).join(", ")])});if(this.state.elevation){info.push([LocaleUtils.tr("mapinfotooltip.elevation"),this.state.elevation+" m"])}if(this.state.extraInfo){info.push.apply(info,_toConsumableArray(this.state.extraInfo))}var title=LocaleUtils.tr("mapinfotooltip.title");var pixel=MapUtils.getHook(MapUtils.GET_PIXEL_FROM_COORDINATES_HOOK)(this.state.point.coordinate);var style={left:this.props.mapMargins.left+pixel[0]+"px",top:this.props.mapMargins.top+pixel[1]+"px"};var text=info.map(function(entry){return entry.join(": ")}).join("\n");var routingButtons=null;if(ConfigUtils.havePlugin("Routing")){var prec=CoordinatesUtils.getPrecision(this.props.map.displayCrs);var pos=CoordinatesUtils.reproject(this.state.point.coordinate,this.props.map.projection,this.props.map.displayCrs);var point={text:pos.map(function(x){return x.toFixed(prec)}).join(", ")+" ("+this.props.map.displayCrs+")",pos:_toConsumableArray(pos),crs:this.props.map.displayCrs};routingButtons=/*#__PURE__*/React.createElement("table",{className:"mapinfotooltip-body-routing"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("b",null,LocaleUtils.tr("routing.route"),":")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("div",{className:"controlgroup"},/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this3.props.setCurrentTask("Routing",null,null,{from:point})}},LocaleUtils.tr("routing.fromhere")),/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this3.props.setCurrentTask("Routing",null,null,{to:point})}},LocaleUtils.tr("routing.tohere")),/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this3.props.setCurrentTask("Routing",null,null,{via:point})}},LocaleUtils.tr("routing.addviapoint"))))),/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("b",null,LocaleUtils.tr("routing.reachability"),":")),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("div",{className:"controlgroup"},/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this3.props.setCurrentTask("Routing",null,null,{isocenter:point})}},LocaleUtils.tr("routing.isocenter")),/*#__PURE__*/React.createElement("button",{className:"button",onClick:function onClick(){return _this3.props.setCurrentTask("Routing",null,null,{isoextracenter:point})}},LocaleUtils.tr("routing.isoextracenter")))))))}return/*#__PURE__*/React.createElement("div",{className:"mapinfotooltip",style:style},/*#__PURE__*/React.createElement("div",{className:"mapinfotooltip-window"},/*#__PURE__*/React.createElement("div",{className:"mapinfotooltip-titlebar"},/*#__PURE__*/React.createElement("span",{className:"mapinfotooltip-title"},title),/*#__PURE__*/React.createElement(CopyButton,{buttonClass:"mapinfotooltip-button",text:text}),/*#__PURE__*/React.createElement(Icon,{className:"mapinfotooltip-button",icon:"remove",onClick:this.clear})),/*#__PURE__*/React.createElement("div",{className:"mapinfotooltip-body"},/*#__PURE__*/React.createElement("table",null,/*#__PURE__*/React.createElement("tbody",null,info.map(function(entry,index){return/*#__PURE__*/React.createElement("tr",{key:"row"+index},/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("b",null,entry[0],":")),/*#__PURE__*/React.createElement("td",null,entry[1]))}))),routingButtons,this.props.plugins.map(function(Plugin,idx){return/*#__PURE__*/React.createElement(Plugin,{closePopup:_this3.clear,key:idx,point:_this3.state.point,projection:_this3.props.map.projection})}))))}}])}(React.Component);_defineProperty(MapInfoTooltip,"propTypes",{/** The number of decimal places to display for elevation values. */elevationPrecision:PropTypes.number,enabled:PropTypes.bool,includeWGS84:PropTypes.bool,map:PropTypes.object,mapMargins:PropTypes.object,/** Additional plugin components for the map info tooltip. */plugins:PropTypes.array,setCurrentTask:PropTypes.func});_defineProperty(MapInfoTooltip,"defaultProps",{elevationPrecision:0,includeWGS84:true,plugins:[]});export default(function(plugins){return connect(function(state){return{mapMargins:state.windows.mapMargins,enabled:state.task.identifyEnabled,map:state.map,plugins:plugins}},{setCurrentTask:setCurrentTask})(MapInfoTooltip)});
package/plugins/View3D.js CHANGED
@@ -17,7 +17,16 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
17
17
  * ...
18
18
  * ],
19
19
  * "tiles3d": [
20
- * {"name": "<name>", "url": "<url_to_tileset.json>", "title": "<title>", "colorAttr": "<tile_batch_attr>"}
20
+ * {
21
+ * "name": "<name>",
22
+ * "url": "<url_to_tileset.json>",
23
+ * "title": "<title>",
24
+ * "idAttr": "<tile_batch_attr>",
25
+ * "tilesetStyleUrl": "<url_to_tilesetStyle.json>",
26
+ * "colorAttr": "<tile_batch_attr>",
27
+ * "alphaAttr": "<tile_batch_attr>",
28
+ * "labelAttr": "<tile_batch_attr>",
29
+ * }
21
30
  * ]
22
31
  * }
23
32
  * ```
@@ -25,10 +34,26 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
25
34
  *
26
35
  * - The DTM should be a cloud optimized GeoTIFF.
27
36
  * - 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.
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
37
+ * - `idAttr`: Batch table attribute which stores the batch object id, used for styling and passed to `tileInfoServiceUrl`. Default: `id`.
38
+ * - `tilesetStyleUrl`: optional, URL to a tileset style JSON dict, see below. Takes precedente over `colorAttr`, `alphaAttr`, `labelAttr`.
39
+ * - `colorAttr`: optional, batch table attribute which stores the batch color, as a 0xRRGGBB integer.
40
+ * - `alphaAttr`: optional, batch table attribute which stores the batch alpha (transparency), as a [0, 255] integer.
41
+ * - `labelAttr`: optional, batch table attribute which stores the batch label, displayed above the geometry.
42
+ *
43
+ * The tileset style JSON is shaped as follows:
44
+ * ```
45
+ * {
46
+ * "<object_id>": {
47
+ * "label": "<label>",
48
+ * "color": "<css RGB(A) color string>"
49
+ * }
50
+ * }
51
+ * ```
52
+ */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;var options={searchMinScaleDenom:_this.props.searchMinScaleDenom,tileInfoServiceUrl:_this.props.tileInfoServiceUrl};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: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
30
53
  var _ReducerIndex$reducer=ReducerIndex.reducers,task=_ReducerIndex$reducer.task,windows=_ReducerIndex$reducer.windows;// Reducer for syncronization with parent store
31
54
  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
32
55
  StandardApp.store.dispatch(action);return state}else{return action.type===syncAction?action[key]:state}}};var displayActions=Object.values(displayExports).filter(function(x){return typeof x==="string"});var themeActions=Object.values(themeExports).filter(function(x){return typeof x==="string"});var display=forwardReducer("display",displayActions,"SYNC_DISPLAY_FROM_PARENT_STORE");var layers=forwardReducer("layers",[],"SYNC_LAYERS_FROM_PARENT_STORE");var localConfig=forwardReducer("localConfig",[],"SYNC_LOCAL_CONFIG_FROM_PARENT_STORE");var theme=forwardReducer("theme",themeActions,"SYNC_THEME_FROM_PARENT_STORE");_this.store=createStore({display:display,layers:layers,localConfig:localConfig,map:map3dReducer,theme:theme,task:task,windows:windows});return _this}_inherits(View3D,_React$Component);return _createClass(View3D,[{key:"componentDidMount",value:function componentDidMount(){if(this.props.startupParams.v==="3d"){this.props.setView3dMode(View3DMode.FULLSCREEN);this.restoreOnComponentLoad=true}else if(this.props.startupParams.v==="3d2d"){this.props.setView3dMode(View3DMode.SPLITSCREEN);this.restoreOnComponentLoad=true}}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var _this2=this,_this$props$theme$cur;if(this.props.enabled&&!prevProps.enabled){this.setState({mode:View3DMode.FULLSCREEN});this.props.setCurrentTask(null)}else if(this.props.display.view3dMode!==View3DMode.DISABLED&&prevProps.display.view3dMode===View3DMode.DISABLED){import("../components/map3d/Map3D").then(function(component){_this2.map3dComponent=component["default"];_this2.map3dComponentRef=null;_this2.setState({componentLoaded:true})})}else if(this.props.display.view3dMode===View3DMode.DISABLED&&prevProps.display.view3dMode!==View3DMode.DISABLED){this.map3dComponent=null;this.map3dComponentRef=null;this.setState({componentLoaded:false})}// Sync parts of parent store
33
56
  if(this.props.display!==prevProps.display){this.store.dispatch({type:"SYNC_DISPLAY_FROM_PARENT_STORE",display:this.props.display})}if(this.props.theme!==prevProps.theme){this.store.dispatch({type:"SYNC_THEME_FROM_PARENT_STORE",theme:this.props.theme})}if(this.props.localConfig!==prevProps.localConfig){this.store.dispatch({type:"SYNC_LOCAL_CONFIG_FROM_PARENT_STORE",localConfig:this.props.localConfig})}if(this.props.layers!==prevProps.layers){this.store.dispatch({type:"SYNC_LAYERS_FROM_PARENT_STORE",layers:this.props.layers})}if(this.props.view3dMode!==prevProps.view3dMode){if(this.props.view3dMode===View3DMode.FULLSCREEN){UrlParams.updateParams({v:"3d"})}else if(this.props.view3dMode===View3DMode.SPLITSCREEN){UrlParams.updateParams({v:"3d2d"})}else{UrlParams.updateParams({v:undefined})}}// Switch to 2D mode if new theme has no 3D configuration
34
- if(this.props.theme.current!==prevProps.theme.current&&!((_this$props$theme$cur=this.props.theme.current)!==null&&_this$props$theme$cur!==void 0&&_this$props$theme$cur.map3d)&&this.props.view3dMode!==View3DMode.DISABLED){this.props.setView3dMode(View3D.DISABLED)}}},{key:"render",value:function render(){var _this$props$theme$cur2;var button=(_this$props$theme$cur2=this.props.theme.current)!==null&&_this$props$theme$cur2!==void 0&&_this$props$theme$cur2.map3d?/*#__PURE__*/React.createElement(View3DSwitcher,{key:"View3DButton",position:this.props.buttonPosition}):null;return[button,this.render3DWindow()]}}])}(React.Component);_defineProperty(View3D,"propTypes",{/** The position slot index of the 3d switch map button, from the bottom (0: bottom slot). */buttonPosition:PropTypes.number,display:PropTypes.object,enabled:PropTypes.bool,/** Default window geometry. */geometry:PropTypes.shape({initialWidth:PropTypes.number,initialHeight:PropTypes.number,initialX:PropTypes.number,initialY:PropTypes.number,initiallyDocked:PropTypes.bool}),layers:PropTypes.object,localConfig:PropTypes.object,mapBBox:PropTypes.object,/** Various configuration options */options:PropTypes.shape({/** Minimum scale denominator when zooming to search result. */searchMinScaleDenom:PropTypes.number}),plugins:PropTypes.object,pluginsConfig:PropTypes.object,projection:PropTypes.string,searchProviders:PropTypes.object,setCurrentTask:PropTypes.func,setView3dMode:PropTypes.func,startupParams:PropTypes.object,startupState:PropTypes.object,theme:PropTypes.object,view3dMode:PropTypes.number});_defineProperty(View3D,"defaultProps",{buttonPosition:6,geometry:{initialWidth:600,initialHeight:800,initialX:0,initialY:0,initiallyDocked:true},options:{searchMinScaleDenom:1000}});export default connect(createSelector([function(state){return state},searchProvidersSelector],function(state,searchProviders){return{enabled:state.task.id==="View3D",display:state.display,mapBBox:state.map.bbox,projection:state.map.projection,layers:state.layers,pluginsConfig:state.localConfig.plugins,theme:state.theme,localConfig:state.localConfig,view3dMode:state.display.view3dMode,startupParams:state.localConfig.startupParams,startupState:state.localConfig.startupState,searchProviders:searchProviders}}),{setCurrentTask:setCurrentTask,setView3dMode:setView3dMode})(View3D);
57
+ if(this.props.theme.current!==prevProps.theme.current&&!((_this$props$theme$cur=this.props.theme.current)!==null&&_this$props$theme$cur!==void 0&&_this$props$theme$cur.map3d)&&this.props.view3dMode!==View3DMode.DISABLED){this.props.setView3dMode(View3D.DISABLED)}}},{key:"render",value:function render(){var _this$props$theme$cur2;var button=(_this$props$theme$cur2=this.props.theme.current)!==null&&_this$props$theme$cur2!==void 0&&_this$props$theme$cur2.map3d?/*#__PURE__*/React.createElement(View3DSwitcher,{key:"View3DButton",position:this.props.buttonPosition}):null;return[button,this.render3DWindow()]}}])}(React.Component);_defineProperty(View3D,"propTypes",{/** The position slot index of the 3d switch map button, from the bottom (0: bottom slot). */buttonPosition:PropTypes.number,display:PropTypes.object,enabled:PropTypes.bool,/** Default window geometry. */geometry:PropTypes.shape({initialWidth:PropTypes.number,initialHeight:PropTypes.number,initialX:PropTypes.number,initialY:PropTypes.number,initiallyDocked:PropTypes.bool}),layers:PropTypes.object,localConfig:PropTypes.object,mapBBox:PropTypes.object,plugins:PropTypes.object,pluginsConfig:PropTypes.object,projection:PropTypes.string,/** Minimum scale denominator when zooming to search result. */searchMinScaleDenom:PropTypes.number,searchProviders:PropTypes.object,setCurrentTask:PropTypes.func,setView3dMode:PropTypes.func,startupParams:PropTypes.object,startupState:PropTypes.object,theme:PropTypes.object,/** URL to service for querying additional tile information.
58
+ * Can contain the `{tileset}` and `{objectid}` placeholders.
59
+ * Expected to return a JSON dict with attributes.*/tileInfoServiceUrl:PropTypes.string,view3dMode:PropTypes.number});_defineProperty(View3D,"defaultProps",{buttonPosition:6,geometry:{initialWidth:600,initialHeight:800,initialX:0,initialY:0,initiallyDocked:true},searchMinScaleDenom:1000});export default connect(createSelector([function(state){return state},searchProvidersSelector],function(state,searchProviders){return{enabled:state.task.id==="View3D",display:state.display,mapBBox:state.map.bbox,projection:state.map.projection,layers:state.layers,pluginsConfig:state.localConfig.plugins,theme:state.theme,localConfig:state.localConfig,view3dMode:state.display.view3dMode,startupParams:state.localConfig.startupParams,startupState:state.localConfig.startupState,searchProviders:searchProviders}}),{setCurrentTask:setCurrentTask,setView3dMode:setView3dMode})(View3D);
@@ -11,4 +11,5 @@ if(mutexVisibilityChanged){var newParent=newlayer;parentPath.forEach(function(in
11
11
  LayerUtils.propagateLayerProperty(newsublayer,action.property,action.newvalue)}if(["parents","both"].includes(recurseDirection)){// recurse to parents
12
12
  LayerUtils.propagateLayerProperty(newlayer,action.property,action.newvalue,action.sublayerpath)}if(newlayer.type==="wms"){Object.assign(newlayer,LayerUtils.buildWMSLayerParams(newlayer,state.filter))}if(newlayer.role===LayerRole.BACKGROUND){UrlParams.updateParams({bl:newlayer.visibility?newlayer.name:""})}return newlayer}else if(layer.role===LayerRole.BACKGROUND&&backgroundVisibilityChanged){return _objectSpread(_objectSpread({},layer),{},{visibility:false})}return layer});UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(newLayers)});return _objectSpread(_objectSpread({},state),{},{flat:newLayers})}case SET_LAYER_DIMENSIONS:{var _newLayers=(state.flat||[]).map(function(layer){if(layer.id===action.layerId){var newLayer=_objectSpread(_objectSpread({},layer),{},{dimensionValues:action.dimensions});Object.assign(newLayer,LayerUtils.buildWMSLayerParams(newLayer,state.filter));return newLayer}return layer});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers})}case ADD_LAYER:{var _action$layer$visibil,_action$layer$opacity;var _newLayers2=(state.flat||[]).concat();var layerId=action.layer.id||uuidv4();var newLayer=_objectSpread(_objectSpread({},action.layer),{},{id:layerId,name:action.layer.name||layerId,role:action.layer.role||LayerRole.USERLAYER,queryable:action.layer.queryable||false,visibility:(_action$layer$visibil=action.layer.visibility)!==null&&_action$layer$visibil!==void 0?_action$layer$visibil:true,opacity:(_action$layer$opacity=action.layer.opacity)!==null&&_action$layer$opacity!==void 0?_action$layer$opacity:255,layertreehidden:action.layer.layertreehidden||action.layer.role>LayerRole.USERLAYER});LayerUtils.addUUIDs(newLayer);if(action.beforename){_newLayers2=LayerUtils.insertLayer(_newLayers2,newLayer,"name",action.beforename)}else{var inspos=0;if(action.pos===null){for(;inspos<_newLayers2.length&&newLayer.role<_newLayers2[inspos].role;++inspos);}else{inspos=action.pos}_newLayers2.splice(inspos,0,newLayer);// Compress layers if possible
13
13
  _newLayers2=LayerUtils.implodeLayers(LayerUtils.explodeLayers(_newLayers2))}var _iterator=_createForOfIteratorHelper(_newLayers2),_step;try{for(_iterator.s();!(_step=_iterator.n()).done;){var lyr=_step.value;if(lyr.type==="wms"){Object.assign(lyr,LayerUtils.buildWMSLayerParams(lyr,state.filter))}}}catch(err){_iterator.e(err)}finally{_iterator.f()}UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(_newLayers2)});if(newLayer.role===LayerRole.BACKGROUND&&newLayer.visibility){UrlParams.updateParams({bl:newLayer.name})}return _objectSpread(_objectSpread({},state),{},{flat:_newLayers2})}case ADD_LAYER_SEPARATOR:{var _newLayers3=LayerUtils.insertSeparator(state.flat,action.title,action.afterLayerId,action.afterSublayerPath);var _iterator2=_createForOfIteratorHelper(_newLayers3),_step2;try{for(_iterator2.s();!(_step2=_iterator2.n()).done;){var layer=_step2.value;if(layer.type==="wms"){Object.assign(layer,LayerUtils.buildWMSLayerParams(layer,state.filter))}}}catch(err){_iterator2.e(err)}finally{_iterator2.f()}UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(_newLayers3)});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers3})}case REMOVE_LAYER:{var _layer=state.flat.find(function(l){return l.id===action.layerId});if(!_layer){return state}var _newLayers4=state.flat;if(_layer.role===LayerRole.BACKGROUND||isEmpty(action.sublayerpath)){var position=state.flat.findIndex(function(l){return l.id===action.layerId});_newLayers4=_toConsumableArray(_newLayers4);_newLayers4.splice(position,1);if(position>0&&position<_newLayers4.length&&_newLayers4[position-1].id===_newLayers4[position].id){// Compress layers
14
- _newLayers4=LayerUtils.implodeLayers(LayerUtils.explodeLayers(_newLayers4))}}else{_newLayers4=LayerUtils.removeLayer(state.flat,_layer,action.sublayerpath).map(function(l){if(l.type==="wms"){return _objectSpread(_objectSpread({},l),LayerUtils.buildWMSLayerParams(l,state.filter))}else{return l}})}UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(_newLayers4)});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers4})}case ADD_LAYER_FEATURES:{var _layerId=action.layer.id||uuidv4();var _newLayers5=(state.flat||[]).concat();var idx=_newLayers5.findIndex(function(layer){return layer.id===_layerId});if(idx===-1){var newFeatures=action.features.map(function(f){return _objectSpread(_objectSpread({},f),{},{id:f.id||(f.properties||{}).id||uuidv4()})});var _newLayer=_objectSpread(_objectSpread({},action.layer),{},{id:_layerId,type:"vector",name:action.layer.name||_layerId,uuid:uuidv4(),features:newFeatures,role:action.layer.role||LayerRole.USERLAYER,queryable:action.layer.queryable||false,visibility:action.layer.visibility||true,opacity:action.layer.opacity||255,layertreehidden:action.layer.layertreehidden||action.layer.role>LayerRole.USERLAYER,bbox:VectorLayerUtils.computeFeaturesBBox(action.features)});var _inspos=0;for(;_inspos<_newLayers5.length&&_newLayer.role<_newLayers5[_inspos].role;++_inspos);_newLayers5.splice(_inspos,0,_newLayer)}else{var addFeatures=action.features.map(function(f){return _objectSpread(_objectSpread({},f),{},{id:f.id||(f.properties||{}).id||uuidv4()})});var _newFeatures=action.clear?addFeatures:[].concat(_toConsumableArray((_newLayers5[idx].features||[]).filter(function(f){return!addFeatures.find(function(g){return g.id===f.id})})),_toConsumableArray(addFeatures));_newLayers5[idx]=_objectSpread(_objectSpread({},_newLayers5[idx]),{},{features:_newFeatures,bbox:VectorLayerUtils.computeFeaturesBBox(_newFeatures),rev:action.layer.rev})}return _objectSpread(_objectSpread({},state),{},{flat:_newLayers5})}case REMOVE_LAYER_FEATURES:{var changed=false;var _newLayers6=(state.flat||[]).reduce(function(result,layer){if(layer.id===action.layerId){var _newFeatures2=(layer.features||[]).filter(function(f){return action.featureIds.includes(f.id)===false});if(!isEmpty(_newFeatures2)||action.keepEmptyLayer){result.push(_objectSpread(_objectSpread({},layer),{},{features:_newFeatures2,bbox:VectorLayerUtils.computeFeaturesBBox(_newFeatures2)}))}changed=true}else{result.push(layer)}return result},[]);if(changed){return _objectSpread(_objectSpread({},state),{},{flat:_newLayers6})}else{return state}}case CLEAR_LAYER:{var _newLayers7=(state.flat||[]).map(function(layer){if(layer.id===action.layerId){return _objectSpread(_objectSpread({},layer),{},{features:[],bbox:null})}else{return layer}});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers7})}case ADD_THEME_SUBLAYER:{var themeLayerIdx=state.flat.findIndex(function(layer){return layer.role===LayerRole.THEME});if(themeLayerIdx>=0){var _newLayers8=state.flat.slice(0);_newLayers8[themeLayerIdx]=LayerUtils.mergeSubLayers(state.flat[themeLayerIdx],action.layer);_newLayers8[themeLayerIdx].visibility=true;var _iterator3=_createForOfIteratorHelper(_newLayers8),_step3;try{for(_iterator3.s();!(_step3=_iterator3.n()).done;){var _lyr=_step3.value;if(_lyr.type==="wms"){Object.assign(_lyr,LayerUtils.buildWMSLayerParams(_lyr,state.filter))}}}catch(err){_iterator3.e(err)}finally{_iterator3.f()}UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(_newLayers8)});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers8})}return state}case REFRESH_LAYER:{var _newLayers9=(state.flat||[]).map(function(layer){if(action.filter(layer)){return _objectSpread(_objectSpread({},layer),{},{rev:+new Date})}return layer});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers9})}case REMOVE_ALL_LAYERS:{return _objectSpread(_objectSpread({},state),{},{flat:[],swipe:null})}case REORDER_LAYER:{var _newLayers10=LayerUtils.reorderLayer(state.flat,action.layer,action.sublayerpath,action.direction,action.preventSplittingGroups).map(function(layer){if(layer.type==="wms"){return _objectSpread(_objectSpread({},layer),LayerUtils.buildWMSLayerParams(layer,state.filter))}else{return layer}});UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(_newLayers10)});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers10})}case REPLACE_PLACEHOLDER_LAYER:{var _newLayers11=state.flat||[];if(action.layer){_newLayers11=_newLayers11.map(function(layer){if(layer.type==="placeholder"&&layer.id===action.id){var _newLayer2=_objectSpread(_objectSpread(_objectSpread({},layer),action.layer),{},{role:layer.role,id:layer.id,uuid:layer.uuid});delete _newLayer2.loading;LayerUtils.addUUIDs(_newLayer2);if(_newLayer2.type==="wms"){Object.assign(_newLayer2,LayerUtils.buildWMSLayerParams(_newLayer2,state.filter))}return _newLayer2}else{return layer}})}else{_newLayers11=_newLayers11.filter(function(layer){return!(layer.type==="placeholder"&&layer.id===action.id)})}UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(_newLayers11)});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers11})}case SET_SWIPE:{return _objectSpread(_objectSpread({},state),{},{swipe:action.swipe})}case SET_LAYERS:{return _objectSpread(_objectSpread({},state),{},{flat:action.layers})}case SET_FILTER:{var filter={filterParams:action.filter,filterGeom:action.filterGeom,timeRange:action.timeRange};var _newLayers12=state.flat.map(function(layer){if(layer.type==="wms"){return _objectSpread(_objectSpread({},layer),LayerUtils.buildWMSLayerParams(layer,filter))}return layer});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers12,filter:filter})}default:return state}}
14
+ _newLayers4=LayerUtils.implodeLayers(LayerUtils.explodeLayers(_newLayers4))}}else{_newLayers4=LayerUtils.removeLayer(state.flat,_layer,action.sublayerpath).map(function(l){if(l.type==="wms"){return _objectSpread(_objectSpread({},l),LayerUtils.buildWMSLayerParams(l,state.filter))}else{return l}})}UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(_newLayers4)});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers4})}case ADD_LAYER_FEATURES:{var _layerId=action.layer.id||uuidv4();var _newLayers5=(state.flat||[]).concat();var idx=_newLayers5.findIndex(function(layer){return layer.id===_layerId});if(idx===-1){var newFeatures=action.features.map(function(f){return _objectSpread(_objectSpread({},f),{},{id:f.id||(f.properties||{}).id||uuidv4()})});var _newLayer=_objectSpread(_objectSpread({},action.layer),{},{id:_layerId,type:"vector",name:action.layer.name||_layerId,uuid:uuidv4(),features:newFeatures,role:action.layer.role||LayerRole.USERLAYER,queryable:action.layer.queryable||false,visibility:action.layer.visibility||true,opacity:action.layer.opacity||255,layertreehidden:action.layer.layertreehidden||action.layer.role>LayerRole.USERLAYER,bbox:VectorLayerUtils.computeFeaturesBBox(action.features)});var _inspos=0;for(;_inspos<_newLayers5.length&&_newLayer.role<_newLayers5[_inspos].role;++_inspos);_newLayers5.splice(_inspos,0,_newLayer)}else{var addFeatures=action.features.map(function(f){return _objectSpread(_objectSpread({},f),{},{id:f.id||(f.properties||{}).id||uuidv4()})});var _newFeatures=action.clear?addFeatures:[].concat(_toConsumableArray((_newLayers5[idx].features||[]).filter(function(f){return!addFeatures.find(function(g){return g.id===f.id})})),_toConsumableArray(addFeatures));_newLayers5[idx]=_objectSpread(_objectSpread({},_newLayers5[idx]),{},{features:_newFeatures,bbox:VectorLayerUtils.computeFeaturesBBox(_newFeatures),rev:action.layer.rev})}return _objectSpread(_objectSpread({},state),{},{flat:_newLayers5})}case REMOVE_LAYER_FEATURES:{var changed=false;var _newLayers6=(state.flat||[]).reduce(function(result,layer){if(layer.id===action.layerId){var _newFeatures2=(layer.features||[]).filter(function(f){return action.featureIds.includes(f.id)===false});if(!isEmpty(_newFeatures2)||action.keepEmptyLayer){result.push(_objectSpread(_objectSpread({},layer),{},{features:_newFeatures2,bbox:VectorLayerUtils.computeFeaturesBBox(_newFeatures2)}))}changed=true}else{result.push(layer)}return result},[]);if(changed){return _objectSpread(_objectSpread({},state),{},{flat:_newLayers6})}else{return state}}case CLEAR_LAYER:{var _newLayers7=(state.flat||[]).map(function(layer){if(layer.id===action.layerId){return _objectSpread(_objectSpread({},layer),{},{features:[],bbox:null})}else{return layer}});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers7})}case ADD_THEME_SUBLAYER:{var themeLayerIdx=state.flat.findIndex(function(layer){return layer.role===LayerRole.THEME});if(themeLayerIdx>=0){var _newLayers8=state.flat.slice(0);_newLayers8[themeLayerIdx]=LayerUtils.mergeSubLayers(state.flat[themeLayerIdx],action.layer);_newLayers8[themeLayerIdx].visibility=true;var _iterator3=_createForOfIteratorHelper(_newLayers8),_step3;try{for(_iterator3.s();!(_step3=_iterator3.n()).done;){var _lyr=_step3.value;if(_lyr.type==="wms"){Object.assign(_lyr,LayerUtils.buildWMSLayerParams(_lyr,state.filter))}}}catch(err){_iterator3.e(err)}finally{_iterator3.f()}UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(_newLayers8)});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers8})}return state}case REFRESH_LAYER:{var _newLayers9=(state.flat||[]).map(function(layer){if(action.filter(layer)){return _objectSpread(_objectSpread({},layer),{},{rev:+new Date})}return layer});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers9})}case REMOVE_ALL_LAYERS:{return _objectSpread(_objectSpread({},state),{},{flat:[],swipe:null})}case REORDER_LAYER:{var _newLayers10=LayerUtils.reorderLayer(state.flat,action.layer,action.sublayerpath,action.direction,action.preventSplittingGroups).map(function(layer){if(layer.type==="wms"){return _objectSpread(_objectSpread({},layer),LayerUtils.buildWMSLayerParams(layer,state.filter))}else{return layer}});UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(_newLayers10)});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers10})}case REPLACE_PLACEHOLDER_LAYER:{var _newLayers11=state.flat||[];if(action.layer){_newLayers11=_newLayers11.map(function(layer){if(layer.type==="placeholder"&&layer.id===action.id){var _newLayer2=_objectSpread(_objectSpread(_objectSpread({},layer),action.layer),{},{role:layer.role,id:layer.id,uuid:layer.uuid,// keep original title and attribution
15
+ title:layer.title||action.layer.title,attribution:layer.attribution||action.layer.attribution});delete _newLayer2.loading;LayerUtils.addUUIDs(_newLayer2);if(_newLayer2.type==="wms"){Object.assign(_newLayer2,LayerUtils.buildWMSLayerParams(_newLayer2,state.filter))}return _newLayer2}else{return layer}})}else{_newLayers11=_newLayers11.filter(function(layer){return!(layer.type==="placeholder"&&layer.id===action.id)})}UrlParams.updateParams({l:LayerUtils.buildWMSLayerUrlParam(_newLayers11)});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers11})}case SET_SWIPE:{return _objectSpread(_objectSpread({},state),{},{swipe:action.swipe})}case SET_LAYERS:{return _objectSpread(_objectSpread({},state),{},{flat:action.layers})}case SET_FILTER:{var filter={filterParams:action.filter,filterGeom:action.filterGeom,timeRange:action.timeRange};var _newLayers12=state.flat.map(function(layer){if(layer.type==="wms"){return _objectSpread(_objectSpread({},layer),LayerUtils.buildWMSLayerParams(layer,filter))}return layer});return _objectSpread(_objectSpread({},state),{},{flat:_newLayers12,filter:filter})}default:return state}}
package/scripts/dist.sh CHANGED
@@ -1,4 +1,5 @@
1
- #/bin/bash
1
+ #!/bin/bash
2
+ set -e
2
3
 
3
4
  rm -rf dist
4
5
  for dir in actions components libs plugins reducers scripts selectors stores utils;
@@ -14,5 +15,10 @@ cp -a package.json dist/
14
15
  cp -a LICENSE dist/
15
16
  cp -a README_npm.md dist/README.md
16
17
 
18
+ if [[ $(grep '"version": ".*-lts"' package.json) != "" ]]; then
19
+ sed -Ei 's|"name":\s*"qwc2",|"name": "qwc2-lts",|' dist/package.json
20
+ sed -Ei 's|"version":\s*"([0-9]+\.[0-9]+\.[0-9]+)-lts",|"version": "\1",|' dist/package.json
21
+ fi
22
+
17
23
  echo "Ready to publish!"
18
24
  echo "Run publish in the dist folder to publish the package."
@@ -389,6 +389,7 @@
389
389
  "areaLabel": "Област",
390
390
  "bearingLabel": "Лагер",
391
391
  "ground": "m AGL",
392
+ "heightDiffLabel": "",
392
393
  "imperial": "Imperial",
393
394
  "lengthLabel": "Дължина",
394
395
  "metric": "Метричен",
@@ -389,6 +389,7 @@
389
389
  "areaLabel": "Àrea",
390
390
  "bearingLabel": "Direcció",
391
391
  "ground": "",
392
+ "heightDiffLabel": "",
392
393
  "imperial": "",
393
394
  "lengthLabel": "Longitud",
394
395
  "metric": "",
@@ -389,6 +389,7 @@
389
389
  "areaLabel": "Plocha",
390
390
  "bearingLabel": "Střed",
391
391
  "ground": "",
392
+ "heightDiffLabel": "",
392
393
  "imperial": "Imperiálně",
393
394
  "lengthLabel": "Délka",
394
395
  "metric": "Metricky",
@@ -389,6 +389,7 @@
389
389
  "areaLabel": "Fläche",
390
390
  "bearingLabel": "Richtung",
391
391
  "ground": "m ü.B.",
392
+ "heightDiffLabel": "Höhenunterschied",
392
393
  "imperial": "Imperial",
393
394
  "lengthLabel": "Länge",
394
395
  "metric": "Metrisch",
@@ -389,6 +389,7 @@
389
389
  "areaLabel": "Fläche",
390
390
  "bearingLabel": "Richtung",
391
391
  "ground": "m ü.B.",
392
+ "heightDiffLabel": "Höhenunterschied",
392
393
  "imperial": "Imperial",
393
394
  "lengthLabel": "Länge",
394
395
  "metric": "Metrisch",
@@ -389,6 +389,7 @@
389
389
  "areaLabel": "Area",
390
390
  "bearingLabel": "Bearing",
391
391
  "ground": "m AGL",
392
+ "heightDiffLabel": "Height diff.",
392
393
  "imperial": "Imperial",
393
394
  "lengthLabel": "Length",
394
395
  "metric": "Metric",
@@ -389,6 +389,7 @@
389
389
  "areaLabel": "Area",
390
390
  "bearingLabel": "Dirección",
391
391
  "ground": "",
392
+ "heightDiffLabel": "",
392
393
  "imperial": "",
393
394
  "lengthLabel": "Longitud",
394
395
  "metric": "",