qwc2 2026.3.24 → 2026.4.2
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.
- package/README.md +2 -23
- package/components/AppMenu.js +29 -30
- package/components/AttributeTableWidget.js +8 -1
- package/components/SearchBox.js +2 -1
- package/components/map/layers/MVTLayer.js +15 -15
- package/components/map3d/ColorLayer3D.js +158 -0
- package/components/map3d/Map3D.js +98 -192
- package/components/map3d/drawtool/NumericInput3D.js +2 -2
- package/components/map3d/layers/GeoTIFFLayer3D.js +5 -4
- package/components/map3d/layers/Layer3D.js +168 -0
- package/components/map3d/layers/MVTLayer3D.js +59 -0
- package/components/map3d/layers/VectorLayer3D.js +10 -7
- package/components/map3d/layers/WFSLayer3D.js +8 -7
- package/components/map3d/layers/WMSLayer3D.js +6 -4
- package/components/map3d/layers/WMTSLayer3D.js +4 -3
- package/components/map3d/layers/index.js +3 -2
- package/components/map3d/utils/MiscUtils3D.js +10 -10
- package/components/style/AppMenu.css +61 -25
- package/components/style/AttributeTableWidget.css +5 -5
- package/icons/sunexp.svg +129 -0
- package/package.json +6 -4
- package/plugins/Bookmark.js +3 -2
- package/plugins/Identify.js +30 -6
- package/plugins/LayerTree.js +21 -1
- package/plugins/TopBar.js +15 -11
- package/plugins/map3d/HideObjects3D.js +4 -2
- package/plugins/map3d/LayerTree3D.js +2 -2
- package/plugins/map3d/MeasureObjects3D.js +8 -6
- package/plugins/map3d/SunExposure3D.js +415 -0
- package/plugins/map3d/TopBar3D.js +11 -5
- package/plugins/map3d/style/SunExposure3D.css +46 -0
- package/plugins/style/Portal.css +0 -5
- package/reducers/layers.js +17 -0
- package/scripts/gen-plugin-docs.js +4 -0
- package/static/translations/bg-BG.json +13 -0
- package/static/translations/ca-ES.json +13 -0
- package/static/translations/cs-CZ.json +13 -0
- package/static/translations/de-CH.json +15 -2
- package/static/translations/de-DE.json +15 -2
- package/static/translations/en-US.json +13 -0
- package/static/translations/es-ES.json +13 -0
- package/static/translations/fi-FI.json +13 -0
- package/static/translations/fr-FR.json +13 -0
- package/static/translations/hu-HU.json +13 -0
- package/static/translations/it-IT.json +13 -0
- package/static/translations/ja-JP.json +13 -0
- package/static/translations/nl-NL.json +13 -0
- package/static/translations/no-NO.json +13 -0
- package/static/translations/pl-PL.json +13 -0
- package/static/translations/pt-BR.json +13 -0
- package/static/translations/pt-PT.json +13 -0
- package/static/translations/ro-RO.json +13 -0
- package/static/translations/ru-RU.json +13 -0
- package/static/translations/sv-SE.json +13 -0
- package/static/translations/tr-TR.json +13 -0
- package/static/translations/tsconfig.json +11 -0
- package/static/translations/uk-UA.json +13 -0
- package/utils/LayerUtils.js +24 -11
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
 QGIS Web Client
