qwc2
Version:
QGIS Web Client
8 lines • 14.5 kB
JavaScript
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 _construct(t,e,r){if(_isNativeReflectConstruct())return Reflect.construct.apply(null,arguments);var o=[null];o.push.apply(o,e);var p=new(t.bind.apply(t,o));return r&&_setPrototypeOf(p,r.prototype),p}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)}/**
* Copyright 2017-2024 Sourcepole AG
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/import React from"react";import{Line}from"react-chartjs-2";import ReactDOM from"react-dom";import Shape from"@giro3d/giro3d/entities/Shape.js";import{Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Filler}from"chart.js";import FileSaver from"file-saver";import PropTypes from"prop-types";import{Vector3}from"three";import LocaleUtils from"../../utils/LocaleUtils";import MeasureUtils from"../../utils/MeasureUtils";import MiscUtils from"../../utils/MiscUtils";import ResizeableWindow from"../ResizeableWindow";import"../../plugins/style/HeightProfile.css";ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Filler);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.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,"scheduleRefreshImage",function(){clearTimeout(_this.refreshTimeout);_this.refreshTimeout=setTimeout(_this.refreshImage,500)});_defineProperty(_this,"refreshImage",function(){var src=_this.props.sceneContext.scene.renderer.domElement.toDataURL("image/png");var width=_this.props.sceneContext.scene.renderer.domElement.offsetWidth;_this.imageEl.innerHTML="<img src=\"".concat(src,"\" style=\"width: 100%; max-width: ").concat(width,"px\" />")});_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);this.props.sceneContext.scene.view.controls.addEventListener("change",this.scheduleRefreshImage)}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){if(this.state.initialized&&!prevState.initialized){this.refreshImage()}}},{key:"componentWillUnmount",value:function componentWillUnmount(){this.closePrintWindow();window.removeEventListener("beforeunload",this.closePrintWindow);this.props.sceneContext.scene.view.controls.removeEventListener("change",this.scheduleRefreshImage)}},{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,onClose:PropTypes.func,sceneContext:PropTypes.object,templatePath:PropTypes.string});var HeightProfile=/*#__PURE__*/function(_React$Component){function HeightProfile(props){var _this3;_classCallCheck(this,HeightProfile);_this3=_callSuper(this,HeightProfile,[props]);_defineProperty(_this3,"state",{printdialog:false,visible:true});_defineProperty(_this3,"onClose",function(){_this3.setState({visible:false,printdialog:false});_this3.marker.visible=false});_defineProperty(_this3,"renderHeightProfile",function(saveRef,interactive){var distanceStr=LocaleUtils.tr("heightprofile.distance");var heightStr=LocaleUtils.tr("heightprofile.height");var aslStr=LocaleUtils.tr("heightprofile.asl");var data={labels:_this3.props.data.map(function(entry){return entry[3]}),datasets:[{data:_this3.props.data.map(function(entry){return entry[2]}),fill:true,backgroundColor:"rgba(255,0,0,0.5)",borderColor:"rgb(255,0,0)",borderWidth:2,pointRadius:0,order:1}]};// Approx 10 ticks
var totLength=_this3.props.data[_this3.props.data.length-1][3];var maxHeight=Math.max.apply(Math,_toConsumableArray(_this3.props.data.map(function(x){return x[2]})));var stepSizeFact=Math.pow(10,Math.ceil(Math.log10(totLength/10)));var stepSize=Math.round(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+": "+MeasureUtils.formatMeasurement(ctx.parsed.y,false,"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(totLength)},y:{ticks:{font:{size:10},callback:function callback(value){return value.toFixed(prec)}},title:{display:true,text:heightStr+" [m "+aslStr+"]"},max:Math.ceil(maxHeight)}},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*totLength)}:undefined};return/*#__PURE__*/React.createElement("div",{className:"height-profile-chart-container",onMouseLeave:_this3.hideMarker,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(dist){var data=_this3.props.data;var i=data.findIndex(function(x){return x[3]>=dist});if(i===0){_this3.marker.setPoints([_construct(Vector3,_toConsumableArray(data[0]))])}else{var lambda=(dist-data[i-1][3])/(data[i][3]-data[i-1][3]);var p=new Vector3(data[i-1][0]+lambda*(data[i][0]-data[i][0]),data[i-1][1]+lambda*(data[i][1]-data[i][1]),data[i-1][2]+lambda*(data[i][2]-data[i][2]));_this3.marker.setPoints([p])}_this3.marker.visible=true});_defineProperty(_this3,"hideMarker",function(){_this3.marker.visible=false});_defineProperty(_this3,"exportProfile",function(){var csv="";csv+="index"+"\t"+"distance"+"\t"+"elevation"+"\n";_this3.props.data.forEach(function(entry,idx){var sample={x:entry[3],y:entry[2]};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:"componentDidMount",value:function componentDidMount(){this.marker=new Shape({showVertexLabels:true,showLine:false,showVertices:true,vertexLabelFormatter:function vertexLabelFormatter(_ref){var position=_ref.position;return MeasureUtils.formatMeasurement(position.z,false,"m")}});this.marker.visible=false;this.props.sceneContext.scene.add(this.marker)}},{key:"componentWillUnmount",value:function componentWillUnmount(){this.props.sceneContext.scene.remove(this.marker)}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){if(this.props.data!==prevProps.data){this.setState({visible:true})}}},{key:"render",value:function render(){var _this4=this;if(!this.state.visible){return null}var extraControls=[{icon:"export",callback:this.exportProfile,title:LocaleUtils.tr("heightprofile.export")},{icon:"print",active:this.state.printdialog,callback:function callback(){return _this4.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.renderHeightProfile(function(el){_this4.chart=el},true)),this.state.printdialog?/*#__PURE__*/React.createElement(HeightProfilePrintDialog,{key:"ProfilePrintDialog",onClose:function onClose(){return _this4.setState({printdialog:false})},sceneContext:this.props.sceneContext,templatePath:this.props.templatePath},this.renderHeightProfile):null]}}])}(React.Component);_defineProperty(HeightProfile,"propTypes",{data:PropTypes.array,/** 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,sceneContext:PropTypes.object,/** Template location for the height profile print functionality */templatePath:PropTypes.string});_defineProperty(HeightProfile,"defaultProps",{heightProfilePrecision:0,height:150,templatePath:":/templates/heightprofileprint.html"});export{HeightProfile as default};