qwc2 2026.4.21 → 2026.4.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/components/AttributeForm.js +26 -11
  2. package/components/EditComboField.js +58 -15
  3. package/components/LinkFeatureForm.js +9 -10
  4. package/components/QtDesignerForm.js +12 -15
  5. package/components/SearchBox.js +77 -52
  6. package/components/map3d/Map3D.js +19 -4
  7. package/components/map3d/layers/WFSLayer3D.js +4 -0
  8. package/components/map3d/utils/MiscUtils3D.js +3 -1
  9. package/components/style/EditComboField.css +5 -0
  10. package/components/widgets/ComboBox.js +11 -2
  11. package/package.json +3 -3
  12. package/plugins/Redlining.js +14 -5
  13. package/plugins/SensorThingsTool.js +41 -22
  14. package/plugins/TaskButton.js +16 -2
  15. package/plugins/map3d/Identify3D.js +18 -10
  16. package/plugins/map3d/MapCopyright3D.js +36 -17
  17. package/plugins/map3d/MapExport3D.js +1 -1
  18. package/plugins/map3d/Measure3D.js +3 -3
  19. package/plugins/style/SensorThingsTool.css +13 -5
  20. package/static/translations/bg-BG.json +1 -0
  21. package/static/translations/ca-ES.json +1 -0
  22. package/static/translations/cs-CZ.json +1 -0
  23. package/static/translations/de-CH.json +1 -0
  24. package/static/translations/de-DE.json +1 -0
  25. package/static/translations/en-US.json +1 -0
  26. package/static/translations/es-ES.json +1 -0
  27. package/static/translations/fi-FI.json +1 -0
  28. package/static/translations/fr-FR.json +1 -0
  29. package/static/translations/hu-HU.json +1 -0
  30. package/static/translations/it-IT.json +1 -0
  31. package/static/translations/ja-JP.json +1 -0
  32. package/static/translations/nl-NL.json +1 -0
  33. package/static/translations/no-NO.json +1 -0
  34. package/static/translations/pl-PL.json +1 -0
  35. package/static/translations/pt-BR.json +1 -0
  36. package/static/translations/pt-PT.json +1 -0
  37. package/static/translations/ro-RO.json +1 -0
  38. package/static/translations/ru-RU.json +1 -0
  39. package/static/translations/sv-SE.json +1 -0
  40. package/static/translations/tr-TR.json +1 -0
  41. package/static/translations/tsconfig.json +1 -0
  42. package/static/translations/uk-UA.json +1 -0
  43. package/utils/EditingUtils.js +2 -1
  44. package/utils/SearchProviders.js +38 -84
@@ -103,8 +103,14 @@ var ComboBox = /*#__PURE__*/function (_React$Component) {
103
103
  });
104
104
  };
