qwc2 2026.8.13 → 2026.8.21

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 (46) hide show
  1. package/README.md +1 -1
  2. package/components/AttributeTableWidget.js +121 -285
  3. package/components/BookmarkPanel.js +3 -2
  4. package/components/IdentifyViewer.js +39 -20
  5. package/components/ImportLayer.js +6 -392
  6. package/components/QtDesignerForm.js +1 -1
  7. package/components/ResizeableWindow.js +10 -0
  8. package/components/map3d/style/Map3D.css +1 -0
  9. package/components/style/AttributeTableWidget.css +1 -140
  10. package/components/widgets/FeaturesTable.js +30 -31
  11. package/components/widgets/MenuButton.js +10 -10
  12. package/components/widgets/TextInput.js +0 -10
  13. package/components/widgets/style/FeaturesTable.css +46 -19
  14. package/icons/public.svg +63 -0
  15. package/package.json +1 -1
  16. package/plugins/BottomBar.js +123 -111
  17. package/plugins/MapDropImport.js +135 -0
  18. package/plugins/map3d/Viewshed3D.js +171 -52
  19. package/plugins/map3d/style/Viewshed3D.css +4 -0
  20. package/plugins/style/BottomBar.css +10 -3
  21. package/plugins/style/MapDropImport.css +19 -0
  22. package/static/translations/bg-BG.json +8 -0
  23. package/static/translations/ca-ES.json +8 -0
  24. package/static/translations/cs-CZ.json +8 -0
  25. package/static/translations/de-CH.json +8 -0
  26. package/static/translations/de-DE.json +8 -0
  27. package/static/translations/en-US.json +8 -0
  28. package/static/translations/es-ES.json +8 -0
  29. package/static/translations/fi-FI.json +8 -0
  30. package/static/translations/fr-FR.json +8 -0
  31. package/static/translations/hu-HU.json +8 -0
  32. package/static/translations/it-IT.json +8 -0
  33. package/static/translations/ja-JP.json +8 -0
  34. package/static/translations/nl-NL.json +8 -0
  35. package/static/translations/no-NO.json +8 -0
  36. package/static/translations/pl-PL.json +8 -0
  37. package/static/translations/pt-BR.json +8 -0
  38. package/static/translations/pt-PT.json +8 -0
  39. package/static/translations/ro-RO.json +8 -0
  40. package/static/translations/ru-RU.json +8 -0
  41. package/static/translations/sv-SE.json +8 -0
  42. package/static/translations/tr-TR.json +8 -0
  43. package/static/translations/tsconfig.json +4 -0
  44. package/static/translations/uk-UA.json +8 -0
  45. package/utils/FileImportUtils.js +390 -0
  46. package/utils/LayerUtils.js +2 -2
