qwc2 2025.9.15 → 2025.9.23

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.
@@ -5,10 +5,10 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
5
5
  *
6
6
  * This source code is licensed under the BSD-style license found in the
7
7
  * LICENSE file in the root directory of this source tree.
8
- */import React from"react";import{connect}from"react-redux";import PropTypes from"prop-types";import ConfigUtils from"../utils/ConfigUtils";import PluginStore from"../utils/PluginStore";import ProcessNotifications from"./ProcessNotifications";import WindowManager from"./WindowManager";import"./style/PluginsContainer.css";export var MapButtonPortalContext=/*#__PURE__*/React.createContext(null);export var MapContainerPortalContext=/*#__PURE__*/React.createContext(null);var PluginsContainer=/*#__PURE__*/function(_React$Component){function PluginsContainer(){var _this;_classCallCheck(this,PluginsContainer);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,PluginsContainer,[].concat(args));_defineProperty(_this,"state",{mapButtonsContainerRef:null,mapContainerRef:null});_defineProperty(_this,"renderPlugins",function(){var device=ConfigUtils.isMobile()?"mobile":"desktop";var plugins=PluginStore.getPlugins();return _this.props.pluginsConfig.map(function(pluginConf){var _this$props$theme,_this$props$theme2,_pluginConf$key;var Plugin=plugins[pluginConf.name+"Plugin"];if(!Plugin){return null}var themeDevicePluginConfig=((_this$props$theme=_this.props.theme)===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme.config)===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme[device])===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme.plugins)===null||_this$props$theme===void 0?void 0:_this$props$theme[pluginConf.name])||{};var themePluginConfig=((_this$props$theme2=_this.props.theme)===null||_this$props$theme2===void 0||(_this$props$theme2=_this$props$theme2.config)===null||_this$props$theme2===void 0||(_this$props$theme2=_this$props$theme2.plugins)===null||_this$props$theme2===void 0?void 0:_this$props$theme2[pluginConf.name])||{};var cfg=_objectSpread(_objectSpread(_objectSpread({},pluginConf.cfg||{}),themePluginConfig),themeDevicePluginConfig);return/*#__PURE__*/React.createElement(Plugin,_extends({key:(_pluginConf$key=pluginConf.key)!==null&&_pluginConf$key!==void 0?_pluginConf$key:pluginConf.name},cfg))})});_defineProperty(_this,"setupTouchEvents",function(el){if(el){el.addEventListener("touchstart",function(ev){_this.touchY=ev.targetTouches[0].clientY},{passive:false});el.addEventListener("touchmove",_this.preventOverscroll,{passive:false});var resizeObserver=new ResizeObserver(function(entries){var contentRectEntry=entries.find(function(entry){return entry.contentRect});if(contentRectEntry){var height=contentRectEntry.contentRect.height;el.style.setProperty("--plugins-container-height","".concat(height,"px"))}});resizeObserver.observe(el)}});_defineProperty(_this,"preventOverscroll",function(ev){if(ev.touches[0].touchType!=="direct"){// Don't do anything for stylus inputs
8
+ */import React from"react";import{connect}from"react-redux";import PropTypes from"prop-types";import ConfigUtils from"../utils/ConfigUtils";import PluginStore from"../utils/PluginStore";import ProcessNotifications from"./ProcessNotifications";import WindowManager from"./WindowManager";import"./style/PluginsContainer.css";export var MapButtonPortalContext=/*#__PURE__*/React.createContext(null);export var MapContainerPortalContext=/*#__PURE__*/React.createContext(null);export var AppInfosPortalContext=/*#__PURE__*/React.createContext(null);var PluginsContainer=/*#__PURE__*/function(_React$Component){function PluginsContainer(){var _this;_classCallCheck(this,PluginsContainer);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,PluginsContainer,[].concat(args));_defineProperty(_this,"state",{mapButtonsContainerRef:null,mapContainerRef:null,appInfosContainerRef:null});_defineProperty(_this,"renderPlugins",function(){var device=ConfigUtils.isMobile()?"mobile":"desktop";var plugins=PluginStore.getPlugins();return _this.props.pluginsConfig.map(function(pluginConf){var _this$props$theme,_this$props$theme2,_pluginConf$key;var Plugin=plugins[pluginConf.name+"Plugin"];if(!Plugin){return null}var themeDevicePluginConfig=((_this$props$theme=_this.props.theme)===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme.config)===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme[device])===null||_this$props$theme===void 0||(_this$props$theme=_this$props$theme.plugins)===null||_this$props$theme===void 0?void 0:_this$props$theme[pluginConf.name])||{};var themePluginConfig=((_this$props$theme2=_this.props.theme)===null||_this$props$theme2===void 0||(_this$props$theme2=_this$props$theme2.config)===null||_this$props$theme2===void 0||(_this$props$theme2=_this$props$theme2.plugins)===null||_this$props$theme2===void 0?void 0:_this$props$theme2[pluginConf.name])||{};var cfg=_objectSpread(_objectSpread(_objectSpread({},pluginConf.cfg||{}),themePluginConfig),themeDevicePluginConfig);return/*#__PURE__*/React.createElement(Plugin,_extends({key:(_pluginConf$key=pluginConf.key)!==null&&_pluginConf$key!==void 0?_pluginConf$key:pluginConf.name},cfg))})});_defineProperty(_this,"setupTouchEvents",function(el){if(el){el.addEventListener("touchstart",function(ev){_this.touchY=ev.targetTouches[0].clientY},{passive:false});el.addEventListener("touchmove",_this.preventOverscroll,{passive:false});var resizeObserver=new ResizeObserver(function(entries){var contentRectEntry=entries.find(function(entry){return entry.contentRect});if(contentRectEntry){var height=contentRectEntry.contentRect.height;el.style.setProperty("--plugins-container-height","".concat(height,"px"))}});resizeObserver.observe(el)}});_defineProperty(_this,"preventOverscroll",function(ev){if(ev.touches[0].touchType!=="direct"){// Don't do anything for stylus inputs
9
9
  return}var scrollEvent=false;var element=ev.target;var direction=ev.targetTouches[0].clientY-_this.touchY;_this.touchY=ev.targetTouches[0].clientY;while(!scrollEvent&&element){var scrollable=element.scrollHeight>element.clientHeight;// Workaround for resizeable-window having scrollHeight > clientHeight even though it has no scrollbar
10
10
  if(element.classList.contains("resizeable-window")){scrollable=false}if(element.type==="range"){// If it is a range element, treat it as a scroll event
11
11
  scrollEvent=true}else if(scrollable&&element.scrollTop+element.clientHeight<element.scrollHeight&&direction<0){// User scrolls down and element is not at end of scroll
12
12
  scrollEvent=true}else if(scrollable&&element.scrollTop>0&&direction>0){// User scrolls up and element is not at start of scroll
13
- scrollEvent=true}else{element=element.parentElement}}if(!scrollEvent){ev.preventDefault()}});_defineProperty(_this,"setMapContainerRef",function(el){_this.setState({mapContainerRef:el})});_defineProperty(_this,"setButtonContainerRef",function(el){_this.setState({mapButtonsContainerRef:el});if(el){var resizeObserver=new ResizeObserver(function(entries){var contentRectEntry=entries.find(function(entry){return entry.contentRect});if(contentRectEntry){var width=contentRectEntry.contentRect.width;var height=contentRectEntry.contentRect.height;el.style.setProperty("--buttons-container-width","".concat(width,"px"));el.style.setProperty("--buttons-container-height","".concat(height,"px"))}});resizeObserver.observe(el);el.recomputeSpacers=function(){var slots=new Set;Array.from(el.childNodes).forEach(function(child){if(child.dataset.spacer){el.removeChild(child)}else{slots.add(child.dataset.slot)}});var maxSlot=Math.max.apply(Math,_toConsumableArray(slots));for(var i=0;i<maxSlot;++i){if(!slots.has(String(i))){var child=document.createElement("div");child.className="map-buttons-spacer";child.dataset.spacer=1;child.style.order=i;el.appendChild(child)}}}}});return _this}_inherits(PluginsContainer,_React$Component);return _createClass(PluginsContainer,[{key:"render",value:function render(){var _this$props$className;var left=this.props.mapMargins.left+this.props.mapMargins.outerLeft;var top=this.props.mapMargins.top;var right=this.props.mapMargins.right+this.props.mapMargins.outerRight;var bottom=this.props.mapMargins.bottom;var mapContainerStyle={left:"calc("+left+"px)",top:"calc(var(--topbar-height) + "+top+"px)",right:"calc("+right+"px)",bottom:"calc(var(--bottombar-height) + "+bottom+"px)"};var haveRefs=this.state.mapButtonsContainerRef&&this.state.mapContainerRef;return/*#__PURE__*/React.createElement("div",{className:"plugins-container "+((_this$props$className=this.props.className)!==null&&_this$props$className!==void 0?_this$props$className:""),ref:this.setupTouchEvents},/*#__PURE__*/React.createElement(MapButtonPortalContext.Provider,{value:this.state.mapButtonsContainerRef},/*#__PURE__*/React.createElement(MapContainerPortalContext.Provider,{value:this.state.mapContainerRef},haveRefs?this.renderPlugins():null,haveRefs?this.props.children:null)),/*#__PURE__*/React.createElement(WindowManager,null),/*#__PURE__*/React.createElement("div",{className:"map-container",ref:this.setMapContainerRef,style:mapContainerStyle},/*#__PURE__*/React.createElement(ProcessNotifications,null)),/*#__PURE__*/React.createElement("div",{className:"map-buttons-container",ref:this.setButtonContainerRef,style:mapContainerStyle}))}}])}(React.Component);_defineProperty(PluginsContainer,"propTypes",{children:PropTypes.oneOfType([PropTypes.node,PropTypes.func]),className:PropTypes.string,mapMargins:PropTypes.object,pluginsConfig:PropTypes.array,theme:PropTypes.object});export default connect(function(state){return{// Just to trigger re-render when custom plugins change
13
+ scrollEvent=true}else{element=element.parentElement}}if(!scrollEvent){ev.preventDefault()}});_defineProperty(_this,"setMapContainerRef",function(el){_this.setState({mapContainerRef:el})});_defineProperty(_this,"setAppInfosContainerRef",function(el){_this.setState({appInfosContainerRef:el})});_defineProperty(_this,"setButtonContainerRef",function(el){_this.setState({mapButtonsContainerRef:el});if(el){var resizeObserver=new ResizeObserver(function(entries){var contentRectEntry=entries.find(function(entry){return entry.contentRect});if(contentRectEntry){var width=contentRectEntry.contentRect.width;var height=contentRectEntry.contentRect.height;el.style.setProperty("--buttons-container-width","".concat(width,"px"));el.style.setProperty("--buttons-container-height","".concat(height,"px"))}});resizeObserver.observe(el);el.recomputeSpacers=function(){var slots=new Set;Array.from(el.childNodes).forEach(function(child){if(child.dataset.spacer){el.removeChild(child)}else{slots.add(child.dataset.slot)}});var maxSlot=Math.max.apply(Math,_toConsumableArray(slots));for(var i=0;i<maxSlot;++i){if(!slots.has(String(i))){var child=document.createElement("div");child.className="map-buttons-spacer";child.dataset.spacer=1;child.style.order=i;el.appendChild(child)}}}}});return _this}_inherits(PluginsContainer,_React$Component);return _createClass(PluginsContainer,[{key:"render",value:function render(){var _this$props$className;var left=this.props.mapMargins.left+this.props.mapMargins.outerLeft;var top=this.props.mapMargins.top;var right=this.props.mapMargins.right+this.props.mapMargins.outerRight;var bottom=this.props.mapMargins.bottom;var mapContainerStyle={left:"calc("+left+"px)",top:"calc(var(--topbar-height) + "+top+"px)",right:"calc("+right+"px)",bottom:"calc(var(--bottombar-height) + "+bottom+"px)"};var haveRefs=this.state.mapButtonsContainerRef&&this.state.mapContainerRef&&this.state.appInfosContainerRef;return/*#__PURE__*/React.createElement("div",{className:"plugins-container "+((_this$props$className=this.props.className)!==null&&_this$props$className!==void 0?_this$props$className:""),ref:this.setupTouchEvents},/*#__PURE__*/React.createElement(AppInfosPortalContext.Provider,{value:this.state.appInfosContainerRef},/*#__PURE__*/React.createElement(MapButtonPortalContext.Provider,{value:this.state.mapButtonsContainerRef},/*#__PURE__*/React.createElement(MapContainerPortalContext.Provider,{value:this.state.mapContainerRef},haveRefs?this.renderPlugins():null,haveRefs?this.props.children:null))),/*#__PURE__*/React.createElement(WindowManager,null),/*#__PURE__*/React.createElement("div",{className:"map-container",ref:this.setMapContainerRef,style:mapContainerStyle},/*#__PURE__*/React.createElement(ProcessNotifications,null)),/*#__PURE__*/React.createElement("div",{className:"map-buttons-container",ref:this.setButtonContainerRef,style:mapContainerStyle}),/*#__PURE__*/React.createElement("div",{className:"app-infos-container",ref:this.setAppInfosContainerRef,style:mapContainerStyle}))}}])}(React.Component);_defineProperty(PluginsContainer,"propTypes",{children:PropTypes.oneOfType([PropTypes.node,PropTypes.func]),className:PropTypes.string,mapMargins:PropTypes.object,pluginsConfig:PropTypes.array,theme:PropTypes.object});export default connect(function(state){return{// Just to trigger re-render when custom plugins change
14
14
  customPlugins:state.localConfig.customPlugins,mapMargins:state.windows.mapMargins,theme:state.theme.current}})(PluginsContainer);
