qwc2 2025.12.18 → 2025.12.19

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.
@@ -0,0 +1,147 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
5
+ function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
6
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
7
+ function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
8
+ function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
9
+ function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
10
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
11
+ function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
12
+ function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
13
+ function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
14
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
15
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
16
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
17
+ /**
18
+ * Copyright 2024 Sourcepole AG
19
+ * All rights reserved.
20
+ *
21
+ * This source code is licensed under the BSD-style license found in the
22
+ * LICENSE file in the root directory of this source tree.
23
+ */
24
+
25
+ import React from 'react';
26
+ import ol from 'openlayers';
27
+ import PropTypes from 'prop-types';
28
+ import viewconeIcon from '../resources/viewcone.svg';
29
+ import OlLayer from './map/OlLayer';
30
+ import './style/OverviewMapButton.css';
31
+ var OverviewMapButton = /*#__PURE__*/function (_React$Component) {
32
+ function OverviewMapButton(props) {
33
+ var _this;
34
+ _classCallCheck(this, OverviewMapButton);
35
+ _this = _callSuper(this, OverviewMapButton, [props]);
36
+ _defineProperty(_this, "state", {
37
+ collapsed: true
38
+ });
39
+ _defineProperty(_this, "initOverviewMap", function (el) {
40
+ if (el) {
41
+ _this.map = new ol.Map({
42
+ layers: [_this.viewConeLayer],
43
+ controls: [],
44
+ target: el
45
+ });
46
+ _this.setupView();
47
+ }
48
+ });
49
+ _defineProperty(_this, "setupView", function () {
50
+ var overviewView = new ol.View({
51
+ enableRotation: false,
52
+ projection: _this.props.projection
53
+ });
54
+ _this.map.setView(overviewView);
55
+ _this.updateViewCone();
56
+ });
57
+ _defineProperty(_this, "updateViewCone", function () {
58
+ if (_this.props.center) {
59
+ _this.map.getView().setCenter(_this.props.center);
60
+ _this.map.getView().setResolution(_this.props.resolution);
61
+ _this.viewConeFeature.getGeometry().setCoordinates(_this.props.center);
62
+ _this.viewConeFeature.set('rotation', _this.props.coneRotation, true);
63
+ _this.viewConeLayer.getSource().changed();
64
+ }
65
+ });
66
+ _this.map = null;
67
+ _this.viewConeFeature = new ol.Feature(new ol.geom.Point([0, 0]));
68
+ _this.viewConeLayer = new ol.layer.Vector({
69
+ source: new ol.source.Vector({
70
+ features: [_this.viewConeFeature]
71
+ }),
72
+ style: function style(feature) {
73
+ return new ol.style.Style({
74
+ fill: new ol.style.Fill({
75
+ color: 'white'
76
+ }),
77
+ stroke: new ol.style.Stroke({
78
+ color: 'red',
79
+ width: 2
80
+ }),
81
+ image: new ol.style.Icon({
82
+ anchor: [0.5, 1],
83
+ anchorXUnits: 'fraction',
84
+ anchorYUnits: 'fraction',
85
+ src: viewconeIcon,
86
+ rotation: feature.get('rotation'),
87
+ scale: 2
88
+ })
89
+ });
90
+ },
91
+ zIndex: 10000
92
+ });
93
+ return _this;
94
+ }
95
+ _inherits(OverviewMapButton, _React$Component);
96
+ return _createClass(OverviewMapButton, [{
97
+ key: "componentDidUpdate",
98
+ value: function componentDidUpdate(prevProps, prevState) {
99
+ if (this.props.projection !== prevProps.projection) {
100
+ this.setupView();
101
+ }
102
+ if (this.map && (this.props.center !== prevProps.center || this.props.resolution !== prevProps.resolution || this.props.coneRotation !== prevProps.coneRotation)) {
103
+ this.updateViewCone();
104
+ }
105
+ }
106
+ }, {
107
+ key: "render",
108
+ value: function render() {
109
+ var _this2 = this;
110
+ var style = {
111
+ display: this.state.collapsed ? 'none' : 'initial'
112
+ };
113
+ return [/*#__PURE__*/React.createElement("div", {
114
+ className: "overview-map",
115
+ key: "OverivewMap"
116
+ }, /*#__PURE__*/React.createElement("div", {
117
+ className: "ol-overviewmap-map",
118
+ ref: this.initOverviewMap,
119
+ style: style
120
+ }), /*#__PURE__*/React.createElement("button", {
121
+ onClick: function onClick() {
122
+ return _this2.setState(function (state) {
123
+ return {
124
+ collapsed: !state.collapsed
125
+ };
126
+ });
127
+ },
128
+ type: "button"
129
+ }, this.state.collapsed ? '«' : '»')), this.map && this.props.layer ? /*#__PURE__*/React.createElement(OlLayer, {
130
+ key: this.props.layer.name,
131
+ map: this.map,
132
+ options: _objectSpread(_objectSpread({}, this.props.layer), {}, {
133
+ visibility: true
134
+ }),
135
+ projection: this.props.projection
136
+ }) : null];
137
+ }
138
+ }]);
139
+ }(React.Component);
140
+ _defineProperty(OverviewMapButton, "propTypes", {
141
+ center: PropTypes.array,
142
+ coneRotation: PropTypes.number,
143
+ layer: PropTypes.object,
144
+ projection: PropTypes.string,
145
+ resolution: PropTypes.number
146
+ });
147
+ export { OverviewMapButton as default };
@@ -1,11 +1,11 @@
1
- div.overview-map-3d {
1
+ div.overview-map {
2
2
  position: absolute;
3
3
  bottom: 0;
4
4
  right: 0;
5
5
  z-index: 101;
6
6
  }
7
7
 
8
- div.overview-map-3d > button {
8
+ div.overview-map > button {
9
9
  font-size: initial!important;
10
10
  right: 0.25em;
11
11
  bottom: 0.25em;
@@ -21,7 +21,7 @@ div.overview-map-3d > button {
21
21
  font-weight: bold;
22
22
  }
23
23
 
24
- div.overview-map-3d > div.ol-overviewmap-map-3d {
24
+ div.overview-map > div.ol-overviewmap-map {
25
25
  position: absolute;
26
26
  right: 1px;
27
27
  bottom: 1px;
@@ -32,6 +32,6 @@ div.overview-map-3d > div.ol-overviewmap-map-3d {
32
32
  border: 1px solid var(--border-color);
33
33
  }
34
34
 
35
- div.overview-map-3d.ol-collapsed > div.ol-overviewmap-map-3d {
35
+ div.overview-map.ol-collapsed > div.ol-overviewmap-map {
36
36
  display: none;
37
37
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2025.12.18",
3
+ "version": "2025.12.19",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
@@ -67,16 +67,16 @@ import './style/Redlining.css';
67
67
  * "pluginData": {
68
68
  * "geometryLinks": [
69
69
  * {
70
- * "name": "<geomLinkName>", // Link name referenced in theme item
71
- * "title": "<geomLinkTitle>", // Link title, displayed in the selection combo
72
- * "geomType": ["<geomType>", "<geomType>"] // Supported geometry types (Point, LineString, Polygon)
73
- * "format": "wkt|geojson", // Format of data to send to application
74
- * "url": "<targetApplicationUrl>", // Application target URL, receiving the POST submit. Can contain the $username$ placeholder parameter.
75
- * "params": {"<key>": "<value>", ...} // Optional: additional form parameters to post to URL
76
- * "target": "<target>" | { // Optional: form POST target which to display the result
77
- * "iframedialog": true, // Use an iframe dialog
78
- * "w": <dialogWidth>, // Dialog width
79
- * "h": <dialogHeight> // Dialog height
70
+ * "name": "<geomLinkName>", // Link name referenced in theme item
71
+ * "title": "<geomLinkTitle>", // Link title, displayed in the selection combo
72
+ * "geomType": ["<geomType>", "<geomType>"], // Supported geometry types (Point, LineString, Polygon)
73
+ * "format": "wkt|geojson", // Format of data to send to application
74
+ * "url": "<targetApplicationUrl>", // Application target URL, receiving the POST submit. Can contain the $username$ placeholder parameter.
75
+ * "params": {"<key>": "<value>", ...} // Optional: additional form parameters to post to URL
76
+ * "target": "<target>" | { // Optional: form POST target which to display the result
77
+ * "iframedialog": true, // Use an iframe dialog
78
+ * "w": <dialogWidth>, // Dialog width
79
+ * "h": <dialogHeight> // Dialog height
80
80
  * }
81
81
  * }
82
82
  * ]
@@ -1,4 +1,6 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2
4
  function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
3
5
  function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
4
6
  function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
@@ -29,12 +31,12 @@ import PropTypes from 'prop-types';
29
31
  import { zoomToExtent } from '../actions/map';
30
32
  import { setCurrentTask } from '../actions/task';
31
33
  import Icon from '../components/Icon';
34
+ import OverviewMapButton from '../components/OverviewMapButton';
32
35
  import ResizeableWindow from '../components/ResizeableWindow';
33
- import LayerRegistry from '../components/map/layers/index';
36
+ import OlLayer from '../components/map/OlLayer';
34
37
  import InputContainer from '../components/widgets/InputContainer';
35
38
  import ConfigUtils from '../utils/ConfigUtils';
36
39
  import CoordinatesUtils from '../utils/CoordinatesUtils';
37
- import LayerUtils from '../utils/LayerUtils';
38
40
  import LocaleUtils from '../utils/LocaleUtils';
39
41
  import MapUtils from '../utils/MapUtils';
40
42
  import MiscUtils from '../utils/MiscUtils';
@@ -42,6 +44,27 @@ import './style/ObliqueView.css';
42
44
 
43
45
  /**
44
46
  * Display oblique satellite imagery.
47
+ *
48
+ * Requires `obliqueImageryServiceUrl` in `config.json` to point to a `qwc-oblique-imagery-service`.
49
+ *
50
+ * You can configure oblique imagery datasets in the `obliqueDatasets` entry in a QWC theme configuration as follows:
51
+ * ```
52
+ * {
53
+ * ...
54
+ * "obliqueDatasets": [{
55
+ * {
56
+ * "name": "<dataset_name>",
57
+ * "default": <false|true>,
58
+ * "backgroundLayer": "<background_layer_name>",
59
+ * "backgroundOpacity": <0-255>,
60
+ * "title": "<dataset_title>",
61
+ * "titleMsgId": "<dataset_title_msgid>"
62
+ * },
63
+ * ...
64
+ * ]
65
+ * }
66
+ * ```
67
+ * where `dataset_name` is the the name of a dataset configured in the `qwc-oblique-imagery-service`.
45
68
  */
46
69
  var ObliqueView = /*#__PURE__*/function (_React$Component) {
47
70
  function ObliqueView(props) {
@@ -93,6 +116,9 @@ var ObliqueView = /*#__PURE__*/function (_React$Component) {
93
116
  /* eslint-disable-next-line */
94
117
  console.warn("Failed to load dataset config");
95
118
  });
119
+ } else {
120
+ _this.obliqueImageryLayer.setSource(null);
121
+ _this.closestImage = null;
96
122
  }
97
123
  });
98
124
  _defineProperty(_this, "setupLayer", function () {
@@ -108,7 +134,6 @@ var ObliqueView = /*#__PURE__*/function (_React$Component) {
108
134
  }, 0);
109
135
  _this.map.setView(new ol.View({
110
136
  projection: projection,
111
- // extent: datasetConfig.extent,
112
137
  center: ol.extent.getCenter(datasetConfig.extent),
113
138
  rotation: _this.getRotation() / 180 * Math.PI,
114
139
  zoom: zoom,
@@ -119,42 +144,25 @@ var ObliqueView = /*#__PURE__*/function (_React$Component) {
119
144
  _this.setState({
120
145
  currentZoom: zoom
121
146
  });
122
- var layers = [];
123
- var themeConfig = _this.props.theme.obliqueDatasets.find(function (entry) {
124
- return entry.name === _this.state.selectedDataset;
125
- });
126
- if (themeConfig.backgroundLayer) {
127
- var _themeConfig$backgrou;
128
- var layerConfig = LayerUtils.splitLayerUrlParam(themeConfig.backgroundLayer);
129
- layerConfig.version = _this.props.themes.defaultWMSVersion || "1.3.0";
130
- layerConfig.opacity = (_themeConfig$backgrou = themeConfig.backgroundOpacity) !== null && _themeConfig$backgrou !== void 0 ? _themeConfig$backgrou : 127;
131
- var layerCreator = LayerRegistry[layerConfig.type];
132
- if (layerCreator) {
133
- layers.push(layerCreator.create(layerConfig, _this.map));
134
- }
135
- }
136
- _this.obliqueImageryLayer = new ol.layer.Tile({
137
- source: new ol.source.XYZ({
138
- projection: projection,
139
- tileGrid: new ol.tilegrid.TileGrid({
140
- extent: datasetConfig.extent,
141
- resolutions: datasetConfig.resolutions,
142
- tileSize: datasetConfig.tileSize,
143
- origin: datasetConfig.origin
144
- }),
145
- url: datasetConfig.url,
146
- crossOrigin: "anonymous",
147
- tileLoadFunction: function tileLoadFunction(tile, src) {
148
- var _this$closestImage;
149
- if (((_this$closestImage = _this.closestImage) !== null && _this$closestImage !== void 0 ? _this$closestImage : null) !== null) {
150
- src += "?img=" + _this.closestImage;
151
- }
152
- tile.getImage().src = src.replace('{direction}', _this.state.currentDirection);
147
+ _this.obliqueImageryLayer.setSource(new ol.source.XYZ({
148
+ projection: projection,
149
+ tileGrid: new ol.tilegrid.TileGrid({
150
+ extent: datasetConfig.extent,
151
+ resolutions: datasetConfig.resolutions,
152
+ tileSize: datasetConfig.tileSize,
153
+ origin: datasetConfig.origin
154
+ }),
155
+ url: datasetConfig.url,
156
+ crossOrigin: "anonymous",
157
+ tileLoadFunction: function tileLoadFunction(tile, src) {
158
+ var _this$closestImage;
159
+ if (((_this$closestImage = _this.closestImage) !== null && _this$closestImage !== void 0 ? _this$closestImage : null) !== null) {
160
+ src += "?img=" + _this.closestImage;
153
161
  }
154
- })
155
- });
156
- layers.push(_this.obliqueImageryLayer);
157
- _this.map.setLayers(layers);
162
+ tile.getImage().src = src.replace('{direction}', _this.state.currentDirection);
163
+ }
164
+ }));
165
+ _this.searchClosestImage();
158
166
  });
159
167
  _defineProperty(_this, "searchClosestImage", function () {
160
168
  var _this$state$datasetCo;
@@ -244,8 +252,9 @@ var ObliqueView = /*#__PURE__*/function (_React$Component) {
244
252
  return null;
245
253
  });
246
254
  });
255
+ _this.obliqueImageryLayer = new ol.layer.Tile();
256
+ _this.map.addLayer(_this.obliqueImageryLayer);
247
257
  _this.closestImage = null;
248
- _this.obliqueImageryLayer = null;
249
258
  _this.state = ObliqueView.defaultState;
250
259
  _this.focusedMap = null;
251
260
  return _this;
@@ -270,7 +279,7 @@ var ObliqueView = /*#__PURE__*/function (_React$Component) {
270
279
  });
271
280
  this.props.setCurrentTask(null);
272
281
  }
273
- if (this.props.active && this.props.theme && this.props.theme !== prevProps.theme || this.props.active && !prevProps.active) {
282
+ if (this.state.active && this.props.theme && (this.props.theme !== prevProps.theme || !prevState.active)) {
274
283
  var _datasets$find$name, _datasets$find, _datasets$;
275
284
  var datasets = this.props.theme.obliqueDatasets || [];
276
285
  var defaultDataset = (_datasets$find$name = (_datasets$find = datasets.find(function (entry) {
@@ -283,8 +292,6 @@ var ObliqueView = /*#__PURE__*/function (_React$Component) {
283
292
  });
284
293
  }
285
294
  if (this.state.selectedDataset !== prevState.selectedDataset) {
286
- this.closestImage = null;
287
- this.obliqueImageryLayer = null;
288
295
  this.queryDatasetConfig();
289
296
  }
290
297
  if (this.state.datasetConfig && this.state.datasetConfig !== prevState.datasetConfig) {
@@ -310,7 +317,9 @@ var ObliqueView = /*#__PURE__*/function (_React$Component) {
310
317
  }, {
311
318
  key: "render",
312
319
  value: function render() {
313
- var _this2 = this;
320
+ var _this2 = this,
321
+ _obliqueConfig$backgr,
322
+ _this$state$selectedD;
314
323
  if (!this.state.active) {
315
324
  return null;
316
325
  }
@@ -331,6 +340,12 @@ var ObliqueView = /*#__PURE__*/function (_React$Component) {
331
340
  title: LocaleUtils.tr("common.lock2dview"),
332
341
  active: this.state.viewsLocked
333
342
  }];
343
+ var obliqueConfig = this.props.theme.obliqueDatasets.find(function (entry) {
344
+ return entry.name === _this2.state.selectedDataset;
345
+ });
346
+ var basemap = this.props.themes.backgroundLayers.find(function (entry) {
347
+ return entry.name === (obliqueConfig === null || obliqueConfig === void 0 ? void 0 : obliqueConfig.backgroundLayer);
348
+ });
334
349
  return /*#__PURE__*/React.createElement(ResizeableWindow, {
335
350
  dockable: this.props.geometry.side,
336
351
  extraControls: extraControls,
@@ -419,9 +434,39 @@ var ObliqueView = /*#__PURE__*/function (_React$Component) {
419
434
  onClick: function onClick() {
420
435
  return _this2.changeZoom(-1);
421
436
  }
422
- })), /*#__PURE__*/React.createElement("div", {
437
+ })), basemap && this.state.datasetConfig ? /*#__PURE__*/React.createElement(OlLayer, {
438
+ map: this.map,
439
+ options: _objectSpread(_objectSpread({}, basemap), {}, {
440
+ opacity: (_obliqueConfig$backgr = obliqueConfig.backgroundOpacity) !== null && _obliqueConfig$backgr !== void 0 ? _obliqueConfig$backgr : 127
441
+ }),
442
+ projection: this.state.datasetConfig.crs,
443
+ zIndex: -1
444
+ }) : null, /*#__PURE__*/React.createElement("div", {
423
445
  className: "obliqueview-bottombar"
424
- }, this.renderScaleChooser())));
446
+ }, /*#__PURE__*/React.createElement("select", {
447
+ onChange: function onChange(ev) {
448
+ return _this2.setState({
449
+ selectedDataset: ev.target.value
450
+ });
451
+ },
452
+ value: (_this$state$selectedD = this.state.selectedDataset) !== null && _this$state$selectedD !== void 0 ? _this$state$selectedD : ""
453
+ }, (this.props.theme.obliqueDatasets || []).map(function (entry) {
454
+ var _entry$title;
455
+ return /*#__PURE__*/React.createElement("option", {
456
+ key: entry.name,
457
+ value: entry.name
458
+ }, LocaleUtils.trWithFallback(entry.titleMsgId, (_entry$title = entry.title) !== null && _entry$title !== void 0 ? _entry$title : entry.name));
459
+ })), /*#__PURE__*/React.createElement("span", {
460
+ className: "obliqueview-bottombar-spacer"
461
+ }), this.renderScaleChooser(), /*#__PURE__*/React.createElement("span", {
462
+ className: "obliqueview-bottombar-spacer"
463
+ }), basemap && this.state.datasetConfig ? /*#__PURE__*/React.createElement(OverviewMapButton, {
464
+ center: this.state.currentCenter,
465
+ coneRotation: this.getRotation() / 180 * Math.PI,
466
+ layer: basemap,
467
+ projection: this.state.datasetConfig.crs,
468
+ resolution: MapUtils.computeForZoom(this.state.datasetConfig.resolutions, this.state.currentZoom) * 0.25
469
+ }) : null)));
425
470
  }
426
471
  }]);
427
472
  }(React.Component);
@@ -293,7 +293,7 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
293
293
  ev.feature.set('shape', _this.props.redlining.geomType);
294
294
  _this.updateFeatureStyle(ev.feature);
295
295
  _this.toggleFeatureMeasurements(ev.feature);
296
- _this.selectFeatures([ev.feature]);
296
+ _this.selectFeatures([ev.feature], false);
297
297
  }, _this);
