qwc2 2025.7.6 → 2025.7.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/actions/layers.js CHANGED
@@ -5,4 +5,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
7
  */import ReducerIndex from"../reducers/index";import layersReducer from"../reducers/layers";ReducerIndex.register("layers",layersReducer);import ConfigUtils from"../utils/ConfigUtils";export var SET_LAYER_LOADING="SET_LAYER_LOADING";export var ADD_LAYER="ADD_LAYER";export var ADD_LAYER_SEPARATOR="ADD_LAYER_SEPARATOR";export var REMOVE_LAYER="REMOVE_LAYER";export var REORDER_LAYER="REORDER_LAYER";export var ADD_LAYER_FEATURES="ADD_LAYER_FEATURES";export var ADD_THEME_SUBLAYER="ADD_THEME_SUBLAYER";export var REMOVE_LAYER_FEATURES="REMOVE_LAYER_FEATURES";export var CLEAR_LAYER="CLEAR_LAYER";export var CHANGE_LAYER_PROPERTY="CHANGE_LAYER_PROPERTY";export var SET_LAYER_DIMENSIONS="SET_LAYER_DIMENSIONS";export var REFRESH_LAYER="REFRESH_LAYER";export var REMOVE_ALL_LAYERS="REMOVE_ALL_LAYERS";export var REPLACE_PLACEHOLDER_LAYER="REPLACE_PLACEHOLDER_LAYER";export var SET_SWIPE="SET_SWIPE";export var SET_FILTER="SET_FILTER";export var SET_THEME_LAYERS_VISIBILITY_PRESET="SET_THEME_LAYERS_VISIBILITY_PRESET";export var LayerRole={BACKGROUND:1,THEME:2,USERLAYER:3,SELECTION:4,MARKER:5};export function addLayer(layer){var pos=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;return{type:ADD_LAYER,layer:layer,pos:pos,options:options}}export function addLayerSeparator(title,afterLayerId,afterSublayerPath){return{type:ADD_LAYER_SEPARATOR,title:title,afterLayerId:afterLayerId,afterSublayerPath:afterSublayerPath}}export function removeLayer(layerId){var sublayerpath=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[];return{type:REMOVE_LAYER,layerId:layerId,sublayerpath:sublayerpath}}export function reorderLayer(layer,sublayerpath,direction){return function(dispatch,getState){dispatch({type:REORDER_LAYER,layer:layer,sublayerpath:sublayerpath,direction:direction,preventSplittingGroups:ConfigUtils.getConfigProp("preventSplittingGroupsWhenReordering",getState().theme.current)})}}export function addLayerFeatures(layer,features){var clear=arguments.length>2&&arguments[2]!==undefined?arguments[2]:false;return{type:ADD_LAYER_FEATURES,layer:layer,features:features,clear:clear}}export function removeLayerFeatures(layerId,featureIds){var keepEmptyLayer=arguments.length>2&&arguments[2]!==undefined?arguments[2]:false;return{type:REMOVE_LAYER_FEATURES,layerId:layerId,featureIds:featureIds,keepEmptyLayer:keepEmptyLayer}}export function clearLayer(layerId){return{type:CLEAR_LAYER,layerId:layerId}}export function addThemeSublayer(layer){return{type:ADD_THEME_SUBLAYER,layer:layer}}// recurseDirection: null (don't recurse), 'parents', 'children', 'both'