@@ -6,12 +6,12 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */import React,{Suspense}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 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 ServiceLayerUtils from"../../utils/ServiceLayerUtils";import ThemeUtils from"../../utils/ThemeUtils";import{MapContainerPortalContext}from"../PluginsContainer";import EditDataset3D from"./EditDataset3D";import MapControls3D from"./MapControls3D";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){},setBaseLayer:function setBaseLayer(layer,visibility){},add3dTiles:function add3dTiles(url,options){},addSceneObject:function addSceneObject(objectId,object){var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};var showEditTool=arguments.length>3&&arguments[3]!==undefined?arguments[3]:false},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){},getSetting:function getSetting(key){},setSetting:function setSetting(key,value){}}),sceneId:null});_defineProperty(_this2,"applyBaseLayer",function(){var _baseLayer$name;var baseLayer=_this2.state.sceneContext.baseLayers.find(function(e){return e.visibility===true});_this2.removeLayer("__baselayer");UrlParams.updateParams({bl3d:(_baseLayer$name=baseLayer===null||baseLayer===void 0?void 0:baseLayer.name)!==null&&_baseLayer$name!==void 0?_baseLayer$name:""});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){var _this2$state$sceneCon;var currentBaseLayer=((_this2$state$sceneCon=_this2.state.sceneContext.baseLayers.find(function(l){return l.visibility===true}))===null||_this2$state$sceneCon===void 0?void 0:_this2$state$sceneCon.name)||"";if(visibility&&(layer===null||layer===void 0?void 0:layer.name)===currentBaseLayer){// Nothing changed
9
- return}_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})})})}})});_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
10
- 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
9
+ return}_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})})})}})});_defineProperty(_this2,"collectColorLayers",function(prevColorLayers,prevLayers){var prevLayerMap=prevLayers.reduce(function(res,layer){return _objectSpread(_objectSpread({},res),{},_defineProperty({},layer.id,layer))},{});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 prevOptions=prevColorLayers[layer.id];if(prevOptions&&layer===prevLayerMap[layer.id]){colorLayers[layer.id]=prevOptions;return colorLayers}var layerCreator=LayerRegistry[layer.type];if(!layerCreator||!layerCreator.create3d){return colorLayers}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
10
+ 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];if(options===prevOptions){return}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
11
11
  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
12
12
  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.props.setCurrentTask("EditDataset3D",null,null,{objectId:name})}});tiles.tiles.addEventListener("needs-update",function(){_this2.instance.notifyChange(tiles)});// Apply style when loading tile
13
13
  tiles.tiles.addEventListener("load-model",function(_ref8){var scene=_ref8.scene;scene.userData.tilesetName=name;scene.userData.featureIdAttr="id";Tiles3DStyle.applyTileStyle(scene,_this2.state.sceneContext.sceneObjects[name],_this2.state.sceneContext);_this2.instance.notifyChange(tiles)});// Show/hide labels when tile visibility changes
14
- 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]:{};var showEditTool=arguments.length>3&&arguments[3]!==undefined?arguments[3]:false;_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))})}});if(showEditTool){_this2.props.setCurrentTask("EditDataset3D",null,null,{objectId:objectId})}});_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
14
+ tiles.tiles.addEventListener("tile-visibility-change",function(_ref9){var _scene$userData$tileL,_scene$userData;var scene=_ref9.scene,visible=_ref9.visible;Object.values((_scene$userData$tileL=scene===null||scene===void 0||(_scene$userData=scene.userData)===null||_scene$userData===void 0?void 0:_scene$userData.tileLabels)!==null&&_scene$userData$tileL!==void 0?_scene$userData$tileL:{}).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]:{};var showEditTool=arguments.length>3&&arguments[3]!==undefined?arguments[3]:false;_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))})}});if(showEditTool){_this2.props.setCurrentTask("EditDataset3D",null,null,{objectId:objectId})}});_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
15
15
  object.traverse(function(c){if(c.isCSS2DObject){c.element.parentNode.removeChild(c.element)}});if(object.tiles){_this2.instance.remove(object)}else{_this2.sceneObjectGroup.remove(object)}delete _this2.objectMap[objectId];_this2.instance.notifyChange();_this2.setState(function(state){var newSceneObjects=_objectSpread({},state.sceneContext.sceneObjects);delete newSceneObjects[objectId];return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{sceneObjects:newSceneObjects})}},callback)});_defineProperty(_this2,"updateSceneObject",function(objectId,options){_this2.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{sceneObjects:_objectSpread(_objectSpread({},state.sceneContext.sceneObjects),{},_defineProperty({},objectId,_objectSpread(_objectSpread({},state.sceneContext.sceneObjects[objectId]),options)))})}})});_defineProperty(_this2,"zoomToObject",function(objectId){var margin=arguments.length>1&&arguments[1]!==undefined?arguments[1]:20;var obj=_this2.state.sceneContext.getSceneObject(objectId);var bbox=new Box3;if(obj!==null&&obj!==void 0&&obj.tiles){obj.tiles.getBoundingBox(bbox)}else{bbox.setFromObject(obj)}if(!bbox.isEmpty()){var bounds=[bbox.min.x-margin,bbox.min.y-margin,bbox.max.x+margin,bbox.max.y+margin];_this2.state.sceneContext.setViewToExtent(bounds,0)}});_defineProperty(_this2,"getMap",function(){return _this2.map});_defineProperty(_this2,"setupContainer",function(el){if(el){_this2.container=el;el.resizeObserver=new ResizeObserver(function(entries){var rect=entries[0].contentRect;_this2.state.sceneContext.scene.view.dispatchEvent({type:"view-resized",width:rect.width,height:rect.height})});el.resizeObserver.observe(el);_this2.setupInstance()}});_defineProperty(_this2,"setupInstance",function(){var _this2$props$theme$ma,_this2$props$theme$ma2,_this2$props$theme$ma3,_this2$props$theme$ma6,_this2$props$theme$ma7,_this2$props$theme$ma8;if(_this2.instance){_this2.disposeInstance()}if(!_this2.props.theme){return}var projection=_this2.props.theme.mapCrs;// Setup instance
16
16
  _this2.instance=new Instance({target:_this2.container,crs:projection,renderer:{clearColor:0,preserveDrawingBuffer:true}});_this2.sceneObjectGroup=new Group;_this2.instance.add(_this2.sceneObjectGroup);// Setup map
17
17
  var bounds=CoordinatesUtils.reprojectBbox(_this2.props.theme.initialBbox.bounds,_this2.props.theme.initialBbox.crs,projection);var extent=new Extent(projection,bounds[0],bounds[2],bounds[1],bounds[3]);_this2.map=new Map({extent:extent,backgroundColor:"white"});_this2.instance.add(_this2.map);// Setup camera
@@ -20,10 +20,10 @@ var cubeTextureLoader=new CubeTextureLoader;cubeTextureLoader.setPath(ConfigUtil
20
20
  var demUrl=MiscUtils.resolveAssetsPath((_this2$props$theme$ma=(_this2$props$theme$ma2=_this2.props.theme.map3d)===null||_this2$props$theme$ma2===void 0||(_this2$props$theme$ma2=_this2$props$theme$ma2.dtm)===null||_this2$props$theme$ma2===void 0?void 0:_this2$props$theme$ma2.url)!==null&&_this2$props$theme$ma!==void 0?_this2$props$theme$ma:"");var demCrs=((_this2$props$theme$ma3=_this2.props.theme.map3d)===null||_this2$props$theme$ma3===void 0||(_this2$props$theme$ma3=_this2$props$theme$ma3.dtm)===null||_this2$props$theme$ma3===void 0?void 0:_this2$props$theme$ma3.crs)||"EPSG:3857";if(demUrl){var _this2$props$theme$ma4,_this2$props$theme$ma5;var demSource=new GeoTIFFSource({url:demUrl,crs:demCrs});var demMin=(_this2$props$theme$ma4=_this2.props.theme.map3d.dtm.min)!==null&&_this2$props$theme$ma4!==void 0?_this2$props$theme$ma4:undefined;var demMax=(_this2$props$theme$ma5=_this2.props.theme.map3d.dtm.max)!==null&&_this2$props$theme$ma5!==void 0?_this2$props$theme$ma5:undefined;var elevationLayer=new ElevationLayer({name:"dem",extent:extent,source:demSource,minmax:demMin!==undefined&&demMax!==undefined?{demMin:demMin,demMax:demMax}:undefined});_this2.addLayer("__dtm",elevationLayer)}// Collect baselayers
21
21
  var externalLayers={};var baseLayers=ThemeUtils.createThemeBackgroundLayers(((_this2$props$theme$ma6=_this2.props.theme.map3d)===null||_this2$props$theme$ma6===void 0?void 0:_this2$props$theme$ma6.basemaps)||[],_this2.props.themes,null,externalLayers);for(var _i=0,_Object$keys=Object.keys(externalLayers);_i<_Object$keys.length;_i++){var key=_Object$keys[_i];var idx=key.indexOf(":");var service=key.slice(0,idx);var serviceUrl=key.slice(idx+1);ServiceLayerUtils.findLayers(service,serviceUrl,externalLayers[key],projection,function(id,layer){// Don't expose sublayers
22
22
  if(layer){layer.sublayers=null}_this2.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{baseLayers:LayerUtils.replacePlaceholderLayer(state.sceneContext.baseLayers,id,layer)})}})})}// Collect color layers