@@ -105,7 +105,8 @@ var BookmarkPanel = /*#__PURE__*/function (_React$Component) {
105
105
  /* eslint-disable-next-line */
106
106
  alert(_this.props.translations.savefailed);
107
107
  _this.setState({
108
- busy: false
108
+ busy: false,
109
+ rename: false
109
110
  });
110
111
  } else {
111
112
  _this.props.bookmarkIface.getList(function (bookmarks) {
@@ -158,7 +159,7 @@ var BookmarkPanel = /*#__PURE__*/function (_React$Component) {
158
159
  var hasPublicBookmarksCap = ConfigUtils.getConfigProp("capabilities", null, []).includes("public_bookmarks");
159
160
  var currentBookmark = this.state.currentBookmark;
160
161
  var buttonsDisabled = !currentBookmark || this.state.busy;
161
- var updatable = currentBookmark === null || currentBookmark === void 0 ? void 0 : currentBookmark.own;
162
+ var updatable = (currentBookmark === null || currentBookmark === void 0 ? void 0 : currentBookmark.own) && !this.state.rename;
162
163
  return /*#__PURE__*/React.createElement("div", {
163
164
  className: "bookmark-body",
164
165
  role: "body"
@@ -414,22 +414,25 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
414
414
  });
415
415
  });
416
416
  _defineProperty(_this, "setHighlightedFeatures", function (features) {
417
- if (isEmpty(features) && _this.props.highlightAllResults) {
418
- var resultTree = _this.state.selectedLayer !== '' ? _defineProperty({}, _this.state.selectedLayer, _this.state.resultTree[_this.state.selectedLayer]) : _this.state.resultTree;
419
- features = Object.values(resultTree).flat();
417
+ if (isEmpty(features)) {
418
+ if (!isEmpty(_this.state.tableSelection)) {
419
+ features = Object.values(_this.state.tableSelection).map(function (sel) {
420
+ return Object.values(sel);
421
+ }).flat();
422
+ } else if (_this.props.highlightAllResults) {
423
+ var resultTree = _this.state.selectedLayer !== '' ? _defineProperty({}, _this.state.selectedLayer, _this.state.resultTree[_this.state.selectedLayer]) : _this.state.resultTree;
424
+ features = Object.values(resultTree).flat();
425
+ }
420
426
  }
421
- features = (features || []).filter(function (feature) {
422
- return feature.type.toLowerCase() === "feature";
423
- }).map(function (feature) {
424
- var newFeature = _objectSpread(_objectSpread({}, feature), {}, {
425
- properties: {}
426
- });
427
- // Ensure selection style is used
428
- delete newFeature.styleName;
429
- delete newFeature.styleOptions;
430
- return newFeature;
431
- });
432
427
  if (!isEmpty(features)) {
428
+ features = features.filter(function (f) {
429
+ return f.geometry;
430
+ }).map(function (f) {
431
+ return {
432
+ id: f.id,
433
+ geometry: f.geometry
434
+ };
435
+ });
433
436
  var layer = {
434
437
  id: "__identifyviewerhighlight",
435
438
  role: LayerRole.SELECTION
@@ -882,17 +885,33 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
882
885
  features: features,
883
886
  fields: Object.values(fields),
884
887
  hideIdColumn: true,
885
- highlightFeatures: _this.setHighlightedFeatures,
888
+ hoverChanged: _this.setHoveredFeature,
889
+ renderField: _this.renderTableField,
886
890
  selectionChanged: function selectionChanged(sel) {
887
- return _this.setState(function (state) {
888
- return {
889
- tableSelection: _objectSpread(_objectSpread({}, state.tableSelection), {}, _defineProperty({}, layerid, sel))
890
- };
891
- });
891
+ return _this.setTableSelection(sel, layerid);
892
892
  }
893
893
  }) : null);
894
894
  }));
895
895
  });
896
+ _defineProperty(_this, "setTableSelection", function (sel, layerid) {
897
+ _this.setState(function (state) {
898
+ var newTableSelection = _objectSpread({}, state.tableSelection);
899
+ if (!isEmpty(sel)) {
900
+ newTableSelection[layerid] = sel;
901
+ } else {
902
+ delete newTableSelection[layerid];
903
+ }
904
+ return {
905
+ tableSelection: newTableSelection
906
+ };
907
+ });
908
+ });
909
+ _defineProperty(_this, "setHoveredFeature", function (feature) {
910
+ _this.setHighlightedFeatures(feature ? [feature] : null);
911
+ });
912
+ _defineProperty(_this, "renderTableField", function (feature, field) {
913
+ return _this.attribValue(feature.properties[field.name], field.name, feature.layername, feature);
914
+ });
896
915
  _defineProperty(_this, "tableAction", function (layerid, action) {
897
916
  if (action === "Export") {
898
917
  var features = isEmpty(_this.state.tableSelection[layerid]) ? _this.state.resultTree[layerid] : Object.values(_this.state.tableSelection[layerid]);
@@ -1,15 +1,4 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
3
- 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."); }
4
- function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
5
- function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
6
- 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; }
7
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
- function _regeneratorKeys(e) { var n = Object(e), r = []; for (var t in n) r.unshift(t); return function e() { for (; r.length;) if ((t = r.pop()) in n) return e.value = t, e.done = !1, e; return e.done = !0, e; }; }
9
- function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
10
- function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
11
- function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
12
- function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
13
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; } } }; }
14
3
  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; } }
15
4
  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; }
@@ -37,17 +26,14 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
37
26
  import React from 'react';
38
27
  import { connect } from 'react-redux';
39
28
  import axios from 'axios';
40
- import isEmpty from 'lodash.isempty';
41
- import Proj4js from 'proj4';
42
29
  import PropTypes from 'prop-types';
