qwc2 2026.2.24 → 2026.2.27

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.
@@ -1098,22 +1098,7 @@ var AttributeTableWidget = /*#__PURE__*/function (_React$Component) {
1098
1098
  sitekey: ConfigUtils.getConfigProp("editServiceCaptchaSiteKey")
1099
1099
  }));
1100
1100
  }
1101
- return /*#__PURE__*/React.createElement("div", {
1102
- className: "AttributeTable"
1103
- }, /*#__PURE__*/React.createElement("div", {
1104
- className: "attribtable-toolbar"
1105
- }, this.props.showLayerSelection ? /*#__PURE__*/React.createElement("select", {
1106
- disabled: loading || editing,
1107
- onChange: function onChange(ev) {
1108
- return _this2.setState({
1109
- selectedLayer: ev.target.value
1110
- });
1111
- },
1112
- value: this.state.selectedLayer || ""
1113
- }, /*#__PURE__*/React.createElement("option", {
1114
- disabled: true,
1115
- value: ""
1116
- }, LocaleUtils.tr("common.selectlayer")), Object.entries(this.props.editConfigs).map(function (_ref3) {
1101
+ var editLayers = Object.entries(this.props.editConfigs).map(function (_ref3) {
1117
1102
  var _ref4 = _slicedToArray(_ref3, 2),
1118
1103
  wmsName = _ref4[0],
1119
1104
  serviceConfigs = _ref4[1];
@@ -1134,12 +1119,34 @@ var AttributeTableWidget = /*#__PURE__*/function (_React$Component) {
1134
1119
  })) === null || _this2$props$layers$f === void 0 ? void 0 : _this2$props$layers$f.translations;
1135
1120
  layerTitle = (_ref9 = (_translations$layertr = translations === null || translations === void 0 || (_translations$layertr2 = translations.layertree) === null || _translations$layertr2 === void 0 ? void 0 : _translations$layertr2[layerName]) !== null && _translations$layertr !== void 0 ? _translations$layertr : editConfig.layerTitle) !== null && _ref9 !== void 0 ? _ref9 : layerName;
1136
1121
  }
1137
- var value = wmsName + "#" + layerName;
1138
- return /*#__PURE__*/React.createElement("option", {
1139
- key: value,
1140
- value: value
1141
- }, layerTitle);
1122
+ return {
1123
+ value: wmsName + "#" + layerName,
1124
+ title: layerTitle
1125
+ };
1142
1126
  });
1127
+ }).flat().filter(Boolean).sort(function (a, b) {
1128
+ return a.title.localeCompare(b.title);
1129
+ });
1130
+ return /*#__PURE__*/React.createElement("div", {
1131
+ className: "AttributeTable"
1132
+ }, /*#__PURE__*/React.createElement("div", {
1133
+ className: "attribtable-toolbar"
1134
+ }, this.props.showLayerSelection ? /*#__PURE__*/React.createElement("select", {
1135
+ disabled: loading || editing,
1136
+ onChange: function onChange(ev) {
1137
+ return _this2.setState({
1138
+ selectedLayer: ev.target.value
1139
+ });
1140
+ },
1141
+ value: this.state.selectedLayer || ""
1142
+ }, /*#__PURE__*/React.createElement("option", {
1143
+ disabled: true,
1144
+ value: ""
1145
+ }, LocaleUtils.tr("common.selectlayer")), editLayers.map(function (entry) {
1146
+ return /*#__PURE__*/React.createElement("option", {
1147
+ key: entry.value,
1148
+ value: entry.value
1149
+ }, entry.title);
1143
1150
  })) : null, /*#__PURE__*/React.createElement("button", {
1144
1151
  className: "button",
1145
1152
  disabled: !this.state.selectedLayer || editing || loading,
@@ -866,7 +866,7 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
866
866
  });
867
867
  });