23
- var colorLayers=_this2.collectColorLayers([]);var sceneObjects={};_this2.objectMap={};// Add 3d tiles
23
+ var colorLayers=_this2.collectColorLayers([],[]);var sceneObjects={};_this2.objectMap={};// Add 3d tiles
24
24
  (((_this2$props$theme$ma7=_this2.props.theme.map3d)===null||_this2$props$theme$ma7===void 0?void 0:_this2$props$theme$ma7.tiles3d)||[]).forEach(function(entry){var _entry$title;var tiles=new Tiles3D({url:MiscUtils.resolveAssetsPath(entry.url),errorTarget:32});tiles.tiles.addEventListener("load-tile-set",function(){_this2.instance.notifyChange(tiles)});tiles.tiles.addEventListener("needs-update",function(){_this2.instance.notifyChange(tiles)});// Apply style when loading tile
25
25
  tiles.tiles.addEventListener("load-model",function(_ref10){var _entry$idAttr;var scene=_ref10.scene;scene.userData.tilesetName=entry.name;scene.userData.featureIdAttr=(_entry$idAttr=entry.idAttr)!==null&&_entry$idAttr!==void 0?_entry$idAttr:"id";Tiles3DStyle.applyTileStyle(scene,_this2.state.sceneContext.sceneObjects[entry.name],_this2.state.sceneContext);_this2.instance.notifyChange(tiles)});// Show/hide labels when tile visibility changes
26
- tiles.tiles.addEventListener("tile-visibility-change",function(_ref11){var scene=_ref11.scene,visible=_ref11.visible;Object.values(scene.userData.tileLabels||{}).forEach(function(label){label.labelObject.visible=visible;label.labelObject.element.style.display=visible?"initial":"none"})});tiles.castShadow=true;tiles.receiveShadow=true;tiles.userData.layertree=true;_this2.instance.add(tiles);_this2.objectMap[entry.name]=tiles;sceneObjects[entry.name]={visibility:true,opacity:255,layertree:true,title:(_entry$title=entry.title)!==null&&_entry$title!==void 0?_entry$title:entry.name,baseColor:entry.baseColor,styles:entry.styles,style:entry.style||Object.keys(entry.styles||{})[0]||null,tilesetStyle:null,idAttr:entry.idAttr,colorAttr:entry.colorAttr,alphaAttr:entry.alphaAttr,labelAttr:entry.labelAttr}});// Add other objects
26
+ tiles.tiles.addEventListener("tile-visibility-change",function(_ref11){var _scene$userData$tileL2,_scene$userData2;var scene=_ref11.scene,visible=_ref11.visible;Object.values((_scene$userData$tileL2=scene===null||scene===void 0||(_scene$userData2=scene.userData)===null||_scene$userData2===void 0?void 0:_scene$userData2.tileLabels)!==null&&_scene$userData$tileL2!==void 0?_scene$userData$tileL2:{}).forEach(function(label){label.labelObject.visible=visible;label.labelObject.element.style.display=visible?"initial":"none"})});tiles.castShadow=true;tiles.receiveShadow=true;tiles.userData.layertree=true;_this2.instance.add(tiles);_this2.objectMap[entry.name]=tiles;sceneObjects[entry.name]={visibility:true,opacity:255,layertree:true,title:(_entry$title=entry.title)!==null&&_entry$title!==void 0?_entry$title:entry.name,baseColor:entry.baseColor,styles:entry.styles,style:entry.style||Object.keys(entry.styles||{})[0]||null,tilesetStyle:null,idAttr:entry.idAttr,colorAttr:entry.colorAttr,alphaAttr:entry.alphaAttr,labelAttr:entry.labelAttr}});// Add other objects
27
27
  (((_this2$props$theme$ma8=_this2.props.theme.map3d)===null||_this2$props$theme$ma8===void 0?void 0:_this2$props$theme$ma8.objects3d)||[]).forEach(function(entry){importGltf(MiscUtils.resolveAssetsPath(entry.url),entry.name,_this2.state.sceneContext)});_this2.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{scene:_this2.instance,map:_this2.map,mapCrs:projection,dtmUrl:demUrl,dtmCrs:demCrs,baseLayers:baseLayers,colorLayers:colorLayers,sceneObjects:sceneObjects}),sceneId:uuidv4()}});// Inspector