43
30
  import { addLayer, addLayerFeatures } from '../actions/layers';
44
31
  import EditableSelect from '../components/widgets/EditableSelect';
45
32
  import ConfigUtils from '../utils/ConfigUtils';
46
- import CoordinatesUtils from '../utils/CoordinatesUtils';
33
+ import FileImportUtils from '../utils/FileImportUtils';
47
34
  import LocaleUtils from '../utils/LocaleUtils';
48
35
  import MiscUtils from '../utils/MiscUtils';
49
36
  import ServiceLayerUtils from '../utils/ServiceLayerUtils';
50
- import VectorLayerUtils from '../utils/VectorLayerUtils';
51
37
  import FileSelector from './widgets/FileSelector';
52
38
  import LayerCatalogWidget from './widgets/LayerCatalogWidget';
53
39
  import Spinner from './widgets/Spinner';
@@ -245,385 +231,13 @@ var ImportLayer = /*#__PURE__*/function (_React$Component) {
245
231
  _this.setState({
246
232
  addingLayer: true
247
233
  });
248
- var file = _this.state.file;
249
- if (file.name.toLowerCase().endsWith(".pdf")) {
250
- _this.addGeoPDFLayer(file);
251
- } else if (file.name.toLowerCase().endsWith(".zip")) {
252
- _this.addSHPLayer(file);
253
- } else if (file.name.toLowerCase().endsWith(".kmz")) {
254
- _this.addKMZLayer(file);
255
- } else {
256
- var reader = new FileReader();
257
- reader.onload = function (ev) {
258
- if (file.name.toLowerCase().endsWith(".kml")) {
259
- _this.addKMLLayer(file.name, ev.target.result);
260
- } else if (file.name.toLowerCase().endsWith(".geojson") || file.name.toLowerCase().endsWith(".json")) {
261
- var data = {};
262
- try {
263
- data = JSON.parse(ev.target.result);
264
- _this.addGeoJSONLayer(file.name, data);
265
- } catch (_unused) {
266
- /* Pass */
267
- }
268
- } else if (file.name.toLowerCase().endsWith(".pdf")) {
269
- _this.addGeoPDFLayer(file.name, ev.target.result);
270
- } else {
271
- /* eslint-disable-next-line */
272
- alert(LocaleUtils.tr("importlayer.unsupportedfile"));
273
- }
274
- _this.setState({
275
- file: null,
276
- addingLayer: false
277
- });
278
- };
279
- reader.readAsText(_this.state.file);
280
- }
281
- });
282
- _defineProperty(_this, "addKMLLayer", function (filename, data) {
283
- _this.addGeoJSONLayer(filename, {
284
- features: VectorLayerUtils.kmlToGeoJSON(data)
285
- });
286
- });
287
- _defineProperty(_this, "addKMZLayer", /*#__PURE__*/function () {
288
- var _ref5 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(file) {
289
- var _yield$import, load, _yield$import2, ZipLoader, fileMap, fileName, decoder, _t, _t2;
290
- return _regenerator().w(function (_context) {
291
- while (1) switch (_context.n) {
292
- case 0:
293
- _context.n = 1;
294
- return import('@loaders.gl/core');
295
- case 1:
296
- _yield$import = _context.v;
297
- load = _yield$import.load;
298
- _context.n = 2;
299
- return import('@loaders.gl/zip');
300
- case 2:
301
- _yield$import2 = _context.v;
302
- ZipLoader = _yield$import2.ZipLoader;
303
- _context.n = 3;
304
- return load(file, ZipLoader);
305
- case 3:
306
- fileMap = _context.v;
307
- _t = _regeneratorKeys(fileMap);
308
- case 4:
309
- if ((_t2 = _t()).done) {
310
- _context.n = 6;
311
- break;
312
- }
313
- fileName = _t2.value;
314
- if (!(fileName === "doc.kml")) {
315
- _context.n = 5;
316
- break;
317
- }
318
- decoder = new TextDecoder();
319
- _this.addKMLLayer(file.name, decoder.decode(fileMap[fileName]));
320
- return _context.a(3, 6);
321
- case 5:
322
- _context.n = 4;
323
- break;
324
- case 6:
325
- _this.setState({
326
- file: null,
327
- addingLayer: false
328
- });
329
- case 7:
330
- return _context.a(2);
331
- }
332
- }, _callee);
333
- }));
334
- return function (_x) {
335
- return _ref5.apply(this, arguments);
336
- };
337
- }());
338
- _defineProperty(_this, "addGeoJSONLayer", function (filename, data) {
339
- if (!data.features && data.type === "Feature") {
340
- data = {
341
- type: "FeatureCollection",
342
- features: [data],
343
- crs: data.crs
344
- };
345
- }
346
- if (!isEmpty(data.features)) {
347
- var defaultCrs = "EPSG:4326";
348
- if (data.crs && data.crs.properties && data.crs.properties.name) {
349
- // Extract CRS from FeatureCollection crs
350
- defaultCrs = CoordinatesUtils.fromOgcUrnCrs(data.crs.properties.name);
351
- }
352
- var features = data.features.map(function (feature) {
353
- var crs = defaultCrs;
354
- if (feature.crs && feature.crs.properties && feature.crs.properties.name) {
355
- crs = CoordinatesUtils.fromOgcUrnCrs(feature.crs.properties.name);
356
- } else if (typeof feature.crs === "string") {
357
- crs = feature.crs;
358
- }
359
- if (feature.geometry && feature.geometry.coordinates) {
360
- feature.geometry.coordinates = feature.geometry.coordinates.map(VectorLayerUtils.convert3dto2d);
361
- }
362
- return _objectSpread(_objectSpread({}, feature), {}, {
363
- crs: crs
364
- });
365
- });
366
- _this.props.addLayerFeatures({
367
- name: filename,
368
- title: filename.replace(/\.[^/.]+$/, ""),
369
- zoomToExtent: true
370
- }, features, true);
371
- } else {
372
- // eslint-disable-next-line
373
- alert(LocaleUtils.tr("importlayer.nofeatures"));
374
- }
375
- });
376
- _defineProperty(_this, "addGeoPDFLayer", function (file) {
377
- var reader = new FileReader();
378
- reader.onload = function (ev) {
379
- var pdfText = atob(ev.target.result.slice(28));
380
- /* FIXME: This is a very ugly way to extract PDF objects */
381
- var GPTS = pdfText.match(/\/GPTS\s+\[([^\]]+)\]/);
382
- var LPTS = pdfText.match(/\/LPTS\s+\[([^\]]+)\]/);
383
- var Viewport = pdfText.match(/<<([^>]+\/Type\s+\/Viewport[^>]+)>>/);
384
- var EPSG = pdfText.match(/\/EPSG\s*(\d+)/);
385
- if (!GPTS || !LPTS || !Viewport || !EPSG) {
386
- /* eslint-disable-next-line */
387
- alert(LocaleUtils.tr("importlayer.notgeopdf"));
388
- _this.setState({
389
- file: null,
390
- addingLayer: false
391
- });
392
- return;
393
- }
394
- var pairs = function pairs(res, value, idx, array) {
395
- return idx % 2 === 0 ? [].concat(_toConsumableArray(res), [array.slice(idx, idx + 2)]) : res;
396
- };
397
- var gpts = GPTS[1].split(/\s+/).filter(Boolean).map(Number).reduce(pairs, []).map(function (e) {
398
- return e.reverse();
399
- }); // lat-lon => lon-lat
400
- var lpts = LPTS[1].split(/\s+/).filter(Boolean).map(Number).reduce(pairs, []);
401
- var viewport = Viewport[1].match(/\/BBox\s+\[([^\]]+)\]/)[1].split(/\s+/).filter(Boolean).map(Number);
402
- var epsg = EPSG[1];
403
- var projDef = Proj4js.defs('EPSG:' + epsg);
404
- if (!projDef) {
405
- /* eslint-disable-next-line */
406
- alert(LocaleUtils.tr("importlayer.unknownproj", 'EPSG:' + epsg));
407
- _this.setState({
408
- file: null,
409
- addingLayer: false
410
- });
411
- return;
412
- }
413
- // Construct geog CS
414
- var geogCs = {
415
- projName: 'longlat',
416
- ellps: projDef.ellps,
417
- datum_params: projDef.datum_params,
418
- no_defs: projDef.no_defs
419
- };
420
-
421
- // Compute the georeferenced area
422
- // Note: this is a simplistic implementation, assuming that the frame is rectangular and not skewed
423
- var getCornerIdx = function getCornerIdx(x, y) {
424
- return lpts.findIndex(function (entry) {
425
- return Math.round(entry[0]) === x && Math.round(entry[1]) === y;
426
- });
427
- };
428
- var idxBL = getCornerIdx(0, 0);
429
- var idxTR = getCornerIdx(1, 1);
430
- var computeCorner = function computeCorner(idx) {
431
- return {
432
- pixel: [viewport[0] * (1 - lpts[idx][0]) + viewport[2] * lpts[idx][0], viewport[1] * (1 - lpts[idx][1]) + viewport[3] * lpts[idx][1]],
433
- // eslint-disable-next-line
434
- coo: Proj4js(geogCs, _this.props.mapCrs, gpts[idx])
435
- };
436
- };
437
- var bl = computeCorner(idxBL);
438
- var tr = computeCorner(idxTR);
439
- var geoextent = [bl.coo[0], bl.coo[1], tr.coo[0], tr.coo[1]];
440
- var imgextent = [bl.pixel[0], bl.pixel[1], tr.pixel[0], tr.pixel[1]];
441
- import('pdfjs-dist').then(function (pdfjsLib) {
442
- pdfjsLib.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString();
443
- pdfjsLib.getDocument(ev.target.result).promise.then(function (pdf) {
444
- pdf.getPage(1).then(function (page) {
445
- var pageViewport = page.getViewport({
446
- scale: 1
447
- });
448
- var canvas = document.createElement('canvas');
449
- canvas.width = imgextent[2] - imgextent[0];
450
- canvas.height = imgextent[3] - imgextent[1];
451
- var context = canvas.getContext('2d');
452
- context.translate(-imgextent[0], -(pageViewport.height - imgextent[3]));
453
- page.render({
454
- canvasContext: context,
455
- viewport: pageViewport
456
- }).promise.then(function () {
457
- _this.props.addLayer({
458
- type: "image",
459
- name: file.name,
460
- title: file.name,
461
- url: canvas.toDataURL(),
462
- projection: _this.props.mapCrs,
463
- imageExtent: geoextent
464
- });
465
- _this.setState({
466
- file: null,
467
- addingLayer: false
468
- });
469
- });
470
- });
471
- });
472
- })["catch"](function () {
473
- /* eslint-disable-next-line */
474
- console.warn("pdfjs import failed");
475
- _this.setState({
476
- file: null,
477
- addingLayer: false
478
- });
234
+ FileImportUtils.importFile(_this.state.file, _this.props.mapCrs, _this.props.addLayer, _this.props.addLayerFeatures)["finally"](function () {
235
+ _this.setState({
236
+ file: null,
237
+ addingLayer: false
479
238
  });
480
- };
481
- reader.readAsDataURL(file);
239
+ });
482
240
  });