298
298
  drawInteraction.on('drawend', function (ev) {
299
299
  _this.commitFeatures([ev.feature], _this.props.redlining, true);
@@ -428,7 +428,7 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
428
428
  evt.feature.set('shape', _this.props.redlining.geomType);
429
429
  _this.updateFeatureStyle(evt.feature);
430
430
  _this.toggleFeatureMeasurements(evt.feature);
431
- _this.selectFeatures([evt.feature]);
431
+ _this.selectFeatures([evt.feature], false);
432
432
  }, _this);
433
433
  drawInteraction.on('drawend', function () {
434
434
  // Draw end
@@ -1,6 +1,4 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
2
  function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
5
3
  function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
6
4
  function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
@@ -23,84 +21,38 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
23
21
  */
24
22
 
25
23
  import React from 'react';
26
- import ol from 'openlayers';
27
24
  import PropTypes from 'prop-types';
28
- import OlLayer from '../../components/map/OlLayer';
29
- import viewconeIcon from '../../resources/viewcone.svg';
30
- import './style/OverviewMap3D.css';
25
+ import OverviewMapButton from '../../components/OverviewMapButton';
31
26
 
32
27
  /**
33
28
  * Overview map for the 3D map.
34
29
  */
35
30
  var OverviewMap3D = /*#__PURE__*/function (_React$Component) {
36
- function OverviewMap3D(props) {
31
+ function OverviewMap3D() {
37
32
  var _this;
38
33
  _classCallCheck(this, OverviewMap3D);
39
- _this = _callSuper(this, OverviewMap3D, [props]);
34
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
35
+ args[_key] = arguments[_key];
36
+ }
37
+ _this = _callSuper(this, OverviewMap3D, [].concat(args));
40
38
  _defineProperty(_this, "state", {
41
- collapsed: true
42
- });
43
- _defineProperty(_this, "initOverviewMap", function (el) {
44
- if (el) {
45
- _this.map = new ol.Map({
46
- layers: [_this.viewConeLayer],
47
- controls: [],
48
- target: el
49
- });
50
- _this.setupView();
51
- }
52
- });
53
- _defineProperty(_this, "setupView", function () {
54
- var overviewView = new ol.View({
55
- enableRotation: false,
56
- projection: _this.props.sceneContext.mapCrs
57
- });
58
- _this.map.setView(overviewView);
59
- _this.updateViewCone();
39
+ center: null,
40
+ resolution: null,
41
+ coneAngle: null
60
42
  });
61
43
  _defineProperty(_this, "updateViewCone", function () {
62
44
  var _scene$view$controls$, _scene$view$controls, _scene$view$controls$2;
63
- if (!_this.map) {
64
- return;
65
- }
66
45
  var scene = _this.props.sceneContext.scene;
67
46
  var x = scene.view.camera.position.x;
68
47
  var y = scene.view.camera.position.y;
69
48
  var azimuth = (_scene$view$controls$ = (_scene$view$controls = scene.view.controls) === null || _scene$view$controls === void 0 || (_scene$view$controls$2 = _scene$view$controls.getAzimuthalAngle) === null || _scene$view$controls$2 === void 0 ? void 0 : _scene$view$controls$2.call(_scene$view$controls)) !== null && _scene$view$controls$ !== void 0 ? _scene$view$controls$ : 0;
70
49
  var cameraHeight = scene.view.camera.position.z;
71
50
  var resolution = cameraHeight / 100;
72
- _this.map.getView().setCenter([x, y]);
73
- _this.map.getView().setResolution(resolution);
74
- _this.viewConeFeature.getGeometry().setCoordinates([x, y]);
75
- _this.viewConeFeature.set('rotation', -azimuth, true);
76
- _this.viewConeLayer.getSource().changed();
77
- });
78
- _this.map = null;
79
- _this.viewConeFeature = new ol.Feature(new ol.geom.Point([0, 0]));
80
- _this.viewConeLayer = new ol.layer.Vector({
81
- source: new ol.source.Vector({
82
- features: [_this.viewConeFeature]
83
- }),
84
- style: function style(feature) {
85
- return new ol.style.Style({
86
- fill: new ol.style.Fill({
87
- color: 'white'
88
- }),
89
- stroke: new ol.style.Stroke({
90
- color: 'red',
91
- width: 2
92
- }),
93
- image: new ol.style.Icon({
94
- anchor: [0.5, 1],
95
- anchorXUnits: 'fraction',
96
- anchorYUnits: 'fraction',
97
- src: viewconeIcon,
98
- rotation: feature.get('rotation'),
99
- scale: 2
100
- })
101
- });
102
- },
103
- zIndex: 10000
51
+ _this.setState({
52
+ center: [x, y],
53
+ resolution: resolution,
54
+ coneAngle: -azimuth
55
+ });
104
56
  });
105
57
  return _this;
106
58
  }
@@ -110,62 +62,35 @@ var OverviewMap3D = /*#__PURE__*/function (_React$Component) {
110
62
  value: function componentDidMount() {
111
63
  this.props.sceneContext.scene.view.controls.addEventListener('change', this.updateViewCone);
112
64
  }
65
+ }, {
66
+ key: "componentWillUnmount",
67
+ value: function componentWillUnmount() {
68
+ this.props.sceneContext.scene.view.controls.removeEventListener('change', this.updateViewCone);
69
+ }
113
70
  }, {
114
71
  key: "componentDidUpdate",
115
72
  value: function componentDidUpdate(prevProps, prevState) {
116
73
  if (this.props.sceneContext.mapCrs !== prevProps.sceneContext.mapCrs) {
117
74
  this.setupView();
118
75
  }
119
- if (this.map) {
120
- if (this.state.center !== prevState.center || this.state.azimuth !== prevState.azimuth) {
121
- this.map.getView().setCenter(this.state.center);
122
- this.viewConeFeature.getGeometry().setCoordinates(this.state.center);
123
- this.viewConeFeature.set('rotation', -this.state.azimuth, true);
124
- this.viewConeLayer.getSource().changed();
125
- }
126
- if (this.state.resolution !== prevState.resolution) {
127
- this.map.getView().setResolution(this.state.resolution);
128
- }
129
- }
130
76
  }
131
77
  }, {
132
78
  key: "render",
133
79
  value: function render() {
134
- var _this$props$sceneCont,
135
- _this2 = this;
136
- var style = {
137
- display: this.state.collapsed ? 'none' : 'initial'
138
- };
80
+ var _this$props$sceneCont;
139
81
  var baseLayer = this.props.sceneContext.baseLayers.find(function (l) {
140
82
  return l.visibility === true;
141
83
  });
142
84
  var overviewLayer = (_this$props$sceneCont = this.props.sceneContext.baseLayers.find(function (l) {
143
85
  return l.overview === true;
144
86
  })) !== null && _this$props$sceneCont !== void 0 ? _this$props$sceneCont : baseLayer;
145
- return [/*#__PURE__*/React.createElement("div", {
146
- className: "overview-map-3d",
147
- key: "map3d-overview-map"
148
- }, /*#__PURE__*/React.createElement("div", {
149
- className: "ol-overviewmap-map-3d",
150
- ref: this.initOverviewMap,
151
- style: style
152
- }), /*#__PURE__*/React.createElement("button", {
153
- onClick: function onClick() {
154
- return _this2.setState(function (state) {
155
- return {
156
- collapsed: !state.collapsed
157
- };
158
- });
159
- },
160
- type: "button"
161
- }, this.state.collapsed ? '«' : '»')), this.map && overviewLayer ? /*#__PURE__*/React.createElement(OlLayer, {
162
- key: overviewLayer.name,
163
- map: this.map,
164
- options: _objectSpread(_objectSpread({}, overviewLayer), {}, {
165
- visibility: true
166
- }),
167
- projection: this.props.sceneContext.mapCrs
168
- }) : null];
87
+ return overviewLayer ? /*#__PURE__*/React.createElement(OverviewMapButton, {
88
+ center: this.state.center,
89
+ coneRotation: this.state.coneAngle,
90
+ layer: overviewLayer,
91
+ projection: this.props.sceneContext.mapCrs,
92
+ resolution: this.state.resolution
93
+ }) : null;
169
94
  }
170
95
  }]);
171
96
  }(React.Component);