28
28
  if(["1","true"].includes((UrlParams.getParam("inspector")||"").toLowerCase())){var inspectorContainer=document.createElement("div");inspectorContainer.className="map3d-inspector";_this2.container.appendChild(inspectorContainer);_this2.inspector=new Inspector(inspectorContainer,_this2.instance)}_this2.instance.addEventListener("update-start",_this2.instanceOnUpdateStart);_this2.instance.addEventListener("update-end",_this2.instanceOnUpdateEnd);_this2.instance.addEventListener("before-entity-update",_this2.instanceOnBeforeEntityUpdate);_this2.instance.addEventListener("after-entity-update",_this2.instanceOnAfterEntityUpdate)});_defineProperty(_this2,"instanceOnUpdateStart",function(){var camera=_this2.instance.view.camera;var quality=_this2.state.sceneContext.settings.sceneQuality;var isFirstPerson=_this2.state.sceneContext.scene.view.controls.isFirstPerson;var maxDistance=isFirstPerson?200+20*quality:500+quality*quality;// Hide scene objects according to scene quality
29
29
  Object.entries(_this2.state.sceneContext.sceneObjects).forEach(function(_ref12){var _ref13=_slicedToArray(_ref12,2),objId=_ref13[0],options=_ref13[1];var object=_this2.objectMap[objId];if(options.layertree&&object.isObject3D&&object.visible){object.children.forEach(function(child){if(child.geometry){if(!child.geometry.boundingBox){child.geometry.computeBoundingBox()}var localCenter=child.geometry.boundingBox.getCenter(new Vector3);var worldCenter=localCenter.applyMatrix4(child.matrixWorld);var distance=camera.position.distanceTo(worldCenter);child.userData.__wasVisible=child.visible;if(distance>maxDistance){child.visible=false}}})}})});_defineProperty(_this2,"instanceOnUpdateEnd",function(){Object.entries(_this2.state.sceneContext.sceneObjects).forEach(function(_ref14){var _ref15=_slicedToArray(_ref14,2),objId=_ref15[0],options=_ref15[1];var object=_this2.objectMap[objId];if(options.layertree&&object.isObject3D){object.children.forEach(function(child){child.visible=child.userData.__wasVisible;delete child.userData.__wasVisible})}})});_defineProperty(_this2,"instanceOnBeforeEntityUpdate",function(_ref16){var entity=_ref16.entity;if(entity!==_this2.map){_this2.instance.view.camera.userData.__previousFar=_this2.instance.view.camera.far;var quality=_this2.state.sceneContext.settings.sceneQuality;var isFirstPerson=_this2.state.sceneContext.scene.view.controls.isFirstPerson;_this2.instance.view.camera.far=isFirstPerson?200+20*quality:500+quality*quality;_this2.instance.view.camera.updateProjectionMatrix()}});_defineProperty(_this2,"instanceOnAfterEntityUpdate",function(_ref17){var entity=_ref17.entity;if(entity!==_this2.map){_this2.instance.view.camera.far=_this2.instance.view.camera.userData.__previousFar;delete _this2.instance.view.camera.userData.__previousFar;_this2.instance.view.camera.updateProjectionMatrix()}});_defineProperty(_this2,"loadTilesetStyle",function(objectId,options){var _options$styles;var url=(_options$styles=options.styles)===null||_options$styles===void 0?void 0:_options$styles[options.style];if(_this2.tilesetStyles[url]){_this2.updateSceneObject(objectId,{tilesetStyle:_this2.tilesetStyles[url]})}else if(url){var fullUrl=MiscUtils.resolveAssetsPath(url);axios.get(fullUrl).then(function(response){_this2.tilesetStyles[url]=response.data;_this2.updateSceneObject(objectId,{tilesetStyle:_this2.tilesetStyles[url]})})["catch"](function(){_this2.tilesetStyles[url]={};_this2.updateSceneObject(objectId,{tilesetStyle:_this2.tilesetStyles[url]})})}else{_this2.tilesetStyles[url]=null;_this2.updateSceneObject(objectId,{tilesetStyle:_this2.tilesetStyles[url]})}});_defineProperty(_this2,"disposeInstance",function(){_this2.instance.removeEventListener("update-start",_this2.instanceOnUpdateStart);_this2.instance.removeEventListener("update-end",_this2.instanceOnUpdateEnd);_this2.instance.removeEventListener("before-entity-update",_this2.instanceOnBeforeEntityUpdate);_this2.instance.removeEventListener("after-entity-update",_this2.instanceOnAfterEntityUpdate);if(_this2.inspector){_this2.inspector.detach()}_this2.map.dispose({disposeLayers:true});Object.values(_this2.objectMap).forEach(function(object){_this2.instance.remove(object)});_this2.instance.dispose();_this2.inspector=null;_this2.map=null;_this2.objectMap={};_this2.sceneObjectGroup=null;_this2.instance=null;_this2.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),Map3D.defaultSceneState)}});_this2.props.setCurrentTask(null)});_defineProperty(_this2,"onUnload",function(key){// Ensure scene has not already been disposed
@@ -37,7 +37,7 @@ var maxPixelX=Math.round((dtmExt[2]-tiepointX)/scaleX)+1;var width=maxPixelX-min
37
37
  elevationResult.samples.sort(function(a,b){return a.resolution-b.resolution});return(_elevationResult$samp=elevationResult.samples[0])===null||_elevationResult$samp===void 0?void 0:_elevationResult$samp.elevation});_defineProperty(_this2,"getSceneIntersection",function(x,y){var objects=arguments.length>2&&arguments[2]!==undefined?arguments[2]:true;var raycaster=new Raycaster;var camera=_this2.instance.view.camera;raycaster.setFromCamera(new Vector2(x,y),camera);// Query object intersection
38
38
  var objInter=objects?raycaster.intersectObjects(_this2.state.sceneContext.collisionObjects,true)[0]:undefined;// Query highest resolution terrain tile (i.e. tile with no children)
39
39
  var terrInter=raycaster.intersectObjects([_this2.map.object3d]).filter(function(result){return result.object.children.length===0})[0];// Return closest result
40
- if(objInter&&terrInter){return objInter.distance<terrInter.distance?objInter:terrInter}return objInter!==null&&objInter!==void 0?objInter:terrInter});_defineProperty(_this2,"getSetting",function(key){return _this2.state.sceneContext.settings[key]});_defineProperty(_this2,"setSetting",function(key,value){_this2.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{settings:_objectSpread(_objectSpread({},state.sceneContext.settings),{},_defineProperty({},key,value))})}})});_defineProperty(_this2,"redrawScene",function(ev){var width=ev.target.innerWidth;var height=ev.target.innerHeight;_this2.instance.renderer.setSize(width,height);_this2.instance.view.camera.aspect=width/height;_this2.instance.view.camera.updateProjectionMatrix();_this2.instance.renderer.render(_this2.instance.scene,_this2.instance.view.camera)});_defineProperty(_this2,"setViewToExtent",function(bounds,rotation){_this2.state.sceneContext.setViewToExtent(bounds,rotation)});_defineProperty(_this2,"store3dState",function(){var promises=Object.entries(_this2.state.sceneContext.sceneObjects).map(function(_ref20){var _ref21=_slicedToArray(_ref20,2),objectId=_ref21[0],entry=_ref21[1];if(!entry.layertree){return null}return new Promise(function(resolve){var object=_this2.state.sceneContext.getSceneObject(objectId);if(entry.drawGroup){var exporter=new GLTFExporter;exporter.parse(object,function(result){resolve({id:objectId,options:entry,data:result})})}else if(entry.imported&&object.tiles){var container=object.tiles.group.parent;var tileset={matrix:container.matrix.elements,label:container.userData.label,url:object.tiles.rootURL};resolve({id:objectId,options:entry,tileset:tileset})}else{resolve({id:objectId,options:entry})}})}).filter(Boolean);return new Promise(function(resolve){Promise.all(promises).then(function(objects){var _this2$state$sceneCon2,_this2$state$sceneCon3;var camera=_this2.state.sceneContext.scene.view.camera.position;var target=_this2.state.sceneContext.scene.view.controls.target;var layers=Object.entries(_this2.state.sceneContext.colorLayers).map(function(_ref22){var _ref23=_slicedToArray(_ref22,2),layerId=_ref23[0],options=_ref23[1];return{id:layerId,options:{visibility:options.visibility,opacity:options.opacity,extrusionHeight:options.extrusionHeight}}});resolve({objects:objects,colorLayers:layers,baseLayer:((_this2$state$sceneCon2=_this2.state.sceneContext.baseLayers.find(function(layer){return layer.visibility===true}))===null||_this2$state$sceneCon2===void 0?void 0:_this2$state$sceneCon2.name)||"",personHeight:(_this2$state$sceneCon3=_this2.state.sceneContext.scene.view.controls.personHeight)!==null&&_this2$state$sceneCon3!==void 0?_this2$state$sceneCon3:0,camera:[camera.x,camera.y,camera.z],target:[target.x,target.y,target.z]})})})});_defineProperty(_this2,"restore3dState",function(data){if(isEmpty(data)){return}(data.objects||[]).forEach(function(item){if(item.data){var loader=new GLTFLoader;loader.parse(item.data,ConfigUtils.getAssetsPath(),function(gltf){gltf.scene.traverse(function(c){if(c.isMesh){c.castShadow=true;c.receiveShadow=true}updateObjectLabel(c,_this2.state.sceneContext)});_this2.state.sceneContext.addSceneObject(item.id,gltf.scene,item.options)})}else if(item.tileset){_this2.add3dTiles(item.tileset.url,item.id,item.options,false,new Matrix4().fromArray(item.tileset.matrix),item.tileset.label)}else if(item.id in _this2.state.sceneContext.sceneObjects){_this2.state.sceneContext.updateSceneObject(item.id,item.options)}});(data.colorLayers||[]).forEach(function(item){if(item.id in _this2.state.sceneContext.colorLayers){_this2.state.sceneContext.updateColorLayer(item.id,item.options)}});_this2.state.sceneContext.restoreView(data);if(data.baseLayer!==undefined){_this2.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{baseLayers:state.sceneContext.baseLayers.map(function(l){return _objectSpread(_objectSpread({},l),{},{visibility:l.name===data.baseLayer})})})}});UrlParams.updateParams({bl3d:data.baseLayer})}_this2.state.sceneContext.scene.notifyChange()});_this2.container=null;_this2.inspector=null;_this2.instance=null;_this2.map=null;_this2.sceneObjectGroup=null;_this2.objectMap={};_this2.tilesetStyles={};_this2.state.sceneContext.addLayer=_this2.addLayer;_this2.state.sceneContext.getLayer=_this2.getLayer;_this2.state.sceneContext.removeLayer=_this2.removeLayer;_this2.state.sceneContext.updateColorLayer=_this2.updateColorLayer;_this2.state.sceneContext.setBaseLayer=_this2.setBaseLayer;_this2.state.sceneContext.add3dTiles=_this2.add3dTiles;_this2.state.sceneContext.addSceneObject=_this2.addSceneObject;_this2.state.sceneContext.getSceneObject=_this2.getSceneObject;_this2.state.sceneContext.removeSceneObject=_this2.removeSceneObject;_this2.state.sceneContext.updateSceneObject=_this2.updateSceneObject;_this2.state.sceneContext.zoomToObject=_this2.zoomToObject;_this2.state.sceneContext.getMap=_this2.getMap;_this2.state.sceneContext.getTerrainHeightFromDTM=_this2.getTerrainHeightFromDTM;_this2.state.sceneContext.getTerrainHeightFromMap=_this2.getTerrainHeightFromMap;_this2.state.sceneContext.getSceneIntersection=_this2.getSceneIntersection;_this2.state.sceneContext.getSetting=_this2.getSetting;_this2.state.sceneContext.setSetting=_this2.setSetting;_this2.state.sceneContext.settings.sceneQuality=props.defaultSceneQuality;registerPermalinkDataStoreHook("map3d",_this2.store3dState);return _this2}_inherits(Map3D,_React$Component2);return _createClass(Map3D,[{key:"componentDidMount",value:function componentDidMount(){this.props.innerRef(this)}},{key:"componentWillUnmount",value:function componentWillUnmount(){unregisterPermalinkDataStoreHook("map3d")}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var _this3=this;if(this.props.theme!==prevProps.theme){this.setupInstance()}else if(this.props.layers!==prevProps.layers){this.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{colorLayers:_this3.collectColorLayers(state.sceneContext.colorLayers)})}})}// Update map layers
40
+ if(objInter&&terrInter){return objInter.distance<terrInter.distance?objInter:terrInter}return objInter!==null&&objInter!==void 0?objInter:terrInter});_defineProperty(_this2,"getSetting",function(key){return _this2.state.sceneContext.settings[key]});_defineProperty(_this2,"setSetting",function(key,value){_this2.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{settings:_objectSpread(_objectSpread({},state.sceneContext.settings),{},_defineProperty({},key,value))})}})});_defineProperty(_this2,"redrawScene",function(ev){var width=ev.target.innerWidth;var height=ev.target.innerHeight;_this2.instance.renderer.setSize(width,height);_this2.instance.view.camera.aspect=width/height;_this2.instance.view.camera.updateProjectionMatrix();_this2.instance.renderer.render(_this2.instance.scene,_this2.instance.view.camera)});_defineProperty(_this2,"setViewToExtent",function(bounds,rotation){_this2.state.sceneContext.setViewToExtent(bounds,rotation)});_defineProperty(_this2,"store3dState",function(){var promises=Object.entries(_this2.state.sceneContext.sceneObjects).map(function(_ref20){var _ref21=_slicedToArray(_ref20,2),objectId=_ref21[0],entry=_ref21[1];if(!entry.layertree){return null}return new Promise(function(resolve){var object=_this2.state.sceneContext.getSceneObject(objectId);if(entry.drawGroup){var exporter=new GLTFExporter;exporter.parse(object,function(result){resolve({id:objectId,options:entry,data:result})})}else if(entry.imported&&object.tiles){var container=object.tiles.group.parent;var tileset={matrix:container.matrix.elements,label:container.userData.label,url:object.tiles.rootURL};resolve({id:objectId,options:entry,tileset:tileset})}else{resolve({id:objectId,options:entry})}})}).filter(Boolean);return new Promise(function(resolve){Promise.all(promises).then(function(objects){var _this2$state$sceneCon2,_this2$state$sceneCon3;var camera=_this2.state.sceneContext.scene.view.camera.position;var target=_this2.state.sceneContext.scene.view.controls.target;var layers=Object.entries(_this2.state.sceneContext.colorLayers).map(function(_ref22){var _ref23=_slicedToArray(_ref22,2),layerId=_ref23[0],options=_ref23[1];return{id:layerId,options:{visibility:options.visibility,opacity:options.opacity,extrusionHeight:options.extrusionHeight}}});resolve({objects:objects,colorLayers:layers,baseLayer:((_this2$state$sceneCon2=_this2.state.sceneContext.baseLayers.find(function(layer){return layer.visibility===true}))===null||_this2$state$sceneCon2===void 0?void 0:_this2$state$sceneCon2.name)||"",personHeight:(_this2$state$sceneCon3=_this2.state.sceneContext.scene.view.controls.personHeight)!==null&&_this2$state$sceneCon3!==void 0?_this2$state$sceneCon3:0,camera:[camera.x,camera.y,camera.z],target:[target.x,target.y,target.z]})})})});_defineProperty(_this2,"restore3dState",function(data){if(isEmpty(data)){return}(data.objects||[]).forEach(function(item){if(item.data){var loader=new GLTFLoader;loader.parse(item.data,ConfigUtils.getAssetsPath(),function(gltf){gltf.scene.traverse(function(c){if(c.isMesh){c.castShadow=true;c.receiveShadow=true}updateObjectLabel(c,_this2.state.sceneContext)});_this2.state.sceneContext.addSceneObject(item.id,gltf.scene,item.options)})}else if(item.tileset){_this2.add3dTiles(item.tileset.url,item.id,item.options,false,new Matrix4().fromArray(item.tileset.matrix),item.tileset.label)}else if(item.id in _this2.state.sceneContext.sceneObjects){_this2.state.sceneContext.updateSceneObject(item.id,item.options)}});(data.colorLayers||[]).forEach(function(item){if(item.id in _this2.state.sceneContext.colorLayers){_this2.state.sceneContext.updateColorLayer(item.id,item.options)}});_this2.state.sceneContext.restoreView(data);if(data.baseLayer!==undefined){_this2.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{baseLayers:state.sceneContext.baseLayers.map(function(l){return _objectSpread(_objectSpread({},l),{},{visibility:l.name===data.baseLayer})})})}});UrlParams.updateParams({bl3d:data.baseLayer})}_this2.state.sceneContext.scene.notifyChange()});_this2.container=null;_this2.inspector=null;_this2.instance=null;_this2.map=null;_this2.sceneObjectGroup=null;_this2.objectMap={};_this2.tilesetStyles={};_this2.state.sceneContext.addLayer=_this2.addLayer;_this2.state.sceneContext.getLayer=_this2.getLayer;_this2.state.sceneContext.removeLayer=_this2.removeLayer;_this2.state.sceneContext.updateColorLayer=_this2.updateColorLayer;_this2.state.sceneContext.setBaseLayer=_this2.setBaseLayer;_this2.state.sceneContext.add3dTiles=_this2.add3dTiles;_this2.state.sceneContext.addSceneObject=_this2.addSceneObject;_this2.state.sceneContext.getSceneObject=_this2.getSceneObject;_this2.state.sceneContext.removeSceneObject=_this2.removeSceneObject;_this2.state.sceneContext.updateSceneObject=_this2.updateSceneObject;_this2.state.sceneContext.zoomToObject=_this2.zoomToObject;_this2.state.sceneContext.getMap=_this2.getMap;_this2.state.sceneContext.getTerrainHeightFromDTM=_this2.getTerrainHeightFromDTM;_this2.state.sceneContext.getTerrainHeightFromMap=_this2.getTerrainHeightFromMap;_this2.state.sceneContext.getSceneIntersection=_this2.getSceneIntersection;_this2.state.sceneContext.getSetting=_this2.getSetting;_this2.state.sceneContext.setSetting=_this2.setSetting;_this2.state.sceneContext.settings.sceneQuality=props.defaultSceneQuality;registerPermalinkDataStoreHook("map3d",_this2.store3dState);return _this2}_inherits(Map3D,_React$Component2);return _createClass(Map3D,[{key:"componentDidMount",value:function componentDidMount(){this.props.innerRef(this)}},{key:"componentWillUnmount",value:function componentWillUnmount(){unregisterPermalinkDataStoreHook("map3d")}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var _this3=this;if(this.props.theme!==prevProps.theme){this.setupInstance()}else if(this.props.layers!==prevProps.layers){this.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{colorLayers:_this3.collectColorLayers(state.sceneContext.colorLayers,prevProps.layers)})}})}// Update map layers
41
41
  if(this.state.sceneContext.baseLayers!==prevState.sceneContext.baseLayers){this.applyBaseLayer()}if(this.state.sceneContext.colorLayers!==prevState.sceneContext.colorLayers){this.applyColorLayerUpdates(this.state.sceneContext.colorLayers,prevState.sceneContext.colorLayers)}// Update scene objects