483
- _defineProperty(_this, "addSHPLayer", /*#__PURE__*/function () {
484
- var _ref6 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(file) {
485
- var _yield$import3, _BrowserFileSystem, load, _yield$import4, Proj4Projection, _yield$import5, ShapefileLoader, _yield$import6, ZipLoader, mimeTypes, projections, fileMap, EXTENSIONS, files, fileName, name, ext, fileList, blob, f, list, fileSystem, fetch, filename, data, _t3, _t4, _t5, _t6;
486
- return _regenerator().w(function (_context2) {
487
- while (1) switch (_context2.p = _context2.n) {
488
- case 0:
489
- _context2.n = 1;
490
- return import('@loaders.gl/core');
491
- case 1:
492
- _yield$import3 = _context2.v;
493
- _BrowserFileSystem = _yield$import3._BrowserFileSystem;
494
- load = _yield$import3.load;
495
- _context2.n = 2;
496
- return import('@math.gl/proj4');
497
- case 2:
498
- _yield$import4 = _context2.v;
499
- Proj4Projection = _yield$import4.Proj4Projection;
500
- _context2.n = 3;
501
- return import('@loaders.gl/shapefile');
502
- case 3:
503
- _yield$import5 = _context2.v;
504
- ShapefileLoader = _yield$import5.ShapefileLoader;
505
- _context2.n = 4;
506
- return import('@loaders.gl/zip');
507
- case 4:
508
- _yield$import6 = _context2.v;
509
- ZipLoader = _yield$import6.ZipLoader;
510
- // Import SHP layer from ZIP. Zip must contain all the required files : shp, dbf, shx, prj, cpg
511
- mimeTypes = ['application/zip', 'application/zip-compressed', 'application/x-zip-compressed'];
512
- if (!mimeTypes.includes(file.type)) {
513
- _context2.n = 16;
514
- break;
515
- }
516
- projections = ConfigUtils.getConfigProp("projections") || [];
517
- if (projections) {
518
- Proj4Projection.defineProjectionAliases(projections);
519
- }
520
- _context2.n = 5;
521
- return load(file, ZipLoader);
522
- case 5:
523
- fileMap = _context2.v;
524
- EXTENSIONS = ['shp', 'shx', 'dbf', 'cpg', 'prj'];
525
- files = {}; // Iterate through all the files in ZIP to get a list of (SHP + sidecar files) by filename
526
- for (fileName in fileMap) {
527
- if (Object.hasOwn(fileMap, fileName)) {
528
- name = fileName.split('.')[0];
529
- ext = fileName.split('.').pop();
530
- fileList = files[name] || [];
531
- if (EXTENSIONS.includes(ext)) {
532
- // Create Blob and File from arrayBuffer loaded by ZipLoader
533
- blob = new Blob([fileMap[fileName]]);
534
- fileList.push(new File([blob], fileName));
535
- }
536
- files[name] = fileList;
537
- }
538
- }
539
- // Load each SHP with sidecar files as GeoJSON features
540
- _t3 = _regeneratorKeys(files);
541
- case 6:
542
- if ((_t4 = _t3()).done) {
543
- _context2.n = 15;
544
- break;
545
- }
546
- f = _t4.value;
547
- if (!Object.hasOwn(files, f)) {
548
- _context2.n = 14;
549
- break;
550
- }
551
- list = files[f];
552
- fileSystem = new _BrowserFileSystem(list);
553
- fetch = fileSystem.fetch.bind(fileSystem.fetch);
554
- filename = "".concat(f, ".shp"); // Load SHP and reproject to mapCrs
555
- data = null;
556
- _context2.p = 7;
557
- _context2.n = 8;
558
- return load(filename, ShapefileLoader, {
559
- fetch: fetch,
560
- shapefile: {
561
- shape: 'geojson-table'
562
- },
563
- gis: {
564
- format: 'geojson',
565
- reproject: true,
566
- _targetCrs: _this.props.mapCrs
567
- }
568
- });
569
- case 8:
570
- data = _context2.v;
571
- _context2.n = 13;
572
- break;
573
- case 9:
574
- _context2.p = 9;
575
- _t5 = _context2.v;
576
- _context2.p = 10;
577
- _context2.n = 11;
578
- return load(filename, ShapefileLoader, {
579
- fetch: fetch,
580
- shapefile: {
581
- shape: 'geojson-table'
582
- },
583
- gis: {
584
- format: 'geojson',
585
- reproject: false,
586
- _targetCrs: _this.props.mapCrs
587
- }
588
- });
589
- case 11:
590
- data = _context2.v;
591
- /* eslint-disable-next-line */
592
- alert(LocaleUtils.tr("importlayer.shpreprojectionerror"));
593
- _context2.n = 13;
594
- break;
595
- case 12:
596
- _context2.p = 12;
597
- _t6 = _context2.v;
598
- data = null;
599
- case 13:
600
- if (data) {
601
- data.crs = {
602
- type: "name",
603
- properties: {
604
- name: CoordinatesUtils.toOgcUrnCrs(_this.props.mapCrs)
605
- }
606
- };
607
- // Add data as GeoJSON layer
608
- _this.addGeoJSONLayer(f, data);
609
- }
610
- case 14:
611
- _context2.n = 6;
612
- break;
613
- case 15:
614
- _this.setState({
615
- file: null,
616
- addingLayer: false
617
- });
618
- case 16:
619
- return _context2.a(2);
620
- }
621
- }, _callee2, null, [[10, 12], [7, 9]]);
622
- }));
623
- return function (_x2) {
624
- return _ref6.apply(this, arguments);
625
- };
626
- }());
627
241
  return _this;
