qwc2 2025.12.17 → 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.
Files changed (75) hide show
  1. package/components/AttributeForm.js +8 -8
  2. package/components/AttributeTableWidget.js +3 -3
  3. package/components/EditComboField.js +1 -1
  4. package/components/EditUploadField.js +1 -1
  5. package/components/IdentifyViewer.js +3 -4
  6. package/components/LinkFeatureForm.js +21 -4
  7. package/components/MeasureSwitcher.js +115 -0
  8. package/components/OverviewMapButton.js +147 -0
  9. package/components/PluginsContainer.js +3 -2
  10. package/components/QtDesignerForm.js +2 -2
  11. package/components/ResizeableWindow.js +1 -1
  12. package/components/SearchBox.js +7 -7
  13. package/components/map3d/drawtool/EditTool3D.js +1 -1
  14. package/components/style/IdentifyViewer.css +1 -1
  15. package/components/style/LocationRecorder.css +1 -6
  16. package/{plugins/map3d/style/OverviewMap3D.css → components/style/OverviewMapButton.css} +4 -4
  17. package/components/style/PluginsContainer.css +11 -6
  18. package/components/timeline/FixedTimeline.js +2 -2
  19. package/components/timeline/InfiniteTimeline.js +2 -2
  20. package/components/timeline/TimelineFeaturesSlider.js +1 -1
  21. package/components/widgets/LayerCatalogWidget.js +1 -1
  22. package/package.json +1 -1
  23. package/plugins/Editing.js +20 -5
  24. package/plugins/FeatureForm.js +1 -1
  25. package/plugins/FeatureSearch.js +3 -3
  26. package/plugins/GeometryDigitizer.js +40 -26
  27. package/plugins/Identify.js +1 -4
  28. package/plugins/MapExport.js +4 -4
  29. package/plugins/MapFilter.js +10 -10
  30. package/plugins/NewsPopup.js +1 -1
  31. package/plugins/ObliqueView.js +177 -61
  32. package/plugins/Print.js +7 -7
  33. package/plugins/Redlining.js +25 -73
  34. package/plugins/Reports.js +3 -3
  35. package/plugins/Routing.js +4 -4
  36. package/plugins/ValueTool.js +1 -1
  37. package/plugins/View3D.js +2 -2
  38. package/plugins/ZoomButtons.js +1 -1
  39. package/plugins/map/EditingSupport.js +50 -20
  40. package/plugins/map/RedliningSupport.js +4 -4
  41. package/plugins/map/SnapSupport.js +12 -10
  42. package/plugins/map/style/SnappingSupport.css +1 -8
  43. package/plugins/map3d/Draw3D.js +2 -2
  44. package/plugins/map3d/ExportObjects3D.js +2 -2
  45. package/plugins/map3d/MapExport3D.js +4 -4
  46. package/plugins/map3d/OverviewMap3D.js +27 -102
  47. package/plugins/style/ObliqueView.css +6 -2
  48. package/reducers/editing.js +6 -1
  49. package/static/translations/bg-BG.json +39 -74
  50. package/static/translations/ca-ES.json +39 -74
  51. package/static/translations/cs-CZ.json +39 -74
  52. package/static/translations/de-CH.json +39 -74
  53. package/static/translations/de-DE.json +39 -74
  54. package/static/translations/en-US.json +39 -74
  55. package/static/translations/es-ES.json +39 -74
  56. package/static/translations/fi-FI.json +39 -74
  57. package/static/translations/fr-FR.json +39 -74
  58. package/static/translations/hu-HU.json +39 -74
  59. package/static/translations/it-IT.json +39 -74
  60. package/static/translations/ja-JP.json +39 -74
  61. package/static/translations/nl-NL.json +39 -74
  62. package/static/translations/no-NO.json +39 -74
  63. package/static/translations/pl-PL.json +39 -74
  64. package/static/translations/pt-BR.json +39 -74
  65. package/static/translations/pt-PT.json +39 -74
  66. package/static/translations/ro-RO.json +39 -74
  67. package/static/translations/ru-RU.json +39 -74
  68. package/static/translations/sv-SE.json +39 -74
  69. package/static/translations/tr-TR.json +39 -74
  70. package/static/translations/tsconfig.json +30 -67
  71. package/static/translations/uk-UA.json +39 -74
  72. package/utils/EditingUtils.js +2 -2
  73. package/utils/FeatureStyles.js +13 -18
  74. package/utils/IdentifyUtils.js +14 -11
  75. package/utils/SearchProviders.js +1 -1