42
42
  if(this.state.sceneContext.sceneObjects!==prevState.sceneContext.sceneObjects){this.applySceneObjectUpdates(this.state.sceneContext.sceneObjects,prevState.sceneContext.sceneObjects);// Update collision objects
43
43
  this.setState(function(state){return{sceneContext:_objectSpread(_objectSpread({},state.sceneContext),{},{collisionObjects:Object.entries(state.sceneContext.sceneObjects).map(function(_ref24){var _ref25=_slicedToArray(_ref24,2),objId=_ref25[0],options=_ref25[1];if(options.layertree&&options.visibility){var _obj$tiles$group,_obj$tiles;var obj=_this3.objectMap[objId];return(_obj$tiles$group=(_obj$tiles=obj.tiles)===null||_obj$tiles===void 0?void 0:_obj$tiles.group)!==null&&_obj$tiles$group!==void 0?_obj$tiles$group:obj}return null}).filter(Boolean)})}})}if(this.state.sceneContext.settings.sceneQuality!==prevState.sceneContext.settings.sceneQuality){var quality=Math.max(20,this.state.sceneContext.settings.sceneQuality);this.map.segments=Math.pow(2,Math.floor(quality/20));this.instance.notifyChange(this.instance.view.camera)}}},{key:"render",value:function render(){var _this4=this;return[/*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div",{className:"map3d-map",id:"map3d",key:"Map3D",ref:this.setupContainer}),this.context),this.state.sceneContext.scene?/*#__PURE__*/React.createElement(UnloadWrapper,{key:this.state.sceneId,onUnload:this.onUnload,sceneId:this.state.sceneId},/*#__PURE__*/React.createElement(MapControls3D,{controlsPosition:this.props.controlsPosition,mouseButtons:this.props.mouseButtons,onCameraChanged:this.props.onCameraChanged,onControlsSet:this.setupControls,sceneContext:this.state.sceneContext},/*#__PURE__*/React.createElement(EditDataset3D,{sceneContext:this.state.sceneContext}),/*#__PURE__*/React.createElement(View3DSwitcher,{position:1}),Object.entries(this.props.plugins3d).map(function(_ref26){var _ref27=_slicedToArray(_ref26,2),name=_ref27[0],Component=_ref27[1];return/*#__PURE__*/React.createElement(Suspense,{key:name},/*#__PURE__*/React.createElement(Component,_extends({sceneContext:_this4.state.sceneContext},_this4.props.pluginOptions[name])))}))):null]}}])}(React.Component);_defineProperty(Map3D,"contextType",MapContainerPortalContext);_defineProperty(Map3D,"propTypes",{controlsPosition:PropTypes.string,defaultSceneQuality:PropTypes.number,innerRef:PropTypes.func,layers:PropTypes.array,mouseButtons:PropTypes.object,onCameraChanged:PropTypes.func,onMapInitialized:PropTypes.func,pluginOptions:PropTypes.object,plugins3d:PropTypes.object,setCurrentTask:PropTypes.func,theme:PropTypes.object,themes:PropTypes.object});_defineProperty(Map3D,"defaultProps",{geometry:{initialWidth:600,initialHeight:800,initialX:0,initialY:0,initiallyDocked:true}});_defineProperty(Map3D,"defaultSceneState",{scene:null,map:null,mapCrs:null,dtmUrl:null,dtmCrs:null,baseLayers:[],colorLayers:{},sceneObjects:{},collisionObjects:[],settings:{sceneQuality:100}});export default connect(function(state){return{theme:state.theme.current,themes:state.theme.themes,layers:state.layers.flat}},{setCurrentTask:setCurrentTask})(Map3D);
@@ -10,6 +10,36 @@ div.map-container {
10
10
  position: absolute;
11
11
  }
12
12
 
13
+ div.app-infos-container {
14
+ position: absolute;
15
+ pointer-events: none;
16
+ display: flex;
17
+ flex-direction: column;
18
+ align-items: flex-start;
19
+ align-content: flex-start;
20
+ justify-content: flex-start;
21
+ flex-wrap: wrap-reverse;
22
+ z-index: 2;
23
+ overflow: hidden;
24
+ padding: 1em 1em 2.5em 1em;
25
+ row-gap: 0.25em;
26
+ }
27
+
28
+ div.app-info {
29
+ z-index: 1;
30
+ color: var(--panel-text-color);
31
+ background-color: var(--panel-bg-color);
32
+ box-shadow: 0 0 4px rgba(136, 136, 136, 0.5);
33
+ padding: 0.25em 0em 0.125em 0em;
34
+ display: flex;
35
+ }
36
+
37
+ div.app-info > span {
38
+ flex: 0 0 auto;
39
+ padding: 0 0.25em;
40
+ }
41
+
42
+
13
43
  div.map-buttons-container {
14
44
  position: absolute;
15
45
  pointer-events: none;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2025.09.15",
3
+ "version": "2025.09.23",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
@@ -4,10 +4,10 @@ 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 ReactDOM from"react-dom";import{connect}from"react-redux";import PropTypes from"prop-types";import url from"url";import Icon from"../components/Icon";import{MapContainerPortalContext}from"../components/PluginsContainer";import ConfigUtils from"../utils/ConfigUtils";import"./style/Authentication.css";/**
7
+ */import React from"react";import ReactDOM from"react-dom";import{connect}from"react-redux";import PropTypes from"prop-types";import url from"url";import Icon from"../components/Icon";import{AppInfosPortalContext}from"../components/PluginsContainer";import ConfigUtils from"../utils/ConfigUtils";import"./style/Authentication.css";/**
8
8
  * Handles authentication
9
9
  *
10
10
  * Invokes the the authentication service specified by `authServiceUrl` in `config.json`.
11
11
  */var Authentication=/*#__PURE__*/function(_React$Component){function Authentication(props){var _this;_classCallCheck(this,Authentication);_this=_callSuper(this,Authentication,[props]);_defineProperty(_this,"showLogin",function(){var urlObj=url.parse(window.location.href,true);if(_this.props.clearLayerParam){delete urlObj.query.l}urlObj.search=undefined;window.location.href=ConfigUtils.getConfigProp("authServiceUrl")+"login?url="+encodeURIComponent(url.format(urlObj))});_defineProperty(_this,"resetIdleTimer",function(){if(_this.idleTimer){clearTimeout(_this.idleTimer);_this.idleTimer=setTimeout(_this.idleAutologout,_this.props.idleTimeout*1000)}});_defineProperty(_this,"idleAutologout",function(){var urlObj=url.parse(window.location.href,true);urlObj.search=undefined;var loginUrl=ConfigUtils.getConfigProp("authServiceUrl")+"login?url="+encodeURIComponent(url.format(urlObj));window.location.href=ConfigUtils.getConfigProp("authServiceUrl")+"logout?url="+encodeURIComponent(loginUrl)});_this.idleTimer=null;return _this}_inherits(Authentication,_React$Component);return _createClass(Authentication,[{key:"componentDidMount",value:function componentDidMount(){var username=ConfigUtils.getConfigProp("username");if(this.props.requireLogin&&!username){this.showLogin()}if(this.props.idleTimeout&&username){this.idleTimer=setTimeout(this.idleAutologout,this.props.idleTimeout*1000);window.addEventListener("keydown",this.resetIdleTimer,{passive:true});window.addEventListener("mousedown",this.resetIdleTimer,{passive:true});window.addEventListener("wheel",this.resetIdleTimer,{passive:true})}}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var task=this.props.task;if(task!==prevProps.task){// "Login" and "Logout" task ids are legacy
12
12
  if(task.id==="Login"||task.id==="Authentication"&&task.mode==="Login"){this.showLogin()}else if(task.id==="Logout"||task.id==="Authentication"&&task.mode==="Logout"){// logout and redirect to custom logoutTargetUrl or current location if not set
13
- window.location.href=ConfigUtils.getConfigProp("authServiceUrl")+"logout?url="+encodeURIComponent(this.props.logoutTargetUrl||window.location.href)}}}},{key:"render",value:function render(){if(!this.props.showLoginUser){return null}var username=ConfigUtils.getConfigProp("username");if(!username){return null}return/*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div",{className:"login-user"},/*#__PURE__*/React.createElement(Icon,{icon:"login"}),/*#__PURE__*/React.createElement("span",null,username)),this.context)}}])}(React.Component);_defineProperty(Authentication,"contextType",MapContainerPortalContext);_defineProperty(Authentication,"availableIn3D",true);_defineProperty(Authentication,"propTypes",{/** Whether to clear the layer parameter from the URL on login. */clearLayerParam:PropTypes.bool,/** An idle timeout in seconds after which the user is automatically logged of. */idleTimeout:PropTypes.number,/** An URL to redirect to on logout, instead of the viewer URL. */logoutTargetUrl:PropTypes.string,/** Whether authentication is required, i.e. the viewer automatically redirects to the login page if no user is authenticated. */requireLogin:PropTypes.bool,/** Whether to display the currently logged in user below the application menu button. */showLoginUser:PropTypes.bool,task:PropTypes.object});export default connect(function(state){return{task:state.task}},{})(Authentication);
13
+ window.location.href=ConfigUtils.getConfigProp("authServiceUrl")+"logout?url="+encodeURIComponent(this.props.logoutTargetUrl||window.location.href)}}}},{key:"render",value:function render(){if(!this.props.showLoginUser){return null}var username=ConfigUtils.getConfigProp("username");if(!username){return null}return/*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div",{className:"app-info login-user"},/*#__PURE__*/React.createElement(Icon,{icon:"login"}),/*#__PURE__*/React.createElement("span",null,username)),this.context)}}])}(React.Component);_defineProperty(Authentication,"contextType",AppInfosPortalContext);_defineProperty(Authentication,"availableIn3D",true);_defineProperty(Authentication,"propTypes",{/** Whether to clear the layer parameter from the URL on login. */clearLayerParam:PropTypes.bool,/** An idle timeout in seconds after which the user is automatically logged of. */idleTimeout:PropTypes.number,/** An URL to redirect to on logout, instead of the viewer URL. */logoutTargetUrl:PropTypes.string,/** Whether authentication is required, i.e. the viewer automatically redirects to the login page if no user is authenticated. */requireLogin:PropTypes.bool,/** Whether to display the currently logged in user below the application menu button. */showLoginUser:PropTypes.bool,task:PropTypes.object});export default connect(function(state){return{task:state.task}},{})(Authentication);
@@ -10,5 +10,5 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
10
10
  * The user can toggle whether to display only layers which are enabled, visible in the current extent and/or visible at the current scale.