628
242
  }
629
243
  _inherits(ImportLayer, _React$Component);
@@ -244,7 +244,7 @@ var QtDesignerForm = /*#__PURE__*/function (_React$Component) {
244
244
  var attr = widget.attribute || {};
245
245
  var fieldname = widget.name.replace(/kvrel__/, '').split("__")[isRelWidget ? 1 : 0];
246
246
  var field = fields[fieldname];
247
- var constraints = (field === null || field === void 0 ? void 0 : field.constraints) || {};
247
+ var constraints = _objectSpread({}, field === null || field === void 0 ? void 0 : field.constraints);
248
248
  constraints.readOnly = _this.props.readOnly || constraints.readOnly === true || String(prop.readOnly) === "true" || String(prop.enabled) === "false" || disabled;
249
249
  constraints.required = !constraints.readOnly && (constraints.required || String(prop.required) === "true");
250
250
  constraints.placeholder = prop.placeholderText || constraints.placeholder || "";
@@ -451,6 +451,9 @@ var ResizeableWindow = /*#__PURE__*/function (_React$Component) {
451
451
  });
452
452
  externalWindow.document.querySelector(':root').style.setProperty('--topbar-height', document.querySelector(':root').style.getPropertyValue('--topbar-height'));
453
453
  externalWindow.document.querySelector(':root').style.setProperty('--bottombar-height', document.querySelector(':root').style.getPropertyValue('--bottombar-height'));