@@ -30,15 +30,20 @@ div.map-bottom-tool-container {
30
30
  position: absolute;
31
31
  pointer-events: none;
32
32
  display: flex;
33
- flex-direction: column-reverse;
34
- align-items: center;
35
- align-content: flex-start;
36
- justify-content: flex-start;
37
- margin-bottom: -1px;
33
+ justify-content: center;
34
+ align-items: flex-end;
38
35
  }
39
36
 
40
- div.map-bottom-tool-container > * {
37
+ div.map-bottom-tool-container > div {
38
+ display: flex;
39
+ flex-wrap: wrap;
40
+ justify-content: center;
41
+ margin-bottom: -1px;
41
42
  pointer-events: initial;
43
+ padding: 0.25em 0.5em;
44
+ gap: 1em;
45
+ background-color: var(--container-bg-color);
46
+ box-shadow: 0px -2px 4px rgba(136, 136, 136, 0.5);
42
47
  }
43
48
 
44
49
  div.app-info {
@@ -158,11 +158,11 @@ var FixedTimeline = /*#__PURE__*/function (_React$Component) {
158
158
  icon: "home"
159
159
  }, {
160
160
  key: "zoomout",
161
- tooltip: LocaleUtils.tr("timemanager.zoomout"),
161
+ tooltip: LocaleUtils.tr("common.zoomout"),
162
162
  icon: "zoomout"
163
163
  }, {
164
164
  key: "zoomin",
165
- tooltip: LocaleUtils.tr("timemanager.zoomin"),
165
+ tooltip: LocaleUtils.tr("common.zoomin"),
166
166
  icon: "zoomin"
167
167
  }];
168
168
  return /*#__PURE__*/React.createElement("div", {
@@ -257,11 +257,11 @@ var InfiniteTimeline = /*#__PURE__*/function (_React$Component) {
257
257
  icon: "home"
258
258
  }, {
259
259
  key: "zoomout",
260
- tooltip: LocaleUtils.tr("timemanager.zoomout"),
260
+ tooltip: LocaleUtils.tr("common.zoomout"),
261
261
  icon: "zoomout"
262
262
  }, {
263
263
  key: "zoomin",
264
- tooltip: LocaleUtils.tr("timemanager.zoomin"),
264
+ tooltip: LocaleUtils.tr("common.zoomin"),
265
265
  icon: "zoomin"
266
266
  }];
267
267
  return /*#__PURE__*/React.createElement("div", {
@@ -414,7 +414,7 @@ var TimelineFeaturesSlider = /*#__PURE__*/function (_React$Component) {
414
414
  onPointerDown: this.pickCurrentTimestamp
415
415
  }, this.props.displayMode === "features" ? this.renderTimeFeatures(sliderGeom) : null, this.props.displayMode === "layers" ? this.renderTimeLayers(sliderGeom) : null, this.renderGradient(sliderGeom)), this.renderCursor(timestamp), this.props.timeFeatures.pendingRequests > 0 ? /*#__PURE__*/React.createElement("div", {
416
416
  className: "timeline-slider-loading"
417
- }, /*#__PURE__*/React.createElement(Spinner, null), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("timemanager.loading"))) : null);
417
+ }, /*#__PURE__*/React.createElement(Spinner, null), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("common.loading"))) : null);
418
418
  }
419
419
  }]);
420
420
  }(React.Component);
@@ -247,7 +247,7 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
247
247
  } else if (isEmpty(this.state.catalog)) {
248
248
  emptyEntry = /*#__PURE__*/React.createElement("div", {
249
249
  className: "layer-catalog-placeholder"
250
- }, LocaleUtils.tr("importlayer.loading"));
250
+ }, LocaleUtils.tr("common.loading"));
251
251
  }
252
252
  var filterplaceholder = LocaleUtils.tr("importlayer.filter");
