qwc2 2026.3.24 → 2026.3.30
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/map3d/utils/MiscUtils3D.js +10 -10
- package/components/style/AppMenu.css +58 -27
- package/components/style/AttributeTableWidget.css +5 -5
- package/package.json +1 -1
- package/plugins/Bookmark.js +3 -2
- package/plugins/LayerTree.js +21 -1
- package/plugins/TopBar.js +15 -11
- package/plugins/map3d/HideObjects3D.js +4 -2
- package/plugins/map3d/MeasureObjects3D.js +8 -6
- package/plugins/map3d/TopBar3D.js +11 -5
- package/plugins/style/Portal.css +0 -5
- package/reducers/layers.js +17 -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) {
|
|
@@ -101,9 +101,10 @@ export function computeOBBXY(mesh) {
|
|
|
101
101
|
var zmin = Infinity;
|
|
102
102
|
var zmax = -Infinity;
|
|
103
103
|
for (var i = 0; i < n; i++) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
var p = new Vector3(pos.getX(i), pos.getY(i), pos.getZ(i)).applyMatrix4(mesh.matrixWorld);
|
|
105
|
+
pointsxy[i] = [p.x, p.y];
|
|
106
|
+
zmin = Math.min(zmin, p.z);
|
|
107
|
+
zmax = Math.max(zmax, p.z);
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
// Compute convex hull
|
|
@@ -125,9 +126,9 @@ export function computeOBBXY(mesh) {
|
|
|
125
126
|
var _vmin = Infinity;
|
|
126
127
|
var _vmax = -Infinity;
|
|
127
128
|
for (var j = 0; j < hull.length; j++) {
|
|
128
|
-
var
|
|
129
|
-
var pu =
|
|
130
|
-
var pv =
|
|
129
|
+
var _p = _construct(Vector2, _toConsumableArray(hull[j]));
|
|
130
|
+
var pu = _p.dot(_u);
|
|
131
|
+
var pv = _p.dot(_v);
|
|
131
132
|
if (pu < _umin) _umin = pu;
|
|
132
133
|
if (pu > _umax) _umax = pu;
|
|
133
134
|
if (pv < _vmin) _vmin = pv;
|
|
@@ -153,12 +154,11 @@ export function computeOBBXY(mesh) {
|
|
|
153
154
|
umax = _best.umax,
|
|
154
155
|
vmin = _best.vmin,
|
|
155
156
|
vmax = _best.vmax;
|
|
156
|
-
var center = new Vector3(u.x * (umin + umax) / 2 + v.x * (vmin + vmax) / 2, u.y * (umin + umax) / 2 + v.y * (vmin + vmax) / 2, (zmin + zmax) / 2)
|
|
157
|
-
var normalMatrix = new Matrix3().getNormalMatrix(mesh.matrixWorld);
|
|
157
|
+
var center = new Vector3(u.x * (umin + umax) / 2 + v.x * (vmin + vmax) / 2, u.y * (umin + umax) / 2 + v.y * (vmin + vmax) / 2, (zmin + zmax) / 2);
|
|
158
158
|
return {
|
|
159
159
|
center: center,
|
|
160
|
-
axes: [new Vector3(u.x, u.y, 0)
|
|
161
|
-
halfSizes: new Vector3((umax - umin) / 2
|
|
160
|
+
axes: [new Vector3(u.x, u.y, 0), new Vector3(v.x, v.y, 0), new Vector3(0, 0, 1)],
|
|
161
|
+
halfSizes: new Vector3((umax - umin) / 2, (vmax - vmin) / 2, (zmax - zmin) / 2)
|
|
162
162
|
};
|
|
163
163
|
}
|
|
164
164
|
export var TileMeshHelper = /*#__PURE__*/function () {
|
|
@@ -36,10 +36,16 @@ div.AppMenu.appmenu-visible .appmenu-label {
|
|
|
36
36
|
color: var(--app-submenu-text-color-hover);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
div.AppMenu .appmenu-icon {
|
|
40
|
+
width: 3.5em;
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
justify-content: center;
|
|
44
|
+
}
|
|
45
|
+
|
|
39
46
|
div.AppMenu .appmenu-icon > span.icon {
|
|
40
47
|
color: var(--app-menu-text-color);
|
|
41
48
|
padding: 0.25em;
|
|
42
|
-
margin: 0 1em;
|
|
43
49
|
border: 2px solid var(--app-menu-text-color);
|
|
44
50
|
transition: color 0.25s, border-color 0.25s, background-color 0.25s;
|
|
45
51
|
}
|
|
@@ -58,47 +64,52 @@ div.AppMenu div.appmenu-menu-container {
|
|
|
58
64
|
position: absolute;
|
|
59
65
|
top: 100%;
|
|
60
66
|
right: 0;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
width: 100%;
|
|
68
|
+
overflow-y: auto;
|
|
69
|
+
overflow-x: hidden;
|
|
70
|
+
height: calc(var(--plugins-container-height) - var(--topbar-height) - var(--bottombar-height));
|
|
71
|
+
pointer-events: none;
|
|
64
72
|
opacity: 0;
|
|
65
73
|
transform-origin: top;
|
|
66
74
|
transform: scaleY(0);
|
|
67
75
|
transition: transform 0.25s, opacity 0.25s;
|
|
68
|
-
overflow-y: auto;
|
|
69
|
-
max-height: calc(var(--plugins-container-height) - var(--topbar-height) - var(--bottombar-height));
|
|
70
|
-
border-radius: 0px 0px 0px var(--border-radius);
|
|
71
76
|
}
|
|
72
77
|
|
|
73
|
-
div.AppMenu.appmenu-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
height: calc(var(--plugins-container-height) - var(--topbar-height) - var(--bottombar-height));
|
|
77
|
-
transition: transform 0.25s, opacity 0.25s, right 0.5s;
|
|
78
|
-
background: var(--app-menu-bg-color);
|
|
79
|
-
box-shadow: 0px 0px 4px rgba(136, 136, 136, 0.5);
|
|
80
|
-
top: 3.5em;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
div.AppMenu.appmenu-icononly div.appmenu-menu-container {
|
|
84
|
-
right: 0;
|
|
85
|
-
width: auto;
|
|
78
|
+
div.AppMenu.appmenu-visible div.appmenu-menu-container {
|
|
79
|
+
transform: scaleY(1);
|
|
80
|
+
opacity: 1;
|
|
86
81
|
}
|
|
87
82
|
|
|
88
|
-
div.AppMenu
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
div.AppMenu div.appmenu-menu-aligner {
|
|
84
|
+
display: flex;
|
|
85
|
+
justify-content: end;
|
|
91
86
|
}
|
|
92
87
|
|
|
93
88
|
div.AppMenu div.appmenu-menu {
|
|
89
|
+
position: relative;
|
|
90
|
+
pointer-events: initial;
|
|
91
|
+
text-align: left;
|
|
94
92
|
background-color: var(--app-menu-bg-color);
|
|
93
|
+
box-shadow: 0px 2px 4px rgba(136, 136, 136, 0.5);
|
|
95
94
|
text-align: left;
|
|
96
|
-
|
|
95
|
+
width: 22.22em;
|
|
96
|
+
font-size: 90%;
|
|
97
|
+
border-radius: 0px 0px 0px var(--border-radius);
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
div.AppMenu.appmenu-
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
div.AppMenu.appmenu-compact div.appmenu-menu {
|
|
101
|
+
right: -18.33em;
|
|
102
|
+
transition: right 0.5s;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
div.AppMenu.appmenu-compact div.appmenu-menu:hover,
|
|
106
|
+
div.AppMenu.appmenu-compact div.appmenu-menu:focus-within {
|
|
107
|
+
right: 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
div.AppMenu.appmenu-icononly div.appmenu-menu {
|
|
111
|
+
width: 3.89em;
|
|
112
|
+
right: 0;
|
|
102
113
|
}
|
|
103
114
|
|
|
104
115
|
div.appmenu-menu-item {
|
|
@@ -106,6 +117,7 @@ div.appmenu-menu-item {
|
|
|
106
117
|
align-items: center;
|
|
107
118
|
color: var(--app-menu-text-color);
|
|
108
119
|
font-weight: bold;
|
|
120
|
+
position: relative;
|
|
109
121
|
}
|
|
110
122
|
|
|
111
123
|
div.appmenu-menu-item:not(:last-child) {
|
|
@@ -126,6 +138,25 @@ div.appmenu-menu-item-comment {
|
|
|
126
138
|
font-size: 90%;
|
|
127
139
|
}
|
|
128
140
|
|
|
141
|
+
span.appmenu-menu-item-tooltip {
|
|
142
|
+
position: absolute;
|
|
143
|
+
display: none;
|
|
144
|
+
background-color: var(--tooltip-bg-color);
|
|
145
|
+
border: 1px solid var(--tooltip-border-color);
|
|
146
|
+
color: var(--tooltip-text-color);
|
|
147
|
+
font-size: 75%;
|
|
148
|
+
font-weight: normal;
|
|
149
|
+
padding: 0.5em;
|
|
150
|
+
border-radius: 0.5em;
|
|
151
|
+
white-space: nowrap;
|
|
152
|
+
right: calc(100% + 0.25em);
|
|
153
|
+
z-index: 2;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
div.appmenu-menu-item:hover span.appmenu-menu-item-tooltip {
|
|
157
|
+
display: inline;
|
|
158
|
+
}
|
|
159
|
+
|
|
129
160
|
div.appmenu-submenu-active,
|
|
130
161
|
div.appmenu-submenu-expanded {
|
|
131
162
|
background-color: var(--app-menu-bg-color-hover);
|
|
@@ -42,10 +42,6 @@ div.attribtable-contents {
|
|
|
42
42
|
position: relative;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
table.attribtable-table {
|
|
46
|
-
min-width: 100%;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
45
|
table.attribtable-table th {
|
|
50
46
|
position: sticky;
|
|
51
47
|
top: 0;
|
|
@@ -109,6 +105,10 @@ table.attribtable-table td:first-child {
|
|
|
109
105
|
width: 2.5em;
|
|
110
106
|
}
|
|
111
107
|
|
|
108
|
+
table.attribtable-table td {
|
|
109
|
+
min-width: 2.5em;;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
112
|
span.attribtable-table-ldraghandle,
|
|
113
113
|
span.attribtable-table-rdraghandle {
|
|
114
114
|
touch-action: none;
|
|
@@ -149,7 +149,7 @@ span.attribtable-table-bdraghandle {
|
|
|
149
149
|
|
|
150
150
|
table.attribtable-table {
|
|
151
151
|
table-layout: fixed;
|
|
152
|
-
width: 100%;
|
|
152
|
+
min-width: 100%;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
table.attribtable-table td {
|
package/package.json
CHANGED
package/plugins/Bookmark.js
CHANGED
|
@@ -316,8 +316,9 @@ var Bookmark = /*#__PURE__*/function (_React$Component) {
|
|
|
316
316
|
}) : null, _this2.state.renameBookmark !== bookmark.key ? /*#__PURE__*/React.createElement(Icon, {
|
|
317
317
|
disabled: _this2.state.busy,
|
|
318
318
|
icon: "trash",
|
|
319
|
-
onClick: function onClick() {
|
|
320
|
-
|
|
319
|
+
onClick: function onClick(ev) {
|
|
320
|
+
_this2.removeBookmark(bookmark.key);
|
|
321
|
+
MiscUtils.killEvent(ev);
|
|
321
322
|
},
|
|
322
323
|
title: LocaleUtils.tr("common.delete")
|
|
323
324
|
}) : null);
|
package/plugins/LayerTree.js
CHANGED
|
@@ -484,6 +484,24 @@ var LayerTree = /*#__PURE__*/function (_React$Component) {
|
|
|
484
484
|
onChange: function onChange(ev) {
|
|
485
485
|
return _this.layerTransparencyChanged(layer, path, ev.target.value, !isEmpty(sublayer.sublayers) ? 'children' : null);
|
|
486
486
|
},
|
|
487
|
+
onMouseDown: function onMouseDown(ev) {
|
|
488
|
+
return ev.stopPropagation();
|
|
489
|
+
},
|
|
490
|
+
onMouseMove: function onMouseMove(ev) {
|
|
491
|
+
return ev.stopPropagation();
|
|
492
|
+
},
|
|
493
|
+
onPointerDown: function onPointerDown(ev) {
|
|
494
|
+
return ev.stopPropagation();
|
|
495
|
+
},
|
|
496
|
+
onPointerMove: function onPointerMove(ev) {
|
|
497
|
+
return ev.stopPropagation();
|
|
498
|
+
},
|
|
499
|
+
onTouchMove: function onTouchMove(ev) {
|
|
500
|
+
return ev.stopPropagation();
|
|
501
|
+
},
|
|
502
|
+
onTouchStart: function onTouchStart(ev) {
|
|
503
|
+
return ev.stopPropagation();
|
|
504
|
+
},
|
|
487
505
|
step: "1",
|
|
488
506
|
type: "range",
|
|
489
507
|
value: 255 - LayerUtils.computeLayerOpacity(sublayer)
|
|
@@ -544,12 +562,14 @@ var LayerTree = /*#__PURE__*/function (_React$Component) {
|
|
|
544
562
|
var usedGroupIds = new Set();
|
|
545
563
|
if (isEmpty(layer.sublayers) && layer.role !== LayerRole.THEME) {
|
|
546
564
|
return _this.renderLayer(layer, layer, [], layer.visibility, false, !haveGroups);
|
|
565
|
+
} else if (_this.props.showRootEntry && layer.role === LayerRole.THEME && isEmpty(layer.sublayers)) {
|
|
566
|
+
return null;
|
|
547
567
|
} else if (_this.props.showRootEntry || layer.role !== LayerRole.THEME) {
|
|
548
568
|
return _this.renderLayerGroup(layer, layer, [], layer.visibility, false, usedGroupIds);
|
|
549
569
|
} else {
|
|
550
570
|
return layer.sublayers.map(function (sublayer, idx) {
|
|
551
571
|
var subpath = [idx];
|
|
552
|
-
if (sublayer.sublayers) {
|
|
572
|
+
if (!isEmpty(sublayer.sublayers)) {
|
|
553
573
|
return _this.renderLayerGroup(layer, sublayer, subpath, layer.visibility, false, usedGroupIds);
|
|
554
574
|
} else {
|
|
555
575
|
return _this.renderLayer(layer, sublayer, subpath, layer.visibility, false, !haveGroups);
|
package/plugins/TopBar.js
CHANGED
|
@@ -166,12 +166,17 @@ var TopBar = /*#__PURE__*/function (_React$Component) {
|
|
|
166
166
|
var searchOptions = _objectSpread(_objectSpread({}, TopBar.defaultProps.searchOptions), this.props.searchOptions);
|
|
167
167
|
searchOptions.minScaleDenom = searchOptions.minScaleDenom || searchOptions.minScale;
|
|
168
168
|
delete searchOptions.minScale;
|
|
169
|
-
//
|
|
170
|
-
var
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
// Validate appMenuDisplayMode
|
|
170
|
+
var appMenuDisplayMode = this.props.appMenuDisplayMode;
|
|
171
|
+
if (ConfigUtils.isMobile() || !["normal", "compact", "icononly"].includes(this.props.appMenuDisplayMode)) {
|
|
172
|
+
appMenuDisplayMode = "normal";
|
|
173
|
+
/* eslint-disable-next-line react/prop-types */
|
|
174
|
+
} else if (this.props.appMenuCompact) {
|
|
175
|
+
/* eslint-disable-next-line no-console */
|
|
176
|
+
console.warn("TopBar: the appMenuCompact prop is deprecated, use appMenuDisplayMode");
|
|
177
|
+
appMenuDisplayMode = "compact";
|
|
178
|
+
}
|
|
173
179
|
// Menu should be visible on startup when appMenu is in compact mode (Visible on Hover)
|
|
174
|
-
var showOnStartup = this.props.appMenuVisibleOnStartup || menuCompact;
|
|
175
180
|
var style = {
|
|
176
181
|
marginLeft: this.props.mapMargins.outerLeft + 'px',
|
|
177
182
|
marginRight: this.props.mapMargins.outerRight + 'px'
|
|
@@ -201,13 +206,11 @@ var TopBar = /*#__PURE__*/function (_React$Component) {
|
|
|
201
206
|
appMenuClearsTask: this.props.appMenuClearsTask,
|
|
202
207
|
appMenuShortcut: this.props.appMenuShortcut,
|
|
203
208
|
buttonLabel: LocaleUtils.tr("appmenu.menulabel"),
|
|
204
|
-
|
|
205
|
-
menuCompact: menuCompact,
|
|
206
|
-
menuIconOnly: this.props.appMenuIconOnly,
|
|
209
|
+
menuDisplayMode: appMenuDisplayMode,
|
|
207
210
|
menuItems: this.state.allowedMenuItems,
|
|
208
211
|
openExternalUrl: this.openUrl,
|
|
209
212
|
showFilterField: this.props.appMenuFilterField,
|
|
210
|
-
showOnStartup:
|
|
213
|
+
showOnStartup: this.props.appMenuVisibleOnStartup
|
|
211
214
|
}) : null, this.props.components.FullscreenSwitcher ? /*#__PURE__*/React.createElement(this.props.components.FullscreenSwitcher, null) : null));
|
|
212
215
|
}
|
|
213
216
|
}]);
|
|
@@ -215,8 +218,8 @@ var TopBar = /*#__PURE__*/function (_React$Component) {
|
|
|
215
218
|
_defineProperty(TopBar, "propTypes", {
|
|
216
219
|
/** Whether opening the app menu clears the active task. */
|
|
217
220
|
appMenuClearsTask: PropTypes.bool,
|
|
218
|
-
/**
|
|
219
|
-
|
|
221
|
+
/** App-Menu display mode. Only available for desktop client. */
|
|
222
|
+
appMenuDisplayMode: PropTypes.oneOf(["normal", "compact", "iconsonly"]),
|
|
220
223
|
/** Whether to display the filter field in the app menu. */
|
|
221
224
|
appMenuFilterField: PropTypes.bool,
|
|
222
225
|
/** Whether to hide the app menu (useful primarely as a theme specific setting). */
|
|
@@ -296,6 +299,7 @@ _defineProperty(TopBar, "defaultProps", {
|
|
|
296
299
|
showResultInSearchText: true,
|
|
297
300
|
minScaleDenom: 1000
|
|
298
301
|
},
|
|
302
|
+
appMenuDisplayMode: 'normal',
|
|
299
303
|
menuItems: [],
|
|
300
304
|
toolbarItems: [],
|
|
301
305
|
logoFormat: "svg"
|
|
@@ -202,7 +202,7 @@ var HideObjects3D = /*#__PURE__*/function (_React$Component) {
|
|
|
202
202
|
var index = pick.object.geometry.getIndex();
|
|
203
203
|
|
|
204
204
|
// Create highlight geometry
|
|
205
|
-
_this.storeHiddenObject(pick, posAttr.array, norAttr.array, index);
|
|
205
|
+
_this.storeHiddenObject(pick, posAttr.array, norAttr === null || norAttr === void 0 ? void 0 : norAttr.array, index);
|
|
206
206
|
});
|
|
207
207
|
_defineProperty(_this, "storeHiddenObject", function (pick, position, normal) {
|
|
208
208
|
var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
@@ -212,7 +212,9 @@ var HideObjects3D = /*#__PURE__*/function (_React$Component) {
|
|
|
212
212
|
});
|
|
213
213
|
var geometry = new BufferGeometry();
|
|
214
214
|
geometry.setAttribute('position', new Float32BufferAttribute(position, 3));
|
|
215
|
-
|
|
215
|
+
if (normal) {
|
|
216
|
+
geometry.setAttribute('normal', new Float32BufferAttribute(normal, 3));
|
|
217
|
+
}
|
|
216
218
|
geometry.setIndex(index);
|
|
217
219
|
var mesh = new Mesh(geometry, material);
|
|
218
220
|
mesh.receiveShadow = true;
|
|
@@ -173,16 +173,16 @@ var MeasureObjects3D = /*#__PURE__*/function (_React$Component) {
|
|
|
173
173
|
_this.storeMeasuredObject(pick, pickPosition, pickNormal, null, pickFeatureId, pickUuid);
|
|
174
174
|
});
|
|
175
175
|
_defineProperty(_this, "measureObjectPick", function (pick) {
|
|
176
|
-
var posAttr = pick.object.geometry.getAttribute('position');
|
|
177
|
-
var norAttr = pick.object.geometry.getAttribute('normal');
|
|
178
|
-
var index = pick.object.geometry.getIndex();
|
|
179
176
|
if (pick.object.uuid in _this.state.measuredObjects) {
|
|
180
177
|
_this.removeMeasurement(_this.state.measuredObjects[pick.object.uuid]);
|
|
181
178
|
return;
|
|
182
179
|
}
|
|
180
|
+
var posAttr = pick.object.geometry.getAttribute('position');
|
|
181
|
+
var norAttr = pick.object.geometry.getAttribute('normal');
|
|
182
|
+
var index = pick.object.geometry.getIndex();
|
|
183
183
|
|
|
184
184
|
// Create highlight geometry
|
|
185
|
-
_this.storeMeasuredObject(pick, posAttr.array, norAttr.array, index, null, pick.object.uuid);
|
|
185
|
+
_this.storeMeasuredObject(pick, posAttr.array, norAttr === null || norAttr === void 0 ? void 0 : norAttr.array, index, null, pick.object.uuid);
|
|
186
186
|
});
|
|
187
187
|
_defineProperty(_this, "storeMeasuredObject", function (pick, position, normal) {
|
|
188
188
|
var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
@@ -193,7 +193,9 @@ var MeasureObjects3D = /*#__PURE__*/function (_React$Component) {
|
|
|
193
193
|
});
|
|
194
194
|
var geometry = new BufferGeometry();
|
|
195
195
|
geometry.setAttribute('position', new Float32BufferAttribute(position, 3));
|
|
196
|
-
|
|
196
|
+
if (normal) {
|
|
197
|
+
geometry.setAttribute('normal', new Float32BufferAttribute(normal, 3));
|
|
198
|
+
}
|
|
197
199
|
geometry.setIndex(index);
|
|
198
200
|
var mesh = new Mesh(geometry, material);
|
|
199
201
|
mesh.receiveShadow = true;
|
|
@@ -285,7 +287,7 @@ var MeasureObjects3D = /*#__PURE__*/function (_React$Component) {
|
|
|
285
287
|
var dim2 = LocaleUtils.toLocaleFixed(2 * obox.halfSizes.y, decimals);
|
|
286
288
|
var dim3 = LocaleUtils.toLocaleFixed(2 * obox.halfSizes.z, decimals);
|
|
287
289
|
boxmesh.userData.label = "<span class=\"map3d-measure-label\"><span style=\"color: red\">".concat(dim1, "</span> \u26CC <span style=\"color: green\">").concat(dim2, "</span> \u26CC <span style=\"color: blue\">").concat(dim3, "</span></<span>");
|
|
288
|
-
boxmesh.userData.labelOffset =
|
|
290
|
+
boxmesh.userData.labelOffset = 5 + obox.halfSizes.z;
|
|
289
291
|
updateObjectLabel(boxmesh, _this.props.sceneContext);
|
|
290
292
|
return boxmesh;
|
|
291
293
|
});
|
|
@@ -132,7 +132,14 @@ var TopBar3D = /*#__PURE__*/function (_React$Component) {
|
|
|
132
132
|
target: "_blank"
|
|
133
133
|
}, logoEl);
|
|
134
134
|
}
|
|
135
|
-
|
|
135
|
+
|
|
136
|
+
// Validate appMenuDisplayMode
|
|
137
|
+
var appMenuDisplayMode = config.appMenuDisplayMode;
|
|
138
|
+
if (!ConfigUtils.isMobile() || !["normal", "compact", "icononly"].includes(config.appMenuDisplayMode)) {
|
|
139
|
+
appMenuDisplayMode = "normal";
|
|
140
|
+
} else if (config.appMenuCompact) {
|
|
141
|
+
appMenuDisplayMode = "compact";
|
|
142
|
+
}
|
|
136
143
|
var classes = classNames({
|
|
137
144
|
TopBar: true,
|
|
138
145
|
mobile: isMobile,
|
|
@@ -162,12 +169,11 @@ var TopBar3D = /*#__PURE__*/function (_React$Component) {
|
|
|
162
169
|
appMenuClearsTask: config.appMenuClearsTask,
|
|
163
170
|
appMenuShortcut: config.appMenuShortcut,
|
|
164
171
|
buttonLabel: LocaleUtils.tr("appmenu.menulabel"),
|
|
165
|
-
|
|
166
|
-
menuCompact: menuCompact,
|
|
167
|
-
menuIconOnly: config.appMenuIconOnly,
|
|
172
|
+
menuDisplayMode: appMenuDisplayMode,
|
|
168
173
|
menuItems: this.state.allowedMenuItems,
|
|
169
174
|
openExternalUrl: this.openUrl,
|
|
170
|
-
showFilterField: config.appMenuFilterField
|
|
175
|
+
showFilterField: config.appMenuFilterField,
|
|
176
|
+
showOnStartup: config.appMenuVisibleOnStartup
|
|
171
177
|
}), this.props.viewMode === ViewMode._3DFullscreen ? /*#__PURE__*/React.createElement(FullscreenSwitcher, null) : null));
|
|
172
178
|
}
|
|
173
179
|
}]);
|
package/plugins/style/Portal.css
CHANGED
|
@@ -31,11 +31,6 @@ span.portal-topbar-spacer {
|
|
|
31
31
|
flex: 1 1 auto;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
div.portal-topbar div.AppMenu div.appmenu-menu-container {
|
|
35
|
-
height: calc(var(--plugins-container-height) - var(--topbar-height) - var(--bottombar-height));
|
|
36
|
-
background-color: var(--app-menu-bg-color);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
34
|
div.portal-topbar div.AppMenu ul.appmenu-menu li:last-child {
|
|
40
35
|
border-bottom: 1px solid var(--app-menu-text-color);
|
|
41
36
|
}
|
package/reducers/layers.js
CHANGED
|
@@ -282,6 +282,23 @@ export default function layers() {
|
|
|
282
282
|
}
|
|
283
283
|
});
|
|
284
284
|
}
|
|
285
|
+
// Ensure (empty) theme layer is present
|
|
286
|
+
if (!_newLayers5.find(function (l) {
|
|
287
|
+
return l.role === LayerRole.THEME;
|
|
288
|
+
})) {
|
|
289
|
+
var prevThemeLayer = state.flat.find(function (l) {
|
|
290
|
+
return l.role === LayerRole.THEME;
|
|
291
|
+
});
|
|
292
|
+
if (prevThemeLayer) {
|
|
293
|
+
var themeLayer = _objectSpread(_objectSpread({}, prevThemeLayer), {}, {
|
|
294
|
+
sublayers: []
|
|
295
|
+
});
|
|
296
|
+
var pos = _newLayers5.findIndex(function (l) {
|
|
297
|
+
return l.role === LayerRole.BACKGROUND;
|
|
298
|
+
});
|
|
299
|
+
_newLayers5.splice(pos === -1 ? _newLayers5.length : pos, 0, _objectSpread(_objectSpread({}, themeLayer), LayerUtils.buildWMSLayerParams(themeLayer, state.filter)));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
285
302
|
UrlParams.updateParams({
|
|
286
303
|
l: LayerUtils.buildWMSLayerUrlParam(_newLayers5)
|
|
287
304
|
});
|
package/utils/LayerUtils.js
CHANGED
|
@@ -92,6 +92,7 @@ var LayerUtils = {
|
|
|
92
92
|
restoreOrderedLayerParams: function restoreOrderedLayerParams(themeLayer, layerConfigs, permalinkLayers, externalLayers) {
|
|
93
93
|
var exploded = LayerUtils.explodeLayers([themeLayer]);
|
|
94
94
|
var reordered = [];
|
|
95
|
+
var haveThemeLayer = false;
|
|
95
96
|
// Iterate over layer configs and reorder items accordingly, create external layer placeholders as neccessary
|
|
96
97
|
var _iterator3 = _createForOfIteratorHelper(layerConfigs),
|
|
97
98
|
_step3;
|
|
@@ -99,6 +100,7 @@ var LayerUtils = {
|
|
|
99
100
|
var _loop2 = function _loop2() {
|
|
100
101
|
var layerConfig = _step3.value;
|
|
101
102
|
if (layerConfig.type === 'theme') {
|
|
103
|
+
haveThemeLayer = true;
|
|
102
104
|
var entry = exploded.find(function (e) {
|
|
103
105
|
return e.sublayer.name === layerConfig.name;
|
|
104
106
|
});
|
|
@@ -125,6 +127,12 @@ var LayerUtils = {
|
|
|
125
127
|
}
|
|
126
128
|
LayerUtils.insertPermalinkLayers(reordered, permalinkLayers);
|
|
127
129
|
var layers = LayerUtils.implodeLayers(reordered);
|
|
130
|
+
if (!haveThemeLayer) {
|
|
131
|
+
// Ensure empty theme layer container is present
|
|
132
|
+
layers.unshift(_objectSpread(_objectSpread({}, themeLayer), {}, {
|
|
133
|
+
sublayers: []
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
128
136
|
LayerUtils.setGroupVisiblities(layers);
|
|
129
137
|
return layers;
|
|
130
138
|
},
|
|
@@ -682,28 +690,32 @@ var LayerUtils = {
|
|
|
682
690
|
implodeLayers: function implodeLayers(exploded) {
|
|
683
691
|
var newlayers = [];
|
|
684
692
|
var usedIds = new Set();
|
|
693
|
+
var prevlayer = null;
|
|
685
694
|
|
|
686
695
|
// Merge all possible items of an exploded layer array
|
|
687
696
|
var _iterator1 = _createForOfIteratorHelper(exploded),
|
|
688
697
|
_step1;
|
|
689
698
|
try {
|
|
690
699
|
for (_iterator1.s(); !(_step1 = _iterator1.n()).done;) {
|
|
700
|
+
var _prevlayer;
|
|
691
701
|
var entry = _step1.value;
|
|
692
702
|
var _layer2 = entry.layer;
|
|
693
703
|
|
|
694
704
|
// Attempt to merge with previous if possible
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
+
if (((_prevlayer = prevlayer) === null || _prevlayer === void 0 ? void 0 : _prevlayer.srcid) === _layer2.srcid) {
|
|
706
|
+
if (isEmpty(prevlayer.sublayers)) {
|
|
707
|
+
prevlayer.sublayers = _layer2.sublayers;
|
|
708
|
+
} else if (!isEmpty(_layer2.sublayers)) {
|
|
709
|
+
// Find deepest nested matching group
|
|
710
|
+
var group = _layer2;
|
|
711
|
+
var prevgroup = prevlayer;
|
|
712
|
+
while (!isEmpty(group.sublayers) && !isEmpty(prevgroup.sublayers) && ((_group$sublayers$ = group.sublayers[0]) === null || _group$sublayers$ === void 0 ? void 0 : _group$sublayers$.name) === ((_prevgroup$sublayers = prevgroup.sublayers[prevgroup.sublayers.length - 1]) === null || _prevgroup$sublayers === void 0 ? void 0 : _prevgroup$sublayers.name)) {
|
|
713
|
+
var _group$sublayers$, _prevgroup$sublayers;
|
|
714
|
+
group = group.sublayers[0]; // Exploded layers have one layer per sublayer level
|
|
715
|
+
prevgroup = prevgroup.sublayers[prevgroup.sublayers.length - 1];
|
|
716
|
+
}
|
|
717
|
+
prevgroup.sublayers.push(group.sublayers[0]);
|
|
705
718
|
}
|
|
706
|
-
target.sublayers.push(source.sublayers[0]);
|
|
707
719
|
} else {
|
|
708
720
|
if (usedIds.has(_layer2.id)) {
|
|
709
721
|
newlayers.push(_objectSpread(_objectSpread({}, _layer2), {}, {
|
|
@@ -712,6 +724,7 @@ var LayerUtils = {
|
|
|
712
724
|
} else {
|
|
713
725
|
newlayers.push(_layer2);
|
|
714
726
|
}
|
|
727
|
+
prevlayer = newlayers[newlayers.length - 1];
|
|
715
728
|
usedIds.add(_layer2.id);
|
|
716
729
|
}
|
|
717
730
|
}
|