8
- export function changeLayerProperty(layerId,property,newvalue){var sublayerpath=arguments.length>3&&arguments[3]!==undefined?arguments[3]:[];var recurseDirection=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;return{type:CHANGE_LAYER_PROPERTY,layerId:layerId,property:property,newvalue:newvalue,sublayerpath:sublayerpath,recurseDirection:recurseDirection}}export function setLayerDimensions(layerId,dimensions){return{type:SET_LAYER_DIMENSIONS,layerId:layerId,dimensions:dimensions}}export function setLayerLoading(layerId,loading){return{type:SET_LAYER_LOADING,layerId:layerId,loading:loading}}export function addMarker(id,point){var label=arguments.length>2&&arguments[2]!==undefined?arguments[2]:"";var crs=arguments.length>3&&arguments[3]!==undefined?arguments[3]:"EPSG:4326";var zIndex=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;var layer={id:"markers",role:LayerRole.MARKER,zIndex:zIndex};var feature={id:id,geometry:{type:"Point",coordinates:point},properties:{label:label},crs:crs,styleName:"marker"};return addLayerFeatures(layer,[feature])}export function removeMarker(id){return removeLayerFeatures("markers",[id])}export function refreshLayer(filter){return{type:REFRESH_LAYER,filter:filter}}export function removeAllLayers(){return{type:REMOVE_ALL_LAYERS}}export function replacePlaceholderLayer(id,layer){return{type:REPLACE_PLACEHOLDER_LAYER,id:id,layer:layer}}export function setSwipe(swipe){return{type:SET_SWIPE,swipe:swipe}}export function setFilter(filter,filterGeom,timeRange){return{type:SET_FILTER,filter:filter,filterGeom:filterGeom,timeRange:timeRange}}export function setThemeLayersVisibilityPreset(preset){return{type:SET_THEME_LAYERS_VISIBILITY_PRESET,preset:preset}};
8
+ export function changeLayerProperty(layerId,property,newvalue){var sublayerpath=arguments.length>3&&arguments[3]!==undefined?arguments[3]:[];var recurseDirection=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;return{type:CHANGE_LAYER_PROPERTY,layerId:layerId,property:property,newvalue:newvalue,sublayerpath:sublayerpath,recurseDirection:recurseDirection}}export function setLayerDimensions(layerId,dimensions){return{type:SET_LAYER_DIMENSIONS,layerId:layerId,dimensions:dimensions}}export function setLayerLoading(layerId,loading){return{type:SET_LAYER_LOADING,layerId:layerId,loading:loading}}export function addMarker(id,point){var label=arguments.length>2&&arguments[2]!==undefined?arguments[2]:"";var crs=arguments.length>3&&arguments[3]!==undefined?arguments[3]:"EPSG:4326";var zIndex=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;var layer={id:"markers",role:LayerRole.MARKER,zIndex:zIndex};var feature={id:id,geometry:{type:"Point",coordinates:point},properties:{label:label},crs:crs,styleName:"marker"};return addLayerFeatures(layer,[feature])}export function removeMarker(id){return removeLayerFeatures("markers",[id])}export function refreshLayer(filter){return{type:REFRESH_LAYER,filter:filter}}export function removeAllLayers(){return{type:REMOVE_ALL_LAYERS}}export function replacePlaceholderLayer(id,layer){return{type:REPLACE_PLACEHOLDER_LAYER,id:id,layer:layer}}export function setSwipe(swipe){return{type:SET_SWIPE,swipe:swipe}}export function setFilter(filter,filterGeom,timeRange){return{type:SET_FILTER,filter:filter,filterGeom:filterGeom,timeRange:timeRange}}export function setThemeLayersVisibilityPreset(preset){return{type:SET_THEME_LAYERS_VISIBILITY_PRESET,preset:preset}}
@@ -4,4 +4,4 @@ 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{v1 as uuidv1}from"uuid";import{processStarted,processFinished}from"../../actions/processNotifications";import ConfigUtils from"../../utils/ConfigUtils";import LocaleUtils from"../../utils/LocaleUtils";import FileSelector from"../widgets/FileSelector";import Spinner from"../widgets/Spinner";import{importGltf}from"./utils/MiscUtils3D";import"./style/ImportObjects3D.css";var ImportObjects3D=/*#__PURE__*/function(_React$Component){function ImportObjects3D(){var _this;_classCallCheck(this,ImportObjects3D);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,ImportObjects3D,[].concat(args));_defineProperty(_this,"state",{importing:false,selectedfile:null});_defineProperty(_this,"importFile",function(){if(!_this.state.selectedfile){return}var file=_this.state.selectedfile;var taskid=uuidv1();_this.setState({importing:true});_this.props.processStarted(taskid,LocaleUtils.tr("import3d.importing",file.name));if(file.name.endsWith(".gltf")){_this.importGltf(file,taskid)}else{_this.importTo3DTiles(file,taskid)}});_defineProperty(_this,"importGltf",function(file,taskid){var reader=new FileReader;reader.onload=function(ev){importGltf(ev.target.result,file.name,_this.props.sceneContext,{drawGroup:true,imported:true});_this.setState({selectedfile:null,importing:false});_this.props.processFinished(taskid,true)};reader.onerror=function(){_this.setState({selectedfile:null,importing:false});_this.props.processFinished(taskid,false)};reader.readAsArrayBuffer(_this.state.selectedfile)});_defineProperty(_this,"importTo3DTiles",function(file,taskid){var target=_this.props.sceneContext.scene.view.controls.target;var formData=new FormData;var jsonBlob=new Blob([JSON.stringify({inputs:[String(target.x),String(target.y),String(target.z),_this.props.sceneContext.mapCrs]})],{type:"application/json"});formData.set("json",jsonBlob);formData.set("file",file);var headers={"Content-Type":"multipart/form-data"};var ogcProcessesUrl=ConfigUtils.getConfigProp("ogcProcessesUrl");if(!ogcProcessesUrl){_this.setState({selectedfile:null,importing:false});_this.props.processFinished(taskid,false,LocaleUtils.tr("import3d.noprocessesserver"));return}axios.post(ogcProcessesUrl.replace(/\/$/,"")+"/modelimport/execution_multipart",formData,{headers:headers}).then(function(response){var tilesetUrl=_this.props.sceneContext.options.importedTilesBaseUrl+response.data.result.value;_this.props.sceneContext.add3dTiles(tilesetUrl,taskid,{title:file.name},true);_this.setState({selectedfile:null,importing:false});_this.props.processFinished(taskid,true)})["catch"](function(err){_this.setState({selectedfile:null,importing:false});_this.props.processFinished(taskid,false)})});return _this}_inherits(ImportObjects3D,_React$Component);return _createClass(ImportObjects3D,[{key:"render",value:function render(){var _this2=this;return/*#__PURE__*/React.createElement("div",{className:"importobjects3d-widget"},/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(FileSelector,{accept:".gltf,.ifc,.gml,.citygml,.cityjson,.3dxf",file:this.state.selectedfile,onFileSelected:function onFileSelected(file){return _this2.setState({selectedfile:file})},title:LocaleUtils.tr("layertree3d.supportedformats")})),/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement("button",{className:"button",disabled:this.state.selectedfile===null||this.state.importing,onClick:this.importFile,type:"button"},this.state.importing?/*#__PURE__*/React.createElement(Spinner,null):null,LocaleUtils.tr("layertree3d.import"))))}}])}(React.Component);_defineProperty(ImportObjects3D,"propTypes",{processFinished:PropTypes.func,processStarted:PropTypes.func,sceneContext:PropTypes.object});export default connect(function(state){return{}},{processFinished:processFinished,processStarted:processStarted})(ImportObjects3D);
7
+ */import React from"react";import{connect}from"react-redux";import axios from"axios";import PropTypes from"prop-types";import{v1 as uuidv1}from"uuid";import{processStarted,processFinished}from"../../actions/processNotifications";import ConfigUtils from"../../utils/ConfigUtils";import LocaleUtils from"../../utils/LocaleUtils";import FileSelector from"../widgets/FileSelector";import Spinner from"../widgets/Spinner";import{importGltf}from"./utils/MiscUtils3D";import"./style/ImportObjects3D.css";var ImportObjects3D=/*#__PURE__*/function(_React$Component){function ImportObjects3D(){var _this;_classCallCheck(this,ImportObjects3D);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,ImportObjects3D,[].concat(args));_defineProperty(_this,"state",{importing:false,selectedfile:null});_defineProperty(_this,"importFile",function(){if(!_this.state.selectedfile){return}var file=_this.state.selectedfile;var taskid=uuidv1();_this.setState({importing:true});_this.props.processStarted(taskid,LocaleUtils.tr("import3d.importing",file.name));if(file.name.endsWith(".gltf")){_this.importGltf(file,taskid)}else{_this.importTo3DTiles(file,taskid)}});_defineProperty(_this,"importGltf",function(file,taskid){var reader=new FileReader;reader.onload=function(ev){importGltf(ev.target.result,file.name,_this.props.sceneContext,{drawGroup:true,imported:true});_this.setState({selectedfile:null,importing:false});_this.props.processFinished(taskid,true)};reader.onerror=function(){_this.setState({selectedfile:null,importing:false});_this.props.processFinished(taskid,false)};reader.readAsArrayBuffer(_this.state.selectedfile)});_defineProperty(_this,"importTo3DTiles",function(file,taskid){var target=_this.props.sceneContext.scene.view.controls.target;var height=_this.props.sceneContext.getTerrainHeightFromMap([target.x,target.y]);var formData=new FormData;var jsonBlob=new Blob([JSON.stringify({inputs:[String(target.x),String(target.y),String(height),_this.props.sceneContext.mapCrs]})],{type:"application/json"});formData.set("json",jsonBlob);formData.set("file",file);var headers={"Content-Type":"multipart/form-data"};var ogcProcessesUrl=ConfigUtils.getConfigProp("ogcProcessesUrl");if(!ogcProcessesUrl){_this.setState({selectedfile:null,importing:false});_this.props.processFinished(taskid,false,LocaleUtils.tr("import3d.noprocessesserver"));return}axios.post(ogcProcessesUrl.replace(/\/$/,"")+"/modelimport/execution_multipart",formData,{headers:headers}).then(function(response){var tilesetUrl=_this.props.sceneContext.options.importedTilesBaseUrl+response.data.result.value;_this.props.sceneContext.add3dTiles(tilesetUrl,taskid,{title:file.name},true);_this.setState({selectedfile:null,importing:false});_this.props.processFinished(taskid,true)})["catch"](function(err){_this.setState({selectedfile:null,importing:false});_this.props.processFinished(taskid,false)})});return _this}_inherits(ImportObjects3D,_React$Component);return _createClass(ImportObjects3D,[{key:"render",value:function render(){var _this2=this;return/*#__PURE__*/React.createElement("div",{className:"importobjects3d-widget"},/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(FileSelector,{accept:".gltf,.ifc,.gml,.citygml,.cityjson,.gpkg",file:this.state.selectedfile,onFileSelected:function onFileSelected(file){return _this2.setState({selectedfile:file})},title:LocaleUtils.tr("layertree3d.supportedformats")})),/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement("button",{className:"button",disabled:this.state.selectedfile===null||this.state.importing,onClick:this.importFile,type:"button"},this.state.importing?/*#__PURE__*/React.createElement(Spinner,null):null,LocaleUtils.tr("layertree3d.import"))))}}])}(React.Component);_defineProperty(ImportObjects3D,"propTypes",{processFinished:PropTypes.func,processStarted:PropTypes.func,sceneContext:PropTypes.object});export default connect(function(state){return{}},{processFinished:processFinished,processStarted:processStarted})(ImportObjects3D);
@@ -4,4 +4,4 @@ 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 classNames from"classnames";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{Box3}from"three";import{setCurrentTask}from"../../actions/task";import LocaleUtils from"../../utils/LocaleUtils";import Icon from"../Icon";import SideBar from"../SideBar";import NumberInput from"../widgets/NumberInput";import ImportObjects3D from"./ImportObjects3D";import"./style/LayerTree3D.css";var LayerTree3D=/*#__PURE__*/function(_React$Component){function LayerTree3D(){var _this;_classCallCheck(this,LayerTree3D);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,LayerTree3D,[].concat(args));_defineProperty(_this,"state",{activestylemenu:null,activemenu:null,importvisible:false});_defineProperty(_this,"renderBody",function(){var sceneContext=_this.props.sceneContext;return/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement("div",{className:"layertree3d-layers"},/*#__PURE__*/React.createElement("div",{className:"layertree3d-section"},LocaleUtils.tr("layertree3d.objects")),Object.entries(sceneContext.sceneObjects).map(function(_ref){var _ref2=_slicedToArray(_ref,2),objectId=_ref2[0],entry=_ref2[1];return _this.renderLayerEntry(objectId,entry,sceneContext.updateSceneObject,true)}),/*#__PURE__*/React.createElement("div",{className:"layertree3d-section"},LocaleUtils.tr("layertree3d.layers")),Object.entries(sceneContext.colorLayers).map(function(_ref3){var _ref4=_slicedToArray(_ref3,2),layerId=_ref4[0],entry=_ref4[1];return _this.renderLayerEntry(layerId,entry,sceneContext.updateColorLayer,false)}),/*#__PURE__*/React.createElement("div",{className:"layertree3d-option",onClick:function onClick(){return _this.setState(function(state){return{importvisible:!state.importvisible}})}},/*#__PURE__*/React.createElement(Icon,{icon:_this.state.importvisible?"collapse":"expand"})," ",LocaleUtils.tr("layertree3d.importobjects"))),_this.state.importvisible?/*#__PURE__*/React.createElement(ImportObjects3D,{sceneContext:_this.props.sceneContext}):null)});_defineProperty(_this,"renderLayerEntry",function(entryId,entry,updateCallback,isObject){var _entry$title,_entry$title2;if(entry.layertree===false){return null}var classes=classNames({"layertree3d-item":true,"layertree3d-item-disabled":!entry.visibility});var styleMenuClasses=classNames({"layertree3d-item-menubutton":true,"layertree3d-item-menubutton-active":_this.state.activestylemenu===entryId});var optMenuClasses=classNames({"layertree3d-item-menubutton":true,"layertree3d-item-menubutton-active":_this.state.activemenu===entryId});return/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-container",key:entryId},/*#__PURE__*/React.createElement("div",{className:classes},/*#__PURE__*/React.createElement(Icon,{className:"layertree3d-item-checkbox",icon:entry.visibility?"checked":"unchecked",onClick:function onClick(){return updateCallback(entryId,{visibility:!entry.visibility})}}),/*#__PURE__*/React.createElement("span",{className:"layertree3d-item-title",title:(_entry$title=entry.title)!==null&&_entry$title!==void 0?_entry$title:entryId},(_entry$title2=entry.title)!==null&&_entry$title2!==void 0?_entry$title2:entryId),!Object.keys(entry.styles||{}).length>1?/*#__PURE__*/React.createElement(Icon,{className:styleMenuClasses,icon:"paint",onClick:function onClick(){return _this.layerStyleMenuToggled(entryId)}}):null,entry.drawGroup||entry.imported?/*#__PURE__*/React.createElement(Icon,{className:"layertree3d-item-remove",icon:"trash",onClick:function onClick(){return _this.props.sceneContext.removeSceneObject(entryId)}}):null,/*#__PURE__*/React.createElement(Icon,{className:optMenuClasses,icon:"cog",onClick:function onClick(){return _this.layerMenuToggled(entryId)}})),_this.state.activemenu===entryId?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-optionsmenu"},/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-optionsmenu-row"},isObject?/*#__PURE__*/React.createElement(Icon,{icon:"zoom",onClick:function onClick(){return _this.props.sceneContext.zoomToObject(entryId)},title:LocaleUtils.tr("layertree3d.zoomtoobject")}):null,entry.imported?/*#__PURE__*/React.createElement(Icon,{icon:"draw",onClick:function onClick(){return _this.editObject(entryId)}}):null,/*#__PURE__*/React.createElement(Icon,{icon:"transparency"}),/*#__PURE__*/React.createElement("input",{className:"layertree3d-item-transparency-slider",max:"255",min:"0",onChange:function onChange(ev){return updateCallback(entryId,{opacity:parseInt(ev.target.value,10)})},step:"1",type:"range",value:entry.opacity})),entry.extrusionHeight!==undefined?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-optionsmenu-row"},/*#__PURE__*/React.createElement("span",null,"Extrude:"),/*#__PURE__*/React.createElement(React.Fragment,null,"\xA0"),/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return updateCallback(entryId,{extrusionHeight:ev.target.value==="__value"?0:ev.target.value})},value:typeof entry.extrusionHeight==="string"?entry.extrusionHeight:"__value"},/*#__PURE__*/React.createElement("option",{value:"__value"},LocaleUtils.tr("layertree3d.customheight")),(entry.fields||[]).map(function(field){return/*#__PURE__*/React.createElement("option",{key:field,value:field},field)})),typeof entry.extrusionHeight!=="string"?/*#__PURE__*/React.createElement(NumberInput,{max:500,min:0,onChange:function onChange(h){return updateCallback(entryId,{extrusionHeight:h})},value:entry.extrusionHeight}):null):null):null,_this.state.activestylemenu===entryId?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-stylemenu"},Object.keys(entry.styles).map(function(name){return/*#__PURE__*/React.createElement("div",{key:name,onClick:function onClick(){return updateCallback(entryId,{style:name})}},/*#__PURE__*/React.createElement(Icon,{icon:entry.style===name?"radio_checked":"radio_unchecked"}),/*#__PURE__*/React.createElement("div",null,name))})):null,!isEmpty(entry.sublayers)?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-sublayers"},entry.sublayers.map(function(sublayer,idx){return _this.renderSublayer(sublayer,entryId,updateCallback,[idx],entry.visibility)})):null)});_defineProperty(_this,"renderSublayer",function(sublayer,entryId,updateCallback,path,parentVisible){var key=entryId+":"+path.join(":");var classes=classNames({"layertree3d-item":true,"layertree3d-item-disabled":!parentVisible||!sublayer.visibility});var optMenuClasses=classNames({"layertree3d-item-menubutton":true,"layertree3d-item-menubutton-active":_this.state.activemenu===key});return/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-container",key:key},/*#__PURE__*/React.createElement("div",{className:classes},/*#__PURE__*/React.createElement(Icon,{className:"layertree3d-item-checkbox",icon:sublayer.visibility?"checked":"unchecked",onClick:function onClick(){return updateCallback(entryId,{visibility:!sublayer.visibility},path)},sublayer:"layertree3d-item-checkbox"}),/*#__PURE__*/React.createElement("span",{className:"layertree3d-item-title",title:sublayer.title},sublayer.title),/*#__PURE__*/React.createElement(Icon,{className:optMenuClasses,icon:"cog",onClick:function onClick(){return _this.layerMenuToggled(key)}})),_this.state.activemenu===key?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-optionsmenu"},/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-optionsmenu-row"},/*#__PURE__*/React.createElement(Icon,{icon:"transparency"}),/*#__PURE__*/React.createElement("input",{className:"layertree3d-item-transparency-slider",max:"255",min:"0",onChange:function onChange(ev){return updateCallback(entryId,{opacity:parseInt(ev.target.value,10)},path)},step:"1",type:"range",value:sublayer.opacity}))):null,!isEmpty(sublayer.sublayers)?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-sublayers"},sublayer.sublayers.map(function(child,idx){return _this.renderSublayer(child,entryId,updateCallback,[].concat(_toConsumableArray(path),[idx]),parentVisible&&sublayer.visibility)})):null)});_defineProperty(_this,"layerStyleMenuToggled",function(entryId){_this.setState(function(state){return{activestylemenu:state.activestylemenu===entryId?null:entryId}})});_defineProperty(_this,"layerMenuToggled",function(entryId){_this.setState(function(state){return{activemenu:state.activemenu===entryId?null:entryId}})});_defineProperty(_this,"editObject",function(objectId){_this.props.setCurrentTask("EditDataset3D",null,null,{objectId:objectId})});return _this}_inherits(LayerTree3D,_React$Component);return _createClass(LayerTree3D,[{key:"render",value:function render(){var _this2=this;return/*#__PURE__*/React.createElement(SideBar,{icon:"layers",id:"LayerTree3D",title:LocaleUtils.tr("appmenu.items.LayerTree3D"),width:"20em"},function(){return{body:_this2.renderBody()}})}}])}(React.Component);_defineProperty(LayerTree3D,"propTypes",{sceneContext:PropTypes.object,setCurrentTask:PropTypes.func});export default connect(function(state){return{}},{setCurrentTask:setCurrentTask})(LayerTree3D);
7
+ */import React from"react";import{connect}from"react-redux";import classNames from"classnames";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{setCurrentTask}from"../../actions/task";import LocaleUtils from"../../utils/LocaleUtils";import Icon from"../Icon";import SideBar from"../SideBar";import NumberInput from"../widgets/NumberInput";import ImportObjects3D from"./ImportObjects3D";import"./style/LayerTree3D.css";var LayerTree3D=/*#__PURE__*/function(_React$Component){function LayerTree3D(){var _this;_classCallCheck(this,LayerTree3D);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,LayerTree3D,[].concat(args));_defineProperty(_this,"state",{activestylemenu:null,activemenu:null,importvisible:false});_defineProperty(_this,"renderBody",function(){var sceneContext=_this.props.sceneContext;return/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement("div",{className:"layertree3d-layers"},/*#__PURE__*/React.createElement("div",{className:"layertree3d-section"},LocaleUtils.tr("layertree3d.objects")),Object.entries(sceneContext.sceneObjects).map(function(_ref){var _ref2=_slicedToArray(_ref,2),objectId=_ref2[0],entry=_ref2[1];return _this.renderLayerEntry(objectId,entry,sceneContext.updateSceneObject,true)}),/*#__PURE__*/React.createElement("div",{className:"layertree3d-section"},LocaleUtils.tr("layertree3d.layers")),Object.entries(sceneContext.colorLayers).map(function(_ref3){var _ref4=_slicedToArray(_ref3,2),layerId=_ref4[0],entry=_ref4[1];return _this.renderLayerEntry(layerId,entry,sceneContext.updateColorLayer,false)}),/*#__PURE__*/React.createElement("div",{className:"layertree3d-option",onClick:function onClick(){return _this.setState(function(state){return{importvisible:!state.importvisible}})}},/*#__PURE__*/React.createElement(Icon,{icon:_this.state.importvisible?"collapse":"expand"})," ",LocaleUtils.tr("layertree3d.importobjects"))),_this.state.importvisible?/*#__PURE__*/React.createElement(ImportObjects3D,{sceneContext:_this.props.sceneContext}):null)});_defineProperty(_this,"renderLayerEntry",function(entryId,entry,updateCallback,isObject){var _entry$title,_entry$title2;if(entry.layertree===false){return null}var classes=classNames({"layertree3d-item":true,"layertree3d-item-disabled":!entry.visibility});var styleMenuClasses=classNames({"layertree3d-item-menubutton":true,"layertree3d-item-menubutton-active":_this.state.activestylemenu===entryId});var optMenuClasses=classNames({"layertree3d-item-menubutton":true,"layertree3d-item-menubutton-active":_this.state.activemenu===entryId});return/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-container",key:entryId},/*#__PURE__*/React.createElement("div",{className:classes},/*#__PURE__*/React.createElement(Icon,{className:"layertree3d-item-checkbox",icon:entry.visibility?"checked":"unchecked",onClick:function onClick(){return updateCallback(entryId,{visibility:!entry.visibility})}}),/*#__PURE__*/React.createElement("span",{className:"layertree3d-item-title",title:(_entry$title=entry.title)!==null&&_entry$title!==void 0?_entry$title:entryId},(_entry$title2=entry.title)!==null&&_entry$title2!==void 0?_entry$title2:entryId),Object.keys(entry.styles||{}).length>1?/*#__PURE__*/React.createElement(Icon,{className:styleMenuClasses,icon:"paint",onClick:function onClick(){return _this.layerStyleMenuToggled(entryId)}}):null,entry.drawGroup||entry.imported?/*#__PURE__*/React.createElement(Icon,{className:"layertree3d-item-remove",icon:"trash",onClick:function onClick(){return _this.props.sceneContext.removeSceneObject(entryId)}}):null,/*#__PURE__*/React.createElement(Icon,{className:optMenuClasses,icon:"cog",onClick:function onClick(){return _this.layerMenuToggled(entryId)}})),_this.state.activemenu===entryId?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-optionsmenu"},/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-optionsmenu-row"},isObject?/*#__PURE__*/React.createElement(Icon,{icon:"zoom",onClick:function onClick(){return _this.props.sceneContext.zoomToObject(entryId)},title:LocaleUtils.tr("layertree3d.zoomtoobject")}):null,entry.imported?/*#__PURE__*/React.createElement(Icon,{icon:"draw",onClick:function onClick(){return _this.editObject(entryId)}}):null,/*#__PURE__*/React.createElement(Icon,{icon:"transparency"}),/*#__PURE__*/React.createElement("input",{className:"layertree3d-item-transparency-slider",max:"255",min:"0",onChange:function onChange(ev){return updateCallback(entryId,{opacity:parseInt(ev.target.value,10)})},step:"1",type:"range",value:entry.opacity})),entry.extrusionHeight!==undefined?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-optionsmenu-row"},/*#__PURE__*/React.createElement("span",null,"Extrude:"),/*#__PURE__*/React.createElement(React.Fragment,null,"\xA0"),/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return updateCallback(entryId,{extrusionHeight:ev.target.value==="__value"?0:ev.target.value})},value:typeof entry.extrusionHeight==="string"?entry.extrusionHeight:"__value"},/*#__PURE__*/React.createElement("option",{value:"__value"},LocaleUtils.tr("layertree3d.customheight")),(entry.fields||[]).map(function(field){return/*#__PURE__*/React.createElement("option",{key:field,value:field},field)})),typeof entry.extrusionHeight!=="string"?/*#__PURE__*/React.createElement(NumberInput,{max:500,min:0,onChange:function onChange(h){return updateCallback(entryId,{extrusionHeight:h})},value:entry.extrusionHeight}):null):null):null,_this.state.activestylemenu===entryId?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-stylemenu"},Object.keys(entry.styles).map(function(name){return/*#__PURE__*/React.createElement("div",{key:name,onClick:function onClick(){return updateCallback(entryId,{style:name})}},/*#__PURE__*/React.createElement(Icon,{icon:entry.style===name?"radio_checked":"radio_unchecked"}),/*#__PURE__*/React.createElement("div",null,name))})):null,!isEmpty(entry.sublayers)?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-sublayers"},entry.sublayers.map(function(sublayer,idx){return _this.renderSublayer(sublayer,entryId,updateCallback,[idx],entry.visibility)})):null)});_defineProperty(_this,"renderSublayer",function(sublayer,entryId,updateCallback,path,parentVisible){var key=entryId+":"+path.join(":");var classes=classNames({"layertree3d-item":true,"layertree3d-item-disabled":!parentVisible||!sublayer.visibility});var optMenuClasses=classNames({"layertree3d-item-menubutton":true,"layertree3d-item-menubutton-active":_this.state.activemenu===key});return/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-container",key:key},/*#__PURE__*/React.createElement("div",{className:classes},/*#__PURE__*/React.createElement(Icon,{className:"layertree3d-item-checkbox",icon:sublayer.visibility?"checked":"unchecked",onClick:function onClick(){return updateCallback(entryId,{visibility:!sublayer.visibility},path)},sublayer:"layertree3d-item-checkbox"}),/*#__PURE__*/React.createElement("span",{className:"layertree3d-item-title",title:sublayer.title},sublayer.title),/*#__PURE__*/React.createElement(Icon,{className:optMenuClasses,icon:"cog",onClick:function onClick(){return _this.layerMenuToggled(key)}})),_this.state.activemenu===key?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-optionsmenu"},/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-optionsmenu-row"},/*#__PURE__*/React.createElement(Icon,{icon:"transparency"}),/*#__PURE__*/React.createElement("input",{className:"layertree3d-item-transparency-slider",max:"255",min:"0",onChange:function onChange(ev){return updateCallback(entryId,{opacity:parseInt(ev.target.value,10)},path)},step:"1",type:"range",value:sublayer.opacity}))):null,!isEmpty(sublayer.sublayers)?/*#__PURE__*/React.createElement("div",{className:"layertree3d-item-sublayers"},sublayer.sublayers.map(function(child,idx){return _this.renderSublayer(child,entryId,updateCallback,[].concat(_toConsumableArray(path),[idx]),parentVisible&&sublayer.visibility)})):null)});_defineProperty(_this,"layerStyleMenuToggled",function(entryId){_this.setState(function(state){return{activestylemenu:state.activestylemenu===entryId?null:entryId}})});_defineProperty(_this,"layerMenuToggled",function(entryId){_this.setState(function(state){return{activemenu:state.activemenu===entryId?null:entryId}})});_defineProperty(_this,"editObject",function(objectId){_this.props.sceneContext.zoomToObject(objectId);_this.props.setCurrentTask("EditDataset3D",null,null,{objectId:objectId})});return _this}_inherits(LayerTree3D,_React$Component);return _createClass(LayerTree3D,[{key:"render",value:function render(){var _this2=this;return/*#__PURE__*/React.createElement(SideBar,{icon:"layers",id:"LayerTree3D",title:LocaleUtils.tr("appmenu.items.LayerTree3D"),width:"20em"},function(){return{body:_this2.renderBody()}})}}])}(React.Component);_defineProperty(LayerTree3D,"propTypes",{sceneContext:PropTypes.object,setCurrentTask:PropTypes.func});export default connect(function(state){return{}},{setCurrentTask:setCurrentTask})(LayerTree3D);
@@ -7,7 +7,7 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
7
7
  */import React from"react";import ReactDOM from"react-dom";import{connect}from"react-redux";import Instance from"@giro3d/giro3d/core/Instance.js";import Coordinates from"@giro3d/giro3d/core/geographic/Coordinates";import Extent from"@giro3d/giro3d/core/geographic/Extent.js";import ElevationLayer from"@giro3d/giro3d/core/layer/ElevationLayer.js";import FeatureCollection from"@giro3d/giro3d/entities/FeatureCollection.js";import Map from"@giro3d/giro3d/entities/Map.js";import Tiles3D from"@giro3d/giro3d/entities/Tiles3D.js";import Inspector from"@giro3d/giro3d/gui/Inspector.js";import GeoTIFFSource from"@giro3d/giro3d/sources/GeoTIFFSource.js";import axios from"axios";import{fromUrl}from"geotiff";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{Vector2,CubeTextureLoader,Group,Raycaster,Mesh,Box3,Vector3,Matrix4}from"three";import{GLTFExporter}from"three/addons/exporters/GLTFExporter.js";import{GLTFLoader}from"three/addons/loaders/GLTFLoader";import{v4 as uuidv4}from"uuid";import{LayerRole}from"../../actions/layers";import{setCurrentTask}from"../../actions/task";import{BackgroundSwitcher}from"../../plugins/BackgroundSwitcher";import ConfigUtils from"../../utils/ConfigUtils";import CoordinatesUtils from"../../utils/CoordinatesUtils";import LayerUtils from"../../utils/LayerUtils";import MiscUtils from"../../utils/MiscUtils";import{registerPermalinkDataStoreHook,unregisterPermalinkDataStoreHook,UrlParams}from"../../utils/PermaLinkUtils";import{MapContainerPortalContext}from"../PluginsContainer";import BottomBar3D from"./BottomBar3D";import Compare3D from"./Compare3D";import Draw3D from"./Draw3D";import EditDataset3D from"./EditDataset3D";import ExportObjects3D from"./ExportObjects3D";import HideObjects3D from"./HideObjects3D";import Identify3D from"./Identify3D";import LayerTree3D from"./LayerTree3D";import Map3DLight from"./Map3DLight";import MapControls3D from"./MapControls3D";import MapExport3D from"./MapExport3D";import Measure3D from"./Measure3D";import OverviewMap3D from"./OverviewMap3D";import TopBar3D from"./TopBar3D";import View3DSwitcher from"./View3DSwitcher";import LayerRegistry from"./layers/index";import{importGltf,updateObjectLabel}from"./utils/MiscUtils3D";import Tiles3DStyle from"./utils/Tiles3DStyle";import"./style/Map3D.css";// Ensures unUnload is called *after* all other children have unmounted
8
8
  var UnloadWrapper=/*#__PURE__*/function(_React$Component){function UnloadWrapper(){var _this;_classCallCheck(this,UnloadWrapper);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,UnloadWrapper,[].concat(args));_defineProperty(_this,"onUnload",function(el){if(!el){_this.props.onUnload(_this.props.sceneId)}});return _this}_inherits(UnloadWrapper,_React$Component);return _createClass(UnloadWrapper,[{key:"render",value:function render(){return/*#__PURE__*/React.createElement("div",null,this.props.children,/*#__PURE__*/React.createElement("span",{ref:this.onUnload}))}}])}(React.Component);_defineProperty(UnloadWrapper,"propTypes",{children:PropTypes.oneOfType([PropTypes.node,PropTypes.func]),onUnload:PropTypes.func,sceneId:PropTypes.string});var Map3D=/*#__PURE__*/function(_React$Component2){function Map3D(props){var _this2;_classCallCheck(this,Map3D);_this2=_callSuper(this,Map3D,[props]);_defineProperty(_this2,"state",{sceneContext:_objectSpread(_objectSpread({},Map3D.defaultSceneState),{},{addLayer:function addLayer(layer){},getLayer:function getLayer(layerId){},removeLayer:function removeLayer(layerId){},updateColorLayer:function updateColorLayer(layerId,options,path){},add3dTiles:function add3dTiles(url,options){},addSceneObject:function addSceneObject(objectId,object){var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{}},getSceneObject:function getSceneObject(objectId){},removeSceneObject:function removeSceneObject(objectId){},updateSceneObject:function updateSceneObject(objectId,options){},zoomToObject:function zoomToObject(objectId){},getMap:function getMap(){},setViewToExtent:function setViewToExtent(bounds,angle){},getTerrainHeightFromDTM:function getTerrainHeightFromDTM(scenePos){},getTerrainHeightFromMap:function getTerrainHeightFromMap(scenePos){},getSceneIntersection:function getSceneIntersection(x,y,objects){}}),sceneId:null});_defineProperty(_this2,"applyBaseLayer",function(){var baseLayer=_this2.state.sceneContext.baseLayers.find(function(e){return e.visibility===true});_this2.removeLayer("__baselayer");if(!baseLayer){return}var layerCreator=LayerRegistry[baseLayer.type];if(layerCreator!==null&&layerCreator!==void 0&&layerCreator.create3d){var layer3d=layerCreator.create3d(baseLayer,_this2.state.sceneContext.mapCrs);_this2.addLayer("__baselayer",layer3d);_this2.map.insertLayerAfter(layer3d,null)}});_defineProperty(_this2,"setBaseLayer",function(layer,visibility){_this2.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{baseLayers:state.sceneContext.baseLayers.map(function(entry){return _objectSpread(_objectSpread({},entry),{},{visibility:entry.name===layer.name?visibility:false})})})}});UrlParams.updateParams({bl3d:visibility?layer.name:""})});_defineProperty(_this2,"collectColorLayers",function(prevColorLayers){return _this2.props.layers.reduce(function(colorLayers,layer){var _prevOptions$visibili,_prevOptions$opacity,_prevOptions$extrusio,_prevOptions$fields;if(layer.role!==LayerRole.THEME&&layer.role!==LayerRole.USERLAYER){return colorLayers}var layerCreator=LayerRegistry[layer.type];if(!layerCreator||!layerCreator.create3d){return colorLayers}var prevOptions=prevColorLayers[layer.id];var _preserveSublayerOptions=function preserveSublayerOptions(entry,prevEntry){var _entry$sublayers,_entry$sublayers$map;return(_entry$sublayers=entry.sublayers)===null||_entry$sublayers===void 0||(_entry$sublayers$map=_entry$sublayers.map)===null||_entry$sublayers$map===void 0?void 0:_entry$sublayers$map.call(_entry$sublayers,function(child){var _prevEntry$sublayers,_prevEntry$sublayers$;var prevChild=prevEntry===null||prevEntry===void 0||(_prevEntry$sublayers=prevEntry.sublayers)===null||_prevEntry$sublayers===void 0||(_prevEntry$sublayers$=_prevEntry$sublayers.find)===null||_prevEntry$sublayers$===void 0?void 0:_prevEntry$sublayers$.call(_prevEntry$sublayers,function(x){return x.name===child.name});if((prevChild===null||prevChild===void 0?void 0:prevChild.name)===child.name){return _objectSpread(_objectSpread({},child),{},{visibility:prevChild.visibility,opacity:prevChild.opacity,sublayers:_preserveSublayerOptions(child,prevChild)})}else{return child}})};colorLayers[layer.id]=_objectSpread(_objectSpread({},layer),{},{visibility:(_prevOptions$visibili=prevOptions===null||prevOptions===void 0?void 0:prevOptions.visibility)!==null&&_prevOptions$visibili!==void 0?_prevOptions$visibili:false,opacity:(_prevOptions$opacity=prevOptions===null||prevOptions===void 0?void 0:prevOptions.opacity)!==null&&_prevOptions$opacity!==void 0?_prevOptions$opacity:255,extrusionHeight:(_prevOptions$extrusio=prevOptions===null||prevOptions===void 0?void 0:prevOptions.extrusionHeight)!==null&&_prevOptions$extrusio!==void 0?_prevOptions$extrusio:["vector","wfs"].includes(layer.type)?0:undefined,fields:(_prevOptions$fields=prevOptions===null||prevOptions===void 0?void 0:prevOptions.fields)!==null&&_prevOptions$fields!==void 0?_prevOptions$fields:undefined,sublayers:_preserveSublayerOptions(layer,prevOptions)});Object.assign(colorLayers[layer.id],LayerUtils.buildWMSLayerParams(colorLayers[layer.id]));if(colorLayers[layer.id].fields===undefined&&layerCreator.getFields){layerCreator.getFields(layer).then(function(fields){_this2.updateColorLayer(layer.id,{fields:fields})})}return colorLayers},{})});_defineProperty(_this2,"applyColorLayerUpdates",function(colorLayers,prevColorLayers){// Add-update new layers
9
9
  var layerBelow=_this2.getLayer("__baselayer");Object.entries(colorLayers).reverse().forEach(function(_ref){var _ref2=_slicedToArray(_ref,2),layerId=_ref2[0],options=_ref2[1];var prevOptions=prevColorLayers[layerId];var layerCreator=LayerRegistry[options.type];var mapLayer=_this2.getLayer(layerId);if(mapLayer){layerCreator.update3d(mapLayer.source,options,prevOptions,_this2.state.sceneContext.mapCrs)}else{mapLayer=layerCreator.create3d(options,_this2.state.sceneContext.mapCrs);_this2.addLayer(layerId,mapLayer)}_this2.map.insertLayerAfter(mapLayer,layerBelow);mapLayer.visible=options.visibility;mapLayer.opacity=options.opacity/255;layerBelow=mapLayer;if(options.extrusionHeight!==0){_this2.createUpdateExtrudedLayer(mapLayer,options,options.features!==(prevOptions===null||prevOptions===void 0?void 0:prevOptions.features))}else if((prevOptions===null||prevOptions===void 0?void 0:prevOptions.extrusionHeight)!==0){_this2.removeExtrudedLayer(options.id)}});// Remove old layers
10
- Object.entries(prevColorLayers).forEach(function(_ref3){var _ref4=_slicedToArray(_ref3,2),layerId=_ref4[0],options=_ref4[1];if(!(layerId in colorLayers)){if(options.extrusionHeight!==0){_this2.removeExtrudedLayer(options.id)}_this2.removeLayer(layerId)}});_this2.instance.notifyChange(_this2.map)});_defineProperty(_this2,"createUpdateExtrudedLayer",function(mapLayer,options){var _options$features,_options$features$red;var forceCreate=arguments.length>2&&arguments[2]!==undefined?arguments[2]:false;var bounds=options.bbox.bounds;var extent=new Extent(options.bbox.crs,bounds[0],bounds[2],bounds[1],bounds[3]);var objId=options.id+":extruded";var makeColor=function makeColor(c){if(Array.isArray(c)){return c[0]<<16|c[1]<<8|c[2]}else if(typeof c==="string"){return parseInt(c.replace("#",""),16)}else{return c}};var obj=_this2.objectMap[objId];if(!obj||forceCreate){var _options$color;if(obj){_this2.instance.remove(obj)}var layercolor=makeColor((_options$color=options.color)!==null&&_options$color!==void 0?_options$color:"#FF0000");obj=new FeatureCollection({source:mapLayer.source.source,extent:extent,minLevel:1,maxLevel:1,ignoreZ:true,elevation:function elevation(feature){var _this2$getTerrainHeig;var coordinates=feature.getGeometry().getCoordinates();while(Array.isArray(coordinates[0])){coordinates=coordinates[0]}return(_this2$getTerrainHeig=_this2.getTerrainHeightFromMap(coordinates))!==null&&_this2$getTerrainHeig!==void 0?_this2$getTerrainHeig:0},extrusionOffset:function extrusionOffset(feature){if(typeof obj.userData.extrusionHeight==="string"){return parseFloat(feature.getProperties()[obj.userData.extrusionHeight])||0}else{return obj.userData.extrusionHeight}},style:function style(feature){var _obj$userData$feature,_obj$userData$feature2;return(_obj$userData$feature=(_obj$userData$feature2=obj.userData.featureStyles)===null||_obj$userData$feature2===void 0?void 0:_obj$userData$feature2[feature.getId()])!==null&&_obj$userData$feature!==void 0?_obj$userData$feature:{fill:{color:layercolor,shading:true}}}});obj.castShadow=true;obj.receiveShadow=true;_this2.instance.add(obj);_this2.objectMap[objId]=obj}obj.userData.extrusionHeight=options.extrusionHeight;obj.userData.featureStyles=(_options$features=options.features)===null||_options$features===void 0||(_options$features$red=_options$features.reduce)===null||_options$features$red===void 0?void 0:_options$features$red.call(_options$features,function(res,feature){return _objectSpread(_objectSpread({},res),{},_defineProperty({},feature.id,{fill:{color:makeColor(feature.styleOptions.fillColor),shading:true}}))},{});obj.opacity=mapLayer.opacity;obj.visible=mapLayer.visible;obj.updateStyles()});_defineProperty(_this2,"removeExtrudedLayer",function(layerId){var objId=layerId+":extruded";if(_this2.objectMap[objId]){_this2.instance.remove(_this2.objectMap[objId]);delete _this2.objectMap[objId]}_this2.instance.notifyChange()});_defineProperty(_this2,"applySceneObjectUpdates",function(sceneObjects,prevSceneObjects){Object.entries(sceneObjects).forEach(function(_ref5){var _ref6=_slicedToArray(_ref5,2),objectId=_ref6[0],options=_ref6[1];var prevOptions=prevSceneObjects===null||prevSceneObjects===void 0?void 0:prevSceneObjects[objectId];var object=_this2.objectMap[objectId];if(options.opacity!==(prevOptions===null||prevOptions===void 0?void 0:prevOptions.opacity)||options.visibility!==(prevOptions===null||prevOptions===void 0?void 0:prevOptions.visibility)){object.visible=options.visibility&&options.opacity>0;if(object.opacity!==undefined){object.opacity=options.opacity/255}else{object.traverse(function(child){if(child instanceof Mesh){child.material.transparent=options.opacity<255;child.material.opacity=options.opacity/255;child.material.needsUpdate=true}})}_this2.instance.notifyChange(object)}if(options.style!==(prevOptions===null||prevOptions===void 0?void 0:prevOptions.style)){_this2.loadTilesetStyle(objectId,options)}if(options.tilesetStyle!==(prevOptions===null||prevOptions===void 0?void 0:prevOptions.tilesetStyle)){object.tiles.group.children.forEach(function(group){Tiles3DStyle.applyTileStyle(group,options)});_this2.instance.notifyChange(object)}})});_defineProperty(_this2,"addLayer",function(layerId,layer){layer.userData.layerId=layerId;_this2.map.addLayer(layer)});_defineProperty(_this2,"getLayer",function(layerId){var _this2$map$getLayers$;return(_this2$map$getLayers$=_this2.map.getLayers(function(l){return l.userData.layerId===layerId})[0])!==null&&_this2$map$getLayers$!==void 0?_this2$map$getLayers$:null});_defineProperty(_this2,"removeLayer",function(layerId){_this2.map.getLayers(function(l){return l.userData.layerId===layerId}).forEach(function(layer){_this2.map.removeLayer(layer,{dispose:true})})});_defineProperty(_this2,"updateColorLayer",function(layerId,options){var path=arguments.length>2&&arguments[2]!==undefined?arguments[2]:[];_this2.setState(function(state){var entry=_objectSpread({},state.sceneContext.colorLayers[layerId]);var subentry=entry;path.forEach(function(idx){subentry.sublayers=_toConsumableArray(subentry.sublayers);subentry.sublayers[idx]=_objectSpread({},subentry.sublayers[idx]);subentry=subentry.sublayers[idx]});Object.assign(subentry,options);Object.assign(entry,LayerUtils.buildWMSLayerParams(entry));return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{colorLayers:_objectSpread(_objectSpread({},state.sceneContext.colorLayers),{},_defineProperty({},layerId,entry))})}})});_defineProperty(_this2,"add3dTiles",function(url,name){var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};var showEditTool=arguments.length>3&&arguments[3]!==undefined?arguments[3]:false;var matrix=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;var label=arguments.length>5&&arguments[5]!==undefined?arguments[5]:null;var tiles=new Tiles3D({url:MiscUtils.resolveAssetsPath(url)});// Recenter tile group
10
+ Object.entries(prevColorLayers).forEach(function(_ref3){var _ref4=_slicedToArray(_ref3,2),layerId=_ref4[0],options=_ref4[1];if(!(layerId in colorLayers)){if(options.extrusionHeight!==0){_this2.removeExtrudedLayer(options.id)}_this2.removeLayer(layerId)}});_this2.instance.notifyChange(_this2.map)});_defineProperty(_this2,"createUpdateExtrudedLayer",function(mapLayer,options){var _options$features,_options$features$red;var forceCreate=arguments.length>2&&arguments[2]!==undefined?arguments[2]:false;var bounds=options.bbox.bounds;var extent=new Extent(options.bbox.crs,bounds[0],bounds[2],bounds[1],bounds[3]);var objId=options.id+":extruded";var makeColor=function makeColor(c){if(Array.isArray(c)){return c[0]<<16|c[1]<<8|c[2]}else if(typeof c==="string"){return parseInt(c.replace("#",""),16)}else{return c}};var obj=_this2.objectMap[objId];if(!obj||forceCreate){var _options$color;if(obj){_this2.instance.remove(obj)}var layercolor=makeColor((_options$color=options.color)!==null&&_options$color!==void 0?_options$color:"#FF0000");obj=new FeatureCollection({source:mapLayer.source.source,extent:extent,minLevel:1,maxLevel:1,ignoreZ:true,elevation:function elevation(feature){var _this2$getTerrainHeig;var coordinates=feature.getGeometry().getCoordinates();while(Array.isArray(coordinates[0])){coordinates=coordinates[0]}return(_this2$getTerrainHeig=_this2.getTerrainHeightFromMap(coordinates))!==null&&_this2$getTerrainHeig!==void 0?_this2$getTerrainHeig:0},extrusionOffset:function extrusionOffset(feature){if(typeof obj.userData.extrusionHeight==="string"){return parseFloat(feature.getProperties()[obj.userData.extrusionHeight])||0}else{return obj.userData.extrusionHeight}},style:function style(feature){var _obj$userData$feature,_obj$userData$feature2;return(_obj$userData$feature=(_obj$userData$feature2=obj.userData.featureStyles)===null||_obj$userData$feature2===void 0?void 0:_obj$userData$feature2[feature.getId()])!==null&&_obj$userData$feature!==void 0?_obj$userData$feature:{fill:{color:layercolor,shading:true}}}});obj.castShadow=true;obj.receiveShadow=true;_this2.instance.add(obj);_this2.objectMap[objId]=obj}obj.userData.extrusionHeight=options.extrusionHeight;obj.userData.featureStyles=(_options$features=options.features)===null||_options$features===void 0||(_options$features$red=_options$features.reduce)===null||_options$features$red===void 0?void 0:_options$features$red.call(_options$features,function(res,feature){return _objectSpread(_objectSpread({},res),{},_defineProperty({},feature.id,{fill:{color:makeColor(feature.styleOptions.fillColor),shading:true}}))},{});obj.opacity=mapLayer.opacity;obj.visible=mapLayer.visible;obj.updateStyles()});_defineProperty(_this2,"removeExtrudedLayer",function(layerId){var objId=layerId+":extruded";if(_this2.objectMap[objId]){_this2.instance.remove(_this2.objectMap[objId]);delete _this2.objectMap[objId]}_this2.instance.notifyChange()});_defineProperty(_this2,"applySceneObjectUpdates",function(sceneObjects,prevSceneObjects){Object.entries(sceneObjects).forEach(function(_ref5){var _ref6=_slicedToArray(_ref5,2),objectId=_ref6[0],options=_ref6[1];var prevOptions=prevSceneObjects===null||prevSceneObjects===void 0?void 0:prevSceneObjects[objectId];var object=_this2.objectMap[objectId];if(options.opacity!==(prevOptions===null||prevOptions===void 0?void 0:prevOptions.opacity)||options.visibility!==(prevOptions===null||prevOptions===void 0?void 0:prevOptions.visibility)){object.visible=options.visibility&&options.opacity>0;if(object.opacity!==undefined){object.opacity=options.opacity/255}else{object.traverse(function(child){if(child instanceof Mesh){child.material.transparent=options.opacity<255;child.material.opacity=options.opacity/255;child.material.needsUpdate=true}})}_this2.instance.notifyChange(object)}if(options.style!==(prevOptions===null||prevOptions===void 0?void 0:prevOptions.style)){_this2.loadTilesetStyle(objectId,options)}if(options.tilesetStyle!==(prevOptions===null||prevOptions===void 0?void 0:prevOptions.tilesetStyle)){object.tiles.group.children.forEach(function(group){Tiles3DStyle.applyTileStyle(group,options,_this2.state.sceneContext)});_this2.instance.notifyChange(object)}})});_defineProperty(_this2,"addLayer",function(layerId,layer){layer.userData.layerId=layerId;_this2.map.addLayer(layer)});_defineProperty(_this2,"getLayer",function(layerId){var _this2$map$getLayers$;return(_this2$map$getLayers$=_this2.map.getLayers(function(l){return l.userData.layerId===layerId})[0])!==null&&_this2$map$getLayers$!==void 0?_this2$map$getLayers$:null});_defineProperty(_this2,"removeLayer",function(layerId){_this2.map.getLayers(function(l){return l.userData.layerId===layerId}).forEach(function(layer){_this2.map.removeLayer(layer,{dispose:true})})});_defineProperty(_this2,"updateColorLayer",function(layerId,options){var path=arguments.length>2&&arguments[2]!==undefined?arguments[2]:[];_this2.setState(function(state){var entry=_objectSpread({},state.sceneContext.colorLayers[layerId]);var subentry=entry;path.forEach(function(idx){subentry.sublayers=_toConsumableArray(subentry.sublayers);subentry.sublayers[idx]=_objectSpread({},subentry.sublayers[idx]);subentry=subentry.sublayers[idx]});Object.assign(subentry,options);Object.assign(entry,LayerUtils.buildWMSLayerParams(entry));return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{colorLayers:_objectSpread(_objectSpread({},state.sceneContext.colorLayers),{},_defineProperty({},layerId,entry))})}})});_defineProperty(_this2,"add3dTiles",function(url,name){var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};var showEditTool=arguments.length>3&&arguments[3]!==undefined?arguments[3]:false;var matrix=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;var label=arguments.length>5&&arguments[5]!==undefined?arguments[5]:null;var tiles=new Tiles3D({url:MiscUtils.resolveAssetsPath(url)});// Recenter tile group
11
11
  tiles.tiles.addEventListener("load-tile-set",function(_ref7){var tileSet=_ref7.tileSet;if(tileSet.root.parent===null){var bbox=new Box3;tiles.tiles.getBoundingBox(bbox);var center=bbox.getCenter(new Vector3);tiles.tiles.group.position.sub(center);if(matrix){tiles.tiles.group.parent.applyMatrix4(matrix)}else{tiles.tiles.group.parent.position.copy(center)}tiles.tiles.group.parent.updateMatrixWorld(true);if(label){tiles.tiles.group.parent.userData.label=label;updateObjectLabel(tiles.tiles.group.parent,_this2.state.sceneContext)}}_this2.instance.notifyChange(tiles);if(showEditTool){_this2.zoomToObject(name);_this2.props.setCurrentTask("EditDataset3D",null,null,{objectId:name})}});tiles.tiles.addEventListener("needs-update",function(){_this2.instance.notifyChange(tiles)});// Apply style when loading tile
12
12
  tiles.tiles.addEventListener("load-model",function(_ref8){var scene=_ref8.scene;scene.userData.tilesetName=name;scene.userData.batchIdAttr="id";Tiles3DStyle.applyTileStyle(scene,_this2.state.sceneContext.sceneObjects[name],_this2.state.sceneContext);_this2.instance.notifyChange(tiles)});// Show/hide labels when tile visibility changes
13
13
  tiles.tiles.addEventListener("tile-visibility-change",function(_ref9){var scene=_ref9.scene,visible=_ref9.visible;Object.values(scene.userData.tileLabels||{}).forEach(function(l){l.labelObject.visible=visible;l.labelObject.element.style.display=visible?"initial":"none"})});tiles.castShadow=true;tiles.receiveShadow=true;tiles.userData.layertree=true;_this2.instance.add(tiles);_this2.objectMap[name]=tiles;_this2.setState(function(state){var objectState=_objectSpread({imported:true,visibility:true,opacity:255,layertree:true,title:name},options);return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{sceneObjects:_objectSpread(_objectSpread({},state.sceneContext.sceneObjects),{},_defineProperty({},name,objectState))})}})});_defineProperty(_this2,"addSceneObject",function(objectId,object){var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};_this2.sceneObjectGroup.add(object);_this2.objectMap[objectId]=object;_this2.instance.notifyChange(object);_this2.setState(function(state){var objectState=_objectSpread({visibility:true,opacity:255,layertree:false},options);return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{sceneObjects:_objectSpread(_objectSpread({},state.sceneContext.sceneObjects),{},_defineProperty({},objectId,objectState))})}})});_defineProperty(_this2,"getSceneObject",function(objectId){return _this2.objectMap[objectId]});_defineProperty(_this2,"removeSceneObject",function(objectId){var callback=arguments.length>1&&arguments[1]!==undefined?arguments[1]:undefined;var object=_this2.objectMap[objectId];if(!object){return}// Ensure labels are removed
@@ -86,6 +86,7 @@
86
86
 
87
87
  #LayerTree3D div.layertree3d-item-stylemenu > div > span.icon {
88
88
  margin-right: 0.25em;
89
+ cursor: pointer;
89
90
  }
90
91
 
91
92
  #LayerTree3D div.layertree3d-item-stylemenu > div > div {
@@ -4,7 +4,7 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
- */import{Box3,BufferGeometry,Group,Mesh,Vector2,Vector3}from"three";import{MeshLine,MeshLineMaterial}from"three.meshline";import{GLTFLoader}from"three/addons/loaders/GLTFLoader";import{CSS2DObject}from"three/addons/renderers/CSS2DRenderer";import{v4 as uuidv4}from"uuid";import ConfigUtils from"../../../utils/ConfigUtils";export function createLabelObject(text,pos,sceneContext,zoffset){var yoffset=arguments.length>4&&arguments[4]!==undefined?arguments[4]:0;var labelEl=document.createElement("span");labelEl.className="map3d-object-label";labelEl.textContent=text;var labelObject=new CSS2DObject(labelEl);labelObject.position.set(pos.x,pos.y+yoffset,pos.z+zoffset);labelObject.updateMatrixWorld();// Leader line
7
+ */import{Box3,BufferGeometry,Mesh,Vector2,Vector3}from"three";import{MeshLine,MeshLineMaterial}from"three.meshline";import{GLTFLoader}from"three/addons/loaders/GLTFLoader";import{CSS2DObject}from"three/addons/renderers/CSS2DRenderer";import{v4 as uuidv4}from"uuid";import ConfigUtils from"../../../utils/ConfigUtils";export function createLabelObject(text,pos,sceneContext,zoffset){var yoffset=arguments.length>4&&arguments[4]!==undefined?arguments[4]:0;var labelEl=document.createElement("span");labelEl.className="map3d-object-label";labelEl.textContent=text;var labelObject=new CSS2DObject(labelEl);labelObject.position.set(pos.x,pos.y+yoffset,pos.z+zoffset);labelObject.updateMatrixWorld();// Leader line
8
8
  var linegeom=new MeshLine;linegeom.setGeometry(new BufferGeometry().setFromPoints([new Vector3(0,-yoffset,-zoffset),new Vector3(0,0,0)]));var resolution=new Vector2(sceneContext.scene.view.width,sceneContext.scene.view.height);var linemat=new MeshLineMaterial({color:3770564,resolution:resolution,lineWidth:2,sizeAttenuation:0});var linemesh=new Mesh(linegeom,linemat);labelObject.add(linemesh);linemesh.updateMatrixWorld();labelObject.userData.sceneResizeCallback=function(_ref){var width=_ref.width,height=_ref.height;linemat.resolution.set(width,height)};sceneContext.scene.view.addEventListener("view-resized",labelObject.userData.sceneResizeCallback);return labelObject}export function updateObjectLabel(sceneObject,sceneContext){var labelObject=sceneObject.children.find(function(child){return child.isCSS2DObject});if(sceneObject.userData.label){if(!labelObject){var _sceneObject$userData;labelObject=createLabelObject(sceneObject.userData.label,new Vector3(0,0,0),sceneContext,(_sceneObject$userData=sceneObject.userData.labelOffset)!==null&&_sceneObject$userData!==void 0?_sceneObject$userData:50);sceneObject.add(labelObject);sceneObject.updateMatrixWorld();labelObject.userData.removeCallback=function(){var _labelObject$element$,_labelObject$element$2;// Explicitly remove label DOM element
9
9
  (_labelObject$element$=labelObject.element.parentNode)===null||_labelObject$element$===void 0||(_labelObject$element$2=_labelObject$element$.removeChild)===null||_labelObject$element$2===void 0||_labelObject$element$2.call(_labelObject$element$,labelObject.element)};sceneObject.addEventListener("removed",labelObject.userData.removeCallback)}else{labelObject.element.textContent=sceneObject.userData.label}}else if(labelObject){sceneObject.removeEventListener("removed",labelObject.userData.removeCallback);sceneContext.scene.view.removeEventListener("view-resized",labelObject.userData.sceneResizeCallback);// Remove leaderline first, as the remove trigger of the CSS2DObject assumes children are CSS2DObjects as well
10
10
  labelObject.children[0].removeFromParent();labelObject.removeFromParent()}}export function importGltf(dataOrUrl,name,sceneContext){var options=arguments.length>3&&arguments[3]!==undefined?arguments[3]:{};var loader=new GLTFLoader;var processor=function processor(gltf){// GLTF is Y-UP, we need Z-UP
@@ -4,9 +4,9 @@ function _slicedToArray(r,e){return _arrayWithHoles(r)||_iterableToArrayLimit(r,
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 isEmpty from"lodash.isempty";import parseCssColor from"parse-css-color";import{Float32BufferAttribute,Group,Vector3}from"three";import{createLabelObject}from"./MiscUtils3D";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){var _config$tilesetStyle$3;return{text:config.tilesetStyle[batchId].label,offset:(_config$tilesetStyle$3=config.tilesetStyle[batchId].labelOffset)!==null&&_config$tilesetStyle$3!==void 0?_config$tilesetStyle$3:80}}else if(config.labelAttr){return batchAttr[config.labelAttr]}else{return null}}var Tiles3DStyle={applyTileStyle:function applyTileStyle(group,config,sceneContext){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");if(!batchidxAttr){return}var batchPosAttr=c.geometry.getAttribute("position");var rgbaColors=[];var rgbColors=[];var haveColor=false;var haveAlpha=false;var baseColor=[1,1,1,1];if(config.baseColor){var _config$baseColor;var color=parseCssColor((_config$baseColor=config.baseColor)!==null&&_config$baseColor!==void 0?_config$baseColor:"white");baseColor=[].concat(_toConsumableArray(color.values.map(function(x){return x/255})),[color.alpha]);haveAlpha|=color[3]<1;haveColor=true}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,_toConsumableArray(baseColor));rgbColors.push.apply(rgbColors,_toConsumableArray(baseColor.slice(0,3)))}// 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.text,labelOffset:label.offset,pos:pos,ymax:pos[1],count:1,matrix:c.matrixWorld}}else{entry.pos[0]+=pos[0];entry.pos[1]+=pos[1];entry.pos[2]+=pos[2];entry.ymax=Math.max(entry.ymax,pos[1]);++entry.count}}});// NOTE: Also update color buffers if they were previously colored
7
+ */import{Parser as ExprParser}from"expr-eval";import isEmpty from"lodash.isempty";import parseCssColor from"parse-css-color";import{Float32BufferAttribute,Group,Vector3}from"three";import MiscUtils from"../../../utils/MiscUtils";import{createLabelObject}from"./MiscUtils3D";var styleExpressionParser=new ExprParser;styleExpressionParser.functions.color=function(name){var alpha=arguments.length>1&&arguments[1]!==undefined?arguments[1]:1;var color=parseCssColor(name);return[].concat(_toConsumableArray(color.values.map(function(c){return c/255})),[alpha])};styleExpressionParser.functions.rgb=function(r,g,b){return[r/255,g/255,g/255,1]};styleExpressionParser.functions.rgba=function(r,g,b,a){return[r/255,g/255,g/255,a]};styleExpressionParser.functions.hsl=function(h,s,l){return[].concat(_toConsumableArray(MiscUtils.hslToRgb(h,s,l)),[1])};styleExpressionParser.functions.hsla=function(h,s,l,a){return[].concat(_toConsumableArray(MiscUtils.hslToRgb(h,s,l)),[a])};function batchColor(batchId,batchAttr,context){var _context$batchStyles$,_context$batchStyles;if(((_context$batchStyles$=(_context$batchStyles=context.batchStyles)===null||_context$batchStyles===void 0||(_context$batchStyles=_context$batchStyles[batchId])===null||_context$batchStyles===void 0?void 0:_context$batchStyles.color)!==null&&_context$batchStyles$!==void 0?_context$batchStyles$:null)!==null){var color=parseCssColor(context.batchStyles[batchId].color);return[].concat(_toConsumableArray(color.values.map(function(c){return c/255})),[color.alpha])}else if(context.colorExpressions.length){try{for(var i=0;i<context.colorExpressions.length;++i){var condition=context.colorExpressions[i][0].evaluate(batchAttr);if(condition){return context.colorExpressions[i][1].evaluate(batchAttr)}}}catch(e){/* eslint-disable-next-line */console.warn("Failed to parse color expression: "+String(e))}return null}else if(batchAttr[context.colorAttr]){var _batchAttr$context$al;var _color=batchAttr[context.colorAttr];var alpha=context.alphaAttr?(_batchAttr$context$al=batchAttr[context.alphaAttr])!==null&&_batchAttr$context$al!==void 0?_batchAttr$context$al: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,context){var _context$batchStyles$2,_context$batchStyles2;if(((_context$batchStyles$2=(_context$batchStyles2=context.batchStyles)===null||_context$batchStyles2===void 0||(_context$batchStyles2=_context$batchStyles2[batchId])===null||_context$batchStyles2===void 0?void 0:_context$batchStyles2.label)!==null&&_context$batchStyles$2!==void 0?_context$batchStyles$2:null)!==null){var _context$batchStyles$3;return{text:context.batchStyles[batchId].label,offset:(_context$batchStyles$3=context.batchStyles[batchId].labelOffset)!==null&&_context$batchStyles$3!==void 0?_context$batchStyles$3:80}}else if(context.labelAttr){return batchAttr[context.labelAttr]}else{return null}}var Tiles3DStyle={applyTileStyle:function applyTileStyle(group,config,sceneContext){var _config$idAttr,_config$tilesetStyle,_config$tilesetStyle2;var batchColorCache={};var batchLabelCache={};var labels={};var idAttr=(_config$idAttr=config.idAttr)!==null&&_config$idAttr!==void 0?_config$idAttr:"id";var context={colorExpressions:[],batchStyles:(_config$tilesetStyle=config.tilesetStyle)===null||_config$tilesetStyle===void 0?void 0:_config$tilesetStyle.batchstyles,colorAttr:config.colorAttr,alphaAttr:config.alphaAttr,labelAttr:config.labelAttr};var baseColor=[1,1,1,1];var customBaseColor=false;if(config.baseColor){var color=parseCssColor(config.baseColor);baseColor=[].concat(_toConsumableArray(color.values.map(function(x){return x/255})),[color.alpha]);customBaseColor=true}var colorRules=(_config$tilesetStyle2=config.tilesetStyle)===null||_config$tilesetStyle2===void 0?void 0:_config$tilesetStyle2.color;var parseExpr=function parseExpr(expr){var cleanExpr=expr.replace(/\$\{(\w+)\}/g,"$1").replaceAll("===","==").replaceAll("!==","==");return styleExpressionParser.parse(cleanExpr)};if(colorRules!==null&&colorRules!==void 0&&colorRules.conditions){colorRules===null||colorRules===void 0||colorRules.conditions.map(function(cond){context.colorExpressions.push([parseExpr(cond[0]),parseExpr(cond[1])])})}else if(typeof colorRules==="string"){context.colorExpressions.push([parseExpr("true"),parseExpr(colorRules)])}group.traverse(function(c){if(c.geometry){var batchidxAttr=c.geometry.getAttribute("_batchid");if(!batchidxAttr){return}var batchPosAttr=c.geometry.getAttribute("position");var rgbaColors=[];var rgbColors=[];var haveColor=customBaseColor;var haveAlpha=baseColor[3]<1;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,context)}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,_toConsumableArray(baseColor));rgbColors.push.apply(rgbColors,_toConsumableArray(baseColor.slice(0,3)))}// Handle label
9
+ var label=batchLabelCache[batchIdx];if(label===undefined){label=batchLabelCache[batchIdx]=batchLabel(batchId,batchAttr,context)}if(label){var pos=batchPosAttr.array.slice(3*idx,3*idx+3);var entry=labels[batchIdx];if(!entry){entry=labels[batchIdx]={label:label.text,labelOffset:label.offset,pos:pos,ymax:pos[1],count:1,matrix:c.matrixWorld}}else{entry.pos[0]+=pos[0];entry.pos[1]+=pos[1];entry.pos[2]+=pos[2];entry.ymax=Math.max(entry.ymax,pos[1]);++entry.count}}});// NOTE: Also update color buffers if they were previously colored
10
10
  if(haveColor||group.userData.haveColor){if(haveAlpha){c.geometry.setAttribute("color",new Float32BufferAttribute(rgbaColors,4))}else{// Discard alpha
11
11
  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;group.userData.haveColor=haveColor}}});// Clear previous labels
12
12
  if(group.userData.labelGroup){group.remove(group.children.find(function(child){return child.uuid===group.userData.labelGroup}));// Explicitly remove label DOM elements
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2025.07.06",
3
+ "version": "2025.07.10",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
@@ -35,6 +35,7 @@
35
35
  "deepmerge": "^4.3.1",
36
36
  "diacritics": "^1.3.0",
37
37
  "driver.js": "^1.3.6",
38
+ "expr-eval": "^2.0.2",
38
39
  "fast-xml-parser": "^4.5.0",
39
40
  "file-saver": "^2.0.5",
40
41
  "flat": "^6.0.1",
package/plugins/API.js CHANGED
@@ -44,13 +44,13 @@ function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var
44
44
  *
45
45
  * - Include the custom plugin code in `index.html`, i.e.
46
46
  *
47
- * <script type="text/javascript" src="assets/js/currenttheme.js" ></script>
47
+ * <script type="text/javascript" src="assets/js/currenttheme.js" ></script>
48
48
  *
49
49
  * - Enable the plugin in the plugins block of `config.json`
50
50
  *
51
- * {
52
- * "name": "CurrentTheme"
53
- * }
51
+ * {
52
+ * "name": "CurrentTheme"
53
+ * }
54
54
  *
55
55
  * The following action functions are exposed in the API:
56
56
  *
package/plugins/Map.js CHANGED
@@ -11,7 +11,7 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
11
11
  this.props.layers.slice(0).reverse().forEach(function(layer){if(layer.type==="wms"&&layer.role===LayerRole.THEME){var sublayers=layer.params.LAYERS.split(",");var opacities=layer.params.OPACITIES.split(",");var styles=(layer.params.STYLES||"").split(",");for(var i=0;i<sublayers.length;++i){if(layer.externalLayerMap&&layer.externalLayerMap[sublayers[i]]){// Sublayer is mapped to an external layer
12
12
  var sublayer=LayerUtils.searchSubLayer(layer,"name",sublayers[i]);if(sublayer.visibility){var extlayer=_objectSpread(_objectSpread({},layer.externalLayerMap[sublayers[i]]),{},{rev:layer.rev,opacity:parseInt(opacities[i],10),visibility:true,role:LayerRole.THEME,minScale:sublayer.minScale,maxScale:sublayer.maxScale});if(extlayer.type==="wms"){extlayer.params=_objectSpread(_objectSpread(_objectSpread({},layer.params),layer.externalLayerMap[sublayers[i]].params),{},{OPACITIES:opacities[i],STYLES:""})}renderLayers.push(extlayer)}}else if(renderLayers.length>0&&renderLayers[renderLayers.length-1].id===layer.id){// Compress with previous renderlayer
13
13
  renderLayers[renderLayers.length-1].params.LAYERS+=","+sublayers[i];renderLayers[renderLayers.length-1].params.OPACITIES+=","+opacities[i];renderLayers[renderLayers.length-1].params.STYLES+=","+(styles[i]||"")}else{// Add new renderlayer
14
- renderLayers.push(_objectSpread(_objectSpread({},layer),{},{uuid:layer.id+"-"+i,params:_objectSpread(_objectSpread({},layer.params),{},{LAYERS:sublayers[i],OPACITIES:opacities[i],STYLES:styles[i]||""})}))}}}else{renderLayers.push(layer)}});// Break out swipe layer if necessary
14
+ renderLayers.push(_objectSpread(_objectSpread({},layer),{},{params:_objectSpread(_objectSpread({},layer.params),{},{LAYERS:sublayers[i],OPACITIES:opacities[i],STYLES:styles[i]||""})}))}}}else{renderLayers.push(layer)}});// Break out swipe layer if necessary
15
15
  var swipeLayer=null;var swipeLayerNameBlacklist=this.props.swipeLayerNameBlacklist.map(function(entry){return new RegExp("^"+entry.split(/\*+/).map(function(s){return s.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&")}).join(".*")+"$")});if(renderLayers.length>0&&this.props.swipe!==null&&renderLayers[renderLayers.length-1].role>LayerRole.BACKGROUND){var _loop=function _loop(){var layer=renderLayers[i];if(layer.role>LayerRole.USERLAYER){return 0;// continue
16
16
  }else if(layer.type==="wms"&&layer.params.LAYERS.split(",").length>=1){var paramLayers=layer.params.LAYERS.split(",");var paramOpacities=layer.params.OPACITIES.split(",");var paramStyles=(layer.params.STYLES||"").split(",");var _loop2=function _loop2(){var layerName=paramLayers[j];if(swipeLayerNameBlacklist.find(function(entry){return layerName.match(entry)})){return 0;// continue
17
17
  }var sublayer=LayerUtils.searchSubLayer(layer,"name",layerName);if(sublayer&&_this2.props.swipeGeometryTypeBlacklist.includes((sublayer.geometryType||"").replace(/[ZM]+$/,""))){return 0;// continue
package/plugins/View3D.js CHANGED
@@ -7,6 +7,8 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
7
7
  */import React from"react";import{connect,Provider}from"react-redux";import PropTypes from"prop-types";import{createSelector}from"reselect";import*as displayExports from"../actions/display";import{setView3dMode,View3DMode}from"../actions/display";import*as layersExports from"../actions/layers";import{LayerRole,addLayerFeatures,removeLayer}from"../actions/layers";import{panTo,zoomToPoint}from"../actions/map";import*as mapExports from"../actions/map";import*as themeExports from"../actions/theme";import PluginsContainer from"../components/PluginsContainer";import ResizeableWindow from"../components/ResizeableWindow";import StandardApp from"../components/StandardApp";import View3DSwitcher from"../components/map3d/View3DSwitcher";import Spinner from"../components/widgets/Spinner";import ReducerIndex from"../reducers/index";import searchProvidersSelector from"../selectors/searchproviders";import{createStore}from"../stores/StandardStore";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import{UrlParams}from"../utils/PermaLinkUtils";import personIcon from"../utils/img/person.png";import"./style/View3D.css";/**
8
8
  * Displays a 3D map view.
9
9
  *
10
+ * ## Configuration
11
+ *
10
12
  * To add a 3D View to a theme, add the following configuration block to a theme item in `themesConfig.json`:
11
13
  * ```
12
14
  * "map3d": {
@@ -46,23 +48,32 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
46
48
  * - `visibility` controls the initially visibile background layer
47
49
  * - `overview: true` controls the name of background layer to display in the overview map. If no background layer is marked with `overview: true`, the currently visibile background layer id dipslayed in the overview map.
48
50
  * - The `tiles3d` entry contains an optional list of 3d tiles to add to the scene, with:
49
- * - `baseColor`: the base color for the tile objects, defaults to white.
50
51
  * - `idAttr`: batch table attribute which stores the batch object id, used for styling and passed to `tileInfoServiceUrl`. Default: `id`.
51
52
  * - `styles`: optional, available tileset styles. Takes precedente over `colorAttr`, `alphaAttr`, `labelAttr`.
52
53
  * - `style`: optional, tileset style enabled by default.
54
+ * - `baseColor`: the fallback color for the tile objects, defaults to white.
53
55
  * - `colorAttr`: optional, batch table attribute which stores the batch color, as a 0xRRGGBB integer.
54
56
  * - `alphaAttr`: optional, batch table attribute which stores the batch alpha (transparency), as a [0, 255] integer.
55
57
  * - `labelAttr`: optional, batch table attribute which stores the batch label, displayed above the geometry.
56
58
  * - The `objects3d` entry contains an optional list of GLTF objects to add to the scene.
57
59
  *
58
- * The tileset style JSON is shaped as follows:
60
+ *
61
+ * ## Styling
62
+ *
63
+ * The tileset style JSON is a [3D Tiles stylesheet](https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling),
64
+ * of which currently the `color` section is supported, and which may in addition also contain a `batchstyles` section as follows:
59
65
  * ```
60
66
  * {
61
- * "<object_id>": {
62
- * "label": "<label>",
63
- * "labelOffset": <offset>,
64
- * "color": "<css RGB(A) color string>"
65
- * }
67
+ * "color": {
68
+ * ...
69
+ * },
70
+ * "batchstyles": {
71
+ * "<object_id>": {
72
+ * "label": "<label>",
73
+ * "labelOffset": <offset>,
74
+ * "color": "<css RGB(A) color string>"
75
+ * }
76
+ * }
66
77
  * }
67
78
  * ```
68
79
  * Where:
@@ -71,6 +82,13 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
71
82
  * - `labelOffset` is an optional number which represents the vertical offset between the object top and the label. Defaults to 80.
72
83
  * - `color` is an optional CSS color string which defines the object color.
73
84
  *
85
+ * *Note*:
86
+ *
87
+ * - The color declarations in the `batchstyles` section override any color resulting from a color expression in the `color` section.
88
+ * - You must ensure that your 3D tiles batch table contains all batch attributes which are referenced as variables in a color expression!
89
+ *
90
+ * ## Import
91
+ *
74
92
  * To import scene objects in formats other than GLTF, a `ogcProcessesUrl` in `config.json` needs to point to a BBOX OGC processes server.
75
93
  */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,viewsLocked:false,storedState:null});_defineProperty(_this,"render3DWindow",function(){if(_this.props.view3dMode>View3DMode.DISABLED){var extraControls=[{icon:"sync",callback:_this.sync2DExtent,title:LocaleUtils.tr("map3d.syncview")},{icon:"lock",callback:_this.setLockViews,title:LocaleUtils.tr("map3d.lockview"),active:_this.state.viewsLocked}];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={defaultDay:_this.props.defaultDay,defaultTime:_this.props.defaultTime,searchMinScaleDenom:_this.props.searchMinScaleDenom,tileInfoServiceUrl:_this.props.tileInfoServiceUrl,importedTilesBaseUrl:_this.props.importedTilesBaseUrl};return/*#__PURE__*/React.createElement(ResizeableWindow,{extraControls:extraControls,fullscreen:_this.props.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,onFocusChanged:_this.windowFocusChanged,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(PluginsContainer,{className:"plugins-container-3d",plugins:_this.props.plugins,pluginsAppConfig:{},pluginsConfig:_this.props.pluginsConfig},/*#__PURE__*/React.createElement(Map3D,{innerRef:_this.setRef,onCameraChanged:_this.onCameraChanged,onMapInitialized:_this.setupMap,options:options,searchProviders:_this.props.searchProviders,theme:_this.props.theme}),_this.props.view3dMode===View3DMode.DISABLING?/*#__PURE__*/React.createElement("div",{className:"view3d-busy-overlay"},/*#__PURE__*/React.createElement(Spinner,null),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("view3d.storingstate"))):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.view3dMode!==View3DMode.FULLSCREEN){_this.props.setView3dMode(View3DMode.FULLSCREEN)}_this.setState({windowDetached:geometry.detached})});_defineProperty(_this,"onCameraChanged",function(center,camera,fov){// Note: If camera pos is NULL, we are in first-person-view
76
94
  if(_this.state.viewsLocked&&_this.focusedMap==="map3d"){var rotation=undefined;if(camera){rotation=Math.atan2(center[1]-camera[1],center[0]-camera[0])-0.5*Math.PI;var distance=Math.sqrt((camera[0]-center[0])*(camera[0]-center[0])+(camera[1]-center[1])*(camera[1]-center[1])+(camera[2]-center[2])*(camera[2]-center[2]));var fovrad=fov/180*Math.PI;var bboxWidth=distance*(2*Math.tan(fovrad/2));var bbox=[-0.5*bboxWidth,0,0.5*bboxWidth,0];var zoom=MapUtils.getZoomForExtent(bbox,_this.props.map.resolutions,_this.props.map.size,0,_this.props.map.scales.length-1);_this.props.zoomToPoint(center.slice(0,2),zoom,_this.props.theme.mapCrs,rotation);if(_this.firstPersonMarker){_this.props.removeLayer("view3d-firstperson-cone");_this.firstPersonMarker=false}}else{_this.props.panTo(center.slice(0,2),_this.props.theme.mapCrs,rotation);var feature={geometry:{type:"Point",coordinates:center.slice(0,2)},crs:_this.props.theme.mapCrs,styleName:"marker",styleOptions:{iconSrc:personIcon}};var layer={id:"view3d-firstperson-marker",role:LayerRole.MARKER};_this.props.addLayerFeatures(layer,[feature],true);_this.firstPersonMarker=true}}else if(_this.firstPersonMarker){_this.props.removeLayer("view3d-firstperson-marker");_this.firstPersonMarker=false}});_defineProperty(_this,"setRef",function(ref){_this.map3dComponentRef=ref});_defineProperty(_this,"sync2DExtent",function(){if(_this.map3dComponentRef){_this.map3dComponentRef.setViewToExtent(_this.props.map.bbox.bounds,_this.props.map.bbox.rotation)}});_defineProperty(_this,"setLockViews",function(){_this.setState(function(state){return{viewsLocked:!state.viewsLocked}});if(_this.firstPersonMarker){_this.props.removeLayer("view3d-firstperson-marker");_this.firstPersonMarker=false}});_defineProperty(_this,"setupMap",function(){if(_this.map3dComponentRef){if(_this.state.storedState){_this.map3dComponentRef.restore3dState(_this.state.storedState)}else{_this.sync2DExtent()}}});_defineProperty(_this,"redrawScene",function(ev){if(_this.map3dComponentRef){_this.map3dComponentRef.redrawScene(ev)}});_defineProperty(_this,"trackFocus",function(ev){var _mapEl$contains,_map3dEl$contains;var mapEl=document.getElementById("map");var map3dEl=document.getElementById("map3d");if(mapEl!==null&&mapEl!==void 0&&(_mapEl$contains=mapEl.contains)!==null&&_mapEl$contains!==void 0&&_mapEl$contains.call(mapEl,document.activeElement)){_this.focusedMap="map"}else if(map3dEl!==null&&map3dEl!==void 0&&(_map3dEl$contains=map3dEl.contains)!==null&&_map3dEl$contains!==void 0&&_map3dEl$contains.call(map3dEl,document.activeElement)){_this.focusedMap="map3d"}else{_this.focusedMap=null}});_this.map3dComponent=null;_this.map3dComponentRef=null;_this.focusedMap=null;_this.firstPersonMarker=true;// Subset of 2d reducers
@@ -310,6 +310,7 @@ img.layertree-item-legend-tooltip {
310
310
 
311
311
  #LayerTree div.layertree-item-stylemenu > div > span.icon {
312
312
  margin-right: 0.25em;
313
+ cursor: pointer;
313
314
  }
314
315
 
315
316
  #LayerTree div.layertree-item-stylemenu > div > div {
@@ -41,7 +41,7 @@ var redLayer=_objectSpread({},layer);var group=redLayer;var _iterator10=_createF
41
41
  var _iterator11=_createForOfIteratorHelper(exploded),_step11;try{for(_iterator11.s();!(_step11=_iterator11.n()).done;){var entry=_step11.value;var _layer2=entry.layer;// Attempt to merge with previous if possible
42
42
  var target=newlayers.length>0?newlayers[newlayers.length-1]:null;var source=_layer2;if(target&&target.sublayers&&target.url===_layer2.url){var innertarget=target.sublayers[target.sublayers.length-1];var innersource=source.sublayers[0];// Exploded entries have only one entry per sublayer level
43
43
  while(innertarget&&innertarget.sublayers&&innertarget.name===innersource.name){target=innertarget;source=innersource;innertarget=target.sublayers[target.sublayers.length-1];innersource=source.sublayers[0];// Exploded entries have only one entry per sublayer level
44
- }target.sublayers.push(source.sublayers[0])}else{if(usedIds.has(_layer2.id)){newlayers.push(_objectSpread(_objectSpread({},_layer2),{},{id:uuidv4()}))}else{newlayers.push(_layer2)}}}// Ensure mutually exclusive groups have exactly one visible layer
44
+ }target.sublayers.push(source.sublayers[0])}else{if(usedIds.has(_layer2.id)){newlayers.push(_objectSpread(_objectSpread({},_layer2),{},{id:uuidv4()}))}else{newlayers.push(_layer2)}usedIds.add(_layer2.id)}}// Ensure mutually exclusive groups have exactly one visible layer
45
45
  }catch(err){_iterator11.e(err)}finally{_iterator11.f()}for(var _i=0,_newlayers=newlayers;_i<_newlayers.length;_i++){var layer=_newlayers[_i];LayerUtils.ensureMutuallyExclusive(layer)}for(var _i2=0,_newlayers2=newlayers;_i2<_newlayers2.length;_i2++){var _layer=_newlayers2[_i2];if(_layer.type==="wms"){Object.assign(_layer,LayerUtils.recomputeLayerBBox(_layer))}}return newlayers},insertLayer:function insertLayer(layers,newlayer,attr,val){var after=arguments.length>4&&arguments[4]!==undefined?arguments[4]:false;var exploded=LayerUtils.explodeLayers(layers);var explodedAdd=LayerUtils.explodeLayers([newlayer]);var index=exploded.findIndex(function(entry){return entry.sublayer[attr]===val});if(index!==-1){if(after){index+=1}exploded.splice.apply(exploded,[index,0].concat(_toConsumableArray(explodedAdd)))}else{exploded.unshift.apply(exploded,_toConsumableArray(explodedAdd))}return LayerUtils.implodeLayers(exploded)},ensureMutuallyExclusive:function ensureMutuallyExclusive(group){if(!isEmpty(group.sublayers)){if(group.mutuallyExclusive){var tristateSublayer=group.sublayers.find(function(sublayer){return sublayer.tristate===true});var visibleSublayer=tristateSublayer||group.sublayers.find(function(sublayer){return sublayer.visibility===true})||group.sublayers[0];var _iterator12=_createForOfIteratorHelper(group.sublayers),_step12;try{for(_iterator12.s();!(_step12=_iterator12.n()).done;){var sublayer=_step12.value;sublayer.visibility=sublayer===visibleSublayer}}catch(err){_iterator12.e(err)}finally{_iterator12.f()}}var _iterator13=_createForOfIteratorHelper(group.sublayers),_step13;try{for(_iterator13.s();!(_step13=_iterator13.n()).done;){var _sublayer=_step13.value;LayerUtils.ensureMutuallyExclusive(_sublayer)}}catch(err){_iterator13.e(err)}finally{_iterator13.f()}}},getSublayerNames:function getSublayerNames(layer){var _this2=this;var toplevel=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;var filter=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;return[toplevel&&layer.sublayers||filter&&!filter(layer)?null:layer.name].concat((layer.sublayers||[]).reduce(function(list,sublayer){return list.concat(_toConsumableArray(_this2.getSublayerNames(sublayer,false,filter)))},[])).filter(function(x){return x})},mergeSubLayers:function mergeSubLayers(baselayer,addlayer){addlayer=_objectSpread(_objectSpread({},baselayer),{},{sublayers:addlayer.sublayers});addlayer.externalLayerMap=_objectSpread({},addlayer.externalLayerMap);LayerUtils.extractExternalLayersFromSublayers(addlayer,addlayer);if(isEmpty(addlayer.sublayers)){return _objectSpread({},baselayer)}if(isEmpty(baselayer.sublayers)){return addlayer}var explodedBase=LayerUtils.explodeLayers([baselayer]);var existing=explodedBase.map(function(entry){return entry.sublayer.name});var explodedAdd=LayerUtils.explodeLayers([addlayer]);explodedAdd=explodedAdd.filter(function(entry){return!existing.includes(entry.sublayer.name)});return LayerUtils.implodeLayers(explodedAdd.concat(explodedBase))[0]},searchSubLayer:function searchSubLayer(layer,attr,value){var path=arguments.length>3&&arguments[3]!==undefined?arguments[3]:[];if(layer.sublayers){var idx=0;var _iterator14=_createForOfIteratorHelper(layer.sublayers),_step14;try{for(_iterator14.s();!(_step14=_iterator14.n()).done;){var sublayer=_step14.value;var match=sublayer[attr]===value?sublayer:LayerUtils.searchSubLayer(sublayer,attr,value,path);if(match){path.unshift(idx);return match}idx+=1}}catch(err){_iterator14.e(err)}finally{_iterator14.f()}}else{if(layer[attr]===value){return layer}}return null},matchSubLayer:function matchSubLayer(layer,func){var path=arguments.length>2&&arguments[2]!==undefined?arguments[2]:[];if(layer.sublayers){var idx=0;var _iterator15=_createForOfIteratorHelper(layer.sublayers),_step15;try{for(_iterator15.s();!(_step15=_iterator15.n()).done;){var sublayer=_step15.value;var match=func(sublayer)?sublayer:LayerUtils.matchSubLayer(sublayer,func,path);if(match){path.unshift(idx);return match}idx+=1}}catch(err){_iterator15.e(err)}finally{_iterator15.f()}}else{if(func(layer)){return layer}}return null},searchLayer:function searchLayer(layers,layerUrl,layerName){var match=null;layers.find(function(layer){var sublayer=null;if(layer.url===layerUrl&&(sublayer=LayerUtils.searchSubLayer(layer,"name",layerName))){match={layer:layer,sublayer:sublayer};return true}return false});return match},sublayerVisible:function sublayerVisible(layer,sublayerpath){var visible=layer.visibility!==false;var sublayer=layer;var _iterator16=_createForOfIteratorHelper(sublayerpath),_step16;try{for(_iterator16.s();!(_step16=_iterator16.n()).done;){var index=_step16.value;sublayer=sublayer.sublayers[index];visible&=sublayer.visibility!==false;if(!visible){return false}}}catch(err){_iterator16.e(err)}finally{_iterator16.f()}return true},computeLayerVisibility:function computeLayerVisibility(layer){if(isEmpty(layer.sublayers)||layer.visibility===false){return layer.visibility?1:0}var visible=0;layer.sublayers.map(function(sublayer){var _sublayer$visibility;var sublayervisibility=(_sublayer$visibility=sublayer.visibility)!==null&&_sublayer$visibility!==void 0?_sublayer$visibility:true;if(sublayer.sublayers&&sublayervisibility){visible+=LayerUtils.computeLayerVisibility(sublayer)}else{visible+=sublayervisibility?1:0}});return visible/layer.sublayers.length},computeLayerOpacity:function computeLayerOpacity(layer){if(isEmpty(layer.sublayers)){var _layer$opacity2;return(_layer$opacity2=layer.opacity)!==null&&_layer$opacity2!==void 0?_layer$opacity2:255}var opacity=0;layer.sublayers.map(function(sublayer){opacity+=LayerUtils.computeLayerOpacity(sublayer)});return opacity/layer.sublayers.length},computeLayerQueryable:function computeLayerQueryable(layer){var queryable=0;layer.sublayers.map(function(sublayer){var _sublayer$omitFromQue;var sublayerqueryable=(_sublayer$omitFromQue=!sublayer.omitFromQueryLayers)!==null&&_sublayer$omitFromQue!==void 0?_sublayer$omitFromQue:true;if(sublayer.sublayers&&sublayerqueryable){queryable+=LayerUtils.computeLayerQueryable(sublayer)}else{queryable+=sublayerqueryable?1:0}});return queryable/layer.sublayers.length},hasQueryableSublayers:function hasQueryableSublayers(layer){return layer.sublayers.find(function(sublayer){return sublayer.sulayers?LayerUtils.hasQueryableSublayers(sublayer):sublayer.queryable})},cloneLayer:function cloneLayer(layer,sublayerpath){var newlayer=_objectSpread({},layer);var cur=newlayer;for(var i=0;i<sublayerpath.length;++i){var idx=sublayerpath[i];cur.sublayers=[].concat(_toConsumableArray(cur.sublayers.slice(0,idx)),[_objectSpread({},cur.sublayers[idx])],_toConsumableArray(cur.sublayers.slice(idx+1)));cur=cur.sublayers[idx]}return{newlayer:newlayer,newsublayer:cur}},collectGroupLayers:function collectGroupLayers(layer,parentGroups,groupLayers){if(!isEmpty(layer.sublayers)){var _iterator17=_createForOfIteratorHelper(layer.sublayers),_step17;try{for(_iterator17.s();!(_step17=_iterator17.n()).done;){var sublayer=_step17.value;LayerUtils.collectGroupLayers(sublayer,parentGroups.concat(layer.name),groupLayers)}}catch(err){_iterator17.e(err)}finally{_iterator17.f()}}else{var _iterator18=_createForOfIteratorHelper(parentGroups),_step18;try{for(_iterator18.s();!(_step18=_iterator18.n()).done;){var group=_step18.value;groupLayers[group]=(groupLayers[group]||[]).concat(layer.name)}}catch(err){_iterator18.e(err)}finally{_iterator18.f()}}},replaceLayerGroups:function replaceLayerGroups(layerConfigs,layer){var groupLayers={};LayerUtils.collectGroupLayers(layer,[],groupLayers);var newLayerConfigs=[];var _iterator19=_createForOfIteratorHelper(layerConfigs),_step19;try{var _loop4=function _loop4(){var layerConfig=_step19.value;if(layerConfig.name in groupLayers){newLayerConfigs.push.apply(newLayerConfigs,_toConsumableArray(groupLayers[layerConfig.name].map(function(name){return _objectSpread(_objectSpread({},layerConfig),{},{name:name})})))}else{newLayerConfigs.push(layerConfig)}};for(_iterator19.s();!(_step19=_iterator19.n()).done;){_loop4()}}catch(err){_iterator19.e(err)}finally{_iterator19.f()}return newLayerConfigs},extractExternalLayersFromSublayers:function extractExternalLayersFromSublayers(toplayer,layer){if(layer.sublayers){layer.sublayers=layer.sublayers.map(function(sublayer){if(sublayer.externalLayer){var externalLayer=_objectSpread({},sublayer.externalLayer);LayerUtils.completeExternalLayer(externalLayer,sublayer,toplayer.mapCrs);toplayer.externalLayerMap[sublayer.name]=externalLayer;sublayer=_objectSpread({},sublayer);delete sublayer.externalLayer}if(sublayer.sublayers){LayerUtils.extractExternalLayersFromSublayers(toplayer,sublayer)}return sublayer})}},completeExternalLayer:function completeExternalLayer(externalLayer,sublayer,mapCrs){externalLayer.title=externalLayer.title||(sublayer||{}).title||externalLayer.name;externalLayer.id=uuidv4();if(externalLayer.type==="wms"||externalLayer.params){externalLayer.version=externalLayer.version||"1.3.0";externalLayer.featureInfoUrl=externalLayer.featureInfoUrl||externalLayer.url;externalLayer.legendUrl=externalLayer.legendUrl||externalLayer.url;externalLayer.queryLayers=externalLayer.queryLayers||externalLayer.params.LAYERS.split(",");var externalLayerFeatureInfoFormats=ConfigUtils.getConfigProp("externalLayerFeatureInfoFormats")||{};for(var _i3=0,_Object$keys=Object.keys(externalLayerFeatureInfoFormats);_i3<_Object$keys.length;_i3++){var entry=_Object$keys[_i3];if(externalLayer.featureInfoUrl.toLowerCase().includes(entry.toLowerCase())){externalLayer.infoFormats=[externalLayerFeatureInfoFormats[entry]];break}}}else if(externalLayer.type==="mvt"){externalLayer.projection=mapCrs;if(externalLayer.tileGridName){externalLayer.tileGridConfig=(ConfigUtils.getConfigProp("mvtTileGrids")||{})[externalLayer.tileGridName];if(!externalLayer.tileGridConfig){/* eslint-disable-next-line */console.warn("Tile grid config not found: "+externalLayer.tileGridName)}}}},getLegendUrl:function getLegendUrl(layer,sublayer,scale,map,bboxDependentLegend,scaleDependentLegend,extraLegendParameters){if(layer.type!=="wms"){return layer.legendUrl||""}var requestParams={SERVICE:"WMS",REQUEST:"GetLegendGraphic",FORMAT:"image/png",CRS:map.projection,SRS:map.projection,SLD_VERSION:"1.1.0",WIDTH:200,HEIGHT:200};if(extraLegendParameters){Object.assign(requestParams,Object.fromEntries(extraLegendParameters.split("&").map(function(entry){return entry.split("=")})))}if(scaleDependentLegend===true||scaleDependentLegend==="theme"&&layer.role===LayerRole.THEME){requestParams.SCALE=Math.round(scale)}if(bboxDependentLegend===true||bboxDependentLegend==="theme"&&layer.role===LayerRole.THEME){var bounds=map.bbox.bounds;if(CoordinatesUtils.getAxisOrder(map.projection).substr(0,2)==="ne"&&layer.version==="1.3.0"){requestParams.BBOX=[bounds[1],bounds[0],bounds[3],bounds[2]].join(",")}else{requestParams.BBOX=bounds.join(",")}}if(layer.externalLayerMap&&layer.externalLayerMap[sublayer.name]){var externalLayer=layer.externalLayerMap[sublayer.name];if(externalLayer.type!=="wms"){return externalLayer.legendUrl||""}var urlParts=url.parse(externalLayer.legendUrl,true);urlParts.query=Object.keys(urlParts.query).filter(function(key){// Filter service, request, version
46
46
  return!["service","request","version"].includes(key.toLowerCase())}).reduce(function(res,key){return _objectSpread(_objectSpread({},res),{},_defineProperty({},key,urlParts.query[key]))},{});urlParts.query=_objectSpread(_objectSpread(_objectSpread({VERSION:layer.version},urlParts.query),requestParams),{},{LAYER:externalLayer.params.LAYERS});delete urlParts.search;return url.format(urlParts)}else{var _layer$params$FILTER;var layername=layer===sublayer?layer.params.LAYERS.split(",").reverse().join(","):sublayer.name;var style=layer===sublayer?layer.params.STYLES.split(",").reverse().join(","):sublayer.style;var _urlParts=url.parse(layer.legendUrl,true);_urlParts.query=Object.keys(_urlParts.query).filter(function(key){// Filter service, request, version
47
47
  return!["service","request","version"].includes(key.toLowerCase())}).reduce(function(res,key){return _objectSpread(_objectSpread({},res),{},_defineProperty({},key,_urlParts.query[key]))},{});_urlParts.query=_objectSpread(_objectSpread(_objectSpread({VERSION:layer.version},_urlParts.query),requestParams),{},{LAYER:layername,STYLES:style,FILTER:(_layer$params$FILTER=layer.params.FILTER)!==null&&_layer$params$FILTER!==void 0?_layer$params$FILTER:""});delete _urlParts.search;return url.format(_urlParts)}},layerScaleInRange:function layerScaleInRange(layer,mapScale){return(layer.minScale===undefined||mapScale>=layer.minScale)&&(layer.maxScale===undefined||mapScale<layer.maxScale)},addExternalLayerPrintParams:function addExternalLayerPrintParams(layer,params,printCrs,counterRef){var qgisServerVersion=ConfigUtils.getConfigProp("qgisServerVersion",null,3);if(qgisServerVersion>=3){if(layer.type==="wms"){var layerUrl=layer.url;var urlParts=url.parse(layerUrl,true);// Resolve relative urls
@@ -11,5 +11,6 @@ var tagRegEx=/(<.[^(><.)]+>)/;if(tagRegEx.exec(text)){return text}var urlRegEx=n
11
11
  "(\\s|^)((http(s)?|(s)?ftp):\\/\\/.)?(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_+.~#?&//=\\u00C0-\\u00FF\\u0370-\\u03FF]*)"),"g");var value=text;var match=null;while(match=urlRegEx.exec(value)){// If URL is part of a HTML attribute, don't add anchor
12
12
  if(value.substring(match.index-2,match.index).match(/^=['"]$/)===null){var url=match[0].substr(match[1].length);var protoUrl=url;if(match[2]===undefined){if(match[0].indexOf("@")!==-1){protoUrl="mailto:"+url}else{protoUrl="http://"+url}}var pos=match.index+match[1].length;var anchor="<a href=\""+MiscUtils.htmlEncode(protoUrl)+"\" target=\"_blank\">"+MiscUtils.htmlEncode(url)+"</a>";value=value.substring(0,pos)+anchor+value.substring(pos+url.length);urlRegEx.lastIndex=pos+anchor.length}}// Reset
13
13
  urlRegEx.lastIndex=0;return value},htmlEncode:function htmlEncode(text){return text.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")},getCsrfToken:function getCsrfToken(){var csrfTag=Array.from(document.getElementsByTagName("meta")).find(function(tag){return tag.getAttribute("name")==="csrf-token"});return csrfTag?csrfTag.getAttribute("content"):""},setupKillTouchEvents:function setupKillTouchEvents(el){if(el){// To stop touchmove propagating to parent which can trigger a swipe
14
- el.addEventListener("touchmove",function(ev){ev.stopPropagation()},{passive:false})}},killEvent:function killEvent(ev){if(ev.cancelable){ev.stopPropagation();ev.preventDefault()}},blendColors:function blendColors(color1,color2,ratio){color1=[parseInt(color1[1]+color1[2],16),parseInt(color1[3]+color1[4],16),parseInt(color1[5]+color1[6],16)];color2=[parseInt(color2[1]+color2[2],16),parseInt(color2[3]+color2[4],16),parseInt(color2[5]+color2[6],16)];var color3=[(1-ratio)*color1[0]+ratio*color2[0],(1-ratio)*color1[1]+ratio*color2[1],(1-ratio)*color1[2]+ratio*color2[2]];var toHex=function toHex(num){return("0"+Math.round(num).toString(16)).slice(-2)};return"#"+toHex(color3[0])+toHex(color3[1])+toHex(color3[2])},ensureArray:function ensureArray(el){if(el===undefined){return[]}else if(Array.isArray(el)){return el}return[el]},capitalizeFirst:function capitalizeFirst(text){return text.slice(0,1).toUpperCase()+text.slice(1)},isBrightColor:function isBrightColor(hex){var color=+("0x"+hex.slice(1).replace(hex.length<5&&/./g,"$&$&"));var r=color>>16;var g=color>>8&255;var b=color&255;var hsp=Math.sqrt(0.299*(r*r)+0.587*(g*g)+0.114*(b*b));return hsp>127.5},adjustProtocol:function adjustProtocol(url){if(location.protocol==="https:"&&url.startsWith("http:")){return"https:"+url.substr(5)}return url},convertEmToPx:function convertEmToPx(emsize){var defaultfontsize=getComputedStyle(document.documentElement).fontSize;return emsize*parseFloat(defaultfontsize)},getFaviconFromIcon:function getFaviconFromIcon(icon,size){var glyph=null;var _iterator=_createForOfIteratorHelper(document.styleSheets),_step;try{for(_iterator.s();!(_step=_iterator.n()).done;){var sheet=_step.value;var _iterator2=_createForOfIteratorHelper(sheet.cssRules),_step2;try{for(_iterator2.s();!(_step2=_iterator2.n()).done;){var rule=_step2.value;if(rule.selectorText===".icon-".concat(icon,"::before")){glyph=rule.style.content.replace(/["']/g,"");break}}}catch(err){_iterator2.e(err)}finally{_iterator2.f()}}}catch(err){_iterator.e(err)}finally{_iterator.f()}if(glyph===null){return null}var canvas=document.createElement("canvas");canvas.width=size;canvas.height=size;var ctx=canvas.getContext("2d");ctx.font="".concat(size-5,"px qwc2-icons");ctx.textAlign="center";ctx.textBaseline="middle";ctx.fillStyle="#FFF";// You can change this color if needed
14
+ el.addEventListener("touchmove",function(ev){ev.stopPropagation()},{passive:false})}},killEvent:function killEvent(ev){if(ev.cancelable){ev.stopPropagation();ev.preventDefault()}},blendColors:function blendColors(color1,color2,ratio){color1=[parseInt(color1[1]+color1[2],16),parseInt(color1[3]+color1[4],16),parseInt(color1[5]+color1[6],16)];color2=[parseInt(color2[1]+color2[2],16),parseInt(color2[3]+color2[4],16),parseInt(color2[5]+color2[6],16)];var color3=[(1-ratio)*color1[0]+ratio*color2[0],(1-ratio)*color1[1]+ratio*color2[1],(1-ratio)*color1[2]+ratio*color2[2]];var toHex=function toHex(num){return("0"+Math.round(num).toString(16)).slice(-2)};return"#"+toHex(color3[0])+toHex(color3[1])+toHex(color3[2])},hslToRgb:function hslToRgb(h,s,l){// Takes h, s, l in [0, 1] range and returns [r, g, b] in [0, 1] range
15
+ var c=(1-Math.abs(2*l-1))*s;var x=c*(1-Math.abs(h/60%2-1));var m=l-c/2;h*=360;var r=0;var g=0;var b=0;if(h>=0&&h<60){r=c;g=x;b=0}else if(h>=60&&h<120){r=x;g=c;b=0}else if(h>=120&&h<180){r=0;g=c;b=x}else if(h>=180&&h<240){r=0;g=x;b=c}else if(h>=240&&h<300){r=x;g=0;b=c}else if(h>=300&&h<360){r=c;g=0;b=x}return[r+m,g+m,b+m]},ensureArray:function ensureArray(el){if(el===undefined){return[]}else if(Array.isArray(el)){return el}return[el]},capitalizeFirst:function capitalizeFirst(text){return text.slice(0,1).toUpperCase()+text.slice(1)},isBrightColor:function isBrightColor(hex){var color=+("0x"+hex.slice(1).replace(hex.length<5&&/./g,"$&$&"));var r=color>>16;var g=color>>8&255;var b=color&255;var hsp=Math.sqrt(0.299*(r*r)+0.587*(g*g)+0.114*(b*b));return hsp>127.5},adjustProtocol:function adjustProtocol(url){if(location.protocol==="https:"&&url.startsWith("http:")){return"https:"+url.substr(5)}return url},convertEmToPx:function convertEmToPx(emsize){var defaultfontsize=getComputedStyle(document.documentElement).fontSize;return emsize*parseFloat(defaultfontsize)},getFaviconFromIcon:function getFaviconFromIcon(icon,size){var glyph=null;var _iterator=_createForOfIteratorHelper(document.styleSheets),_step;try{for(_iterator.s();!(_step=_iterator.n()).done;){var sheet=_step.value;var _iterator2=_createForOfIteratorHelper(sheet.cssRules),_step2;try{for(_iterator2.s();!(_step2=_iterator2.n()).done;){var rule=_step2.value;if(rule.selectorText===".icon-".concat(icon,"::before")){glyph=rule.style.content.replace(/["']/g,"");break}}}catch(err){_iterator2.e(err)}finally{_iterator2.f()}}}catch(err){_iterator.e(err)}finally{_iterator.f()}if(glyph===null){return null}var canvas=document.createElement("canvas");canvas.width=size;canvas.height=size;var ctx=canvas.getContext("2d");ctx.font="".concat(size-5,"px qwc2-icons");ctx.textAlign="center";ctx.textBaseline="middle";ctx.fillStyle="#FFF";// You can change this color if needed
15
16
  ctx.fillText(glyph,size/2,size/2);return canvas.toDataURL("image/png")},resolveAssetsPath:function resolveAssetsPath(path){return path&&path.startsWith(":/")?ConfigUtils.getAssetsPath()+path.substr(1):path}};export default MiscUtils;