11
11
  *
12
12
  * See https://docs.qgis.org/3.28/en/docs/server_manual/services/wms.html#wms-getlegendgraphic for supported extra legend params.
13
- */var MapLegend=/*#__PURE__*/function(_React$Component){function MapLegend(props){var _this;_classCallCheck(this,MapLegend);_this=_callSuper(this,MapLegend,[props]);_defineProperty(_this,"state",{onlyVisibleLegend:false,bboxDependentLegend:false,scaleDependentLegend:false,visible:false});_defineProperty(_this,"onClose",function(){_this.setState({visible:false})});_defineProperty(_this,"printLayerLegend",function(layer,sublayer,mapScale){var isCategorized=(sublayer.sublayers||[]).find(function(entry){return entry.category_sublayer===true});if(_this.props.excludeLayers.includes(sublayer.name)){return null}else if(sublayer.sublayers&&!isCategorized&&(!_this.state.onlyVisibleLegend||sublayer.visibility)){if(_this.props.addGroupTitles){var children=sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)}).filter(function(x){return x});if(isEmpty(children)){return null}else{return/*#__PURE__*/React.createElement("div",{className:"map-legend-group",key:sublayer.name},/*#__PURE__*/React.createElement("div",{className:"map-legend-group-title"},sublayer.title||sublayer.name),/*#__PURE__*/React.createElement("div",{className:"map-legend-group-entries"},sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)})))}}else{return sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)})}}else{if(_this.state.onlyVisibleLegend&&!sublayer.visibility){return null}if((_this.state.onlyVisibleLegend||_this.state.scaleDependentLegend)&&!LayerUtils.layerScaleInRange(sublayer,mapScale)){return null}var request=LayerUtils.getLegendUrl(layer,{name:sublayer.name},mapScale,_this.props.map,_this.state.bboxDependentLegend,_this.state.scaleDependentLegend,_this.props.extraLegendParameters);return request?/*#__PURE__*/React.createElement("div",{className:"map-legend-legend-entry",key:sublayer.name},/*#__PURE__*/React.createElement("div",null,_this.props.addLayerTitles&&!sublayer.category_sublayer?/*#__PURE__*/React.createElement("div",{className:"map-legend-entry-title"},sublayer.title||sublayer.name):null,/*#__PURE__*/React.createElement("div",{className:"map-legend-entry-image"},/*#__PURE__*/React.createElement(Image,{src:request})))):null}});_this.state.onlyVisibleLegend=props.onlyVisibleLegend;_this.state.bboxDependentLegend=props.bboxDependentLegend;_this.state.scaleDependentLegend=props.scaleDependentLegend;return _this}_inherits(MapLegend,_React$Component);return _createClass(MapLegend,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){if(this.props.active&&!prevProps.active){this.setState({visible:true});// Clear task immediately, visibility is stored as state
13
+ */var MapLegend=/*#__PURE__*/function(_React$Component){function MapLegend(props){var _this;_classCallCheck(this,MapLegend);_this=_callSuper(this,MapLegend,[props]);_defineProperty(_this,"state",{onlyVisibleLegend:false,bboxDependentLegend:false,scaleDependentLegend:false,visible:false});_defineProperty(_this,"onClose",function(){_this.setState({visible:false})});_defineProperty(_this,"printLayerLegend",function(layer,sublayer,mapScale){var isCategorized=(sublayer.sublayers||[]).find(function(entry){return entry.category_sublayer===true});if(_this.props.excludeLayers.includes(sublayer.name)){return null}else if(sublayer.sublayers&&!isCategorized&&(!_this.state.onlyVisibleLegend||sublayer.visibility)){if(_this.props.addGroupTitles){var children=sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)}).filter(function(x){return x});if(isEmpty(children)){return null}else{return/*#__PURE__*/React.createElement("div",{className:"map-legend-group",key:sublayer.name},/*#__PURE__*/React.createElement("div",{className:"map-legend-group-title"},sublayer.title||sublayer.name),/*#__PURE__*/React.createElement("div",{className:"map-legend-group-entries"},sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)})))}}else{return sublayer.sublayers.map(function(subsublayer){return _this.printLayerLegend(layer,subsublayer,mapScale)})}}else{if(_this.state.onlyVisibleLegend&&!sublayer.visibility){return null}if((_this.state.onlyVisibleLegend||_this.state.scaleDependentLegend)&&!LayerUtils.layerScaleInRange(sublayer,mapScale)){return null}var request=LayerUtils.getLegendUrl(layer,sublayer,mapScale,_this.props.map,_this.state.bboxDependentLegend,_this.state.scaleDependentLegend,_this.props.extraLegendParameters);return request?/*#__PURE__*/React.createElement("div",{className:"map-legend-legend-entry",key:sublayer.name},/*#__PURE__*/React.createElement("div",null,_this.props.addLayerTitles&&!sublayer.category_sublayer?/*#__PURE__*/React.createElement("div",{className:"map-legend-entry-title"},sublayer.title||sublayer.name):null,/*#__PURE__*/React.createElement("div",{className:"map-legend-entry-image"},/*#__PURE__*/React.createElement(Image,{src:request})))):null}});_this.state.onlyVisibleLegend=props.onlyVisibleLegend;_this.state.bboxDependentLegend=props.bboxDependentLegend;_this.state.scaleDependentLegend=props.scaleDependentLegend;return _this}_inherits(MapLegend,_React$Component);return _createClass(MapLegend,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){if(this.props.active&&!prevProps.active){this.setState({visible:true});// Clear task immediately, visibility is stored as state
14
14
  this.props.setCurrentTask(null)}}},{key:"render",value:function render(){var _this2=this;if(!this.state.visible&&!this.props.lockedWindow){return null}var mapScale=MapUtils.computeForZoom(this.props.map.scales,this.props.map.zoom);var extraControls=[{icon:"eye",callback:function callback(){return _this2.setState(function(state){return{onlyVisibleLegend:!state.onlyVisibleLegend}})},active:this.state.onlyVisibleLegend,title:LocaleUtils.tr("maplegend.onlyvisible")},{icon:"box",callback:function callback(){return _this2.setState(function(state){return{bboxDependentLegend:!state.bboxDependentLegend}})},active:this.state.bboxDependentLegend,title:LocaleUtils.tr("maplegend.bboxdependent")},{icon:"scale",callback:function callback(){return _this2.setState(function(state){return{scaleDependentLegend:!state.scaleDependentLegend}})},active:this.state.scaleDependentLegend,title:LocaleUtils.tr("maplegend.scaledependent")}];return/*#__PURE__*/React.createElement(ResizeableWindow,{dockable:this.props.lockedWindow?false:this.props.geometry.side,extraControls:extraControls,icon:"list-alt",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,maximizeable:false,onClose:this.props.lockedWindow?null:this.onClose,title:LocaleUtils.tr("maplegend.windowtitle")},/*#__PURE__*/React.createElement("div",{className:"map-legend",role:"body"},this.props.layers.map(function(layer){if(_this2.state.onlyVisibleLegend&&!layer.visibility){return null}else if(layer.legendUrl){return _this2.printLayerLegend(layer,layer,mapScale)}else if(layer.color){return/*#__PURE__*/React.createElement("div",{className:"map-legend-legend-entry",key:layer.name},/*#__PURE__*/React.createElement("span",{className:"map-legend-color-box",style:{backgroundColor:layer.color}}),/*#__PURE__*/React.createElement("span",{className:"map-legend-entry-title"},layer.title||layer.name))}else{return null}})))}}])}(React.Component);_defineProperty(MapLegend,"propTypes",{active:PropTypes.bool,/** Whether to add group titles to the legend. */addGroupTitles:PropTypes.bool,/** Whether to add layer titles to the legend. Note that often the legend image itself already contains the layer title. */addLayerTitles:PropTypes.bool,/** Whether to display a BBOX-dependent legend by default. */bboxDependentLegend:PropTypes.bool,/** List of layernames to exclude from the legend. */excludeLayers:PropTypes.array,/** Extra parameters to add to the GetLegendGraphics request. */extraLegendParameters:PropTypes.string,/** Default window geometry with size, position and docking status. A locked window is not closeable and not resizeable. Positive position values (including '0') are related to top (InitialY) and left (InitialX), negative values (including '-0') to bottom (InitialY) and right (InitialX). */geometry:PropTypes.shape({initialWidth:PropTypes.number,initialHeight:PropTypes.number,initialX:PropTypes.number,initialY:PropTypes.number,initiallyDocked:PropTypes.bool,side:PropTypes.string}),layers:PropTypes.array,/** Whether the legend window is locked (always visible, not moveable or closeable). Set position and size via `geometry`. */lockedWindow:PropTypes.bool,map:PropTypes.object,/** Whether to only include enabled layers in the legend by default. */onlyVisibleLegend:PropTypes.bool,/** Whether to display a scale-dependent legend by default. */scaleDependentLegend:PropTypes.bool,setCurrentTask:PropTypes.func});_defineProperty(MapLegend,"defaultProps",{addGroupTitles:false,addLayerTitles:false,bboxDependentLegend:false,excludeLayers:[],onlyVisibleLegend:false,scaleDependentLegend:false,geometry:{initialWidth:320,initialHeight:320,initialX:0,initialY:0,initiallyDocked:false,side:"left"}});export default connect(function(state){return{active:state.task.id==="MapLegend",layers:state.layers.flat,map:state.map}},{setCurrentTask:setCurrentTask})(MapLegend);