|
|
1
|
+
 QGIS Web Client · [qwc.app](https://qwc.app)
|
|
2
2
|
=================
|
|
3
3
|
|
|
4
4
|
## Introduction
|
|
@@ -10,28 +10,7 @@ The `qwc2` NPM package can be used as a dependency to build a custom QWC applica
|
|
|
10
10
|
|
|
11
11
|
### Main Features
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
- Responsive, separately configurable for desktop and mobile devices
|
|
15
|
-
- Theme switcher
|
|
16
|
-
- Search with configurable search providers
|
|
17
|
-
- Layer tree
|
|
18
|
-
* Toggle layers and groups
|
|
19
|
-
* Change layer order and opacity
|
|
20
|
-
* Import external WMS/WFS/WMTS/GeoJSON/KML layers
|
|
21
|
-
* Compare layers
|
|
22
|
-
- Feature info
|
|
23
|
-
- Printing using QGIS print layouts
|
|
24
|
-
- Share permalinks
|
|
25
|
-
- Bookmarks
|
|
26
|
-
- Measuring tools
|
|
27
|
-
- Height profile
|
|
28
|
-
- Redlining
|
|
29
|
-
- Editing and attribute table
|
|
30
|
-
- Attribute table
|
|
31
|
-
- Export map (raster images, DXF)
|
|
32
|
-
- Time manager for temporal layers
|
|
33
|
-
- Themeable with color schemes
|
|
34
|
-
- [Additional plugins!](https://qwc-services.github.io/master/references/qwc2_plugins/)
|
|
13
|
+
See [qwc.app/features](https://qwc.app/features).
|
|
35
14
|
|
|
36
15
|
## Quick start
|
|
37
16
|
|
package/components/AppMenu.js
CHANGED
|
@@ -72,8 +72,8 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
72
72
|
_this.props.setCurrentTask(null);
|
|
73
73
|
}
|
|
74
74
|
_this.props.onMenuToggled(!_this.state.menuVisible);
|
|
75
|
-
if (_this.props.
|
|
76
|
-
_this.props.setMenuMargin(!_this.state.menuVisible ? MiscUtils.convertEmToPx(3.
|
|
75
|
+
if (_this.props.menuDisplayMode !== "normal") {
|
|
76
|
+
_this.props.setMenuMargin(!_this.state.menuVisible ? MiscUtils.convertEmToPx(3.5) : 0, 0);
|
|
77
77
|
}
|
|
78
78
|
_this.setState(function (state) {
|
|
79
79
|
return {
|
|
@@ -84,7 +84,7 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
84
84
|
});
|
|
85
85
|
});
|
|
86
86
|
_defineProperty(_this, "checkCloseMenu", function (ev) {
|
|
87
|
-
if (_this.menuEl && !_this.menuEl.contains(ev.target) &&
|
|
87
|
+
if (_this.menuEl && !_this.menuEl.contains(ev.target) && _this.props.menuDisplayMode === "normal") {
|
|
88
88
|
_this.toggleMenu();
|
|
89
89
|
MiscUtils.killEvent(ev);
|
|
90
90
|
}
|
|
@@ -98,7 +98,7 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
98
98
|
});
|
|
99
99
|
});
|
|
100
100
|
_defineProperty(_this, "onMenuitemClicked", function (item) {
|
|
101
|
-
if (
|
|
101
|
+
if (_this.props.menuDisplayMode === "normal" && _this.state.menuVisible) {
|
|
102
102
|
_this.toggleMenu();
|
|
103
103
|
}
|
|
104
104
|
if (item.url) {
|
|
@@ -111,6 +111,10 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
111
111
|
_defineProperty(_this, "renderMenuItems", function (items, level, filter) {
|
|
112
112
|
var submenu = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
113
113
|
return (items || []).map(function (item) {
|
|
114
|
+
var trargs = item.trargs || [];
|
|
115
|
+
var label = item.title ? LocaleUtils.tr.apply(LocaleUtils, [item.title].concat(_toConsumableArray(trargs))) : LocaleUtils.tr.apply(LocaleUtils, ["appmenu.items." + item.key + (item.mode || "")].concat(_toConsumableArray(trargs)));
|
|
116
|
+
var comment = item.comment ? LocaleUtils.tr.apply(LocaleUtils, ["appmenu.items." + item.key + (item.mode || "") + "_comment"].concat(_toConsumableArray(trargs))) : "";
|
|
117
|
+
var labelclass = _this.props.menuDisplayMode === "icononly" ? "appmenu-menu-item-tooltip" : "appmenu-menu-item-label";
|
|
114
118
|
if (item.subitems) {
|
|
115
119
|
var _item$key;
|
|
116
120
|
var expanded = filter || _this.state.submenusVisible[level] === item.key;
|
|
@@ -123,7 +127,6 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
123
127
|
"appmenu-submenu": true,
|
|
124
128
|
"appmenu-submenu-expanded": expanded
|
|
125
129
|
});
|
|
126
|
-
var label = item.title ? LocaleUtils.tr(item.title) : LocaleUtils.tr("appmenu.items." + item.key);
|
|
127
130
|
return [/*#__PURE__*/React.createElement("div", {
|
|
128
131
|
className: className,
|
|
129
132
|
key: (_item$key = item.key) !== null && _item$key !== void 0 ? _item$key : item.title,
|
|
@@ -137,14 +140,12 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
137
140
|
tabIndex: 0
|
|
138
141
|
}, /*#__PURE__*/React.createElement(Icon, {
|
|
139
142
|
icon: item.icon,
|
|
140
|
-
size: "xlarge"
|
|
141
|
-
|
|
142
|
-
|
|
143
|
+
size: "xlarge"
|
|
144
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
145
|
+
className: labelclass
|
|
146
|
+
}, label)), subitems];
|
|
143
147
|
} else {
|
|
144
|
-
|
|
145
|
-
var _label = item.title ? LocaleUtils.tr.apply(LocaleUtils, [item.title].concat(_toConsumableArray(trargs))) : LocaleUtils.tr.apply(LocaleUtils, ["appmenu.items." + item.key + (item.mode || "")].concat(_toConsumableArray(trargs)));
|
|
146
|
-
var comment = item.comment ? LocaleUtils.tr.apply(LocaleUtils, ["appmenu.items." + item.key + (item.mode || "") + "_comment"].concat(_toConsumableArray(trargs))) : "";
|
|
147
|
-
if (!filter || removeDiacritics(_label.toLowerCase()).match(filter) || comment && removeDiacritics(comment.toLowerCase()).match(filter)) {
|
|
148
|
+
if (!filter || removeDiacritics(label.toLowerCase()).match(filter) || comment && removeDiacritics(comment.toLowerCase()).match(filter)) {
|
|
148
149
|
var _className = classnames({
|
|
149
150
|
"appmenu-menu-item": true,
|
|
150
151
|
"appmenu-menu-item-nested": submenu
|
|
@@ -162,13 +163,10 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
162
163
|
tabIndex: 0
|
|
163
164
|
}, /*#__PURE__*/React.createElement(Icon, {
|
|
164
165
|
icon: item.icon,
|
|
165
|
-
size: "xlarge"
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}, _label, comment ? /*#__PURE__*/React.createElement("div", {
|
|
170
|
-
className: "appmenu-menu-item-comment"
|
|
171
|
-
}, comment) : null) : null);
|
|
166
|
+
size: "xlarge"
|
|
167
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
168
|
+
className: labelclass
|
|
169
|
+
}, label));
|
|
172
170
|
}
|
|
173
171
|
return null;
|
|
174
172
|
}
|
|
@@ -215,7 +213,7 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
215
213
|
MiscUtils.killEvent(ev);
|
|
216
214
|
} else if (ev.key === 'Escape') {
|
|
217
215
|
var _this$menuBtn, _this$menuBtn$focus;
|
|
218
|
-
if (
|
|
216
|
+
if (_this.props.menuDisplayMode === "normal") {
|
|
219
217
|
_this.toggleMenu();
|
|
220
218
|
}
|
|
221
219
|
(_this$menuBtn = _this.menuBtn) === null || _this$menuBtn === void 0 || (_this$menuBtn$focus = _this$menuBtn.focus) === null || _this$menuBtn$focus === void 0 || _this$menuBtn$focus.call(_this$menuBtn);
|
|
@@ -237,7 +235,7 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
237
235
|
return _createClass(AppMenu, [{
|
|
238
236
|
key: "componentDidMount",
|
|
239
237
|
value: function componentDidMount() {
|
|
240
|
-
if (this.props.showOnStartup) {
|
|
238
|
+
if (this.props.showOnStartup || this.props.menuDisplayMode !== "normal") {
|
|
241
239
|
this.toggleMenu();
|
|
242
240
|
}
|
|
243
241
|
this.addKeyBindings(this.props.menuItems);
|
|
@@ -249,7 +247,7 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
249
247
|
key: "componentDidUpdate",
|
|
250
248
|
value: function componentDidUpdate(prevProps, prevState) {
|
|
251
249
|
var _this2 = this;
|
|
252
|
-
if (this.state.menuVisible && !prevState.menuVisible
|
|
250
|
+
if (this.state.menuVisible && !prevState.menuVisible) {
|
|
253
251
|
// Need to wait until slide in transition is over
|
|
254
252
|
setTimeout(function () {
|
|
255
253
|
var _this2$filterfield, _this2$filterfield$fo;
|
|
@@ -259,7 +257,7 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
259
257
|
setTimeout(function () {
|
|
260
258
|
return document.addEventListener('click', _this2.checkCloseMenu);
|
|
261
259
|
}, 0);
|
|
262
|
-
} else if (prevState.menuVisible && !this.state.menuVisible
|
|
260
|
+
} else if (prevState.menuVisible && !this.state.menuVisible) {
|
|
263
261
|
document.removeEventListener('click', this.checkCloseMenu);
|
|
264
262
|
}
|
|
265
263
|
}
|
|
@@ -281,13 +279,13 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
281
279
|
_this$props$buttonCon;
|
|
282
280
|
var isMobile = ConfigUtils.isMobile();
|
|
283
281
|
var visible = !this.props.currentTaskBlocked && this.state.menuVisible;
|
|
284
|
-
var showLabel =
|
|
282
|
+
var showLabel = this.props.menuDisplayMode === "normal" && !isMobile;
|
|
285
283
|
var className = classnames({
|
|
286
284
|
"AppMenu": true,
|
|
287
285
|
"appmenu-blocked": this.props.currentTaskBlocked,
|
|
288
286
|
"appmenu-visible": visible,
|
|
289
|
-
"appmenu-compact": this.props.
|
|
290
|
-
"appmenu-icononly": this.props.
|
|
287
|
+
"appmenu-compact": this.props.menuDisplayMode === "compact",
|
|
288
|
+
"appmenu-icononly": this.props.menuDisplayMode === "icononly",
|
|
291
289
|
"appmenu-nolabel": !showLabel
|
|
292
290
|
});
|
|
293
291
|
var filter = this.state.filter ? new RegExp(removeDiacritics(this.state.filter).replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"), "i") : null;
|
|
@@ -313,6 +311,8 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
313
311
|
}))]), /*#__PURE__*/React.createElement("div", {
|
|
314
312
|
className: "appmenu-menu-container",
|
|
315
313
|
tabIndex: -1
|
|
314
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
315
|
+
className: "appmenu-menu-aligner"
|
|
316
316
|
}, /*#__PURE__*/React.createElement("div", {
|
|
317
317
|
className: "appmenu-menu",
|
|
318
318
|
inert: !visible,
|
|
@@ -321,7 +321,7 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
321
321
|
_this3.menuEl = el;
|
|
322
322
|
MiscUtils.setupKillTouchEvents(el);
|
|
323
323
|
}
|
|
324
|
-
}, this.props.showFilterField ? /*#__PURE__*/React.createElement("div", {
|
|
324
|
+
}, this.props.showFilterField && this.props.menuDisplayMode !== "icononly" ? /*#__PURE__*/React.createElement("div", {
|
|
325
325
|
className: "appmenu-menu-item appmenu-menu-item-filter",
|
|
326
326
|
onFocus: this.focusFilterField,
|
|
327
327
|
onKeyDown: this.keyNav,
|
|
@@ -352,7 +352,7 @@ var AppMenu = /*#__PURE__*/function (_React$Component) {
|
|
|
352
352
|
});
|
|
353
353
|
},
|
|
354
354
|
role: "suffix"
|
|
355
|
-
}))) : null, this.renderMenuItems(this.props.menuItems, 0, filter))));
|
|
355
|
+
}))) : null, this.renderMenuItems(this.props.menuItems, 0, filter)))));
|
|
356
356
|
}
|
|
357
357
|
}]);
|
|
358
358
|
}(React.Component);
|
|
@@ -362,8 +362,7 @@ _defineProperty(AppMenu, "propTypes", {
|
|
|
362
362
|
buttonContents: PropTypes.object,
|
|
363
363
|
buttonLabel: PropTypes.string,
|
|
364
364
|
currentTaskBlocked: PropTypes.bool,
|
|
365
|
-
|
|
366
|
-
menuCompact: PropTypes.bool,
|
|
365
|
+
menuDisplayMode: PropTypes.string,
|
|
367
366
|
menuIconOnly: PropTypes.bool,
|
|
368
367
|
menuItems: PropTypes.array,
|
|
369
368
|
onMenuToggled: PropTypes.func,
|
|
@@ -388,7 +388,7 @@ var AttributeTableWidget = /*#__PURE__*/function (_React$Component) {
|
|
|
388
388
|
};
|
|
389
389
|
newState[stateField] = val;
|
|
390
390
|
// Reset page if a reload is triggered (either filter changed with a set filter value, or filter value cleared)
|
|
391
|
-
if (newState.filterVal || _this.state.filterVal && !newState.filterVal) {
|
|
391
|
+
if (newState.filterField && (newState.filterVal || _this.state.filterVal && !newState.filterVal)) {
|
|
392
392
|
newState.currentPage = 0;
|
|
393
393
|
_this.reload(_this.state.selectedLayer, false, newState);
|
|
394
394
|
} else {
|
|
@@ -814,6 +814,13 @@ var AttributeTableWidget = /*#__PURE__*/function (_React$Component) {
|
|
|
814
814
|
if (this.state.highlightedFeature !== prevState.highlightedFeature || this.state.features !== prevState.features || this.state.selectedFeatures !== prevState.selectedFeatures) {
|
|
815
815
|
this.highlightFeatures();
|
|
816
816
|
}
|
|
817
|
+
if (this.state.loadedLayer !== prevState.loadedLayer && this.props.showDisplayFieldOnly) {
|
|
818
|
+
this.setState(function (state) {
|
|
819
|
+
return {
|
|
820
|
+
filterField: state.curEditConfig.displayField
|
|
821
|
+
};
|
|
822
|
+
});
|
|
823
|
+
}
|
|
817
824
|
}
|
|
818
825
|
}, {
|
|
819
826
|
key: "componentWillUnmount",
|
package/components/SearchBox.js
CHANGED
|
@@ -1025,12 +1025,13 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
|
|
|
1025
1025
|
var text = LocaleUtils.tr("search.existinglayer") + ": " + existingLayerName;
|
|
1026
1026
|
_this.props.showNotification("existinglayer", text);
|
|
1027
1027
|
} else {
|
|
1028
|
+
var _existingLayer$role;
|
|
1028
1029
|
var existingLayer = _this.props.layers.find(function (l) {
|
|
1029
1030
|
return l.type === layer.type && l.url === layer.url;
|
|
1030
1031
|
});
|
|
1031
1032
|
_this.props.addLayer(_objectSpread(_objectSpread({}, layer), {}, {
|
|
1032
1033
|
srcid: existingLayer === null || existingLayer === void 0 ? void 0 : existingLayer.srcid,
|
|
1033
|
-
role: LayerRole.USERLAYER
|
|
1034
|
+
role: (_existingLayer$role = existingLayer === null || existingLayer === void 0 ? void 0 : existingLayer.role) !== null && _existingLayer$role !== void 0 ? _existingLayer$role : LayerRole.USERLAYER
|
|
1034
1035
|
}));
|
|
1035
1036
|
}
|
|
1036
1037
|
if (_this.props.searchOptions.zoomToLayers && layer.bbox) {
|
|
@@ -15,21 +15,21 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
15
15
|
import axios from 'axios';
|
|
16
16
|
import { applyStyle } from 'ol-mapbox-style';
|
|
17
17
|
import ol from 'openlayers';
|
|
18
|
+
export var createLayer = function createLayer(options) {
|
|
19
|
+
return new ol.layer.VectorTile(_objectSpread({
|
|
20
|
+
minResolution: options.minResolution,
|
|
21
|
+
maxResolution: options.maxResolution,
|
|
22
|
+
declutter: options.declutter,
|
|
23
|
+
source: new ol.source.VectorTile(_objectSpread({
|
|
24
|
+
projection: options.projection,
|
|
25
|
+
format: new ol.format.MVT({}),
|
|
26
|
+
url: options.url,
|
|
27
|
+
tileGrid: options.tileGridConfig ? new ol.tilegrid.TileGrid(_objectSpread({}, options.tileGridConfig)) : undefined
|
|
28
|
+
}, options.sourceConfig || {}))
|
|
29
|
+
}, options.layerConfig || {}));
|
|
30
|
+
};
|
|
18
31
|
export default {
|
|
19
32
|
create: function create(options) {
|
|
20
|
-
var createLayer = function createLayer() {
|
|
21
|
-
return new ol.layer.VectorTile(_objectSpread({
|
|
22
|
-
minResolution: options.minResolution,
|
|
23
|
-
maxResolution: options.maxResolution,
|
|
24
|
-
declutter: options.declutter,
|
|
25
|
-
source: new ol.source.VectorTile(_objectSpread({
|
|
26
|
-
projection: options.projection,
|
|
27
|
-
format: new ol.format.MVT({}),
|
|
28
|
-
url: options.url,
|
|
29
|
-
tileGrid: options.tileGridConfig ? new ol.tilegrid.TileGrid(_objectSpread({}, options.tileGridConfig)) : undefined
|
|
30
|
-
}, options.sourceConfig || {}))
|
|
31
|
-
}, options.layerConfig || {}));
|
|
32
|
-
};
|
|
33
33
|
var group = new ol.layer.Group();
|
|
34
34
|
if (options.style) {
|
|
35
35
|
axios.get(options.style).then(function (response) {
|
|
@@ -40,7 +40,7 @@ export default {
|
|
|
40
40
|
Object.keys(glStyle.sources).forEach(function (styleSource) {
|
|
41
41
|
var _glStyle$sources$styl;
|
|
42
42
|
((_glStyle$sources$styl = glStyle.sources[styleSource].url) === null || _glStyle$sources$styl === void 0 ? void 0 : _glStyle$sources$styl.startsWith(".")) && (glStyle.sources[styleSource].url = new URL(glStyle.sources[styleSource].url, options.style).href);
|
|
43
|
-
var layer = createLayer();
|
|
43
|
+
var layer = createLayer(options);
|
|
44
44
|
applyStyle(layer, glStyle, styleSource, options.styleOptions).then(function () {
|
|
45
45
|
group.getLayers().push(layer);
|
|
46
46
|
})["catch"](function (e) {
|
|
@@ -53,7 +53,7 @@ export default {
|
|
|
53
53
|
console.warn("Unable to load style " + options.style + ": " + String(e));
|
|
54
54
|
});
|
|
55
55
|
} else {
|
|
56
|
-
group.getLayers().push(createLayer());
|
|
56
|
+
group.getLayers().push(createLayer(options));
|
|
57
57
|
}
|
|
58
58
|
return group;
|
|
59
59
|
}
|
|
@@ -0,0 +1,158 @@
|
|
|
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 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; }
|
|
3
|
+
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; }
|
|
4
|
+
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
5
|
+
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
6
|
+
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
7
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
8
|
+
function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
|
|
9
|
+
function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
|
|
10
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
11
|
+
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
|
|
12
|
+
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
|
|
13
|
+
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
|
|
14
|
+
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; }
|
|
15
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
16
|
+
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); }
|
|
17
|
+
/**
|
|
18
|
+
* Copyright 2026 Sourcepole AG
|
|
19
|
+
* All rights reserved.
|
|
20
|
+
*
|
|
21
|
+
* This source code is licensed under the BSD-style license found in the
|
|
22
|
+
* LICENSE file in the root directory of this source tree.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import React from 'react';
|
|
26
|
+
import DrapedFeatureCollection from '@giro3d/giro3d/entities/DrapedFeatureCollection';
|
|
27
|
+
import PropTypes from 'prop-types';
|
|
28
|
+
import LayerRegistry3D from './layers/index';
|
|
29
|
+
var ColorLayer3D = /*#__PURE__*/function (_React$Component) {
|
|
30
|
+
function ColorLayer3D(props) {
|
|
31
|
+
var _this;
|
|
32
|
+
_classCallCheck(this, ColorLayer3D);
|
|
33
|
+
_this = _callSuper(this, ColorLayer3D, [props]);
|
|
34
|
+
_defineProperty(_this, "applyLayerOptions", function (layerCreator, prevOptions) {
|
|
35
|
+
var _this$props$map$getLa;
|
|
36
|
+
var options = _this.props.options;
|
|
37
|
+
// Reorder layer
|
|
38
|
+
var layerBelow = (_this$props$map$getLa = _this.props.map.getLayers(function (l) {
|
|
39
|
+
return l.userData.layerId === _this.props.prevLayerId;
|
|
40
|
+
})[0]) !== null && _this$props$map$getLa !== void 0 ? _this$props$map$getLa : null;
|
|
41
|
+
_this.mapLayer.moveAfter(layerBelow);
|
|
42
|
+
// WMS layer handles visibility and opacity internally
|
|
43
|
+
if (_this.props.options.type !== "wms") {
|
|
44
|
+
_this.mapLayer.setVisible(options.visibility);
|
|
45
|
+
_this.mapLayer.setOpacity(options.opacity / 255);
|
|
46
|
+
}
|
|
47
|
+
if (_this.props.options.extrusionHeight !== undefined && _this.props.options.extrusionHeight !== 0) {
|
|
48
|
+
_this.createUpdateExtrudedLayer(layerCreator, options, options.features !== (prevOptions === null || prevOptions === void 0 ? void 0 : prevOptions.features));
|
|
49
|
+
} else if ((prevOptions === null || prevOptions === void 0 ? void 0 : prevOptions.extrusionHeight) !== undefined && (prevOptions === null || prevOptions === void 0 ? void 0 : prevOptions.extrusionHeight) !== 0) {
|
|
50
|
+
_this.props.sceneContext.removeSceneObject(_this.props.options.id + ":extruded");
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
_defineProperty(_this, "createUpdateExtrudedLayer", function (layerCreator, options) {
|
|
54
|
+
var _options$features, _options$features$red;
|
|
55
|
+
var forceCreate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
56
|
+
var objId = options.id + ":extruded";
|
|
57
|
+
var makeColor = function makeColor(c) {
|
|
58
|
+
if (Array.isArray(c)) {
|
|
59
|
+
return c[0] << 16 | c[1] << 8 | c[2];
|
|
60
|
+
} else if (typeof c === "string") {
|
|
61
|
+
return parseInt(c.replace("#", ""), 16);
|
|
62
|
+
} else {
|
|
63
|
+
return c;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var obj = _this.props.sceneContext.getSceneObject(objId);
|
|
67
|
+
if (!obj || forceCreate) {
|
|
68
|
+
var _options$color;
|
|
69
|
+
if (obj) {
|
|
70
|
+
_this.props.sceneContext.removeSceneObject(objId);
|
|
71
|
+
}
|
|
72
|
+
var layercolor = makeColor((_options$color = options.color) !== null && _options$color !== void 0 ? _options$color : "#FF0000");
|
|
73
|
+
obj = new DrapedFeatureCollection({
|
|
74
|
+
source: layerCreator.createFeatureSource(_this.mapLayer, options, _this.props.sceneContext.mapCrs),
|
|
75
|
+
drapingMode: 'per-feature',
|
|
76
|
+
extrusionOffset: function extrusionOffset(feature) {
|
|
77
|
+
if (typeof obj.userData.extrusionHeight === "string") {
|
|
78
|
+
return parseFloat(feature.getProperties()[obj.userData.extrusionHeight]) || 0;
|
|
79
|
+
} else {
|
|
80
|
+
return obj.userData.extrusionHeight;
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
style: function style(feature) {
|
|
84
|
+
var _obj$userData$feature, _obj$userData$feature2;
|
|
85
|
+
return (_obj$userData$feature = (_obj$userData$feature2 = obj.userData.featureStyles) === null || _obj$userData$feature2 === void 0 ? void 0 : _obj$userData$feature2[feature.getId()]) !== null && _obj$userData$feature !== void 0 ? _obj$userData$feature : {
|
|
86
|
+
fill: {
|
|
87
|
+
color: layercolor,
|
|
88
|
+
shading: true
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
obj.castShadow = true;
|
|
94
|
+
obj.receiveShadow = true;
|
|
95
|
+
_this.props.sceneContext.addSceneObject(objId, obj, false, {}, false, function () {
|
|
96
|
+
obj.attach(_this.props.map);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
obj.userData.extrusionHeight = options.extrusionHeight;
|
|
100
|
+
obj.userData.featureStyles = (_options$features = options.features) === null || _options$features === void 0 || (_options$features$red = _options$features.reduce) === null || _options$features$red === void 0 ? void 0 : _options$features$red.call(_options$features, function (res, feature) {
|
|
101
|
+
return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, feature.id, {
|
|
102
|
+
fill: {
|
|
103
|
+
color: makeColor(feature.styleOptions.fillColor),
|
|
104
|
+
shading: true
|
|
105
|
+
}
|
|
106
|
+
}));
|
|
107
|
+
}, {});
|
|
108
|
+
obj.opacity = _this.mapLayer.opacity();
|
|
109
|
+
obj.visible = _this.mapLayer.visible();
|
|
110
|
+
if (obj.visible) {
|
|
111
|
+
obj.updateStyles();
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
_this.mapLayer = null;
|
|
115
|
+
return _this;
|
|
116
|
+
}
|
|
117
|
+
_inherits(ColorLayer3D, _React$Component);
|
|
118
|
+
return _createClass(ColorLayer3D, [{
|
|
119
|
+
key: "componentDidMount",
|
|
120
|
+
value: function componentDidMount() {
|
|
121
|
+
var layerCreator = LayerRegistry3D[this.props.options.type];
|
|
122
|
+
if (layerCreator) {
|
|
123
|
+
this.mapLayer = layerCreator.create3d(this.props.options, this.props.sceneContext.mapCrs);
|
|
124
|
+
this.mapLayer.attach(this.props.map);
|
|
125
|
+
this.applyLayerOptions(layerCreator, {});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}, {
|
|
129
|
+
key: "componentDidUpdate",
|
|
130
|
+
value: function componentDidUpdate(prevProps) {
|
|
131
|
+
var layerCreator = LayerRegistry3D[this.props.options.type];
|
|
132
|
+
if (this.mapLayer && layerCreator) {
|
|
133
|
+
layerCreator.update3d(this.mapLayer, this.props.options, prevProps.options, this.props.sceneContext.mapCrs);
|
|
134
|
+
this.applyLayerOptions(layerCreator, prevProps.options);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}, {
|
|
138
|
+
key: "componentWillUnmount",
|
|
139
|
+
value: function componentWillUnmount() {
|
|
140
|
+
if (this.mapLayer) {
|
|
141
|
+
this.props.sceneContext.removeSceneObject(this.props.options.id + ":extruded");
|
|
142
|
+
this.mapLayer.dispose();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}, {
|
|
146
|
+
key: "render",
|
|
147
|
+
value: function render() {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}]);
|
|
151
|
+
}(React.Component);
|
|
152
|
+
_defineProperty(ColorLayer3D, "propTypes", {
|
|
153
|
+
map: PropTypes.object,
|
|
154
|
+
options: PropTypes.object,
|
|
155
|
+
prevLayerId: PropTypes.string,
|
|
156
|
+
sceneContext: PropTypes.object
|
|
157
|
+
});
|
|
158
|
+
export { ColorLayer3D as default };
|