qwc2 2026.4.23 → 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.
@@ -186,7 +186,13 @@ var EditComboField = /*#__PURE__*/function (_React$Component) {
186
186
  key: "componentDidUpdate",
187
187
  value: function componentDidUpdate(prevProps) {
188
188
  var _this3 = this;
189
- if (this.props.keyvalrel && this.props.filterExpr !== prevProps.filterExpr) {
189
+ if (this.props.values && this.props.values !== prevProps.values) {
190
+ // This does not handle the case a selected value has disappeared from values, caller should handle that
191
+ this.setState({
192
+ values: this.props.values,
193
+ showPlaceholder: !this.hasEmptyValue(this.props.values)
194
+ });
195
+ } else if (this.props.keyvalrel && this.props.filterExpr !== prevProps.filterExpr) {
190
196
  var _this$props$filterExp3;
191
197
  KeyValCache.get(this.props.editIface, this.props.mapPrefix + "." + this.props.keyvalrel, (_this$props$filterExp3 = this.props.filterExpr) !== null && _this$props$filterExp3 !== void 0 ? _this$props$filterExp3 : null).then(function (values) {
192
198
  _this3.setState({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2026.04.23",
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",
@@ -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) {
@@ -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({
@@ -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",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Procurar feição",
44
44
  "GeometryDigitizer": "",
45
45
  "IdentifyPoint": "Identificar ponto",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Identificar região",
47
48
  "LayerCatalog": "Catálogo de camadas",
48
49
  "Login": "Inicio da sessão",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Pesquisa de Recurso",
44
44
  "GeometryDigitizer": "",
45
45
  "IdentifyPoint": "Identificar Ponto",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Identificar Região",
47
48
  "LayerCatalog": "Catálogo de Camadas",
48
49
  "Login": "Iniciar Sessão",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "",
44
44
  "GeometryDigitizer": "",
45
45
  "IdentifyPoint": "Interogare punct",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Interogare regiune",
47
48
  "LayerCatalog": "Catalog de straturi",
48
49
  "Login": "Conectează-te",
@@ -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": "",
44
44
  "GeometryDigitizer": "",
45
45
  "IdentifyPoint": "",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Identifiera med område",
47
48
  "LayerCatalog": "",
48
49
  "Login": "Logga in",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "Obje Arama",
44
44
  "GeometryDigitizer": "Geometri Sayısallaştırıcı",
45
45
  "IdentifyPoint": "Nokta bilgisi al",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Bölgeden Bilgi Al",
47
48
  "LayerCatalog": "Katman Kataloğu",
48
49
  "Login": "Giriş",
@@ -34,6 +34,7 @@
34
34
  "appmenu.items.GeometryDigitizer",
35
35
  "appmenu.items.Help",
36
36
  "appmenu.items.IdentifyPoint",
37
+ "appmenu.items.IdentifyRadius",
37
38
  "appmenu.items.IdentifyRegion",
38
39
  "appmenu.items.LayerCatalog",
39
40
  "appmenu.items.LayerTree",
@@ -43,6 +43,7 @@
43
43
  "FeatureSearch": "",
44
44
  "GeometryDigitizer": "",
45
45
  "IdentifyPoint": "",
46
+ "IdentifyRadius": "",
46
47
  "IdentifyRegion": "Визначити регіон",
47
48
  "LayerCatalog": "",
48
49
  "Login": "",