@@ -4,7 +4,7 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
- */import React from"react";import{connect}from"react-redux";import PropTypes from"prop-types";import Icon from"../components/Icon";import SideBar from"../components/SideBar";import ThemeLayersListWindow from"../components/ThemeLayersListWindow";import ThemeList from"../components/ThemeList";import InputContainer from"../components/widgets/InputContainer";import ConfigUtils from"../utils/ConfigUtils";import LocaleUtils from"../utils/LocaleUtils";import"./style/ThemeSwitcher.css";/**
7
+ */import React from"react";import ReactDOM from"react-dom";import{connect}from"react-redux";import PropTypes from"prop-types";import Icon from"../components/Icon";import{AppInfosPortalContext}from"../components/PluginsContainer";import SideBar from"../components/SideBar";import ThemeLayersListWindow from"../components/ThemeLayersListWindow";import ThemeList from"../components/ThemeList";import InputContainer from"../components/widgets/InputContainer";import ConfigUtils from"../utils/ConfigUtils";import LocaleUtils from"../utils/LocaleUtils";import"./style/ThemeSwitcher.css";/**
8
8
  * Theme switcher panel.
9
9
  */var ThemeSwitcher=/*#__PURE__*/function(_React$Component){function ThemeSwitcher(){var _this;_classCallCheck(this,ThemeSwitcher);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,ThemeSwitcher,[].concat(args));_defineProperty(_this,"state",{filter:""});_defineProperty(_this,"focusFilterField",function(el){if(el){// Need to wait until slide in transition is over
10
- setTimeout(function(){if(_this.props.currentTask&&_this.props.currentTask.id==="ThemeSwitcher"){el.focus()}},500)}});return _this}_inherits(ThemeSwitcher,_React$Component);return _createClass(ThemeSwitcher,[{key:"render",value:function render(){var _this2=this;var allowAddingOtherThemes=ConfigUtils.getConfigProp("allowAddingOtherThemes",this.props.activeTheme)===true;var showAddThemeButton=allowAddingOtherThemes&&!this.props.hideAddThemeButton;var showAddThemeLayersButton=allowAddingOtherThemes&&!this.props.hideAddThemeLayersButton;var themeFilter=this.props.showThemeFilter?/*#__PURE__*/React.createElement(InputContainer,{className:"theme-switcher-filter"},/*#__PURE__*/React.createElement("input",{onChange:function onChange(ev){return _this2.setState({filter:ev.target.value})},placeholder:LocaleUtils.tr("themeswitcher.filter"),ref:this.focusFilterField,role:"input",type:"text",value:this.state.filter}),/*#__PURE__*/React.createElement(Icon,{icon:"remove",onClick:function onClick(){return _this2.setState({filter:""})},role:"suffix"})):null;var extraTitlebarContent=themeFilter;return/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(SideBar,{extraTitlebarContent:extraTitlebarContent,icon:"themes",id:"ThemeSwitcher",minWidth:"16em",side:this.props.side,title:LocaleUtils.tr("appmenu.items.ThemeSwitcher"),width:this.props.width},function(){return{body:/*#__PURE__*/React.createElement(ThemeList,{activeTheme:_this2.props.activeTheme,allowAddingOtherThemeLayers:showAddThemeLayersButton,allowAddingOtherThemes:showAddThemeButton,collapsibleGroups:_this2.props.collapsibleGroups,filter:_this2.state.filter,showDefaultThemeSelector:_this2.props.showDefaultThemeSelector,showLayerAfterChangeTheme:_this2.props.showLayerAfterChangeTheme})}}),showAddThemeLayersButton?/*#__PURE__*/React.createElement(ThemeLayersListWindow,{windowSize:this.props.themeLayersListWindowSize}):null)}}])}(React.Component);_defineProperty(ThemeSwitcher,"availableIn3D",true);_defineProperty(ThemeSwitcher,"propTypes",{activeTheme:PropTypes.object,/** Whether to allow collapsing theme groups. */collapsibleGroups:PropTypes.bool,currentTask:PropTypes.object,/** Whether to hide the add theme button. Note: the button will also be hidden if the global option `allowAddingOtherThemes` is `false`. */hideAddThemeButton:PropTypes.bool,/** Whether to hide the add theme layers button. Note: the button will also be hidden if the global option `allowAddingOtherThemes` is `false`. */hideAddThemeLayersButton:PropTypes.bool,/** Whether to show an icon to select the default theme/bookmark (of a logged in user). */showDefaultThemeSelector:PropTypes.bool,/** Whether to show the LayerTree by default after switching the theme. */showLayerAfterChangeTheme:PropTypes.bool,/** Wether to show the theme filter field in the top bar. */showThemeFilter:PropTypes.bool,/** The side of the application on which to display the sidebar. */side:PropTypes.string,/** The default window size for the theme layers dialog. */themeLayersListWindowSize:PropTypes.shape({width:PropTypes.number,height:PropTypes.number}),/** Default width as a CSS string. */width:PropTypes.string});_defineProperty(ThemeSwitcher,"defaultProps",{width:"50%",showThemeFilter:true,showDefaultThemeSelector:true,showLayerAfterChangeTheme:false,themeLayersListWindowSize:{width:400,height:300},side:"right"});var selector=function selector(state){return{activeTheme:state.theme.current}};export default connect(selector,{})(ThemeSwitcher);
10
+ setTimeout(function(){if(_this.props.currentTask&&_this.props.currentTask.id==="ThemeSwitcher"){el.focus()}},500)}});return _this}_inherits(ThemeSwitcher,_React$Component);return _createClass(ThemeSwitcher,[{key:"render",value:function render(){var _this2=this;var allowAddingOtherThemes=ConfigUtils.getConfigProp("allowAddingOtherThemes",this.props.activeTheme)===true;var showAddThemeButton=allowAddingOtherThemes&&!this.props.hideAddThemeButton;var showAddThemeLayersButton=allowAddingOtherThemes&&!this.props.hideAddThemeLayersButton;var themeFilter=this.props.showThemeFilter?/*#__PURE__*/React.createElement(InputContainer,{className:"theme-switcher-filter"},/*#__PURE__*/React.createElement("input",{onChange:function onChange(ev){return _this2.setState({filter:ev.target.value})},placeholder:LocaleUtils.tr("themeswitcher.filter"),ref:this.focusFilterField,role:"input",type:"text",value:this.state.filter}),/*#__PURE__*/React.createElement(Icon,{icon:"remove",onClick:function onClick(){return _this2.setState({filter:""})},role:"suffix"})):null;var extraTitlebarContent=themeFilter;return/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(SideBar,{extraTitlebarContent:extraTitlebarContent,icon:"themes",id:"ThemeSwitcher",minWidth:"16em",side:this.props.side,title:LocaleUtils.tr("appmenu.items.ThemeSwitcher"),width:this.props.width},function(){return{body:/*#__PURE__*/React.createElement(ThemeList,{activeTheme:_this2.props.activeTheme,allowAddingOtherThemeLayers:showAddThemeLayersButton,allowAddingOtherThemes:showAddThemeButton,collapsibleGroups:_this2.props.collapsibleGroups,filter:_this2.state.filter,showDefaultThemeSelector:_this2.props.showDefaultThemeSelector,showLayerAfterChangeTheme:_this2.props.showLayerAfterChangeTheme})}}),showAddThemeLayersButton?/*#__PURE__*/React.createElement(ThemeLayersListWindow,{windowSize:this.props.themeLayersListWindowSize}):null,this.props.showActiveTheme&&this.props.activeTheme?(/*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div",{className:"app-info active-theme"},/*#__PURE__*/React.createElement(Icon,{icon:"themes"}),/*#__PURE__*/React.createElement("span",null,this.props.activeTheme.title||this.props.activeTheme.name||this.props.activeTheme.id)),this.context)):null)}}])}(React.Component);_defineProperty(ThemeSwitcher,"contextType",AppInfosPortalContext);_defineProperty(ThemeSwitcher,"availableIn3D",true);_defineProperty(ThemeSwitcher,"propTypes",{activeTheme:PropTypes.object,/** Whether to allow collapsing theme groups. */collapsibleGroups:PropTypes.bool,currentTask:PropTypes.object,/** Whether to hide the add theme button. Note: the button will also be hidden if the global option `allowAddingOtherThemes` is `false`. */hideAddThemeButton:PropTypes.bool,/** Whether to hide the add theme layers button. Note: the button will also be hidden if the global option `allowAddingOtherThemes` is `false`. */hideAddThemeLayersButton:PropTypes.bool,/** Whether to display the currently active theme below the application menu button. Default: false */showActiveTheme:PropTypes.bool,/** Whether to show an icon to select the default theme/bookmark (of a logged in user). */showDefaultThemeSelector:PropTypes.bool,/** Whether to show the LayerTree by default after switching the theme. */showLayerAfterChangeTheme:PropTypes.bool,/** Wether to show the theme filter field in the top bar. */showThemeFilter:PropTypes.bool,/** The side of the application on which to display the sidebar. */side:PropTypes.string,/** The default window size for the theme layers dialog. */themeLayersListWindowSize:PropTypes.shape({width:PropTypes.number,height:PropTypes.number}),/** Default width as a CSS string. */width:PropTypes.string});_defineProperty(ThemeSwitcher,"defaultProps",{width:"50%",showActiveTheme:false,showThemeFilter:true,showDefaultThemeSelector:true,showLayerAfterChangeTheme:false,themeLayersListWindowSize:{width:400,height:300},side:"right"});var selector=function selector(state){return{activeTheme:state.theme.current}};export default connect(selector,{})(ThemeSwitcher);
@@ -1,16 +1,3 @@
1
1
  div.login-user {
2
- position: absolute;
3
- right: 0.25em;
4
- top: 0.25em;
5
- z-index: 1;
6
- color: var(--panel-text-color);
7
- background-color: var(--panel-bg-color);
8
- box-shadow: 0 0 4px rgba(136, 136, 136, 0.5);
9
- padding: 0.25em 0em 0.125em 0em;
10
- display: flex;
11
- }
12
-
13
- div.login-user > span {
14
- flex: 0 0 auto;
15
- padding: 0 0.25em;
2
+ order: 1;
16
3
  }
@@ -5,3 +5,7 @@ div.theme-switcher-filter {
5
5
  color: var(--text-color);
6
6
  margin: 0 0.5em;
7
7
  }