253
253
  var catalog = (_this$state$filteredC = this.state.filteredCatalog) !== null && _this$state$filteredC !== void 0 ? _this$state$filteredC : this.state.catalog;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2025.12.17",
3
+ "version": "2025.12.19",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
@@ -33,6 +33,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
33
33
  */
34
34
 
35
35
  import React from 'react';
36
+ import ReactDOM from 'react-dom';
36
37
  import { connect } from 'react-redux';
37
38
  import { parseNumber } from '@norbulcz/num-parse';
38
39
  import dateParser from 'any-date-parser';
@@ -46,7 +47,9 @@ import { setSnappingConfig } from '../actions/map';
46
47
  import { setCurrentTask, setCurrentTaskBlocked } from '../actions/task';
47
48
  import AttributeForm from '../components/AttributeForm';
48
49
  import Icon from '../components/Icon';
50
+ import MeasureSwitcher from '../components/MeasureSwitcher';
49
51
  import PickFeature from '../components/PickFeature';
52
+ import { BottomToolPortalContext } from '../components/PluginsContainer';
50
53
  import SideBar from '../components/SideBar';
51
54
  import ButtonBar from '../components/widgets/ButtonBar';
52
55
  import ConfigUtils from '../utils/ConfigUtils';
@@ -173,7 +176,7 @@ var Editing = /*#__PURE__*/function (_React$Component) {
173
176
  actionButtons.push({
174
177
  key: 'Pick',
175
178
  icon: 'pick',
176
- label: LocaleUtils.tr("editing.pick"),
179
+ label: LocaleUtils.tr("common.pick"),
177
180
  data: {
178
181
  action: 'Pick',
179
182
  feature: null
@@ -258,7 +261,7 @@ var Editing = /*#__PURE__*/function (_React$Component) {
258
261
  }, /*#__PURE__*/React.createElement("option", {
259
262
  disabled: true,
260
263
  value: ""
261
- }, LocaleUtils.tr("editing.selectlayer")), Object.entries(_this.props.editConfigs).map(function (_ref) {
264
+ }, LocaleUtils.tr("common.selectlayer")), Object.entries(_this.props.editConfigs).map(function (_ref) {
262
265
  var _ref2 = _slicedToArray(_ref, 2),
263
266
  mapName = _ref2[0],
264
267
  serviceConfigs = _ref2[1];
@@ -285,6 +288,11 @@ var Editing = /*#__PURE__*/function (_React$Component) {
285
288
  onClick: _this.actionClicked
286
289
  }), featureSelection, pickBar, attributeForm);
287
290
  });
291
+ _defineProperty(_this, "changeMeasurementState", function (diff) {
292
+ _this.props.setEditContext('Editing', {
293
+ measurements: _objectSpread(_objectSpread({}, _this.props.editContext.measurements), diff)
294
+ });
295
+ });
288
296
  _defineProperty(_this, "actionClicked", function (action, data) {
289
297
  _this.setState({
290
298
  drawPick: false,
@@ -635,8 +643,9 @@ var Editing = /*#__PURE__*/function (_React$Component) {
635
643
  }, {
636
644
  key: "render",
637
645
  value: function render() {
638
- var _this3 = this;
639
- var minMaxTooltip = this.state.minimized ? LocaleUtils.tr("editing.maximize") : LocaleUtils.tr("editing.minimize");
646
+ var _this3 = this,
647
+ _this$props$editConte3;
648
+ var minMaxTooltip = this.state.minimized ? LocaleUtils.tr("window.maximize") : LocaleUtils.tr("window.minimize");
640
649
  var extraTitlebarContent = /*#__PURE__*/React.createElement(Icon, {
641
650
  className: "editing-minimize-maximize",
642
651
  icon: this.state.minimized ? 'chevron-down' : 'chevron-up',
@@ -669,10 +678,16 @@ var Editing = /*#__PURE__*/function (_React$Component) {
669
678
  featureFilter: this.pickFilter,
670
679
  featurePicked: this.geomPicked,
671
680
  key: "FeaturePicker"
672
- }) : null];
681
+ }) : null, this.props.editContext.action === "Draw" || (_this$props$editConte3 = this.props.editContext.feature) !== null && _this$props$editConte3 !== void 0 && _this$props$editConte3.geometry ? /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement(MeasureSwitcher, {
682
+ changeMeasureState: this.changeMeasurementState,
683
+ geomType: this.props.editContext.geomType,
684
+ iconSize: "large",
685
+ measureState: this.props.editContext.measurements
686
+ }), this.context) : null];
673
687
  }
674
688
  }]);