454
+ if (_this.props.colorScheme) {
455
+ externalWindow.document.querySelector(':root').classList.add(_this.props.colorScheme);
456
+ }
454
457
  // Inherit API
455
458
  externalWindow.qwc2 = window.qwc2;
456
459
  _this.setState(function (state) {
@@ -534,6 +537,11 @@ var ResizeableWindow = /*#__PURE__*/function (_React$Component) {
534
537
  this.props.onGeometryChanged(this.state.geometry);
535
538
  WINDOW_GEOMETRIES[this.props.title] = this.state.geometry;
536
539
  }
540
+ if (this.props.colorScheme !== prevProps.colorScheme && this.state.externalWindow) {
541
+ var externalWindowRoot = this.state.externalWindow.document.querySelector(':root');
542
+ externalWindowRoot.classList.remove(prevProps.colorScheme);
543
+ externalWindowRoot.classList.add(this.props.colorScheme);
544
+ }
537
545
  if (this.props.splitScreenWhenDocked && (this.props.visible !== prevProps.visible || this.state.geometry !== prevState.geometry || this.state.externalWindow !== prevState.externalWindow)) {
538
546
  if (!this.props.visible && prevProps.visible || this.state.geometry.docked === false && prevState.geometry.docked !== false || this.state.geometry.maximized === true && prevState.geometry.maximized !== true || this.state.externalWindow && !prevState.externalWindow) {
539
547
  this.props.setSplitScreen(this.id, null, null, false);
@@ -563,6 +571,7 @@ _defineProperty(ResizeableWindow, "propTypes", {
563
571
  bottombarHeight: PropTypes.number,
564
572
  busyIcon: PropTypes.bool,
565
573
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
574
+ colorScheme: PropTypes.string,
566
575
  detachable: PropTypes.bool,
567
576
  dockable: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
568
577
  extraControls: PropTypes.arrayOf(PropTypes.shape({
@@ -628,6 +637,7 @@ _defineProperty(ResizeableWindow, "defaultProps", {
628
637
  });
629
638
  export default connect(function (state) {
630
639
  return {
640
+ colorScheme: state.localConfig.colorScheme,
631
641
  windowStacking: state.windows.stacking,
632
642
  topbarHeight: state.windows.topbarHeight,
633
643
  bottombarHeight: state.windows.bottombarHeight,
@@ -18,6 +18,7 @@ div.map3d-titlebar > span.icon-remove {
18
18
 
19
19
  div.map3d-map {
20
20
  user-select: none;
21
+ touch-action: none;
21
22
  position: absolute;
22
23
  left: 0;
23
24
  right: 0;