@@ -90,7 +90,8 @@ div.obliqueview-bottombar {
90
90
  right: 0;
91
91
  bottom: 0;
92
92
  height: 3em;
93
- z-index: 100;
93
+ padding: 0 0.5em;
94
+ z-index: 3;
94
95
  color: var(--panel-text-color);
95
96
  background-color: var(--panel-bg-color);
96
97
  box-shadow: 0 -2px 4px rgba(136, 136, 136, 0.5);
@@ -98,7 +99,10 @@ div.obliqueview-bottombar {
98
99
  font-size: 75%;
99
100
  display: flex;
100
101
  align-items: center;
101
- justify-content: center;
102
+ }
103
+
104
+ span.obliqueview-bottombar-spacer {
105
+ flex: 1 1 auto;
102
106
  }
103
107
 
104
108
  div.obliqueview-scalechooser {
@@ -283,8 +283,8 @@ export function getFeatureTemplate(editConfig, feature, editIface, mapPrefix, ma
283
283
  parseExpressionsAsync(defaultFieldExpressions, feature, editConfig, editIface, mapPrefix, mapCrs).then(function (result) {
284
284
  // Adjust values based on field type
285
285
  editConfig.fields.forEach(function (field) {
286
- if (field.id in result && field.type === "date") {
287
- result[field.id] = result[field.id].split("T")[0];
286
+ if (field.id in result && result[field.id] && field.type === "date") {
287
+ result[field.id] = String(result[field.id]).split("T")[0];
288
288
  }
289
289
  });
290
290
  callback(_objectSpread(_objectSpread({}, feature), {}, {