8
+
9
+ div.active-theme {
10
+ order: 0;
11
+ }
@@ -9,4 +9,4 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
9
9
  console.warn("Could not find background layer "+entry.name)}};for(_iterator.s();!(_step=_iterator.n()).done;){if(_loop())continue}}catch(err){_iterator.e(err)}finally{_iterator.f()}if(visibleIdx>=0){bgLayers[visibleIdx].visibility=true}else if(defaultVisibleIdx>=0&&visibleLayer!==""){bgLayers[defaultVisibleIdx].visibility=true}return bgLayers},createThemeLayer:function createThemeLayer(theme,themes){var role=arguments.length>2&&arguments[2]!==undefined?arguments[2]:LayerRole.THEME;var subLayers=arguments.length>3&&arguments[3]!==undefined?arguments[3]:null;var urlParts=url.parse(theme.url,true);// Resolve relative urls
10
10
  if(!urlParts.host){var locationParts=url.parse(window.location.href);urlParts.protocol=locationParts.protocol;urlParts.host=locationParts.host}var sublayerNames=LayerUtils.getSublayerNames({sublayers:subLayers!==null&&subLayers!==void 0?subLayers:theme.sublayers});var baseParams=urlParts.query;var layer={type:"wms",id:theme.id,url:url.format(urlParts),version:theme.version||themes.defaultWMSVersion||"1.3.0",visibility:true,expanded:theme.expanded,name:theme.name,title:theme.title,bbox:theme.bbox,sublayers:subLayers!==null&&subLayers!==void 0?subLayers:theme.sublayers,tiled:theme.tiled,tileSize:theme.tileSize,ratio:!theme.tiled?1:undefined,serverType:"qgis",format:theme.format,rev:+new Date,role:role,attribution:theme.attribution,legendUrl:ThemeUtils.inheritBaseUrlParams(theme.legendUrl,theme.url,baseParams),printUrl:ThemeUtils.inheritBaseUrlParams(theme.printUrl,theme.url,baseParams),featureInfoUrl:ThemeUtils.inheritBaseUrlParams(theme.featureInfoUrl,theme.url,baseParams),infoFormats:theme.infoFormats,mapFormats:theme.availableFormats,layerTreeHiddenSublayers:theme.layerTreeHiddenSublayers,predefinedFilters:(theme.predefinedFilters||[]).filter(function(entry){return Object.keys(entry.filter).find(function(name){return sublayerNames.includes(name)})}),externalLayerMap:_objectSpread(_objectSpread({},theme.externalLayerMap),(theme.externalLayers||[]).reduce(function(res,cur){res[cur.internalLayer]=_objectSpread({},themes.externalLayers.find(function(entry){return entry.name===cur.name}));LayerUtils.completeExternalLayer(res[cur.internalLayer],LayerUtils.searchSubLayer(theme,"name",cur.internalLayer));return res},{})),translations:theme.translations};layer=LayerUtils.recomputeLayerBBox(layer);// Drawing order only makes sense if layer reordering is disabled
11
11
  if(ConfigUtils.getConfigProp("allowReorderingLayers",theme)!==true){layer.drawingOrder=theme.drawingOrder}return layer},inheritBaseUrlParams:function inheritBaseUrlParams(capabilityUrl,baseUrl,baseParams){if(!capabilityUrl){return baseUrl}if(capabilityUrl.split("?")[0]===baseUrl.split("?")[0]){var parts=url.parse(capabilityUrl,true);parts.query=_objectSpread(_objectSpread({},baseParams),parts.query);return url.format(parts)}return capabilityUrl},searchThemes:function searchThemes(themes,searchtext){var filter=new RegExp(removeDiacritics(searchtext).replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&"),"i");var matches=[];var _searchThemeGroup=function searchThemeGroup(themeGroup){(themeGroup.subdirs||[]).forEach(function(subdir){return _searchThemeGroup(subdir,filter)});matches.push.apply(matches,_toConsumableArray((themeGroup.items||[]).filter(function(item){return removeDiacritics(item.title).match(filter)||removeDiacritics(item.keywords||"").match(filter)||removeDiacritics(item["abstract"]||"").match(filter)})))};_searchThemeGroup(themes,filter);return isEmpty(matches)?[]:[{id:"themes",titlemsgid:"search.themes",type:SearchResultType.THEME,items:matches.map(function(theme){return{id:theme.id,text:theme.title,theme:theme,layer:ThemeUtils.createThemeLayer(theme,themes),thumbnail:ConfigUtils.getAssetsPath()+"/"+theme.thumbnail}})}]},searchThemeLayers:function searchThemeLayers(themes,searchtext){var filter=new RegExp(removeDiacritics(searchtext).replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&"),"i");var matches=[];var _searchLayer=function searchLayer(theme,layer){var path=arguments.length>2&&arguments[2]!==undefined?arguments[2]:[];(layer.sublayers||[]).forEach(function(sublayer,idx){var subpath=[].concat(_toConsumableArray(path),[idx]);if(removeDiacritics(sublayer.name).match(filter)||removeDiacritics(sublayer.title).match(filter)){// Clone theme, ensuring path to layer is visible
12
- var newtheme=_objectSpread({},theme);var cur=newtheme;var _loop2=function _loop2(i){var isMutuallyExclusive=cur.mutuallyExclusive;cur.sublayers=cur.sublayers.map(function(entry,j){return _objectSpread(_objectSpread({},entry),{},{visibility:j===subpath[i]||entry.visibility&&!isMutuallyExclusive})});cur=cur.sublayers[subpath[i]]};for(var i=0;i<subpath.length;++i){_loop2(i)}matches.push({theme:newtheme,layer:ThemeUtils.createThemeLayer(newtheme,themes,LayerRole.USERLAYER,[cur])})}_searchLayer(theme,sublayer,subpath)})};var _searchThemeGroup2=function searchThemeGroup(themeGroup){(themeGroup.subdirs||[]).forEach(function(subdir){return _searchThemeGroup2(subdir,filter)});(themeGroup.items||[]).forEach(function(item){return _searchLayer(item,item)})};_searchThemeGroup2(themes,filter);return isEmpty(matches)?[]:[{id:"themelayers",titlemsgid:"search.themelayers",type:SearchResultType.THEMELAYER,items:matches.map(function(result){return{id:result.layer.id+":"+result.layer.sublayers[0].name,text:result.layer.title+": "+result.layer.sublayers[0].title,layer:result.layer,theme:result.theme}})}]},getThemeNames:function getThemeNames(themes){var names=(themes.items||[]).reduce(function(res,theme){return _objectSpread(_objectSpread({},res),{},_defineProperty({},theme.id,theme.title))},{});(themes.subdirs||[]).forEach(function(group){Object.assign(names,ThemeUtils.getThemeNames(group))});return names},themeFlagsAllowed:function themeFlagsAllowed(theme,flagWhitelist,flagBlacklist){var themeFlags=(theme===null||theme===void 0?void 0:theme.flags)||[];if(flagBlacklist&&flagBlacklist.find(function(flag){return themeFlags.includes(flag)})!==undefined){return false}if(flagWhitelist&&flagWhitelist.find(function(flag){return themeFlags.includes(flag)})===undefined){return false}return true},allowedItems:function allowedItems(items,theme){var filter=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;return(items||[]).map(function(item){if(item.subitems){var subitems=ThemeUtils.allowedItems(item.subitems,items,filter).filter(Boolean);if(!isEmpty(subitems)){return _objectSpread(_objectSpread({},item),{},{subitems:subitems})}else{return null}}else{if(filter&&!filter(item)){return null}if(theme){if(!ThemeUtils.themeFlagsAllowed(theme,item.themeFlagWhitelist,item.themeFlagBlacklist)){return null}if(item.themeBlacklist&&(item.themeBlacklist.includes(theme.title)||item.themeBlacklist.includes(theme.name))){return null}if(item.themeWhitelist&&!(item.themeWhitelist.includes(theme.title)||item.themeWhitelist.includes(theme.name))){return null}if(item.requireAuth&&!ConfigUtils.getConfigProp("username")){return null}}return item}}).filter(Boolean)},applyTranslations:function applyTranslations(group){return _objectSpread(_objectSpread({},group),{},{subdirs:group.subdirs?group.subdirs.map(ThemeUtils.applyTranslations):null,items:group.items?group.items.map(function(item){var _item$translations$th,_item$translations;return _objectSpread(_objectSpread({},LayerUtils.applyTranslations(item,item.translations)),{},{title:(_item$translations$th=(_item$translations=item.translations)===null||_item$translations===void 0||(_item$translations=_item$translations.theme)===null||_item$translations===void 0?void 0:_item$translations.title)!==null&&_item$translations$th!==void 0?_item$translations$th:item.title})}):null})}};export default ThemeUtils;
12
+ var newtheme=_objectSpread({},theme);var cur=newtheme;var _loop2=function _loop2(i){var isMutuallyExclusive=cur.mutuallyExclusive;cur.sublayers=cur.sublayers.map(function(entry,j){return _objectSpread(_objectSpread({},entry),{},{visibility:j===subpath[i]||entry.visibility&&!isMutuallyExclusive})});cur=cur.sublayers[subpath[i]]};for(var i=0;i<subpath.length;++i){_loop2(i)}matches.push({theme:newtheme,layer:ThemeUtils.createThemeLayer(newtheme,themes,LayerRole.USERLAYER,[cur])})}_searchLayer(theme,sublayer,subpath)})};var _searchThemeGroup2=function searchThemeGroup(themeGroup){(themeGroup.subdirs||[]).forEach(function(subdir){return _searchThemeGroup2(subdir,filter)});(themeGroup.items||[]).forEach(function(item){return _searchLayer(item,item)})};_searchThemeGroup2(themes,filter);return isEmpty(matches)?[]:[{id:"themelayers",titlemsgid:"search.themelayers",type:SearchResultType.THEMELAYER,items:matches.map(function(result){return{id:result.layer.id+":"+result.layer.sublayers[0].name,text:result.layer.title+": "+result.layer.sublayers[0].title,layer:result.layer,theme:result.theme}})}]},getThemeNames:function getThemeNames(themes){var names=(themes.items||[]).reduce(function(res,theme){return _objectSpread(_objectSpread({},res),{},_defineProperty({},theme.id,theme.title))},{});(themes.subdirs||[]).forEach(function(group){Object.assign(names,ThemeUtils.getThemeNames(group))});return names},themeFlagsAllowed:function themeFlagsAllowed(theme,flagWhitelist,flagBlacklist){var themeFlags=(theme===null||theme===void 0?void 0:theme.flags)||[];if(flagBlacklist&&flagBlacklist.find(function(flag){return themeFlags.includes(flag)})!==undefined){return false}if(flagWhitelist&&flagWhitelist.find(function(flag){return themeFlags.includes(flag)})===undefined){return false}return true},allowedItems:function allowedItems(items,theme){var filter=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;return(items||[]).map(function(item){if(item.subitems){var subitems=ThemeUtils.allowedItems(item.subitems,theme,filter).filter(Boolean);if(!isEmpty(subitems)){return _objectSpread(_objectSpread({},item),{},{subitems:subitems})}else{return null}}else{if(filter&&!filter(item)){return null}if(theme){if(!ThemeUtils.themeFlagsAllowed(theme,item.themeFlagWhitelist,item.themeFlagBlacklist)){return null}if(item.themeBlacklist&&(item.themeBlacklist.includes(theme.title)||item.themeBlacklist.includes(theme.name))){return null}if(item.themeWhitelist&&!(item.themeWhitelist.includes(theme.title)||item.themeWhitelist.includes(theme.name))){return null}if(item.requireAuth&&!ConfigUtils.getConfigProp("username")){return null}}return item}}).filter(Boolean)},applyTranslations:function applyTranslations(group){return _objectSpread(_objectSpread({},group),{},{subdirs:group.subdirs?group.subdirs.map(ThemeUtils.applyTranslations):null,items:group.items?group.items.map(function(item){var _item$translations$th,_item$translations;return _objectSpread(_objectSpread({},LayerUtils.applyTranslations(item,item.translations)),{},{title:(_item$translations$th=(_item$translations=item.translations)===null||_item$translations===void 0||(_item$translations=_item$translations.theme)===null||_item$translations===void 0?void 0:_item$translations.title)!==null&&_item$translations$th!==void 0?_item$translations$th:item.title})}):null})}};export default ThemeUtils;