675
689
  }(React.Component);
690
+ _defineProperty(Editing, "contextType", BottomToolPortalContext);
676
691
  _defineProperty(Editing, "propTypes", {
677
692
  addLayerFeatures: PropTypes.func,
678
693
  /** Whether to enable the "Clone existing geometry" functionality. */
@@ -233,7 +233,7 @@ var FeatureForm = /*#__PURE__*/function (_React$Component) {
233
233
  className: "feature-query-body"
234
234
  }, /*#__PURE__*/React.createElement("span", {
235
235
  className: "identify-body-message"
236
- }, LocaleUtils.tr("featureform.noresults")));
236
+ }, LocaleUtils.tr("common.noresults")));
237
237
  } else {
238
238
  var featureText = LocaleUtils.tr("featureform.feature");
239
239
  var attributeForm = null;
@@ -86,7 +86,7 @@ var FeatureSearch = /*#__PURE__*/function (_React$Component) {
86
86
  }, /*#__PURE__*/React.createElement("option", {
87
87
  disabled: true,
88
88
  value: ""
89
- }, LocaleUtils.tr("featuresearch.select")), Object.entries(_this.state.providerGroups).map(function (_ref) {
89
+ }, LocaleUtils.tr("common.select")), Object.entries(_this.state.providerGroups).map(function (_ref) {
90
90
  var _ref2 = _slicedToArray(_ref, 2),
91
91
  group = _ref2[0],
92
92
  entries = _ref2[1];
@@ -165,7 +165,7 @@ var FeatureSearch = /*#__PURE__*/function (_React$Component) {
165
165
  }, /*#__PURE__*/React.createElement("option", {
166
166
  disabled: true,
167
167
  value: ""
168
- }, LocaleUtils.tr("featuresearch.select")), options.map(function (entry) {
168
+ }, LocaleUtils.tr("common.select")), options.map(function (entry) {
169
169
  var _entry$value, _entry$value2, _entry$label;
170
170
  return /*#__PURE__*/React.createElement("option", {
171
171
  key: (_entry$value = entry.value) !== null && _entry$value !== void 0 ? _entry$value : entry,
@@ -195,7 +195,7 @@ var FeatureSearch = /*#__PURE__*/function (_React$Component) {
195
195
  className: "feature-search-results"
196
196
  }, isEmpty(_this.state.searchResults) ? /*#__PURE__*/React.createElement("div", {
197
197
  className: "feature-search-noresults"
198
- }, LocaleUtils.tr("featuresearch.noresults")) : /*#__PURE__*/React.createElement(IdentifyViewer, {
198
+ }, LocaleUtils.tr("common.noresults")) : /*#__PURE__*/React.createElement(IdentifyViewer, {
199
199
  collapsible: true,
200
200
  displayResultTree: false,
201
201
  enableExport: _this.props.enableExport,
@@ -32,6 +32,7 @@ import React from 'react';
32
32
  import { connect } from 'react-redux';
33
33
  import polySelfIntersections from 'geojson-polygon-self-intersections';
34
34
  import isEmpty from 'lodash.isempty';
35
+ import omit from 'lodash.omit';
35
36
  import PropTypes from 'prop-types';
36
37
  import { LayerRole, removeLayer, addLayerFeatures, removeLayerFeatures, clearLayer } from '../actions/layers';
37
38
  import { changeRedliningState, resetRedliningState } from '../actions/redlining';
@@ -42,6 +43,7 @@ import ButtonBar from '../components/widgets/ButtonBar';
42
43
  import NumberInput from '../components/widgets/NumberInput';
43
44
  import Spinner from '../components/widgets/Spinner';
44
45
  import ConfigUtils from '../utils/ConfigUtils';
46
+ import { EXCLUDE_ATTRS, EXCLUDE_PROPS } from '../utils/IdentifyUtils';
45
47
  import LocaleUtils from '../utils/LocaleUtils';
46
48
  import MiscUtils from '../utils/MiscUtils';
47
49
  import VectorLayerUtils from '../utils/VectorLayerUtils';
@@ -65,21 +67,26 @@ import './style/Redlining.css';
65
67
  * "pluginData": {
66
68
  * "geometryLinks": [
67
69
  * {
68
- * "name": "<geomLinkName>", // Link name referenced in theme item
69
- * "title": "<geomLinkTitle>", // Link title, displayed in the selection combo
70
- * "geomType": ["<geomType>", "<geomType>"] // Supported geometry types (Point, LineString, Polygon)
71
- * "url": "<targetApplicationUrl>", // Application target URL, receiving the POST submit
72
- * "params": {"<key>": "<value>", ...} // Optional: additional form parameters to post to URL
73
- * "target": "<target>" | { // Optional: form POST target which to display the result
74
- * "iframedialog": true, // Use an iframe dialog
75
- * "w": <dialogWidth>, // Dialog width
76
- * "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
77
80
  * }
78
81
  * }
79
82
  * ]
80
83
  * }
81
84
  * }
82
85
  * ```
86
+ * If you are using `qwc-services`, you will need to explicitly permit the geometry links in the `qwc-admin-gui` as follows:
87
+ *
88
+ * * Create and permit a `Plugin` resource with name `geometryLinks`
89
+ * * Create and permit `Plugin data` resources with name equal to `<geomLinkName>`
83
90
  */
84
91
  var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
85
92
  function GeometryDigitizer(props) {
@@ -109,7 +116,7 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
109
116
  _this.props.resetRedliningState();
110
117
  });
111
118
  _defineProperty(_this, "renderBody", function () {
112
- var _this$props$layers$fi, _geomLinkData$target, _geomLinkData$target2, _this$props$theme$plu;
119
+ var _this$props$layers$fi, _geomLinkData$target, _geomLinkData$target2, _this$props$theme$plu, _geomLinkData$url;
113
120
  var geomLinkData = _this.geometryLinkData(_this.state.geomLink);
114
121
  var activeButton = null;
115
122
  if (_this.state.pickGeomType) {
@@ -129,7 +136,7 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
129
136
  }
130
137
  } : {
131
138
  key: "Point",
132
- tooltip: LocaleUtils.tr("redlining.point"),
139
+ tooltip: LocaleUtils.tr("common.point"),
133
140
  icon: "point",
134
141
  data: {
135
142
  action: "Draw",
@@ -148,7 +155,7 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
148
155
  }
149
156
  } : {
150
157
  key: "LineString",
151
- tooltip: LocaleUtils.tr("redlining.line"),
158
+ tooltip: LocaleUtils.tr("common.line"),
152
159
  icon: "line",
153
160
  data: {
154
161
  action: "Draw",
@@ -158,7 +165,7 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
158
165
  disabled: !supportedGeomType.includes("LineString")
159
166
  }, {
160
167
  key: "Polygon",
161
- tooltip: LocaleUtils.tr("redlining.polygon"),
168
+ tooltip: LocaleUtils.tr("common.polygon"),
162
169
  icon: "polygon",
163
170
  data: {
164
171
  action: "Draw",
@@ -169,7 +176,7 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
169
176
  }];
170
177
  var editButtons = [{
171
178
  key: "Pick",
172
- tooltip: LocaleUtils.tr("redlining.pick"),
179
+ tooltip: LocaleUtils.tr("common.pick"),
173
180
  icon: "pick",
174
181
  data: {
175
182
  action: "Pick",
@@ -178,7 +185,7 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
178
185
  }
179
186
  }, {
180
187
  key: "Delete",
181
- tooltip: LocaleUtils.tr("redlining.delete"),
188
+ tooltip: LocaleUtils.tr("common.delete"),
182
189
  icon: "trash",
183
190
  data: {
184
191
  action: "Delete",
@@ -237,7 +244,7 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
237
244
  }
238
245
  })), /*#__PURE__*/React.createElement("div", {
239
246
  className: "redlining-groupcontrol"
240
- }, /*#__PURE__*/React.createElement("div", null, LocaleUtils.tr("redlining.pick")), /*#__PURE__*/React.createElement(ButtonBar, {
247
+ }, /*#__PURE__*/React.createElement("div", null, LocaleUtils.tr("common.pick")), /*#__PURE__*/React.createElement(ButtonBar, {
241
248
  active: activeButton,
242
249
  buttons: pickButtons,
243
250
  onClick: function onClick(key, data) {
@@ -271,7 +278,7 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
271
278
  value: entry
272
279
  }, _this.geometryLinkData(entry).title);
273
280
  })), /*#__PURE__*/React.createElement("form", {
274
- action: geomLinkData.url,
281
+ action: (_geomLinkData$url = geomLinkData.url) === null || _geomLinkData$url === void 0 ? void 0 : _geomLinkData$url.replace('$username$', ConfigUtils.getConfigProp("username") || ""),
275
282
  method: "post",
276
283
  onSubmit: _this.submitGeometryLink,
277
284
  target: target
@@ -335,7 +342,7 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
335
342
  className: "geomdigitizer-output-window-body"
336
343
  }, !_this.state.outputLoaded ? /*#__PURE__*/React.createElement("span", {
337
344
  className: "geomdigitizer-output-window-wait"
338
- }, /*#__PURE__*/React.createElement(Spinner, null), " ", /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("geomdigitizer.wait"))) : null, /*#__PURE__*/React.createElement("iframe", {
345
+ }, /*#__PURE__*/React.createElement(Spinner, null), " ", /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("common.loading"))) : null, /*#__PURE__*/React.createElement("iframe", {
339
346
  name: "geomdigitizer-output-window",
340
347
  onLoad: function onLoad() {
341
348
  return _this.setState({
@@ -492,19 +499,26 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
492
499
  }
493
500
  var data = _this.geometryLinkData(_this.state.geomLink);
494
501
  var supportedGeomType = data.geomType || [];
495
- var geometries = features.filter(function (feature) {
502
+ var supportedFeatures = features.filter(function (feature) {
496
503
  return supportedGeomType.includes(_this.state.bufferDistance > 0 ? "Polygon" : feature.geometry.type.replace(/^Multi/, ''));
497
- }).map(function (feature) {
498
- return VectorLayerUtils.geoJSONGeomToWkt(feature.geometry);
499
504
  });
500
- if (isEmpty(geometries)) {
505
+ if (isEmpty(supportedFeatures)) {
501
506
  ev.preventDefault();
502
507
  return;
503
- } else {
504
- ev.target.GEOMETRIES.value = geometries.join(";");
505
- ev.target.GEOMCOUNT.value = geometries.length;
506
- ev.target.BUFFERDIST.value = _this.state.bufferDistance;
507
508
  }
509
+ var geometries = (data.format || "wkt").toLowerCase() === "wkt" ? supportedFeatures.map(function (feature) {
510
+ return VectorLayerUtils.geoJSONGeomToWkt(feature.geometry);
511
+ }).join(";") : JSON.stringify({
512
+ type: "FeatureCollection",
513
+ features: supportedFeatures.map(function (feature) {
514
+ var newFeature = omit(feature, EXCLUDE_PROPS);
515
+ newFeature.properties = omit(newFeature.properties, EXCLUDE_ATTRS);
516
+ return newFeature;
517
+ })
518
+ });
519
+ ev.target.GEOMETRIES.value = geometries;
520
+ ev.target.GEOMCOUNT.value = supportedFeatures.length;
521
+ ev.target.BUFFERDIST.value = _this.state.bufferDistance;
508
522
  if (ev.target.target === "geomdigitizer-output-window") {
509
523
  _this.setState({
510
524
  outputWindowVisible: true,
@@ -230,7 +230,7 @@ var Identify = /*#__PURE__*/function (_React$Component) {
230
230
  });
231
231
  _defineProperty(_this, "parseResult", function (response, layer, format, clickPoint) {
232
232
  var ctrlPick = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
233
- var newResults = IdentifyUtils.parseResponse(response, layer, format, clickPoint, _this.props.map.projection, _this.props.featureInfoReturnsLayerName);
233
+ var newResults = IdentifyUtils.parseResponse(response, layer, format, clickPoint, _this.props.map.projection);
234
234
  // Merge with previous
235
235
  _this.setState(function (state) {
236
236
  var identifyResults = _objectSpread({}, state.identifyResults);
@@ -481,8 +481,6 @@ _defineProperty(Identify, "propTypes", {
481
481
  exitTaskOnResultsClose: PropTypes.bool,
482
482
  /** Whether to include the geometry in exported features. Default: `true`. */
483
483
  exportGeometry: PropTypes.bool,
484
- /** Whether to assume that XML GetFeatureInfo responses specify the technical layer name in the `name` attribute, rather than the layer title. */
485
- featureInfoReturnsLayerName: PropTypes.bool,
486
484
  /** Default window geometry with size, position and docking status. Positive position values (including '0') are related to top (InitialY) and left (InitialX), negative values (including '-0') to bottom (InitialY) and right (InitialX). */
487
485
  geometry: PropTypes.shape({
488
486
  initialWidth: PropTypes.number,
@@ -527,7 +525,6 @@ _defineProperty(Identify, "defaultProps", {
527
525
  resultDisplayMode: 'flat',
528
526
  resultGridSize: 200,
529
527
  replaceImageUrls: true,
530
- featureInfoReturnsLayerName: true,
531
528
  geometry: {
532
529
  initialWidth: 240,
533
530
  initialHeight: 320,
@@ -169,7 +169,7 @@ var MapExport = /*#__PURE__*/function (_React$Component) {
169
169
  }
170
170
  }, /*#__PURE__*/React.createElement("table", {
171
171
  className: "options-table"
172
- }, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("mapexport.format")), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("select", {
172
+ }, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("common.format")), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("select", {
173
173
  onChange: _this.changeFormat,
174
174
  value: _this.state.selectedFormat
175
175
  }, _this.state.availableFormats.map(function (format) {
@@ -199,7 +199,7 @@ var MapExport = /*#__PURE__*/function (_React$Component) {
199
199
  key: "size_" + idx,
200
200
  value: idx
201
201
  }, entry.name);
202
- })))) : null, scaleChooser && _this.state.pageSize !== null ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("mapexport.scale")), /*#__PURE__*/React.createElement("td", null, scaleChooser)) : null, _this.props.dpis && _this.state.selectedFormat !== "application/dxf" ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("mapexport.resolution")), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("select", {
202
+ })))) : null, scaleChooser && _this.state.pageSize !== null ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("mapexport.scale")), /*#__PURE__*/React.createElement("td", null, scaleChooser)) : null, _this.props.dpis && _this.state.selectedFormat !== "application/dxf" ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("common.resolution")), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("select", {
203
203
  onChange: _this.changeResolution,
204
204
  value: _this.state.dpi
205
205
  }, _this.props.dpis.map(function (dpi) {
@@ -227,7 +227,7 @@ var MapExport = /*#__PURE__*/function (_React$Component) {
227
227
  type: "submit"
228
228
  }, _this.state.exporting ? /*#__PURE__*/React.createElement("span", {
229
229
  className: "mapexport-wait"
230
- }, /*#__PURE__*/React.createElement(Spinner, null), " ", LocaleUtils.tr("mapexport.wait")) : LocaleUtils.tr("mapexport.submit")))));
230
+ }, /*#__PURE__*/React.createElement(Spinner, null), " ", LocaleUtils.tr("common.wait")) : LocaleUtils.tr("common.export")))));
231
231
  });
232
232
  _defineProperty(_this, "renderPrintSelection", function () {
233
233
  if (_this.state.pageSize !== null) {
@@ -517,7 +517,7 @@ var MapExport = /*#__PURE__*/function (_React$Component) {
517
517
  key: "render",
518
518
  value: function render() {
519
519
  var _this2 = this;
520
- var minMaxTooltip = this.state.minimized ? LocaleUtils.tr("print.maximize") : LocaleUtils.tr("print.minimize");
520
+ var minMaxTooltip = this.state.minimized ? LocaleUtils.tr("window.maximize") : LocaleUtils.tr("window.minimize");
521
521
  var extraTitlebarContent = /*#__PURE__*/React.createElement(Icon, {
522
522
  className: "mapexport-minimize-maximize",
523
523
  icon: this.state.minimized ? 'chevron-down' : 'chevron-up',
@@ -290,12 +290,12 @@ var MapFilter = /*#__PURE__*/function (_React$Component) {
290
290
  var commitButtons = [{
291
291
  key: 'Save',
292
292
  icon: 'ok',
293
- label: LocaleUtils.tr("mapfilter.save"),
293
+ label: LocaleUtils.tr("common.save"),
294
294
  extraClasses: "button-accept"
295
295
  }, {
296
296
  key: 'Cancel',
297
297
  icon: 'remove',
298
- label: LocaleUtils.tr("mapfilter.cancel"),
298
+ label: LocaleUtils.tr("common.cancel"),
299
299
  extraClasses: "button-reject"
300
300
  }];
301
301
  var sampleFilters = '["field", "=", "val"]\n' + '[["field", ">", "val1"], "and", ["field", "<", "val2"]]';
@@ -389,7 +389,7 @@ var MapFilter = /*#__PURE__*/function (_React$Component) {
389
389
  value: _this.state.filters[config.id].values[field.id]
390
390
  }, !field.defaultValue ? /*#__PURE__*/React.createElement("option", {
391
391
  value: ""
392
- }, LocaleUtils.tr("mapfilter.select")) : null, field.inputConfig.options.map(function (entry) {
392
+ }, LocaleUtils.tr("common.select")) : null, field.inputConfig.options.map(function (entry) {
393
393
  var _entry$value, _entry$value2, _entry$label;
394
394
  return /*#__PURE__*/React.createElement("option", {
395
395
  key: (_entry$value = entry.value) !== null && _entry$value !== void 0 ? _entry$value : entry,
@@ -483,7 +483,7 @@ var MapFilter = /*#__PURE__*/function (_React$Component) {
483
483
  onChange: function onChange(value) {
484
484
  return _this.updateCustomFilter(key, 'layer', value);
485
485
  },
486
- placeholder: LocaleUtils.tr("mapfilter.selectlayer"),
486
+ placeholder: LocaleUtils.tr("common.selectlayer"),
487
487
  value: entry.layer
488
488
  }, layerNames.map(function (layerName) {
489
489
  return /*#__PURE__*/React.createElement("div", {
@@ -518,19 +518,19 @@ var MapFilter = /*#__PURE__*/function (_React$Component) {
518
518
  var geomFilter = _this.state.geomFilter;
519
519
  var filterButtons = [{
520
520
  key: "Polygon",
521
- tooltip: LocaleUtils.tr("redlining.polygon"),
521
+ tooltip: LocaleUtils.tr("common.polygon"),
522
522
  icon: "polygon",
523
- label: LocaleUtils.tr("redlining.polygon")
523
+ label: LocaleUtils.tr("common.polygon")
524
524
  }, {
525
525
  key: "Circle",
526
- tooltip: LocaleUtils.tr("redlining.circle"),
526
+ tooltip: LocaleUtils.tr("common.circle"),
527
527
  icon: "circle",
528
- label: LocaleUtils.tr("redlining.circle")
528
+ label: LocaleUtils.tr("common.circle")
529
529
  }, {
530
530
  key: "Pick",
531
- tooltip: LocaleUtils.tr("redlining.pick"),
531
+ tooltip: LocaleUtils.tr("common.pick"),
532
532
  icon: "pick",
533
- label: LocaleUtils.tr("redlining.pick")
533
+ label: LocaleUtils.tr("common.pick")
534
534
  }];
535
535
  var active = geomFilter.picking ? "Pick" : geomFilter.geomType || "";
536
536
  return /*#__PURE__*/React.createElement("div", {
@@ -57,7 +57,7 @@ var NewsPopup = /*#__PURE__*/function (_React$Component) {
57
57
  className: "newspopup-dialog-popup-buttonbar"
58
58
  }, /*#__PURE__*/React.createElement("button", {
59
59
  onClick: _this.closeDialog
60
- }, LocaleUtils.tr("newspopup.dialogclose")), /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
60
+ }, LocaleUtils.tr("common.close")), /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
61
61
  onChange: function onChange(ev) {
62
62
  return _this.setState({
63
63
  dontShowAgain: ev.target.checked