105
105
  return /*#__PURE__*/React.createElement("div", {
106
- className: "combobox " + (this.props.className || "")
107
- }, /*#__PURE__*/React.createElement("div", {
106
+ className: "combobox " + (this.props.className || ""),
107
+ style: this.props.style
108
+ }, this.props.name && /*#__PURE__*/React.createElement("input", {
109
+ name: this.props.name,
110
+ required: this.props.required,
111
+ type: "hidden",
112
+ value: this.props.value
113
+ }), /*#__PURE__*/React.createElement("div", {
108
114
  className: "combobox-button",
109
115
  onClick: onClick,
110
116
  onKeyDown: MiscUtils.checkKeyActivate,
@@ -161,9 +167,12 @@ _defineProperty(ComboBox, "propTypes", {
161
167
  className: PropTypes.string,
162
168
  filterable: PropTypes.bool,
163
169
  menuClassName: PropTypes.string,
170
+ name: PropTypes.string,
164
171
  onChange: PropTypes.func,
165
172
  placeholder: PropTypes.string,
166
173
  readOnly: PropTypes.bool,
174
+ required: PropTypes.bool,
175
+ style: PropTypes.object,
167
176
  value: PropTypes.string
168
177
  });
169
178
  _defineProperty(ComboBox, "defaultProps", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2026.04.21",
3
+ "version": "2026.04.29",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
@@ -17,7 +17,7 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "@furkot/webfonts-generator": "^2.0.3",
20
- "@giro3d/giro3d": "^2.0.1",
20
+ "@giro3d/giro3d": "^2.0.2",
21
21
  "@kayahr/text-encoding": "^2.1.0",
22
22
  "@loaders.gl/core": "^4.3.4",
23
23
  "@loaders.gl/shapefile": "^4.3.4",
@@ -101,7 +101,7 @@
101
101
  "toposort": "^2.0.2",
102
102
  "url": "^0.11.4",
103
103
  "utif": "^3.1.0",
104
- "uuid": "^13.0.0",
104
+ "uuid": "^14.0.0",
105
105
  "xlsx": "^0.18.5"
106
106
  },
107
107
  "devDependencies": {
@@ -35,7 +35,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
35
35
  import React from 'react';
36
36
  import { connect } from 'react-redux';
37
37
  import PropTypes from 'prop-types';
38
- import { LayerRole, addLayer } from '../actions/layers';
38
+ import { LayerRole, addLayer, changeLayerProperty } from '../actions/layers';
39
39
  import { setSnappingConfig } from '../actions/map';
40
40
  import { changeRedliningState, resetRedliningState } from '../actions/redlining';
41
41
  import Icon from '../components/Icon';
@@ -70,13 +70,18 @@ var Redlining = /*#__PURE__*/function (_React$Component) {
70
70
  geomType: (_data$geomType = data === null || data === void 0 ? void 0 : data.geomType) !== null && _data$geomType !== void 0 ? _data$geomType : null
71
71
  }, _this.redliningStateDefaults()));
72
72
  _this.props.setSnappingConfig(_this.props.snapping, _this.props.snappingActive);
73
+ var layer = null;
73
74
  if (data && data.layerId) {
74
- var layer = _this.props.layers.find(function (l) {
75
+ layer = _this.props.layers.find(function (l) {
75
76
  return l.id === data.layerId;
76
77
  });
77
- if (layer) {
78
- _this.changeRedliningLayer(layer);
79
- }
78
+ } else {
79
+ layer = _this.props.layers.find(function (l) {
80
+ return l.id === _this.props.redlining.layer;
81
+ });
82
+ }
83
+ if (layer) {
84
+ _this.changeRedliningLayer(layer);
80
85
  }
81
86
  });
82
87
  _defineProperty(_this, "onHide", function () {
@@ -550,6 +555,8 @@ var Redlining = /*#__PURE__*/function (_React$Component) {
550
555
  layerTitle: layer.title,
551
556
  action: action
552
557
  });
558
+ // Ensure layer is visible
559
+ _this.props.changeLayerProperty(layer.id, "visibility", true);
553
560
  });
554
561
  _this.labelInput = null;
555
562
  _this.dashIcons = {};
@@ -617,6 +624,7 @@ _defineProperty(Redlining, "propTypes", {
617
624
  addLayer: PropTypes.func,
618
625
  /** Whether to allow labeling geometric figures. */
619
626
  allowGeometryLabels: PropTypes.bool,
627
+ changeLayerProperty: PropTypes.func,
620
628
  changeRedliningState: PropTypes.func,
621
629
  /** Default area unit. Options: `metric`, `imperial`, `sqm`, `ha`, `sqkm`, `sqft`, `acre`, `sqmi` */
622
630
  defaultAreaUnit: PropTypes.string,
@@ -675,6 +683,7 @@ export default (function (plugins) {
675
683
  };
676
684
  }, {
677
685
  changeRedliningState: changeRedliningState,
686
+ changeLayerProperty: changeLayerProperty,
678
687
  addLayer: addLayer,
679
688
  resetRedliningState: resetRedliningState,
680
689
  setSnappingConfig: setSnappingConfig
@@ -235,9 +235,9 @@ var SensorThingsTool = /*#__PURE__*/function (_React$Component) {
235
235
  showLocationInfoWindow: false,
236
236
  // currently selected Datastreams filter options
237
237
  currentDatastreamsFilter: {
238
- thingId: -1,
239
- sensorId: -1,
240
- observedPropertyId: -1
238
+ thingId: '-1',
239
+ sensorId: '-1',
240
+ observedPropertyId: '-1'
241
241
  },
242
242
  // show Datastreams filter window for currently selected Location if true
243
243
  showDatastreamsFilterWindow: false,
@@ -666,7 +666,7 @@ var SensorThingsTool = /*#__PURE__*/function (_React$Component) {
666
666
  locationSelect = /*#__PURE__*/React.createElement("div", null, LocaleUtils.tr("sensorthingstool.locationLabel"), ":\xA0", /*#__PURE__*/React.createElement("select", {
667
667
  onChange: function onChange(ev) {
668
668
  return _this.setState({
669
- currentLocationId: parseInt(ev.target.value, 10)
669
+ currentLocationId: ev.target.value
670
670
  });
671
671
  },
672
672
  value: _this.state.currentLocationId
@@ -693,14 +693,14 @@ var SensorThingsTool = /*#__PURE__*/function (_React$Component) {
693
693
  icon: "trash"
694
694
  }));
695
695
  if (_this.state.currentSensorLocation !== null) {
696
- var datastreamsFilterActive = _this.state.currentDatastreamsFilter.thingId !== -1 || _this.state.currentDatastreamsFilter.sensorId !== -1 || _this.state.currentDatastreamsFilter.observedPropertyId !== -1;
696
+ var datastreamsFilterActive = _this.state.currentDatastreamsFilter.thingId !== '-1' || _this.state.currentDatastreamsFilter.sensorId !== '-1' || _this.state.currentDatastreamsFilter.observedPropertyId !== '-1';
697
697
  if (_this.state.currentSensorLocation.filteredDatastreams.length > 0) {
698
698
  datastreamSelect = /*#__PURE__*/React.createElement("div", {
699
699
  className: "sensor-things-location-datastreams"
700
700
  }, LocaleUtils.tr("sensorthingstool.datastreamLabel"), ":\xA0", /*#__PURE__*/React.createElement("select", {
701
701
  onChange: function onChange(ev) {
702
702
  return _this.setState({
703
- currentDatastreamId: parseInt(ev.target.value, 10)
703
+ currentDatastreamId: ev.target.value
704
704
  });
705
705
  },
706
706
  value: _this.state.currentDatastreamId
@@ -929,14 +929,30 @@ var SensorThingsTool = /*#__PURE__*/function (_React$Component) {
929
929
  // show popup with list of Locations at picking pos, cf. MapInfoTooltip
930
930
  var pixel = MapUtils.getHook(MapUtils.GET_PIXEL_FROM_COORDINATES_HOOK)(_this.state.pickGeom.coordinates);
931
931
  var style = {
932
- left: pixel[0] + 16 + "px",
932
+ left: pixel[0] + 32 + "px",
933
933
  top: pixel[1] + "px"
934
934
  };
935
935
  return /*#__PURE__*/React.createElement("div", {
936
936
  className: "sensor-things-location-select",
937
937
  key: "SensorThingsLocationSelectPopup",
938
938
  style: style
939
- }, /*#__PURE__*/React.createElement("b", null, LocaleUtils.tr("sensorthingstool.selectLocation"), ":"), /*#__PURE__*/React.createElement("br", null), _this.state.locationsAtPoint.map(function (location, idx) {
939
+ }, /*#__PURE__*/React.createElement("div", {
940
+ className: "sensor-things-location-select-header"
941
+ }, /*#__PURE__*/React.createElement("b", null, LocaleUtils.tr("sensorthingstool.selectLocation")), /*#__PURE__*/React.createElement("div", {
942
+ className: "sensor-things-toolbar-spacer"
943
+ }), /*#__PURE__*/React.createElement("button", {
944
+ className: "button",
945
+ onClick: function onClick() {
946
+ return _this.setState({
947
+ locationsAtPoint: []
948
+ });
949
+ },
950
+ title: LocaleUtils.tr("common.close")
951
+ }, /*#__PURE__*/React.createElement(Icon, {
952
+ icon: "remove"
953
+ }))), /*#__PURE__*/React.createElement("div", {
954
+ className: "sensor-things-location-select-list"
955
+ }, _this.state.locationsAtPoint.map(function (location, idx) {
940
956
  return /*#__PURE__*/React.createElement("div", {
941
957
  key: "select-location-" + idx,
942
958
  onClickCapture: function onClickCapture() {
@@ -953,7 +969,7 @@ var SensorThingsTool = /*#__PURE__*/function (_React$Component) {
953
969
  });
954
970
  }
955
971
  }, location.name, ": ", location.description);
956
- }));
972
+ })));
957
973
  } else {
958
974
  return null;
959
975
  }
@@ -1053,9 +1069,9 @@ var SensorThingsTool = /*#__PURE__*/function (_React$Component) {
1053
1069
  currentLocationId: nextSelectedLocationId,
1054
1070
  currentSensorLocation: null,
1055
1071
  currentDatastreamsFilter: {
1056
- thingId: -1,
1057
- sensorId: -1,
1058
- observedPropertyId: -1
1072
+ thingId: '-1',
1073
+ sensorId: '-1',
1074
+ observedPropertyId: '-1'
1059
1075
  },
1060
1076
  currentDatastreamId: null,
1061
1077
  datastreams: nextDatastreams,
@@ -1075,7 +1091,7 @@ var SensorThingsTool = /*#__PURE__*/function (_React$Component) {
1075
1091
  _defineProperty(_this, "updateDatastreamsFilter", function (field, value) {
1076
1092
  _this.setState(function (state) {
1077
1093
  return {
1078
- currentDatastreamsFilter: _objectSpread(_objectSpread({}, state.currentDatastreamsFilter), {}, _defineProperty({}, field, parseInt(value, 10)))
1094
+ currentDatastreamsFilter: _objectSpread(_objectSpread({}, state.currentDatastreamsFilter), {}, _defineProperty({}, field, value))
1079
1095
  };
1080
1096
  });
1081
1097
  });
@@ -2236,9 +2252,9 @@ var SensorThingsTool = /*#__PURE__*/function (_React$Component) {
2236
2252
  filteredDatastreams: datastreamIds
2237
2253
  },
2238
2254
  currentDatastreamsFilter: {
2239
- thingId: -1,
2240
- sensorId: -1,
2241
- observedPropertyId: -1
2255
+ thingId: '-1',
2256
+ sensorId: '-1',
2257
+ observedPropertyId: '-1'
2242
2258
  },
2243
2259
  currentDatastreamId: datastreamIds[0],
2244
2260
  datastreams: _objectSpread(_objectSpread({}, state.datastreams), datastreamsLookup)
@@ -2252,22 +2268,25 @@ var SensorThingsTool = /*#__PURE__*/function (_React$Component) {
2252
2268
  _defineProperty(_this, "filterLocationDatastreams", function () {
2253
2269
  if (_this.state.currentSensorLocation !== null) {
2254
2270
  var filteredDatastreams = _this.state.currentSensorLocation.datastreams;
2255
- if (_this.state.currentDatastreamsFilter.thingId !== -1) {
2271
+
2272
+ // NOTE: entity IDs may be integer or UUID strings, so compare them as string
2273
+
2274
+ if (_this.state.currentDatastreamsFilter.thingId !== '-1') {
2256
2275
  // filter by Thing
2257
2276
  filteredDatastreams = filteredDatastreams.filter(function (datastreamId) {
2258
- return _this.state.datastreams[datastreamId].thing.id === _this.state.currentDatastreamsFilter.thingId;
2277
+ return _this.state.datastreams[datastreamId].thing.id.toString() === _this.state.currentDatastreamsFilter.thingId;
2259
2278
  });
2260
2279
  }
2261
- if (_this.state.currentDatastreamsFilter.sensorId !== -1) {
2280
+ if (_this.state.currentDatastreamsFilter.sensorId !== '-1') {
2262
2281
  // filter by Sensor
2263
2282
  filteredDatastreams = filteredDatastreams.filter(function (datastreamId) {
2264
- return _this.state.datastreams[datastreamId].sensor.id === _this.state.currentDatastreamsFilter.sensorId;
2283
+ return _this.state.datastreams[datastreamId].sensor.id.toString() === _this.state.currentDatastreamsFilter.sensorId;
2265
2284
  });
2266
2285
  }
2267
- if (_this.state.currentDatastreamsFilter.observedPropertyId !== -1) {
2286
+ if (_this.state.currentDatastreamsFilter.observedPropertyId !== '-1') {
2268
2287
  // filter by ObservedProperty
2269
2288
  filteredDatastreams = filteredDatastreams.filter(function (datastreamId) {
2270
- return _this.state.datastreams[datastreamId].observedProperty.id === _this.state.currentDatastreamsFilter.observedPropertyId;
2289
+ return _this.state.datastreams[datastreamId].observedProperty.id.toString() === _this.state.currentDatastreamsFilter.observedPropertyId;
2271
2290
  });
2272
2291
  }
2273
2292
  _this.setState(function (state) {
@@ -23,6 +23,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
23
23
  import React from 'react';
24
24
  import { connect } from 'react-redux';
25
25
  import PropTypes from 'prop-types';
26
+ import { setActiveServiceInfo } from '../actions/serviceinfo';
26
27
  import { setCurrentTask } from '../actions/task';
27
28
  import MapButton from '../components/MapButton';
28
29
  import ConfigUtils from '../utils/ConfigUtils';
@@ -31,6 +32,12 @@ import ThemeUtils from '../utils/ThemeUtils';
31
32
 
32
33
  /**
33
34
  * Generic map button to launch a task.
35
+ *
36
+ * The `task` generally corresponds to the `key` of a menuItem or toolbaritem.
37
+ *
38
+ * The following special values for `task` are suppported:
39
+ *
40
+ * * `ServiceInfo`: Open the service info of the current theme.
34
41
  */
35
42
  var TaskButton = /*#__PURE__*/function (_React$Component) {
36
43
  function TaskButton() {
@@ -41,8 +48,13 @@ var TaskButton = /*#__PURE__*/function (_React$Component) {
41
48
  }
42
49
  _this = _callSuper(this, TaskButton, [].concat(args));
43
50
  _defineProperty(_this, "buttonClicked", function () {
44
- var mapClickAction = ConfigUtils.getPluginConfig(_this.props.task).mapClickAction;
45
- _this.props.setCurrentTask(_this.props.currentTask === _this.props.task ? null : _this.props.task, _this.props.mode, mapClickAction);
51
+ // Special cases
52
+ if (_this.props.task === "ServiceInfo") {
53
+ _this.props.setActiveServiceInfo(_this.props.theme);
54
+ } else {
55
+ var mapClickAction = ConfigUtils.getPluginConfig(_this.props.task).mapClickAction;
56
+ _this.props.setCurrentTask(_this.props.currentTask === _this.props.task ? null : _this.props.task, _this.props.mode, mapClickAction);
57
+ }
46
58
  });
47
59
  return _this;
48
60
  }
@@ -72,6 +84,7 @@ _defineProperty(TaskButton, "propTypes", {
72
84
  mode: PropTypes.string,
73
85
  /** The position slot index of the map button, from the bottom (0: bottom slot). */
74
86
  position: PropTypes.number,
87
+ setActiveServiceInfo: PropTypes.func,
75
88
  setCurrentTask: PropTypes.func,
76
89
  /** The task name. */
77
90
  task: PropTypes.string,
@@ -91,5 +104,6 @@ var selector = function selector(state) {
91
104
  };
92
105
  };
93
106
  export default connect(selector, {
107
+ setActiveServiceInfo: setActiveServiceInfo,
94
108
  setCurrentTask: setCurrentTask
95
109
  })(TaskButton);
@@ -120,9 +120,17 @@ var Identify3D = /*#__PURE__*/function (_React$Component) {
120
120
  }
121
121
  });
122
122
  _defineProperty(_this, "identifyTilePick", function (pick) {
123
+ var _pick$object$userData, _pick$object$userData2;
123
124
  var helper = new TileMeshHelper(pick.object);
124
125
  var pickFeatureId = helper.getPickFeatureId(pick);
125
126
  var featureAttrs = helper.getFeatureProperties(pickFeatureId);
127
+ var infoAttrBlacklist = (_pick$object$userData = (_pick$object$userData2 = pick.object.userData) === null || _pick$object$userData2 === void 0 || (_pick$object$userData2 = _pick$object$userData2.parentEntity) === null || _pick$object$userData2 === void 0 || (_pick$object$userData2 = _pick$object$userData2.userData) === null || _pick$object$userData2 === void 0 ? void 0 : _pick$object$userData2.infoAttrBlacklist) !== null && _pick$object$userData !== void 0 ? _pick$object$userData : [];
128
+ var infoAttrs = Object.fromEntries(Object.entries(featureAttrs).filter(function (_ref) {
129
+ var _ref2 = _slicedToArray(_ref, 2),
130
+ key = _ref2[0],
131
+ value = _ref2[1];
132
+ return !infoAttrBlacklist.includes(key);
133
+ }));
126
134
 
127
135
  // Extract feature geometry
128
136
  var pickPosition = [];
@@ -147,23 +155,23 @@ var Identify3D = /*#__PURE__*/function (_React$Component) {
147
155
  var url = _this.props.tileInfoServiceUrl.replace('{tileset}', tilesetName).replace('{objectid}', featureAttrs[featureIdAttr]);
148
156
  axios.get(url).then(function (response) {
149
157
  response.data.forEach(function (attr) {
150
- if (attr.name in featureAttrs && featureAttrs[attr.name] === attr.value) {
158
+ if (attr.name in infoAttrs && infoAttrs[attr.name] === attr.value) {
151
159
  // Use attribute alias
152
- delete featureAttrs[attr.name];
160
+ delete infoAttrs[attr.name];
153
161
  }
154
- featureAttrs[attr.alias] = attr.value;
162
+ infoAttrs[attr.alias] = attr.value;
155
163
  });
156
164
  _this.setState({
157
- pickAttrs: featureAttrs
165
+ pickAttrs: infoAttrs
158
166
  });
159
167
  })["catch"](function () {
160
168
  _this.setState({
161
- pickAttrs: featureAttrs
169
+ pickAttrs: infoAttrs
162
170
  });
163
171
  });
164
172
  } else {
165
173
  _this.setState({
166
- pickAttrs: featureAttrs
174
+ pickAttrs: infoAttrs
167
175
  });
168
176
  }
169
177
  });
@@ -233,10 +241,10 @@ var Identify3D = /*#__PURE__*/function (_React$Component) {
233
241
  className: "identify-result-box"
234
242
  }, /*#__PURE__*/React.createElement("table", {
235
243
  className: "attribute-list"
236
- }, /*#__PURE__*/React.createElement("tbody", null, Object.entries(this.state.pickAttrs).map(function (_ref) {
237
- var _ref2 = _slicedToArray(_ref, 2),
238
- key = _ref2[0],
239
- value = _ref2[1];
244
+ }, /*#__PURE__*/React.createElement("tbody", null, Object.entries(this.state.pickAttrs).map(function (_ref3) {
245
+ var _ref4 = _slicedToArray(_ref3, 2),
246
+ key = _ref4[0],
247
+ value = _ref4[1];
240
248
  return /*#__PURE__*/React.createElement("tr", {
241
249
  key: key
242
250
  }, /*#__PURE__*/React.createElement("td", {
@@ -32,6 +32,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
32
32
 
33
33
  import React from 'react';
34
34
  import ReactDOM from 'react-dom';
35
+ import { connect } from 'react-redux';
35
36
  import DOMPurify from 'dompurify';
36
37
  import isEmpty from 'lodash.isempty';
37
38
  import PropTypes from 'prop-types';
@@ -53,6 +54,28 @@ var MapCopyright3D = /*#__PURE__*/function (_React$Component) {
53
54
  _defineProperty(_this, "state", {
54
55
  currentCopyrights: {}
55
56
  });
57
+ _defineProperty(_this, "collectCopyrights", function () {
58
+ var layers = [_this.props.theme];
59
+ if (!_this.props.showThemeCopyrightOnly) {
60
+ layers.push.apply(layers, _toConsumableArray(_this.props.sceneContext.baseLayers));
61
+ layers.push.apply(layers, _toConsumableArray(Object.values(_this.props.sceneContext.colorLayers)));
62
+ }
63
+ var copyrights = layers.reduce(function (res, layer) {
64
+ var _layer$attribution;
65
+ if ((_layer$attribution = layer.attribution) !== null && _layer$attribution !== void 0 && _layer$attribution.Title) {
66
+ var _res$key;
67
+ var key = layer.attribution.OnlineResource || layer.attribution.Title;
68
+ res[key] = {
69
+ title: layer.attribution.OnlineResource ? layer.attribution.Title : null,
70
+ layers: [].concat(_toConsumableArray(((_res$key = res[key]) === null || _res$key === void 0 ? void 0 : _res$key.layers) || []), [layer])
71
+ };
72
+ }
73
+ return res;
74
+ }, {});
75
+ _this.setState({
76
+ currentCopyrights: copyrights
77
+ });
78
+ });
56
79
  _defineProperty(_this, "layerNames", function (layers) {
57
80
  if (!_this.props.prefixCopyrightsWithLayerNames) {
58
81
  return "";
@@ -66,24 +89,15 @@ var MapCopyright3D = /*#__PURE__*/function (_React$Component) {
66
89
  }
67
90
  _inherits(MapCopyright3D, _React$Component);
68
91
  return _createClass(MapCopyright3D, [{
92
+ key: "componentDidMount",
93
+ value: function componentDidMount() {
94
+ this.collectCopyrights();
95
+ }
96
+ }, {
69
97
  key: "componentDidUpdate",
70
98
  value: function componentDidUpdate(prevProps) {
71
99
  if (this.props.sceneContext.baseLayers !== prevProps.sceneContext.baseLayers || this.props.sceneContext.colorLayers !== prevProps.sceneContext.colorLayers) {
72
- var layers = this.props.sceneContext.baseLayers.concat(this.props.sceneContext.colorLayers);
73
- var copyrights = layers.reduce(function (res, layer) {
74
- if (layer.attribution && layer.attribution.Title) {
75
- var _res$key;
76
- var key = layer.attribution.OnlineResource || layer.attribution.Title;
77
- res[key] = {
78
- title: layer.attribution.OnlineResource ? layer.attribution.Title : null,
79
- layers: [].concat(_toConsumableArray(((_res$key = res[key]) === null || _res$key === void 0 ? void 0 : _res$key.layers) || []), [layer])
80
- };
81
- }
82
- return res;
83
- }, {});
84
- this.setState({
85
- currentCopyrights: copyrights
86
- });
100
+ this.collectCopyrights();
87
101
  }
88
102
  }
89
103
  }, {
@@ -129,6 +143,11 @@ _defineProperty(MapCopyright3D, "propTypes", {
129
143
  prefixCopyrightsWithLayerNames: PropTypes.bool,
130
144
  sceneContext: PropTypes.object,
131
145
  /** Whether to only display the attribution of the theme, omitting external layers. */
132
- showThemeCopyrightOnly: PropTypes.bool
146
+ showThemeCopyrightOnly: PropTypes.bool,
147
+ theme: PropTypes.object
133
148
  });
134
- export { MapCopyright3D as default };
149
+ export default connect(function (state) {
150
+ return {
151
+ theme: state.theme.current
152
+ };
153
+ }, {})(MapCopyright3D);
@@ -352,7 +352,7 @@ var MapExport3D = /*#__PURE__*/function (_React$Component) {
352
352
  var exportScale = _this.state.exportScaleFactor / 100;
353
353
  if (_this.state.selectedFormat === "application/pdf") {
354
354
  var mapWidthMM = _this.state.layout.map.width;
355
- var exportWidthPx = _this.state.width;
355
+ var exportWidthPx = _this.state.frame.width;
356
356
  exportScale = Math.min(5, _this.state.exportDpi / (exportWidthPx * 25.4 / mapWidthMM));
357
357
  }
358
358
  _this.setState({
@@ -343,9 +343,9 @@ var Measure3D = /*#__PURE__*/function (_React$Component) {
343
343
  _this.setState({
344
344
  result: {
345
345
  pos: [pos.x, pos.y, pos.z],
346
- ground: ground,
347
- haveResult: true
348
- }
346
+ ground: ground
347
+ },
348
+ haveResult: true
349
349
  });
350
350
 
351
351
  // Setup for next measurement
@@ -150,18 +150,26 @@ table.sensor-things-datastream-statistics-table td.sensor-things-datastream-stat
150
150
  }
151
151
 
152
152
  div.sensor-things-location-select {
153
- max-height: 16em;
154
- overflow-y: auto;
155
- padding: 0.25em;
156
153
  position: fixed;
157
154
  background-color: var(--container-bg-color);
158
155
  box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.75);
159
156
  z-index: 2;
160
157
  }
161
- div.sensor-things-location-select div {
158
+ div.sensor-things-location-select-header {
159
+ display: flex;
160
+ padding-left: 0.25em;
161
+ align-items: center;
162
+ background-color: var(--button-bg-color);
163
+ }
164
+ div.sensor-things-location-select-list {
165
+ padding: 0.25em;
166
+ max-height: 16em;
167
+ overflow-y: auto;
168
+ }
169
+ div.sensor-things-location-select-list div {
162
170
  padding-top: 0.25em;
163
171
  }
164
- div.sensor-things-location-select div:hover {
172
+ div.sensor-things-location-select-list div:hover {
165
173
  font-weight: bold;
166
174
  cursor: pointer;
167
175
  }
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Търсене на функции",
44
44
  "GeometryDigitizer": "Дигитайзер на геометрия",
45
45
  "IdentifyPoint": "Идентифициране на точка",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Определяне на региона",
47
48
  "LayerCatalog": "Каталог на слоевете",
48
49
  "Login": "Вход",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Cerca d'element",
44
44
  "GeometryDigitizer": "Digitalitzador de geometria",
45
45
  "IdentifyPoint": "Identificar punt",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Identificar zona",
47
48
  "LayerCatalog": "Capes",
48
49
  "Login": "Inicio de sessió",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "",
44
44
  "GeometryDigitizer": "",
45
45
  "IdentifyPoint": "Informace o bodu",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Informace o oblasti",
47
48
  "LayerCatalog": "Katalog vrstev",
48
49
  "Login": "Přihlášení",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Objektsuche",
44
44
  "GeometryDigitizer": "Geometriedigitalisierung",
45
45
  "IdentifyPoint": "Punkt abfragen",
46
+ "IdentifyRadius": "Radius abfragen",
46
47
  "IdentifyRegion": "Region abfragen",
47
48
  "LayerCatalog": "Ebenenkatalog",
48
49
  "Login": "Anmelden",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Objektsuche",
44
44
  "GeometryDigitizer": "Geometriedigitalisierung",
45
45
  "IdentifyPoint": "Punkt abfragen",
46
+ "IdentifyRadius": "Radius abfragen",
46
47
  "IdentifyRegion": "Region abfragen",
47
48
  "LayerCatalog": "Ebenenkatalog",
48
49
  "Login": "Anmelden",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Feature Search",
44
44
  "GeometryDigitizer": "Geometry digitizer",
45
45
  "IdentifyPoint": "Identify Point",
46
+ "IdentifyRadius": "Identify in Radius",
46
47
  "IdentifyRegion": "Identify Region",
47
48
  "LayerCatalog": "Layer catalog",
48
49
  "Login": "Login",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Búsqueda de elemento",
44
44
  "GeometryDigitizer": "Digitalizador de geometría",
45
45
  "IdentifyPoint": "Identificar punto",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Identificar zona",
47
48
  "LayerCatalog": "Capa catálogo",
48
49
  "Login": "Inicio de sesión",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "",
44
44
  "GeometryDigitizer": "",
45
45
  "IdentifyPoint": "",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Tunnista alue",
47
48
  "LayerCatalog": "",
48
49
  "Login": "Kirjaudu",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Recherche objet",
44
44
  "GeometryDigitizer": "Digitalisation des géométries",
45
45
  "IdentifyPoint": "Interroger point",
46
+ "IdentifyRadius": "Interroger dans un rayon",
46
47
  "IdentifyRegion": "Interroger la région",
47
48
  "LayerCatalog": "Catalogue des couches",
48
49
  "Login": "Connexion",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "",
44
44
  "GeometryDigitizer": "",
45
45
  "IdentifyPoint": "",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Adatok lekérdezése",
47
48
  "LayerCatalog": "",
48
49
  "Login": "",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Ricerca oggetto",
44
44
  "GeometryDigitizer": "Digitalizzazione geometrie",
45
45
  "IdentifyPoint": "Identifica punto",
46
+ "IdentifyRadius": "Identifica in un raggio",
46
47
  "IdentifyRegion": "Identifica in un poligono",
47
48
  "LayerCatalog": "Catalogo livelli",
48
49
  "Login": "Accedi",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "地物検索",
44
44
  "GeometryDigitizer": "ジオメトリ・デジタイザ",
45
45
  "IdentifyPoint": "点で地物を確認",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "領域内の地物を確認",
47
48
  "LayerCatalog": "レイヤ・カタログ",
48
49
  "Login": "ログイン",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Zoeken op kenmerken",
44
44
  "GeometryDigitizer": "Geometry digitizer",
45
45
  "IdentifyPoint": "",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Data opvragen",
47
48
  "LayerCatalog": "Lagencatalogus",
48
49
  "Login": "Inloggen",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "",
44
44
  "GeometryDigitizer": "",
45
45
  "IdentifyPoint": "",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Identifiser med område",
47
48
  "LayerCatalog": "",
48
49
  "Login": "Logg inn",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "",
44
44
  "GeometryDigitizer": "",
45
45
  "IdentifyPoint": "",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Identifikuj Obszar",
47
48
  "LayerCatalog": "",
48
49
  "Login": "Zaloguj",