@vcmap/ui 6.1.0-rc.6 → 6.1.0
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/config/base.config.json +7 -3
- package/config/cluster.config.json +5 -14
- package/config/dev.config.json +175 -56
- package/config/projects.config.json +2 -1
- package/config/splashscreen.config.json +6 -10
- package/config/vectorTile.config.json +42 -1
- package/dist/assets/{cesium-f5e8e354.js → cesium-664ad022.js} +53 -23
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core-c134a524.js → core-841b71a4.js} +8458 -5828
- package/dist/assets/core.js +1 -1
- package/dist/assets/{ol-2752311f.js → ol-2e095c08.js} +87 -37
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui-2fd6f47d.css +1 -0
- package/dist/assets/{ui-83514586.js → ui-2fd6f47d.js} +21376 -20063
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.js +1 -1
- package/dist/assets/{vuetify-5dbe2644.css → vuetify-4bc77ff7.css} +2 -2
- package/dist/assets/{vuetify-5dbe2644.js → vuetify-4bc77ff7.js} +7520 -7373
- package/dist/assets/vuetify.js +1 -1
- package/dist/index.html +1 -1
- package/index.d.ts +15 -5
- package/index.html +1 -1
- package/index.js +14 -5
- package/package.json +12 -8
- package/plugins/@vcmap-show-case/theming-example/src/index.js +1 -0
- package/plugins/@vcmap-show-case/vector-properties-example/src/LayerSettings.vue +39 -0
- package/plugins/@vcmap-show-case/vector-properties-example/src/VectorPropertiesExample.vue +3 -0
- package/plugins/@vcmap-show-case/vector-properties-example/src/lib.js +13 -0
- package/plugins/@vcmap-show-case/window-tester/src/WindowExample.vue +9 -0
- package/plugins/package.json +7 -5
- package/src/actions/actionHelper.d.ts +6 -0
- package/src/actions/actionHelper.js +22 -0
- package/src/actions/deepPickingAction.d.ts +23 -0
- package/src/actions/deepPickingAction.js +399 -0
- package/src/application/MapsGroupMobileMenu.vue +105 -0
- package/src/application/MapsGroupMobileMenu.vue.d.ts +7 -0
- package/src/application/VcsApp.vue +51 -24
- package/src/application/VcsApp.vue.d.ts +9 -2
- package/src/application/VcsAttributionsFooter.vue +1 -0
- package/src/application/VcsContainer.vue +36 -13
- package/src/application/VcsContainer.vue.d.ts +7 -0
- package/src/application/VcsMobileMenuList.vue +111 -0
- package/src/application/VcsMobileMenuList.vue.d.ts +2 -0
- package/src/application/VcsNavbar.vue +15 -3
- package/src/application/VcsNavbarMobile.vue +206 -0
- package/src/application/VcsNavbarMobile.vue.d.ts +42 -0
- package/src/application/VcsPositionDisplay.vue +1 -0
- package/src/application/VcsSplashScreen.vue +39 -7
- package/src/application/VcsSplashScreen.vue.d.ts +6 -0
- package/src/application/uiConfigHelper.d.ts +12 -0
- package/src/application/uiConfigHelper.js +37 -0
- package/src/components/buttons/VcsActionButtonList.vue +1 -0
- package/src/components/buttons/VcsToolButton.vue +8 -1
- package/src/components/buttons/VcsToolButton.vue.d.ts +1 -0
- package/src/components/form-inputs-controls/VcsSelect.vue +8 -6
- package/src/components/form-output/VcsTemplateMarkdown.vue +43 -0
- package/src/components/form-output/VcsTemplateMarkdown.vue.d.ts +9 -0
- package/src/components/icons/+all.d.ts +5 -0
- package/src/components/icons/+all.js +14 -0
- package/src/components/lists/VcsActionList.vue +1 -0
- package/src/components/lists/VcsGroupedList.vue +2 -1
- package/src/components/lists/VcsListItemComponent.vue +1 -0
- package/src/components/lists/VcsTreeNode.vue +11 -2
- package/src/components/lists/VcsTreeview.vue +40 -3
- package/src/components/lists/VcsTreeview.vue.d.ts +1 -0
- package/src/components/lists/VcsTreeviewTitle.vue +8 -1
- package/src/components/style/{MenuWrapper.vue → StyleMenuWrapper.vue} +2 -1
- package/src/components/style/VcsFillMenu.vue +4 -4
- package/src/components/style/VcsImageMenu.vue +4 -4
- package/src/components/style/VcsStrokeMenu.vue +4 -4
- package/src/components/style/VcsTextMenu.vue +4 -4
- package/src/contentTree/LayerTree.vue +8 -46
- package/src/contentTree/LayerTree.vue.d.ts +1 -3
- package/src/contentTree/contentTreeCollection.d.ts +7 -0
- package/src/contentTree/contentTreeCollection.js +31 -10
- package/src/contentTree/contentTreeItem.d.ts +4 -4
- package/src/contentTree/contentTreeItem.js +2 -2
- package/src/contentTree/flightContentTreeItem.d.ts +8 -1
- package/src/contentTree/flightContentTreeItem.js +26 -3
- package/src/contentTree/groupContentTreeItem.d.ts +21 -0
- package/src/contentTree/groupContentTreeItem.js +32 -2
- package/src/contentTree/layerContentTreeItem.d.ts +8 -1
- package/src/contentTree/layerContentTreeItem.js +26 -4
- package/src/contentTree/layerGroupContentTreeItem.d.ts +6 -0
- package/src/contentTree/layerGroupContentTreeItem.js +27 -3
- package/src/contentTree/nodeContentTreeItem.d.ts +21 -0
- package/src/contentTree/nodeContentTreeItem.js +31 -2
- package/src/contentTree/obliqueCollectionContentTreeItem.d.ts +6 -0
- package/src/contentTree/obliqueCollectionContentTreeItem.js +22 -2
- package/src/contentTree/wmsChildContentTreeItem.d.ts +56 -0
- package/src/contentTree/wmsChildContentTreeItem.js +159 -0
- package/src/contentTree/wmsGroupContentTreeItem.d.ts +171 -0
- package/src/contentTree/wmsGroupContentTreeItem.js +619 -0
- package/src/featureInfo/BalloonComponent.vue +6 -6
- package/src/featureInfo/ClusterFeatureComponent.vue +47 -11
- package/src/featureInfo/ClusterFeatureComponent.vue.d.ts +1 -0
- package/src/featureInfo/MarkdownBalloonComponent.vue +3 -9
- package/src/featureInfo/MarkdownBalloonComponent.vue.d.ts +1 -11
- package/src/featureInfo/balloonFeatureInfoView.d.ts +3 -0
- package/src/featureInfo/balloonFeatureInfoView.js +78 -11
- package/src/featureInfo/balloonHelper.js +9 -13
- package/src/featureInfo/featureInfo.d.ts +32 -7
- package/src/featureInfo/featureInfo.js +192 -93
- package/src/featureInfo/markdownBalloonFeatureInfoView.d.ts +0 -6
- package/src/featureInfo/markdownBalloonFeatureInfoView.js +5 -14
- package/src/featureInfo/markdownFeatureInfoView.d.ts +2 -8
- package/src/featureInfo/markdownFeatureInfoView.js +6 -15
- package/src/i18n/de.d.ts +64 -50
- package/src/i18n/de.js +9 -0
- package/src/i18n/en.d.ts +64 -50
- package/src/i18n/en.js +9 -0
- package/src/legend/VcsLegend.vue +21 -2
- package/src/legend/VcsLegend.vue.d.ts +1 -0
- package/src/legend/legendHelper.d.ts +0 -13
- package/src/legend/legendHelper.js +3 -27
- package/src/manager/navbarManager.d.ts +14 -1
- package/src/manager/navbarManager.js +22 -2
- package/src/manager/toolbox/GroupToolboxComponent.vue +17 -3
- package/src/manager/toolbox/GroupToolboxComponent.vue.d.ts +1 -0
- package/src/manager/toolbox/SelectToolboxComponent.vue +17 -3
- package/src/manager/toolbox/SelectToolboxComponent.vue.d.ts +1 -0
- package/src/manager/toolbox/ToolboxManagerComponent.vue +45 -14
- package/src/manager/toolbox/ToolboxManagerComponent.vue.d.ts +9 -0
- package/src/manager/toolbox/toolboxManager.d.ts +2 -1
- package/src/manager/toolbox/toolboxManager.js +13 -1
- package/src/manager/window/WindowComponent.vue +3 -2
- package/src/manager/window/WindowComponentHeader.vue +9 -1
- package/src/manager/window/WindowComponentHeader.vue.d.ts +1 -0
- package/src/manager/window/WindowManager.vue +175 -30
- package/src/manager/window/WindowManager.vue.d.ts +5 -0
- package/src/manager/window/windowManager.d.ts +2 -2
- package/src/manager/window/windowManager.js +12 -10
- package/src/navigation/MapNavigation.vue +29 -19
- package/src/navigation/MapNavigation.vue.d.ts +1 -0
- package/src/notifier/NotifierComponent.vue +1 -0
- package/src/search/ResultsComponent.vue +44 -17
- package/src/search/ResultsComponent.vue.d.ts +11 -1
- package/src/search/SearchComponent.vue +60 -9
- package/src/search/SearchComponent.vue.d.ts +2 -0
- package/src/search/search.js +3 -16
- package/src/state.d.ts +2 -1
- package/src/state.js +2 -1
- package/src/uiConfig.d.ts +9 -0
- package/src/uiConfig.js +1 -0
- package/src/vuePlugins/vuetify.d.ts +4 -0
- package/src/vuePlugins/vuetify.js +49 -3
- package/dist/assets/ui-83514586.css +0 -1
- /package/dist/assets/{vue-f8b1b5f8.js → vue-71fd14e8.js} +0 -0
- /package/src/components/style/{MenuWrapper.vue.d.ts → StyleMenuWrapper.vue.d.ts} +0 -0
@@ -0,0 +1,399 @@
|
|
1
|
+
import {
|
2
|
+
cartesianToMercator,
|
3
|
+
FeatureProviderInteraction,
|
4
|
+
getFeatureFromPickObject,
|
5
|
+
isProvidedClusterFeature,
|
6
|
+
isProvidedFeature,
|
7
|
+
markVolatile,
|
8
|
+
maxZIndex,
|
9
|
+
mercatorProjection,
|
10
|
+
mercatorToCartesian,
|
11
|
+
moduleIdSymbol,
|
12
|
+
originalFeatureSymbol,
|
13
|
+
vcsLayerName,
|
14
|
+
vectorClusterGroupName,
|
15
|
+
VectorLayer,
|
16
|
+
VectorStyleItem,
|
17
|
+
volatileModuleId,
|
18
|
+
} from '@vcmap/core';
|
19
|
+
import { Feature } from 'ol';
|
20
|
+
import { Point, LineString } from 'ol/geom.js';
|
21
|
+
import { Icon } from 'ol/style.js';
|
22
|
+
import { Cartesian3, Ray } from '@vcmap-cesium/engine';
|
23
|
+
import { watch } from 'vue';
|
24
|
+
import { getColorByKey } from '../vuePlugins/vuetify.js';
|
25
|
+
import ClusterFeatureComponent from '../featureInfo/ClusterFeatureComponent.vue';
|
26
|
+
import { WindowSlot } from '../manager/window/windowManager.js';
|
27
|
+
import { vcsAppSymbol } from '../pluginHelper.js';
|
28
|
+
import {
|
29
|
+
featureInfoViewSymbol,
|
30
|
+
getFeatureInfoViewForFeature,
|
31
|
+
getGroupedFeatureList,
|
32
|
+
} from '../featureInfo/featureInfo.js';
|
33
|
+
import { getColoredMapIcon } from '../components/icons/+all.js';
|
34
|
+
|
35
|
+
const scratchCartesian = new Cartesian3();
|
36
|
+
const pickingZOffset = 10.0;
|
37
|
+
const iconScale = 1.5;
|
38
|
+
|
39
|
+
export const deepPickingWindowId = 'deep-picking-window';
|
40
|
+
|
41
|
+
/**
|
42
|
+
* @param {import("@vcmap/ui").VcsUiApp} app
|
43
|
+
* @returns {{ layer: import("@vcmap/core").VectorLayer, destroy: () => void }}
|
44
|
+
*/
|
45
|
+
export function setupDeepPickingLayer(app) {
|
46
|
+
const layer = new VectorLayer({
|
47
|
+
zIndex: maxZIndex,
|
48
|
+
projection: mercatorProjection.toJSON(),
|
49
|
+
vectorProperties: {
|
50
|
+
altitudeMode: 'absolute',
|
51
|
+
eyeOffset: [0, 0, -200],
|
52
|
+
},
|
53
|
+
allowPicking: false,
|
54
|
+
});
|
55
|
+
markVolatile(layer);
|
56
|
+
app.layers.add(layer);
|
57
|
+
layer.activate();
|
58
|
+
|
59
|
+
const style = new VectorStyleItem({
|
60
|
+
image: {
|
61
|
+
...getColoredMapIcon(getColorByKey(app, 'primary')),
|
62
|
+
scale: iconScale,
|
63
|
+
},
|
64
|
+
fill: {
|
65
|
+
color: 'rgba(237, 237, 237, 0.1)',
|
66
|
+
},
|
67
|
+
stroke: {
|
68
|
+
color: getColorByKey(app, 'primary'),
|
69
|
+
width: 5,
|
70
|
+
},
|
71
|
+
});
|
72
|
+
layer.setStyle(style);
|
73
|
+
|
74
|
+
function setIconColor() {
|
75
|
+
const color = getColorByKey(app, 'primary');
|
76
|
+
style.stroke?.setColor(color);
|
77
|
+
style.image = new Icon({ ...getColoredMapIcon(color), scale: iconScale });
|
78
|
+
layer.forceRedraw();
|
79
|
+
}
|
80
|
+
|
81
|
+
const themChangedListener = app.themeChanged.addEventListener(setIconColor);
|
82
|
+
|
83
|
+
const destroy = () => {
|
84
|
+
layer.deactivate();
|
85
|
+
app.layers.remove(layer);
|
86
|
+
layer.destroy();
|
87
|
+
themChangedListener();
|
88
|
+
};
|
89
|
+
|
90
|
+
return { layer, destroy };
|
91
|
+
}
|
92
|
+
|
93
|
+
/**
|
94
|
+
* Retrieves features from an OpenLayers map at a given pixel.
|
95
|
+
* @param {import("ol/Map.js").OLMap} map
|
96
|
+
* @param {[number, number]} pixel
|
97
|
+
* @param {number} hitTolerance
|
98
|
+
* @param {number} drill
|
99
|
+
* @returns {import("ol").Feature[]}
|
100
|
+
*/
|
101
|
+
function getFeaturesFromOlMap(map, pixel, hitTolerance, drill) {
|
102
|
+
const features = [];
|
103
|
+
let i = 0;
|
104
|
+
map.forEachFeatureAtPixel(
|
105
|
+
pixel,
|
106
|
+
(feat) => {
|
107
|
+
if (
|
108
|
+
feat &&
|
109
|
+
(feat.get('olcs_allowPicking') == null ||
|
110
|
+
feat.get('olcs_allowPicking') === true)
|
111
|
+
) {
|
112
|
+
const feature = feat[originalFeatureSymbol] || feat;
|
113
|
+
if (!feature[vectorClusterGroupName]) {
|
114
|
+
features.push(feature);
|
115
|
+
}
|
116
|
+
}
|
117
|
+
i += 1;
|
118
|
+
return i >= drill;
|
119
|
+
},
|
120
|
+
{ hitTolerance },
|
121
|
+
);
|
122
|
+
|
123
|
+
return features;
|
124
|
+
}
|
125
|
+
|
126
|
+
/**
|
127
|
+
* Retrieves features from a Cesium scene at a given window position.
|
128
|
+
* @param {import("@vcmap-cesium/engine").Scene} scene
|
129
|
+
* @param {import("@vcmap-cesium/engine").Ray} ray
|
130
|
+
* @param {number} hitTolerance
|
131
|
+
* @param {number} drill
|
132
|
+
* @returns {Promise<{ features: import("@vcmap/core").EventFeature[], minZ: number }>}
|
133
|
+
*/
|
134
|
+
async function getFeaturesFromScene(scene, ray, hitTolerance, drill) {
|
135
|
+
const { depthTestAgainstTerrain } = scene.globe;
|
136
|
+
scene.globe.depthTestAgainstTerrain = false;
|
137
|
+
|
138
|
+
let minZ = 0;
|
139
|
+
const objects = await scene.drillPickFromRay(
|
140
|
+
ray,
|
141
|
+
drill,
|
142
|
+
undefined,
|
143
|
+
hitTolerance,
|
144
|
+
);
|
145
|
+
|
146
|
+
scene.globe.depthTestAgainstTerrain = depthTestAgainstTerrain;
|
147
|
+
|
148
|
+
const features = objects
|
149
|
+
.map(({ object, position }) => {
|
150
|
+
let feature;
|
151
|
+
if (object) {
|
152
|
+
if (position) {
|
153
|
+
const z = cartesianToMercator(position)[2];
|
154
|
+
minZ = Math.min(minZ, z);
|
155
|
+
}
|
156
|
+
feature = getFeatureFromPickObject(object);
|
157
|
+
if (feature?.[vectorClusterGroupName]) {
|
158
|
+
const clusterFeatures = feature.get('features');
|
159
|
+
return [...clusterFeatures];
|
160
|
+
}
|
161
|
+
}
|
162
|
+
return feature;
|
163
|
+
})
|
164
|
+
.filter((f, i, a) => !!f && a.indexOf(f) === i);
|
165
|
+
return { features, minZ };
|
166
|
+
}
|
167
|
+
|
168
|
+
/**
|
169
|
+
* @param {import("@vcmap/core").InteractionEvent} event
|
170
|
+
* @param {number} [hitTolerance=10]
|
171
|
+
* @param {number} [drillLimit]
|
172
|
+
* @returns {Promise<{ features: import("@vcmap/core").EventFeature[], minZ: number }>}
|
173
|
+
*/
|
174
|
+
async function getDeepPickingFeatures(
|
175
|
+
event,
|
176
|
+
hitTolerance = 10,
|
177
|
+
drillLimit = undefined,
|
178
|
+
) {
|
179
|
+
let features = [];
|
180
|
+
let minZ = 0;
|
181
|
+
if (
|
182
|
+
event.map.className === 'OpenlayersMap' ||
|
183
|
+
event.map.className === 'ObliqueMap'
|
184
|
+
) {
|
185
|
+
features = getFeaturesFromOlMap(
|
186
|
+
event.map.olMap,
|
187
|
+
[event.windowPosition.x, event.windowPosition.y],
|
188
|
+
hitTolerance,
|
189
|
+
drillLimit,
|
190
|
+
);
|
191
|
+
} else if (event.map.className === 'CesiumMap') {
|
192
|
+
const cesiumMap = event.map;
|
193
|
+
const scene = cesiumMap.getScene();
|
194
|
+
|
195
|
+
if (!scene) {
|
196
|
+
return features;
|
197
|
+
}
|
198
|
+
|
199
|
+
const [x, y, z] = event.position;
|
200
|
+
const origin = mercatorToCartesian([
|
201
|
+
x,
|
202
|
+
y,
|
203
|
+
Number.isNaN(z) ? pickingZOffset : z + pickingZOffset,
|
204
|
+
]);
|
205
|
+
const direction = Cartesian3.normalize(
|
206
|
+
Cartesian3.negate(origin, scratchCartesian),
|
207
|
+
scratchCartesian,
|
208
|
+
);
|
209
|
+
const ray = new Ray(origin, direction);
|
210
|
+
|
211
|
+
({ features, minZ } = await getFeaturesFromScene(
|
212
|
+
scene,
|
213
|
+
ray,
|
214
|
+
hitTolerance,
|
215
|
+
drillLimit,
|
216
|
+
));
|
217
|
+
}
|
218
|
+
|
219
|
+
if (
|
220
|
+
event.feature &&
|
221
|
+
!event.feature[isProvidedFeature] && // provided features will be provided again.
|
222
|
+
!features.includes(event.feature)
|
223
|
+
) {
|
224
|
+
features.unshift(event.feature);
|
225
|
+
}
|
226
|
+
|
227
|
+
return { features, minZ };
|
228
|
+
}
|
229
|
+
|
230
|
+
/**
|
231
|
+
* @param {import("@vcmap/core").AbstractInteraction} interaction
|
232
|
+
* @param {import("@vcmap/core").InteractionEvent} event
|
233
|
+
* @returns {Promise<import("@vcmap/core").EventFeature[]>}
|
234
|
+
*/
|
235
|
+
async function getInteractionFeatures(interaction, event) {
|
236
|
+
const pipedEvent = await interaction.pipe({
|
237
|
+
...event,
|
238
|
+
feature: undefined,
|
239
|
+
});
|
240
|
+
const { feature } = pipedEvent;
|
241
|
+
if (feature) {
|
242
|
+
if (feature[isProvidedClusterFeature]) {
|
243
|
+
return feature.get('features');
|
244
|
+
}
|
245
|
+
return [feature];
|
246
|
+
}
|
247
|
+
return [];
|
248
|
+
}
|
249
|
+
|
250
|
+
/**
|
251
|
+
* @returns {{ collectFeatures: (event: import("@vcmap/core").InteractionEvent) => Promise<{ features: import("@vcmap/core").EventFeature[], minZ: number }>, destroy: () => void}}
|
252
|
+
*/
|
253
|
+
function createCollectFeatures() {
|
254
|
+
const featureProviderInteraction = new FeatureProviderInteraction();
|
255
|
+
return {
|
256
|
+
async collectFeatures(event) {
|
257
|
+
const { features: deepPickingFeatures, minZ } =
|
258
|
+
await getDeepPickingFeatures(event);
|
259
|
+
return {
|
260
|
+
features: [
|
261
|
+
...deepPickingFeatures,
|
262
|
+
...(await getInteractionFeatures(featureProviderInteraction, event)),
|
263
|
+
],
|
264
|
+
minZ,
|
265
|
+
};
|
266
|
+
},
|
267
|
+
destroy() {
|
268
|
+
featureProviderInteraction.destroy();
|
269
|
+
},
|
270
|
+
};
|
271
|
+
}
|
272
|
+
|
273
|
+
/**
|
274
|
+
* @param {import("../vcsUiApp.js").default} app
|
275
|
+
* @param {import("ol/Feature").default} f
|
276
|
+
* @returns {boolean}
|
277
|
+
*/
|
278
|
+
function featurePredicate(app, f) {
|
279
|
+
if (f[featureInfoViewSymbol]) {
|
280
|
+
return true;
|
281
|
+
}
|
282
|
+
|
283
|
+
const l = app.layers.getByKey(f[vcsLayerName]);
|
284
|
+
if (l?.[moduleIdSymbol] === volatileModuleId) {
|
285
|
+
return !!getFeatureInfoViewForFeature(app, f);
|
286
|
+
}
|
287
|
+
|
288
|
+
return !!l;
|
289
|
+
}
|
290
|
+
|
291
|
+
/**
|
292
|
+
* @param {import("../vcsUiApp.js").default} app
|
293
|
+
* @param {import("@vcmap/core").VectorLayer} layer
|
294
|
+
* @param {(event: import("@vcmap/core").InteractionEvent) => Promise<import("@vcmap/core").EventFeature[]>} collectFeatures
|
295
|
+
* @param {import("@vcmap/core").InteractionEvent} event
|
296
|
+
* @returns {import("./actionHelper.js").VcsAction}
|
297
|
+
*/
|
298
|
+
export function createDeepPickingAction(app, layer, collectFeatures, event) {
|
299
|
+
return {
|
300
|
+
name: 'featureInfo.deepPicking.title',
|
301
|
+
icon: '$vcsInfo',
|
302
|
+
async callback() {
|
303
|
+
const { features, minZ } = await collectFeatures(event);
|
304
|
+
const { items, groups } = getGroupedFeatureList(
|
305
|
+
app,
|
306
|
+
features.filter((f) => featurePredicate(app, f)),
|
307
|
+
event.position,
|
308
|
+
);
|
309
|
+
|
310
|
+
if (app.windowManager.has(deepPickingWindowId)) {
|
311
|
+
app.windowManager.remove(deepPickingWindowId);
|
312
|
+
}
|
313
|
+
|
314
|
+
app.windowManager.add(
|
315
|
+
{
|
316
|
+
id: deepPickingWindowId,
|
317
|
+
component: ClusterFeatureComponent,
|
318
|
+
props: {
|
319
|
+
items,
|
320
|
+
groups,
|
321
|
+
},
|
322
|
+
state: {
|
323
|
+
headerTitle: 'featureInfo.deepPicking.headerTitle',
|
324
|
+
headerIcon: '$vcsInfo',
|
325
|
+
},
|
326
|
+
slot: WindowSlot.DYNAMIC_LEFT,
|
327
|
+
},
|
328
|
+
vcsAppSymbol,
|
329
|
+
);
|
330
|
+
|
331
|
+
const windowListener = app.windowManager.removed.addEventListener(
|
332
|
+
({ id: windowId }) => {
|
333
|
+
if (windowId === deepPickingWindowId) {
|
334
|
+
layer.removeAllFeatures();
|
335
|
+
windowListener();
|
336
|
+
}
|
337
|
+
},
|
338
|
+
);
|
339
|
+
|
340
|
+
const [x, y, z] = event.position;
|
341
|
+
const coordinate = [
|
342
|
+
x,
|
343
|
+
y,
|
344
|
+
Number.isNaN(z) ? pickingZOffset : z + pickingZOffset,
|
345
|
+
];
|
346
|
+
const pickFeature = new Feature({
|
347
|
+
geometry: new Point(coordinate),
|
348
|
+
});
|
349
|
+
const rayFeature = new Feature({
|
350
|
+
geometry: new LineString([coordinate, [x, y, minZ]]),
|
351
|
+
});
|
352
|
+
layer.addFeatures([pickFeature, rayFeature]);
|
353
|
+
},
|
354
|
+
};
|
355
|
+
}
|
356
|
+
|
357
|
+
/**
|
358
|
+
* This adds deep picking action to the context menu, if not disabled in uiConfig
|
359
|
+
* @param {import("../vcsUiApp.js").default} app
|
360
|
+
* @returns {() => void}
|
361
|
+
*/
|
362
|
+
export function setupDeepPicking(app) {
|
363
|
+
const { layer, destroy: destroyLayer } = setupDeepPickingLayer(app);
|
364
|
+
const { collectFeatures, destroy: destroyCollectFeatures } =
|
365
|
+
createCollectFeatures();
|
366
|
+
|
367
|
+
const handler = async (event) => {
|
368
|
+
if (event.windowPosition) {
|
369
|
+
return [createDeepPickingAction(app, layer, collectFeatures, event)];
|
370
|
+
}
|
371
|
+
return [];
|
372
|
+
};
|
373
|
+
|
374
|
+
if (app.uiConfig.enableDeepPicking !== false) {
|
375
|
+
app.contextMenuManager.addEventHandler(handler, vcsAppSymbol);
|
376
|
+
}
|
377
|
+
|
378
|
+
const stopWatching = watch(
|
379
|
+
() => app.uiConfig.config.enableDeepPicking,
|
380
|
+
(value, oldValue) => {
|
381
|
+
if (value !== false) {
|
382
|
+
if (!(oldValue !== false)) {
|
383
|
+
app.contextMenuManager.addEventHandler(handler, vcsAppSymbol);
|
384
|
+
}
|
385
|
+
} else {
|
386
|
+
app.contextMenuManager.removeHandler(handler);
|
387
|
+
}
|
388
|
+
},
|
389
|
+
);
|
390
|
+
|
391
|
+
return () => {
|
392
|
+
stopWatching();
|
393
|
+
destroyLayer();
|
394
|
+
destroyCollectFeatures();
|
395
|
+
layer.deactivate();
|
396
|
+
layer.destroy();
|
397
|
+
app.layers.remove(layer);
|
398
|
+
};
|
399
|
+
}
|
@@ -0,0 +1,105 @@
|
|
1
|
+
<template>
|
2
|
+
<div v-if="mapActions.length > 0" class="maps-group-mobile-menu">
|
3
|
+
<v-menu v-model="open" location="center" z-index="99">
|
4
|
+
<template #activator="{ props }">
|
5
|
+
<VcsToolButton
|
6
|
+
class="vcs-toolbox-toggle-button pl-4"
|
7
|
+
width="50"
|
8
|
+
:icon="activeIcon"
|
9
|
+
v-bind="props"
|
10
|
+
>
|
11
|
+
<v-icon>{{ open ? 'mdi-chevron-up' : 'mdi-chevron-down' }}</v-icon>
|
12
|
+
</VcsToolButton>
|
13
|
+
</template>
|
14
|
+
|
15
|
+
<v-toolbar
|
16
|
+
class="vcs-toolbox-toolbar--secondary mx-auto bottom-align rounded-t elevation-4 opacity-80 px-1"
|
17
|
+
:height="toolboxHeight"
|
18
|
+
>
|
19
|
+
<v-toolbar-items class="w-100">
|
20
|
+
<div class="d-flex align-center justify-space-between gc-1 w-100">
|
21
|
+
<VcsToolButton
|
22
|
+
v-for="action in mapActions"
|
23
|
+
:key="action.id"
|
24
|
+
:tooltip="action.title"
|
25
|
+
:icon="action.icon"
|
26
|
+
:disabled="action.disabled"
|
27
|
+
:active="action.active"
|
28
|
+
@click.stop="
|
29
|
+
() => {
|
30
|
+
$emit('click', $event);
|
31
|
+
open = false;
|
32
|
+
action.callback($event);
|
33
|
+
}
|
34
|
+
"
|
35
|
+
v-bind="{ ...$attrs }"
|
36
|
+
/>
|
37
|
+
</div>
|
38
|
+
</v-toolbar-items>
|
39
|
+
</v-toolbar>
|
40
|
+
</v-menu>
|
41
|
+
</div>
|
42
|
+
</template>
|
43
|
+
<style lang="scss" scoped>
|
44
|
+
.bottom-align {
|
45
|
+
bottom: calc(var(--v-vcs-font-size) * 3 - 2px) !important;
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
<script>
|
49
|
+
import { computed, ref, inject } from 'vue';
|
50
|
+
import { VMenu, VIcon, VToolbar, VToolbarItems } from 'vuetify/components';
|
51
|
+
import VcsToolButton from '../components/buttons/VcsToolButton.vue';
|
52
|
+
import { useFontSize } from '../vuePlugins/vuetify.js';
|
53
|
+
import {
|
54
|
+
ButtonLocation,
|
55
|
+
deviceSymbol,
|
56
|
+
getActionsByLocation,
|
57
|
+
} from '../manager/navbarManager.js';
|
58
|
+
|
59
|
+
export default {
|
60
|
+
name: 'MapsGroupMobileMenu',
|
61
|
+
components: {
|
62
|
+
VcsToolButton,
|
63
|
+
VMenu,
|
64
|
+
VIcon,
|
65
|
+
VToolbar,
|
66
|
+
VToolbarItems,
|
67
|
+
},
|
68
|
+
setup() {
|
69
|
+
const app = inject('vcsApp');
|
70
|
+
const open = ref(false);
|
71
|
+
|
72
|
+
const mobileButtonComponents = computed(() =>
|
73
|
+
app.navbarManager.componentIds
|
74
|
+
.map((id) => app.navbarManager.get(id))
|
75
|
+
.filter((buttonComponent) => {
|
76
|
+
return buttonComponent[deviceSymbol].mobile;
|
77
|
+
}),
|
78
|
+
);
|
79
|
+
|
80
|
+
const mapActions = computed(() =>
|
81
|
+
getActionsByLocation(
|
82
|
+
mobileButtonComponents.value,
|
83
|
+
ButtonLocation.MAP,
|
84
|
+
[...app.plugins].map((p) => p.name),
|
85
|
+
),
|
86
|
+
);
|
87
|
+
|
88
|
+
const activeIcon = computed(
|
89
|
+
() => mapActions.value.find((a) => a.active)?.icon,
|
90
|
+
);
|
91
|
+
|
92
|
+
const fontSize = useFontSize();
|
93
|
+
const toolboxHeight = computed(() => {
|
94
|
+
return fontSize.value * 3 + 5;
|
95
|
+
});
|
96
|
+
|
97
|
+
return {
|
98
|
+
open,
|
99
|
+
activeIcon,
|
100
|
+
toolboxHeight,
|
101
|
+
mapActions,
|
102
|
+
};
|
103
|
+
},
|
104
|
+
};
|
105
|
+
</script>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {
|
2
|
+
open: import("vue").Ref<boolean>;
|
3
|
+
activeIcon: import("vue").ComputedRef<string | undefined>;
|
4
|
+
toolboxHeight: import("vue").ComputedRef<number>;
|
5
|
+
mapActions: import("vue").ComputedRef<import("../actions/actionHelper.js", { with: { "resolution-mode": "import" } }).VcsAction[]>;
|
6
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
7
|
+
export default _default;
|