868
868
  _defineProperty(_this, "startSearch", function () {
869
- var _this$state$filterGeo2;
869
+ var _ref5, _this$state$filterGeo2;
870
870
  var provider = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
871
871
  var uniquePlaceResult = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
872
872
  var availableProviders = _this.props.searchProviders;
@@ -893,15 +893,16 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
893
893
  var searchParams = {
894
894
  mapcrs: _this.props.map.projection,
895
895
  displaycrs: _this.props.map.displayCrs,
896
+ extracrs: (_ref5 = _this.props.searchOptions.extraCoordinateSearchCrs === "mousecrs" ? _this.props.theme.additionalMouseCrs : _this.props.searchOptions.extraCoordinateSearchCrs) !== null && _ref5 !== void 0 ? _ref5 : [],
896
897
  lang: LocaleUtils.lang(),
897
898
  limit: _this.props.searchOptions.resultLimit,
898
899
  filterPoly: (_this$state$filterGeo2 = _this.state.filterGeometry) === null || _this$state$filterGeo2 === void 0 || (_this$state$filterGeo2 = _this$state$filterGeo2.coordinates) === null || _this$state$filterGeo2 === void 0 ? void 0 : _this$state$filterGeo2[0],
899
900
  filterBBox: _this.state.filterGeometry ? VectorLayerUtils.computeFeatureBBox(_this.state.filterGeometry) : null
900
901
  };
901
- Object.entries(availableProviders).forEach(function (_ref5) {
902
- var _ref6 = _slicedToArray(_ref5, 2),
903
- provKey = _ref6[0],
904
- prov = _ref6[1];
902
+ Object.entries(availableProviders).forEach(function (_ref6) {
903
+ var _ref7 = _slicedToArray(_ref6, 2),
904
+ provKey = _ref7[0],
905
+ prov = _ref7[1];
905
906
  prov.onSearch(searchText, _objectSpread(_objectSpread({
906
907
  cfgParams: prov.cfgParams
907
908
  }, prov.params), searchParams), function (response) {
@@ -930,10 +931,10 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
930
931
  return entry !== provKey;
931
932
  });
932
933
  if (isEmpty(newPendingSearches) && uniquePlaceResult) {
933
- var providersWithResults = Object.entries(searchResults).filter(function (_ref7) {
934
- var _ref8 = _slicedToArray(_ref7, 2),
935
- _ = _ref8[0],
936
- providerResults = _ref8[1];
934
+ var providersWithResults = Object.entries(searchResults).filter(function (_ref8) {
935
+ var _ref9 = _slicedToArray(_ref8, 2),
936
+ _ = _ref9[0],
937
+ providerResults = _ref9[1];
937
938
  return providerResults.tot_result_count > 0;
938
939
  });
939
940
  if (providersWithResults.length === 1 && providersWithResults[0][1].tot_result_count === 1) {
@@ -1076,8 +1077,8 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
1076
1077
  }
1077
1078
  // Label first feature
1078
1079
  if (!_this.props.searchOptions.hideResultLabels) {
1079
- var _ref9, _item$label;
1080
- var label = ((_ref9 = (_item$label = item.label) !== null && _item$label !== void 0 ? _item$label : item.text) !== null && _ref9 !== void 0 ? _ref9 : '').replace(/<\/?\w+\s*\/?>/g, '');
1080
+ var _ref0, _item$label;
1081
+ var label = ((_ref0 = (_item$label = item.label) !== null && _item$label !== void 0 ? _item$label : item.text) !== null && _ref0 !== void 0 ? _ref0 : '').replace(/<\/?\w+\s*\/?>/g, '');
1081
1082
  features[0].properties = _objectSpread(_objectSpread({}, features[0].properties), {}, {
1082
1083
  label: label
1083
1084
  });
@@ -1097,8 +1098,8 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
1097
1098
  styleName: 'marker'
1098
1099
  };
1099
1100
  if (!_this.props.searchOptions.hideResultLabels) {
1100
- var _ref0, _item$label2;
1101
- var _label = ((_ref0 = (_item$label2 = item.label) !== null && _item$label2 !== void 0 ? _item$label2 : item.text) !== null && _ref0 !== void 0 ? _ref0 : '').replace(/<\/?\w+\s*\/?>/g, '');
1101
+ var _ref1, _item$label2;
1102
+ var _label = ((_ref1 = (_item$label2 = item.label) !== null && _item$label2 !== void 0 ? _item$label2 : item.text) !== null && _ref1 !== void 0 ? _ref1 : '').replace(/<\/?\w+\s*\/?>/g, '');
1102
1103
  marker.properties = {
1103
1104
  label: _label
1104
1105
  };
@@ -1266,6 +1267,7 @@ _defineProperty(SearchBox, "propTypes", {
1266
1267
  searchOptions: PropTypes.shape({
1267
1268
  allowAddLayerAsGroup: PropTypes.bool,
1268
1269
  allowSearchFilters: PropTypes.bool,
1270
+ extraCoordinateSearchCrs: PropTypes.oneOfType([PropTypes.array, PropTypes.string]),
1269
1271
  focusOnStartup: PropTypes.bool,
1270
1272
  hideResultLabels: PropTypes.bool,
1271
1273
  highlightStyle: PropTypes.object,
@@ -170,7 +170,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
170
170
  var _this2$state$sceneCon;
171
171
  var currentBaseLayer = ((_this2$state$sceneCon = _this2.state.sceneContext.baseLayers.find(function (l) {
172
172
  return l.visibility === true;
173
- })) === null || _this2$state$sceneCon === void 0 ? void 0 : _this2$state$sceneCon.name) || "";
173
+ })) === null || _this2$state$sceneCon === void 0 ? void 0 : _this2$state$sceneCon.name) || null;
174
174
  if (visibility && layer.name === currentBaseLayer) {
175
175
  // Nothing changed
176
176
  return;
@@ -594,7 +594,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
594
594
  }
595
595
  // Ensure labels are removed
596
596
  object.traverse(function (c) {
597
- if (c.isCSS2DObject) {
597
+ if (c.isCSS2DObject && c.element.parentNode) {
598
598
  c.element.parentNode.removeChild(c.element);
599
599
  }
600
600
  });
@@ -645,6 +645,9 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
645
645
  });
646
646
  _defineProperty(_this2, "applySceneObjectState", function (objectId, options, prevOptions, objectTree) {
647
647
  var object = _this2.objectMap[objectId];
648
+ if (!object) {
649
+ return;
650
+ }
648
651
  var changed = false;
649
652
  if (options.visibility !== prevOptions.visibility || options.opacity !== (prevOptions === null || prevOptions === void 0 ? void 0 : prevOptions.opacity)) {
650
653
  var _objectTree$options$p;
@@ -935,7 +938,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
935
938
  visibility: (_entry$visibility3 = entry.visibility) !== null && _entry$visibility3 !== void 0 ? _entry$visibility3 : true,
936
939
  opacity: 255
937
940
  };
938
- _this2.importObject3D(entry, entry.name, false, {}, false, function () {
941
+ _this2.importObject3D(MiscUtils.resolveAssetsPath(entry.url), entry.name, false, {}, false, function () {
939
942
  _this2.applySceneObjectState(entry.name, objectTree[entry.name], {}, objectTree);
940
943
  });
941
944
  nodeIds.push(entry.name);
@@ -1300,10 +1303,13 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
1300
1303
  }
1301
1304
  });
1302
1305
  _this2.state.sceneContext.restoreView(data);
1303
- var bl3d = (_data$baseLayer = data.baseLayer) !== null && _data$baseLayer !== void 0 ? _data$baseLayer : "";
1304
- _this2.setBaseLayer({
1305
- name: bl3d
1306
- }, bl3d !== "null");
1306
+ if (((_data$baseLayer = data.baseLayer) !== null && _data$baseLayer !== void 0 ? _data$baseLayer : null) !== null) {
1307
+ var _data$baseLayer2;
1308
+ var bl3d = (_data$baseLayer2 = data.baseLayer) !== null && _data$baseLayer2 !== void 0 ? _data$baseLayer2 : "";
1309
+ _this2.setBaseLayer({
1310
+ name: bl3d
1311
+ }, bl3d !== "null");
1312
+ }
1307
1313
  _this2.state.sceneContext.scene.notifyChange();
1308
1314
  });
1309
1315
  _this2.container = null;
@@ -1383,11 +1389,16 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
1383
1389
  this.setState(function (state) {
1384
1390
  return {
1385
1391
  sceneContext: _objectSpread(_objectSpread({}, state.sceneContext), {}, {
1386
- collisionObjects: Object.entries(state.sceneContext.objectTree).reduce(function (res, entry) {
1392
+ collisionObjects: Object.entries(state.sceneContext.objectTree).reduce(function (res, _ref12) {
1393
+ var _ref13 = _slicedToArray(_ref12, 2),
1394
+ objectid = _ref13[0],
1395
+ entry = _ref13[1];
1387
1396
  if (entry.visibility && entry.opacity > 0) {
1388
- var _obj$tiles$group, _obj$tiles;
1389
1397
  var obj = _this3.objectMap[entry.objectId];
1390
- res.push((_obj$tiles$group = (_obj$tiles = obj.tiles) === null || _obj$tiles === void 0 ? void 0 : _obj$tiles.group) !== null && _obj$tiles$group !== void 0 ? _obj$tiles$group : obj);
1398
+ if (obj) {
1399
+ var _obj$tiles$group, _obj$tiles;
1400
+ res.push((_obj$tiles$group = (_obj$tiles = obj.tiles) === null || _obj$tiles === void 0 ? void 0 : _obj$tiles.group) !== null && _obj$tiles$group !== void 0 ? _obj$tiles$group : obj);
1401
+ }
1391
1402
  }
1392
1403
  return res;
1393
1404
  }, [])
@@ -1428,10 +1439,10 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
1428
1439
  sceneContext: this.state.sceneContext
1429
1440
  }), /*#__PURE__*/React.createElement(ViewSwitcher, {
1430
1441
  position: 1
1431
- }), Object.entries(this.props.plugins3d).map(function (_ref12) {
1432
- var _ref13 = _slicedToArray(_ref12, 2),
1433
- name = _ref13[0],
1434
- Component = _ref13[1];
1442
+ }), Object.entries(this.props.plugins3d).map(function (_ref14) {
1443
+ var _ref15 = _slicedToArray(_ref14, 2),
1444
+ name = _ref15[0],
1445
+ Component = _ref15[1];
1435
1446
  return /*#__PURE__*/React.createElement(Suspense, {
1436
1447
  key: name
1437
1448
  }, /*#__PURE__*/React.createElement(Component, _extends({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2026.02.24",
3
+ "version": "2026.02.27",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
package/plugins/API.js CHANGED
@@ -154,6 +154,16 @@ var actionFunctions = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_o
154
154
  * "params": [[2684764, 1247841], 18, "EPSG:2056"]
155
155
  * }, "http://<qwc_hostname>:<port>")
156
156
  * ```
157
+ * You can also post multiple calls at once as follows:
158
+ * ```
159
+ * qwcframe.contentWindow.postMessage([{
160
+ * "method": "zoomToPoint",
161
+ * "params": [[2684764, 1247841], 18, "EPSG:2056"]
162
+ * }, {
163
+ * "method": "addMarker",
164
+ * "params": ["mymarker", [2684764, 1247841], "Hello world", "EPSG:2056"]
165
+ * }], "http://<qwc_hostname>:<port>")
166
+ * ```
157
167
  * If you call a method which returns a value, pass a `requestId` and listen to response messages:
158
168
  *
159
169
  * ```
@@ -259,21 +269,17 @@ var actionFunctions = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_o
259
269
  * In addition, the following methods are available on `window.qwc2`:
260
270
  */
261
271
  var API = /*#__PURE__*/function (_React$Component) {
262
- function API() {
272
+ function API(props) {
263
273
  var _this;
264
274
  _classCallCheck(this, API);
265
- for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {
266
- _args[_key] = arguments[_key];
267
- }
268
- _this = _callSuper(this, API, [].concat(_args));
275
+ _this = _callSuper(this, API, [props]);
269
276
  _defineProperty(_this, "handleMessage", function (ev) {
270
- var _ev$data;
271
277
  if (!_this.props.allowedMessageOrigins.includes(ev.origin)) {
272
278
  /* eslint-disable-next-line */
273
279
  console.warn("Discarding message from not-allowed origin " + ev.origin);
274
280
  return;
275
281
  }
276
- var allowedMemberFunctions = ["addExternalLayer", "getState"];
282
+ var allowedMemberFunctions = ["addExternalLayer", "getState", "drawGeometry", "onMapClick"];
277
283
  if (ev.data === "help") {
278
284
  var signatures = Object.fromEntries(Object.entries(actionFunctions).map(function (_ref3) {
279
285
  var _val$toString$match$, _val$toString$match;
@@ -289,28 +295,57 @@ var API = /*#__PURE__*/function (_React$Component) {
289
295
  /* eslint-disable-next-line */
290
296
  console.log(signatures);
291
297
  }
292
- if ((_ev$data = ev.data) !== null && _ev$data !== void 0 && _ev$data.method) {
293
- var _ev$data$params;
294
- var func = ev.data.method;
295
- var args = (_ev$data$params = ev.data.params) !== null && _ev$data$params !== void 0 ? _ev$data$params : [];
296
- var result = null;
297
- if (func in actionFunctions) {
298
- var _this$props;
299
- result = (_this$props = _this.props)[func].apply(_this$props, _toConsumableArray(args));
300
- } else if (allowedMemberFunctions.includes(func)) {
301
- var _this2;
302
- result = (_this2 = _this)[func].apply(_this2, _toConsumableArray(args));
303
- } else {
304
- /* eslint-disable-next-line */
305
- console.warn("Unhandeled message: " + JSON.stringify(ev.data));
306
- }
307
- if (ev.data.requestId) {
308
- ev.source.postMessage({
309
- requestId: ev.data.requestId,
310
- result: result
311
- }, ev.origin);
298
+ var messages = Array.isArray(ev.data) ? ev.data : [ev.data];
299
+ messages.forEach(function (message) {
300
+ if (message !== null && message !== void 0 && message.method) {
301
+ var _message$params;
302
+ var func = message.method;
303
+ var args = (_message$params = message.params) !== null && _message$params !== void 0 ? _message$params : [];
304
+ var result = null;
305
+ var postResult = true;
306
+ if (func in actionFunctions) {
307
+ var _this$props;
308
+ result = (_this$props = _this.props)[func].apply(_this$props, _toConsumableArray(args));
309
+ } else if (allowedMemberFunctions.includes(func)) {
310
+ var _this2;
311
+ // Inject proper callback function
312
+ if (func === "drawGeometry") {
313
+ args.splice(2, 0, function (features, crs) {
314
+ if (message.requestId) {
315
+ ev.source.postMessage({
316
+ requestId: message.requestId,
317
+ result: {
318
+ features: features,
319
+ crs: crs
320
+ }
321
+ }, ev.origin);
322
+ }
323
+ });
324
+ postResult = false;
325
+ } else if (func === "onMapClick") {
326
+ args = [function (click) {
327
+ if (message.requestId) {
328
+ ev.source.postMessage({
329
+ requestId: message.requestId,
330
+ result: click
331
+ }, ev.origin);
332
+ }
333
+ }];
334
+ postResult = false;
335
+ }
336
+ result = (_this2 = _this)[func].apply(_this2, _toConsumableArray(args));
337
+ } else {
338
+ /* eslint-disable-next-line */
339
+ console.warn("Unhandeled message: " + JSON.stringify(message));
340
+ }
341
+ if (postResult && message.requestId) {
342
+ ev.source.postMessage({
343
+ requestId: message.requestId,
344
+ result: result
345
+ }, ev.origin);
346
+ }
312
347
  }
313
- }
348
+ });
314
349
  });
315
350
  /**
316
351
  * Add custom plugin
@@ -434,7 +469,9 @@ var API = /*#__PURE__*/function (_React$Component) {
434
469
  });
435
470
  });
436
471
  /**
437
- * Draw geometries, and return these as GeoJSON to the calling application.
472
+ * Draw geometries, and return these as GeoJSON to the calling application.
473
+ *
474
+ * *NOTE*: when calling `drawGeometry` through the `postMessage` interface, omit the `callback` parameter. The response will be sent via the response message.
438
475
  *
439
476
  * * `geomType`: `Point`, `LineString`, `Polygon`, `Circle` or `Box`.
440
477
  * * `message`: A descriptive string to display in the tool taskbar.
@@ -465,6 +502,11 @@ var API = /*#__PURE__*/function (_React$Component) {
465
502
  _defineProperty(_this, "getState", function () {
466
503
  return _this.props.state;
467
504
  });
505
+ /** Fires the callback on the next click on the map. */
506
+ _defineProperty(_this, "onMapClick", function (callback) {
507
+ _this.onclickCallbacks.push(callback);
508
+ });
509
+ _this.onclickCallbacks = [];
468
510
  return _this;
469
511
  }
470
512
  _inherits(API, _React$Component);
@@ -577,6 +619,17 @@ var API = /*#__PURE__*/function (_React$Component) {
577
619
  window.addEventListener("message", this.handleMessage);
578
620
  window.dispatchEvent(new Event("QWC2ApiReady"));
579
621
  }
622
+ }, {
623
+ key: "componentDidUpdate",
624
+ value: function componentDidUpdate(prevProps) {
625
+ var _this3 = this;
626
+ if (this.props.click !== prevProps.click && this.onclickCallbacks.length > 0) {
627
+ this.onclickCallbacks.forEach(function (cb) {
628
+ return cb(_objectSpread({}, _this3.props.click));
629
+ });
630
+ this.onclickCallbacks = [];
631
+ }
632
+ }
580
633
  }, {
581
634
  key: "render",
582
635
  value: function render() {
@@ -588,6 +641,7 @@ _defineProperty(API, "propTypes", {
588
641
  addLayer: PropTypes.func,
589
642
  /* List of origins which are allowed to post messages via `qwcIframe.postMessage`. */
590
643
  allowedMessageOrigins: PropTypes.arrayOf(PropTypes.string),
644
+ click: PropTypes.object,
591
645
  mapCrs: PropTypes.string,
592
646
  registerCustomPlugin: PropTypes.func,
593
647
  setCurrentTask: PropTypes.func,
@@ -599,6 +653,9 @@ _defineProperty(API, "defaultProps", {
599
653
  });
600
654
  export default connect(function (state) {
601
655
  return {
656
+ click: state.map.click || {
657
+ modifiers: {}
658
+ },
602
659
  mapCrs: state.map.projection,
603
660
  state: state
604
661
  };
@@ -245,21 +245,7 @@ var Editing = /*#__PURE__*/function (_React$Component) {
245
245
  translations: translations
246
246
  });
247
247
  }
248
- return /*#__PURE__*/React.createElement("div", {
249
- className: "editing-body"
250
- }, /*#__PURE__*/React.createElement("div", {
251
- className: "editing-layer-selection"
252
- }, /*#__PURE__*/React.createElement("select", {
253
- className: "combo editing-layer-select",
254
- disabled: _this.props.editContext.changed === true || _this.props.editContext.id !== _this.props.currentEditContext,
255
- onChange: function onChange(ev) {
256
- return _this.changeSelectedLayer(ev.target.value);
257
- },
258
- value: _this.state.selectedLayer || ""
259
- }, /*#__PURE__*/React.createElement("option", {
260
- disabled: true,
261
- value: ""
262
- }, LocaleUtils.tr("common.selectlayer")), Object.entries(_this.props.editConfigs).map(function (_ref) {
248
+ var editLayers = Object.entries(_this.props.editConfigs).map(function (_ref) {
263
249
  var _ref2 = _slicedToArray(_ref, 2),
264
250
  mapName = _ref2[0],
265
251
  serviceConfigs = _ref2[1];
@@ -278,12 +264,33 @@ var Editing = /*#__PURE__*/function (_React$Component) {
278
264
  return null;
279
265
  }
280
266
  var layerTitle = (_ref5 = (_ref6 = (_match$layer$translat = (_match$layer$translat2 = match.layer.translations) === null || _match$layer$translat2 === void 0 || (_match$layer$translat2 = _match$layer$translat2.layertree) === null || _match$layer$translat2 === void 0 ? void 0 : _match$layer$translat2[layerName]) !== null && _match$layer$translat !== void 0 ? _match$layer$translat : edConfig.layerTitle) !== null && _ref6 !== void 0 ? _ref6 : match === null || match === void 0 || (_match$sublayer = match.sublayer) === null || _match$sublayer === void 0 ? void 0 : _match$sublayer.title) !== null && _ref5 !== void 0 ? _ref5 : layerName;
281
- var value = mapName + "#" + layerName;
282
- return /*#__PURE__*/React.createElement("option", {
283
- key: value,
284
- value: value
285
- }, layerTitle);
267
+ return {
268
+ value: mapName + "#" + layerName,
269
+ title: layerTitle
270
+ };
286
271
  });
272
+ }).flat().filter(Boolean).sort(function (a, b) {
273
+ return a.title.localeCompare(b.title);
274
+ });
275
+ return /*#__PURE__*/React.createElement("div", {
276
+ className: "editing-body"
277
+ }, /*#__PURE__*/React.createElement("div", {
278
+ className: "editing-layer-selection"
279
+ }, /*#__PURE__*/React.createElement("select", {
280
+ className: "combo editing-layer-select",
281
+ disabled: _this.props.editContext.changed === true || _this.props.editContext.id !== _this.props.currentEditContext,
282
+ onChange: function onChange(ev) {
283
+ return _this.changeSelectedLayer(ev.target.value);
284
+ },
285
+ value: _this.state.selectedLayer || ""
286
+ }, /*#__PURE__*/React.createElement("option", {
287
+ disabled: true,
288
+ value: ""
289
+ }, LocaleUtils.tr("common.selectlayer")), editLayers.map(function (entry) {
290
+ return /*#__PURE__*/React.createElement("option", {
291
+ key: entry.value,
292
+ value: entry.value
293
+ }, entry.title);
287
294
  }))), /*#__PURE__*/React.createElement(ButtonBar, {
288
295
  active: _this.state.drawPick ? "Draw" : _this.props.editContext.action,
289
296
  buttons: actionButtons,
@@ -249,16 +249,7 @@ var FeatureForm = /*#__PURE__*/function (_React$Component) {
249
249
  translations: translations
250
250
  });
251
251
  }
252
- body = /*#__PURE__*/React.createElement("div", {
253
- className: "feature-query-body"
254
- }, Object.keys(this.state.pickedFeatures).length > 1 ? /*#__PURE__*/React.createElement("div", {
255
- className: "feature-query-selection"
256
- }, /*#__PURE__*/React.createElement("select", {
257
- onChange: function onChange(ev) {
258
- return _this2.setSelectedFeature(ev.target.value);
259
- },
260
- value: this.state.selectedFeature
261
- }, Object.entries(this.state.pickedFeatures).map(function (_ref7) {
252
+ var results = Object.entries(this.state.pickedFeatures).map(function (_ref7) {
262
253
  var _ref9, _ref0, _match$layer$translat, _match$layer$translat2, _match$sublayer;
263
254
  var _ref8 = _slicedToArray(_ref7, 2),
264
255
  id = _ref8[0],
@@ -272,10 +263,27 @@ var FeatureForm = /*#__PURE__*/function (_React$Component) {
272
263
  var match = LayerUtils.searchLayer(_this2.props.layers, 'wms_name', mapName, 'name', layerName);
273
264
  var layerTitle = (_ref9 = (_ref0 = (_match$layer$translat = (_match$layer$translat2 = match.layer.translations) === null || _match$layer$translat2 === void 0 || (_match$layer$translat2 = _match$layer$translat2.layertree) === null || _match$layer$translat2 === void 0 ? void 0 : _match$layer$translat2[layerName]) !== null && _match$layer$translat !== void 0 ? _match$layer$translat : editConfig.layerTitle) !== null && _ref0 !== void 0 ? _ref0 : match === null || match === void 0 || (_match$sublayer = match.sublayer) === null || _match$sublayer === void 0 ? void 0 : _match$sublayer.title) !== null && _ref9 !== void 0 ? _ref9 : layerName;
274
265
  var featureName = editConfig.displayField ? feature.properties[editConfig.displayField] : featureText + " " + featureId;
266
+ return {
267
+ value: id,
268
+ title: layerTitle + ": " + featureName
269
+ };
270
+ }).sort(function (a, b) {
271
+ return a.title.localeCompare(b.title);
272
+ });
273
+ body = /*#__PURE__*/React.createElement("div", {
274
+ className: "feature-query-body"
275
+ }, Object.keys(this.state.pickedFeatures).length > 1 ? /*#__PURE__*/React.createElement("div", {
276
+ className: "feature-query-selection"
277
+ }, /*#__PURE__*/React.createElement("select", {
278
+ onChange: function onChange(ev) {
279
+ return _this2.setSelectedFeature(ev.target.value);
280
+ },
281
+ value: this.state.selectedFeature
282
+ }, results.map(function (entry) {
275
283
  return /*#__PURE__*/React.createElement("option", {
276
- key: id,
277
- value: id
278
- }, layerTitle + ": " + featureName);
284
+ key: entry.value,
285
+ value: entry.value
286
+ }, entry.title);
279
287
  }))) : null, attributeForm);
280
288
  }
281
289
  resultWindow = /*#__PURE__*/React.createElement(ResizeableWindow, {
@@ -110,6 +110,7 @@ var MapLegend = /*#__PURE__*/function (_React$Component) {
110
110
  _this.state.onlyVisibleLegend = props.onlyVisibleLegend;
111
111
  _this.state.bboxDependentLegend = props.bboxDependentLegend;
112
112
  _this.state.scaleDependentLegend = props.scaleDependentLegend;
113
+ _this.state.visible = props.showOnStartup;
113
114
  return _this;
114
115
  }
115
116
  _inherits(MapLegend, _React$Component);
@@ -233,7 +234,9 @@ _defineProperty(MapLegend, "propTypes", {
233
234
  onlyVisibleLegend: PropTypes.bool,
234
235
  /** Whether to display a scale-dependent legend by default. */
235
236
  scaleDependentLegend: PropTypes.bool,
236
- setCurrentTask: PropTypes.func
237
+ setCurrentTask: PropTypes.func,
238
+ /** Whether to show the MapLegend on startup. Useful if `startupTask` is already set to another task. */
239
+ showOnStartup: PropTypes.bool
237
240
  });
238
241
  _defineProperty(MapLegend, "defaultProps", {
239
242
  addGroupTitles: false,
@@ -55,6 +55,7 @@ var TaskButton = /*#__PURE__*/function (_React$Component) {
55
55
  }
56
56
  var title = LocaleUtils.tr("appmenu.items." + this.props.task + (this.props.mode || ""));
57
57
  return /*#__PURE__*/React.createElement(MapButton, {
58
+ active: this.props.currentTask === this.props.task,
58
59
  icon: this.props.icon,
59
60
  onClick: this.buttonClicked,
60
61
  position: this.props.position,
package/plugins/TopBar.js CHANGED
@@ -245,6 +245,8 @@ _defineProperty(TopBar, "propTypes", {
245
245
  allowAddLayerAsGroup: PropTypes.bool,
246
246
  /** Whether to show the search filter widget. */
247
247
  allowSearchFilters: PropTypes.bool,
248
+ /** List of additional CRS for which the coordinate search should display results. Alternatively, the string `mousecrs` to indicate the CRS listed in `additionalMouseCrs` of the current theme. */
249
+ extraCoordinateSearchCrs: PropTypes.oneOfType([PropTypes.array, PropTypes.string]),
248
250
  /** Whether to focus the search field on startup. */
249
251
  focusOnStartup: PropTypes.bool,
250
252
  /** Whether to hide the result labels on the map. */
@@ -81,6 +81,18 @@ function parsePropType(type) {
81
81
  return type.name;
82
82
  }
83
83
  }
84
+ function parsePropDesc(prop) {
85
+ if (prop.type.name === 'shape') {
86
+ return prop.description.replaceAll("\n", "<br />") + "<br />" + Object.entries(prop.type.value).map(function (_ref3) {
87
+ var _ref4 = _slicedToArray(_ref3, 2),
88
+ name = _ref4[0],
89
+ subprop = _ref4[1];
90
+ return "- `" + name + "`: " + subprop.description;
91
+ }).join("<br />");
92
+ } else {
93
+ return prop.description.replaceAll("\n", "<br />");
94
+ }
95
+ }
84
96
  function genPluginDoc(plugin) {
85
97
  var output = "";
86
98
  if (!plugin.description) {
@@ -94,10 +106,10 @@ function genPluginDoc(plugin) {
94
106
  if (props.length > 0) {
95
107
  output += "| Property | Type | Description | Default value |\n";
96
108
  output += "|----------|------|-------------|---------------|\n";
97
- props.forEach(function (_ref3) {
98
- var _ref4 = _slicedToArray(_ref3, 2),
99
- name = _ref4[0],
100
- prop = _ref4[1];
109
+ props.forEach(function (_ref5) {
110
+ var _ref6 = _slicedToArray(_ref5, 2),
111
+ name = _ref6[0],
112
+ prop = _ref6[1];
101
113
  if (!prop.description) {
102
114
  return;
103
115
  }
@@ -105,7 +117,7 @@ function genPluginDoc(plugin) {
105
117
  return '`' + x.replace(' ', ' ') + '`';
106
118
  }).join("<br />") : "`undefined`";
107
119
  var type = "`" + parsePropType(prop.type).replaceAll(' ', ' ').replaceAll("\n", "`<br />`") + "`";
108
- output += "| ".concat(name, " | ").concat(type, " | ").concat(prop.description.replaceAll("\n", "<br />"), " | ").concat(defaultValue, " |\n");
120
+ output += "| ".concat(name, " | ").concat(type, " | ").concat(parsePropDesc(prop), " | ").concat(defaultValue, " |\n");
109
121
  });
110
122
  output += "\n";
111
123
  }
@@ -1,13 +1,7 @@
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
2
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
3
- function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
4
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
5
- function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
6
- function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
7
3
  function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
8
4
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
9
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
10
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
11
5
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
12
6
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
13
7
  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; }
@@ -18,6 +12,12 @@ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r),
18
12
  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; }
19
13
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
20
14
  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); }
15
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
16
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
17
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
18
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
19
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
20
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
21
21
  /**
22
22
  * Copyright 2016-2021 Sourcepole AG
23
23
  * All rights reserved.
@@ -50,16 +50,19 @@ function coordinatesSearch(text, searchParams, callback) {
50
50
  if (matches && matches.length >= 3) {
51
51
  var x = parseFloat(matches[1]);
52
52
  var y = parseFloat(matches[2]);
53
- if (displaycrs !== "EPSG:4326") {
53
+ var searchCrs = [displaycrs].concat(_toConsumableArray(searchParams.extracrs.filter(function (crs) {
54
+ return !['EPSG:4326', displaycrs].includes(crs);
55
+ })));
56
+ searchCrs.forEach(function (crs) {
54
57
  items.push({
55
- id: "coord0",
56
- text: x + ", " + y + " (" + displaycrs + ")",
58
+ id: "coord" + items.length,
59
+ text: x + ", " + y + " (" + crs + ")",
57
60
  x: x,
58
61
  y: y,
59
- crs: displaycrs,
62
+ crs: crs,
60
63
  bbox: [x, y, x, y]
61
64
  });
62
- }
65
+ });
63
66
  if (x >= -180 && x <= 180 && y >= -90 && y <= 90) {
64
67
  var title = Math.abs(x) + (x >= 0 ? "°E" : "°W") + ", " + Math.abs(y) + (y >= 0 ? "°N" : "°S");
65
68
  items.push({