@geode/opengeodeweb-front 10.31.0 → 10.32.0-rc.1
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/app/components/CameraOrientation.vue +1 -1
- package/app/components/HybridRenderingView.vue +8 -0
- package/app/components/Ruler.vue +144 -0
- package/app/components/ViewToolbar.vue +12 -0
- package/app/components/Viewer/Ui.vue +27 -1
- package/app/stores/hybrid_viewer.js +52 -262
- package/internal/stores/{hybrid_viewer_brightness.js → hybrid_viewer/brightness.js} +29 -5
- package/internal/stores/{hybrid_viewer_camera.js → hybrid_viewer/camera.js} +105 -55
- package/internal/stores/hybrid_viewer/filters.js +38 -0
- package/internal/stores/hybrid_viewer/highlight.js +162 -0
- package/internal/stores/hybrid_viewer/ruler.js +121 -0
- package/internal/stores/hybrid_viewer/scene.js +141 -0
- package/internal/stores/hybrid_viewer/viewport.js +148 -0
- package/package.json +3 -3
- package/internal/stores/hybrid_viewer.js +0 -300
- package/internal/stores/hybrid_viewer_highlight.js +0 -114
- /package/internal/stores/{hybrid_viewer_camera_animation.js → hybrid_viewer/camera_animation.js} +0 -0
- /package/internal/stores/{hybrid_viewer_constants.js → hybrid_viewer/constants.js} +0 -0
|
@@ -3,8 +3,11 @@ import {
|
|
|
3
3
|
SHORT_ANIMATION_DURATION,
|
|
4
4
|
animateCamera,
|
|
5
5
|
computeAnimationDuration,
|
|
6
|
-
} from "
|
|
6
|
+
} from "./camera_animation";
|
|
7
7
|
import { dot } from "@kitware/vtk.js/Common/Core/Math";
|
|
8
|
+
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
9
|
+
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
10
|
+
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
8
11
|
|
|
9
12
|
const BUMP_MULTIPLIER = 0.2;
|
|
10
13
|
const ALIGNMENT_THRESHOLD = 0.9;
|
|
@@ -19,8 +22,59 @@ const ORIENTATIONS = {
|
|
|
19
22
|
xminus: { position: [-1, 0, 0], view_up: [0, 0, 1] },
|
|
20
23
|
};
|
|
21
24
|
|
|
25
|
+
function getImageStyle() {
|
|
26
|
+
const { genericRenderWindow } = useHybridViewerStore();
|
|
27
|
+
if (!genericRenderWindow.value) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
const webGLRenderWindow = genericRenderWindow.value.getApiSpecificRenderWindow();
|
|
31
|
+
if (!webGLRenderWindow) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
const bgImage = webGLRenderWindow.getReferenceByName("bgImage");
|
|
35
|
+
return bgImage ? bgImage.style : undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function useHybridViewerCamera() {
|
|
39
|
+
const camera_options = reactive({});
|
|
40
|
+
|
|
41
|
+
function syncRemoteCamera() {
|
|
42
|
+
performSyncRemoteCamera();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function setCamera(targetCameraOptions) {
|
|
46
|
+
performSetCamera(targetCameraOptions);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function resetCamera() {
|
|
50
|
+
const { genericRenderWindow } = useHybridViewerStore();
|
|
51
|
+
const renderer = genericRenderWindow.value.getRenderer();
|
|
52
|
+
renderer.resetCamera();
|
|
53
|
+
const renderWindow = genericRenderWindow.value.getRenderWindow();
|
|
54
|
+
renderWindow.render();
|
|
55
|
+
syncRemoteCamera();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function focusCameraOnObject(id, block_ids = []) {
|
|
59
|
+
await performFocusCameraOnObject(id, block_ids);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function setCameraOrientation(orientation) {
|
|
63
|
+
performCameraOrientation(orientation);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
camera_options,
|
|
68
|
+
syncRemoteCamera,
|
|
69
|
+
setCamera,
|
|
70
|
+
resetCamera,
|
|
71
|
+
focusCameraOnObject,
|
|
72
|
+
setCameraOrientation,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
22
76
|
function getCameraOptions(camera) {
|
|
23
|
-
if (!camera
|
|
77
|
+
if (!camera || !camera.getFocalPoint) {
|
|
24
78
|
return camera;
|
|
25
79
|
}
|
|
26
80
|
return {
|
|
@@ -34,7 +88,7 @@ function getCameraOptions(camera) {
|
|
|
34
88
|
}
|
|
35
89
|
|
|
36
90
|
function applyCameraOptions(camera, options) {
|
|
37
|
-
if (camera
|
|
91
|
+
if (camera && camera.set && options) {
|
|
38
92
|
camera.set({
|
|
39
93
|
focalPoint: options.focal_point,
|
|
40
94
|
viewUp: options.view_up,
|
|
@@ -59,9 +113,13 @@ function centerCameraOnPosition(camera, pickedPosition) {
|
|
|
59
113
|
);
|
|
60
114
|
}
|
|
61
115
|
|
|
62
|
-
function performSetCamera(targetCameraOptions
|
|
63
|
-
const
|
|
64
|
-
const
|
|
116
|
+
function performSetCamera(targetCameraOptions) {
|
|
117
|
+
const hybridViewerStore = useHybridViewerStore();
|
|
118
|
+
const { genericRenderWindow, syncRemoteCamera } = hybridViewerStore;
|
|
119
|
+
const { is_moving } = storeToRefs(hybridViewerStore);
|
|
120
|
+
const imageStyle = getImageStyle();
|
|
121
|
+
const renderer = genericRenderWindow.value.getRenderer();
|
|
122
|
+
const camera = renderer.getActiveCamera();
|
|
65
123
|
const startState = getCameraOptions(camera);
|
|
66
124
|
const duration = computeAnimationDuration(startState, targetCameraOptions);
|
|
67
125
|
is_moving.value = true;
|
|
@@ -75,20 +133,27 @@ function performSetCamera(targetCameraOptions, options) {
|
|
|
75
133
|
duration,
|
|
76
134
|
bumpMultiplier: 0,
|
|
77
135
|
easeExponent: EASE_EXPONENT,
|
|
78
|
-
onUpdate: () =>
|
|
136
|
+
onUpdate: () => {
|
|
137
|
+
const renderWindow = genericRenderWindow.value.getRenderWindow();
|
|
138
|
+
renderWindow.render();
|
|
139
|
+
},
|
|
79
140
|
onEnd: () => {
|
|
80
141
|
applyCameraOptions(camera, targetCameraOptions);
|
|
81
|
-
genericRenderWindow.getRenderWindow()
|
|
142
|
+
const renderWindow = genericRenderWindow.value.getRenderWindow();
|
|
143
|
+
renderWindow.render();
|
|
82
144
|
is_moving.value = false;
|
|
83
145
|
syncRemoteCamera();
|
|
84
146
|
},
|
|
85
147
|
});
|
|
86
148
|
}
|
|
87
149
|
|
|
88
|
-
function performCameraOrientation(orientation
|
|
89
|
-
const
|
|
150
|
+
function performCameraOrientation(orientation) {
|
|
151
|
+
const hybridViewerStore = useHybridViewerStore();
|
|
152
|
+
const { genericRenderWindow, syncRemoteCamera } = hybridViewerStore;
|
|
153
|
+
const { is_moving } = storeToRefs(hybridViewerStore);
|
|
154
|
+
const imageStyle = getImageStyle();
|
|
90
155
|
const config = ORIENTATIONS[orientation.toLowerCase()];
|
|
91
|
-
const renderer = genericRenderWindow.getRenderer();
|
|
156
|
+
const renderer = genericRenderWindow.value.getRenderer();
|
|
92
157
|
const camera = renderer.getActiveCamera();
|
|
93
158
|
const startState = getCameraOptions(camera);
|
|
94
159
|
|
|
@@ -105,7 +170,9 @@ function performCameraOrientation(orientation, options) {
|
|
|
105
170
|
const duration =
|
|
106
171
|
alignment > ALIGNMENT_THRESHOLD ? LONG_ANIMATION_DURATION : SHORT_ANIMATION_DURATION;
|
|
107
172
|
is_moving.value = true;
|
|
108
|
-
imageStyle
|
|
173
|
+
if (imageStyle) {
|
|
174
|
+
imageStyle.opacity = 0;
|
|
175
|
+
}
|
|
109
176
|
|
|
110
177
|
animateCamera({
|
|
111
178
|
camera,
|
|
@@ -114,7 +181,10 @@ function performCameraOrientation(orientation, options) {
|
|
|
114
181
|
duration,
|
|
115
182
|
bumpMultiplier: BUMP_MULTIPLIER,
|
|
116
183
|
easeExponent: EASE_EXPONENT,
|
|
117
|
-
onUpdate: () =>
|
|
184
|
+
onUpdate: () => {
|
|
185
|
+
const renderWindow = genericRenderWindow.value.getRenderWindow();
|
|
186
|
+
renderWindow.render();
|
|
187
|
+
},
|
|
118
188
|
onEnd: () => {
|
|
119
189
|
is_moving.value = false;
|
|
120
190
|
syncRemoteCamera();
|
|
@@ -122,22 +192,14 @@ function performCameraOrientation(orientation, options) {
|
|
|
122
192
|
});
|
|
123
193
|
}
|
|
124
194
|
|
|
125
|
-
async function performFocusCameraOnObject(id,
|
|
126
|
-
const {
|
|
127
|
-
hybridDb,
|
|
128
|
-
viewerStore,
|
|
129
|
-
viewer_schemas,
|
|
130
|
-
genericRenderWindow,
|
|
131
|
-
block_ids = [],
|
|
132
|
-
is_moving,
|
|
133
|
-
imageStyle,
|
|
134
|
-
syncRemoteCamera,
|
|
135
|
-
} = options;
|
|
195
|
+
async function performFocusCameraOnObject(id, block_ids = []) {
|
|
196
|
+
const { genericRenderWindow, hybridDb } = useHybridViewerStore();
|
|
136
197
|
|
|
137
198
|
if (!hybridDb[id]) {
|
|
138
199
|
return;
|
|
139
200
|
}
|
|
140
201
|
|
|
202
|
+
const viewerStore = useViewerStore();
|
|
141
203
|
let bounds = [];
|
|
142
204
|
if (block_ids.length > 0) {
|
|
143
205
|
const schema = viewer_schemas.opengeodeweb_viewer.model.get_blocks_bounds;
|
|
@@ -147,25 +209,21 @@ async function performFocusCameraOnObject(id, options) {
|
|
|
147
209
|
bounds = hybridDb[id].actor.getBounds();
|
|
148
210
|
}
|
|
149
211
|
|
|
150
|
-
const renderer = genericRenderWindow.getRenderer();
|
|
212
|
+
const renderer = genericRenderWindow.value.getRenderer();
|
|
151
213
|
const camera = renderer.getActiveCamera();
|
|
152
214
|
const startOptions = getCameraOptions(camera);
|
|
153
215
|
renderer.resetCamera(bounds);
|
|
154
216
|
const targetOptions = getCameraOptions(camera);
|
|
155
217
|
applyCameraOptions(camera, startOptions);
|
|
156
218
|
|
|
157
|
-
performSetCamera(targetOptions
|
|
158
|
-
genericRenderWindow,
|
|
159
|
-
is_moving,
|
|
160
|
-
imageStyle,
|
|
161
|
-
syncRemoteCamera,
|
|
162
|
-
});
|
|
219
|
+
performSetCamera(targetOptions);
|
|
163
220
|
}
|
|
164
221
|
|
|
165
|
-
function performSyncRemoteCamera(
|
|
166
|
-
const { genericRenderWindow,
|
|
167
|
-
|
|
168
|
-
const
|
|
222
|
+
function performSyncRemoteCamera() {
|
|
223
|
+
const { genericRenderWindow, camera_options, remoteRender } = useHybridViewerStore();
|
|
224
|
+
const viewerStore = useViewerStore();
|
|
225
|
+
const renderer = genericRenderWindow.value.getRenderer();
|
|
226
|
+
const camera = renderer.getActiveCamera();
|
|
169
227
|
const options_camera = getCameraOptions(camera);
|
|
170
228
|
const schema = viewer_schemas.opengeodeweb_viewer.viewer.update_camera;
|
|
171
229
|
const params = { camera_options: options_camera };
|
|
@@ -177,39 +235,30 @@ function performSyncRemoteCamera(options) {
|
|
|
177
235
|
{
|
|
178
236
|
response_function: () => {
|
|
179
237
|
remoteRender();
|
|
180
|
-
|
|
238
|
+
if (camera_options) {
|
|
239
|
+
Object.assign(camera_options, options_camera);
|
|
240
|
+
}
|
|
181
241
|
},
|
|
182
242
|
},
|
|
183
243
|
);
|
|
184
244
|
}
|
|
185
245
|
|
|
186
|
-
async function applySnapshot(snapshot
|
|
187
|
-
const { genericRenderWindow, setZScaling, syncRemoteCamera, setCamera } = options;
|
|
246
|
+
async function applySnapshot(snapshot) {
|
|
188
247
|
if (!snapshot) {
|
|
189
248
|
return;
|
|
190
249
|
}
|
|
191
|
-
const
|
|
192
|
-
if (typeof
|
|
193
|
-
await setZScaling(
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (setCamera) {
|
|
198
|
-
setCamera(snapshot_camera_options);
|
|
199
|
-
} else {
|
|
200
|
-
applyCameraOptions(
|
|
201
|
-
genericRenderWindow.getRenderer().getActiveCamera(),
|
|
202
|
-
snapshot_camera_options,
|
|
203
|
-
);
|
|
204
|
-
genericRenderWindow.getRenderWindow().render();
|
|
205
|
-
syncRemoteCamera();
|
|
206
|
-
}
|
|
250
|
+
const { setZScaling, setCamera } = useHybridViewerStore();
|
|
251
|
+
if (typeof snapshot.zScale === "number") {
|
|
252
|
+
await setZScaling(snapshot.zScale);
|
|
253
|
+
}
|
|
254
|
+
if (snapshot.camera_options) {
|
|
255
|
+
setCamera(snapshot.camera_options);
|
|
207
256
|
}
|
|
208
257
|
}
|
|
209
258
|
|
|
210
259
|
export {
|
|
211
|
-
BUMP_MULTIPLIER,
|
|
212
260
|
ALIGNMENT_THRESHOLD,
|
|
261
|
+
BUMP_MULTIPLIER,
|
|
213
262
|
EASE_EXPONENT,
|
|
214
263
|
ORIENTATIONS,
|
|
215
264
|
applyCameraOptions,
|
|
@@ -220,4 +269,5 @@ export {
|
|
|
220
269
|
performFocusCameraOnObject,
|
|
221
270
|
performSetCamera,
|
|
222
271
|
performSyncRemoteCamera,
|
|
272
|
+
useHybridViewerCamera,
|
|
223
273
|
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
2
|
+
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
3
|
+
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
4
|
+
|
|
5
|
+
function useHybridViewerFilters() {
|
|
6
|
+
async function setClippingPlanes(ids, planes) {
|
|
7
|
+
await performSetClippingPlanes(ids, planes);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function setShrink(ids, shrink_factor) {
|
|
11
|
+
await performSetShrink(ids, shrink_factor);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
setClippingPlanes,
|
|
16
|
+
setShrink,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function performSetClippingPlanes(ids, planes) {
|
|
21
|
+
const viewerStore = useViewerStore();
|
|
22
|
+
const { remoteRender } = useHybridViewerStore();
|
|
23
|
+
const schema = viewer_schemas.opengeodeweb_viewer.viewer.clipping_planes;
|
|
24
|
+
const params = { ids, planes };
|
|
25
|
+
await viewerStore.request({ schema, params });
|
|
26
|
+
await remoteRender();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function performSetShrink(ids, shrink_factor) {
|
|
30
|
+
const viewerStore = useViewerStore();
|
|
31
|
+
const { remoteRender } = useHybridViewerStore();
|
|
32
|
+
const schema = viewer_schemas.opengeodeweb_viewer.viewer.shrink;
|
|
33
|
+
const params = { ids, shrink_factor };
|
|
34
|
+
await viewerStore.request({ schema, params });
|
|
35
|
+
await remoteRender();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { performSetClippingPlanes, performSetShrink, useHybridViewerFilters };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { HOVER_DEBOUNCE_MS, HOVER_TIMEOUT_MS } from "./constants";
|
|
2
|
+
import { database } from "@ogw_internal/database/database.js";
|
|
3
|
+
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
4
|
+
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
5
|
+
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
6
|
+
|
|
7
|
+
function useHybridViewerHighlight() {
|
|
8
|
+
const is_hover_highlight = ref(false);
|
|
9
|
+
const hover_highlight_field_type = ref("CELL");
|
|
10
|
+
const hoverData = ref(undefined);
|
|
11
|
+
const hoverPosition = ref({ x: 0, y: 0 });
|
|
12
|
+
const hoverTimeoutRef = ref(undefined);
|
|
13
|
+
const currentHoverId = ref(undefined);
|
|
14
|
+
|
|
15
|
+
const clearHoverData = createClearHoverData(hoverTimeoutRef, hoverData, currentHoverId);
|
|
16
|
+
|
|
17
|
+
const hoverHighlight = createHoverHighlight({ hoverTimeoutRef, currentHoverId, clearHoverData });
|
|
18
|
+
|
|
19
|
+
function clearHoverHighlight() {
|
|
20
|
+
clearHoverData();
|
|
21
|
+
performClearHoverHighlight();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
is_hover_highlight,
|
|
26
|
+
hover_highlight_field_type,
|
|
27
|
+
hoverData,
|
|
28
|
+
hoverPosition,
|
|
29
|
+
clearHoverHighlight,
|
|
30
|
+
hoverHighlight,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function performHoverHighlight(event, onResponse) {
|
|
35
|
+
const hybridViewerStore = useHybridViewerStore();
|
|
36
|
+
const { genericRenderWindow, hybridDb } = hybridViewerStore;
|
|
37
|
+
const { is_hover_highlight, hover_highlight_field_type } = storeToRefs(hybridViewerStore);
|
|
38
|
+
if (!is_hover_highlight.value) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const container = genericRenderWindow.value?.getContainer();
|
|
42
|
+
if (!container) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const viewerStore = useViewerStore();
|
|
46
|
+
const rect = container.getBoundingClientRect();
|
|
47
|
+
const schema = viewer_schemas.opengeodeweb_viewer.viewer.highlight;
|
|
48
|
+
const params = {
|
|
49
|
+
x: Math.round(event.clientX - rect.left),
|
|
50
|
+
y: Math.round(rect.height - (event.clientY - rect.top)),
|
|
51
|
+
field_type: hover_highlight_field_type.value,
|
|
52
|
+
ids: Object.keys(hybridDb),
|
|
53
|
+
};
|
|
54
|
+
viewerStore.request({ schema, params }, { response_function: onResponse });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function performClearHoverHighlight() {
|
|
58
|
+
const { hybridDb } = useHybridViewerStore();
|
|
59
|
+
const { hover_highlight_field_type } = storeToRefs(useHybridViewerStore());
|
|
60
|
+
const viewerStore = useViewerStore();
|
|
61
|
+
const schema = viewer_schemas.opengeodeweb_viewer.viewer.highlight;
|
|
62
|
+
const params = {
|
|
63
|
+
x: -1,
|
|
64
|
+
y: -1,
|
|
65
|
+
field_type: hover_highlight_field_type.value,
|
|
66
|
+
ids: Object.keys(hybridDb),
|
|
67
|
+
};
|
|
68
|
+
viewerStore.request({ schema, params });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function createClearHoverData(hoverTimeoutRef, hoverData, currentHoverId) {
|
|
72
|
+
return function clearHoverData() {
|
|
73
|
+
if (hoverTimeoutRef.value) {
|
|
74
|
+
clearTimeout(hoverTimeoutRef.value);
|
|
75
|
+
hoverTimeoutRef.value = undefined;
|
|
76
|
+
}
|
|
77
|
+
hoverData.value = undefined;
|
|
78
|
+
currentHoverId.value = undefined;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function createHoverHighlight({ hoverTimeoutRef, currentHoverId, clearHoverData }) {
|
|
83
|
+
return useDebounceFn((event) => {
|
|
84
|
+
const hybridViewerStore = useHybridViewerStore();
|
|
85
|
+
const { genericRenderWindow } = hybridViewerStore;
|
|
86
|
+
const { is_hover_highlight, hoverData, hoverPosition } = storeToRefs(hybridViewerStore);
|
|
87
|
+
const containerElement = genericRenderWindow.value?.getContainer();
|
|
88
|
+
const relativeMousePosition = containerElement
|
|
89
|
+
? {
|
|
90
|
+
x: event.clientX - containerElement.getBoundingClientRect().left,
|
|
91
|
+
y: event.clientY - containerElement.getBoundingClientRect().top,
|
|
92
|
+
}
|
|
93
|
+
: { x: event.clientX, y: event.clientY };
|
|
94
|
+
|
|
95
|
+
performHoverHighlight(event, async (response) => {
|
|
96
|
+
const isResponseValid =
|
|
97
|
+
response && response.id && response.picked_id !== undefined && response.picked_id !== -1;
|
|
98
|
+
if (!is_hover_highlight.value || !isResponseValid) {
|
|
99
|
+
clearHoverData();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const hoverKey = `${response.id}_${response.field_type}_${response.picked_id}`;
|
|
104
|
+
if (currentHoverId.value === hoverKey) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (hoverTimeoutRef.value) {
|
|
109
|
+
clearTimeout(hoverTimeoutRef.value);
|
|
110
|
+
hoverTimeoutRef.value = undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
hoverData.value = undefined;
|
|
114
|
+
currentHoverId.value = hoverKey;
|
|
115
|
+
|
|
116
|
+
let componentInfo = undefined;
|
|
117
|
+
let modelName = undefined;
|
|
118
|
+
|
|
119
|
+
const modelRecord = await database.data.get(response.id);
|
|
120
|
+
if (modelRecord) {
|
|
121
|
+
modelName = modelRecord.name;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (response.geode_id) {
|
|
125
|
+
const components = database.model_components.where("[id+geode_id]");
|
|
126
|
+
const query = components.equals([response.id, response.geode_id]);
|
|
127
|
+
const component = await query.first();
|
|
128
|
+
if (component) {
|
|
129
|
+
componentInfo = {
|
|
130
|
+
name: component.name,
|
|
131
|
+
id: component.geode_id,
|
|
132
|
+
type: component.type,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const newHoverData = {
|
|
138
|
+
modelId: response.id,
|
|
139
|
+
modelName,
|
|
140
|
+
blockName: response.geode_id,
|
|
141
|
+
pickedId: response.picked_id,
|
|
142
|
+
fieldType: response.field_type,
|
|
143
|
+
component: componentInfo,
|
|
144
|
+
attributes: response.attributes || {},
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
hoverTimeoutRef.value = setTimeout(() => {
|
|
148
|
+
hoverPosition.value = relativeMousePosition;
|
|
149
|
+
hoverData.value = newHoverData;
|
|
150
|
+
hoverTimeoutRef.value = undefined;
|
|
151
|
+
}, HOVER_TIMEOUT_MS);
|
|
152
|
+
});
|
|
153
|
+
}, HOVER_DEBOUNCE_MS);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export {
|
|
157
|
+
createClearHoverData,
|
|
158
|
+
createHoverHighlight,
|
|
159
|
+
performClearHoverHighlight,
|
|
160
|
+
performHoverHighlight,
|
|
161
|
+
useHybridViewerHighlight,
|
|
162
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
2
|
+
import { useViewerStore } from "@ogw_front/stores/viewer";
|
|
3
|
+
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
|
|
4
|
+
|
|
5
|
+
function useHybridViewerRuler() {
|
|
6
|
+
const is_ruler_active = ref(false);
|
|
7
|
+
const ruler_snap = ref(false);
|
|
8
|
+
const ruler_point1 = ref(undefined);
|
|
9
|
+
const ruler_point2 = ref(undefined);
|
|
10
|
+
const ruler_distance = ref(undefined);
|
|
11
|
+
const ruler_awaiting_point = ref(1);
|
|
12
|
+
const ruler_previous_hover_state = ref({ active: false, fieldType: "CELL" });
|
|
13
|
+
|
|
14
|
+
function updateRulerSnapHighlight() {
|
|
15
|
+
const hybridViewerStore = useHybridViewerStore();
|
|
16
|
+
const { is_hover_highlight, hover_highlight_field_type } = storeToRefs(hybridViewerStore);
|
|
17
|
+
const { clearHoverHighlight } = hybridViewerStore;
|
|
18
|
+
|
|
19
|
+
if (is_ruler_active.value && ruler_snap.value) {
|
|
20
|
+
ruler_previous_hover_state.value = {
|
|
21
|
+
active: is_hover_highlight.value,
|
|
22
|
+
fieldType: hover_highlight_field_type.value,
|
|
23
|
+
};
|
|
24
|
+
is_hover_highlight.value = true;
|
|
25
|
+
hover_highlight_field_type.value = "POINT";
|
|
26
|
+
} else {
|
|
27
|
+
is_hover_highlight.value = ruler_previous_hover_state.value.active;
|
|
28
|
+
hover_highlight_field_type.value = ruler_previous_hover_state.value.fieldType;
|
|
29
|
+
if (!is_hover_highlight.value) {
|
|
30
|
+
clearHoverHighlight();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
watch([is_ruler_active, ruler_snap], updateRulerSnapHighlight);
|
|
36
|
+
|
|
37
|
+
async function applyRuler() {
|
|
38
|
+
if (!ruler_point1.value) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const points = ruler_point2.value
|
|
42
|
+
? [ruler_point1.value, ruler_point2.value]
|
|
43
|
+
: [ruler_point1.value];
|
|
44
|
+
const { remoteRender } = useHybridViewerStore();
|
|
45
|
+
const viewerStore = useViewerStore();
|
|
46
|
+
const schema = viewer_schemas.opengeodeweb_viewer.viewer.ruler;
|
|
47
|
+
const response = await viewerStore.request({ schema, params: { points } });
|
|
48
|
+
ruler_distance.value = response.distance;
|
|
49
|
+
await remoteRender();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function handleRulerClick(x, y) {
|
|
53
|
+
const { hybridDb } = useHybridViewerStore();
|
|
54
|
+
const viewerStore = useViewerStore();
|
|
55
|
+
let coords = undefined;
|
|
56
|
+
if (ruler_snap.value) {
|
|
57
|
+
const schema = viewer_schemas.opengeodeweb_viewer.viewer.highlight;
|
|
58
|
+
const params = {
|
|
59
|
+
x: Math.round(x),
|
|
60
|
+
y: Math.round(y),
|
|
61
|
+
field_type: "POINT",
|
|
62
|
+
ids: Object.keys(hybridDb),
|
|
63
|
+
};
|
|
64
|
+
const response = await viewerStore.request({ schema, params });
|
|
65
|
+
coords = response.attributes?.coordinates;
|
|
66
|
+
} else {
|
|
67
|
+
const schema = viewer_schemas.opengeodeweb_viewer.viewer.get_point_position;
|
|
68
|
+
const params = { x: Math.round(x), y: Math.round(y) };
|
|
69
|
+
const response = await viewerStore.request({ schema, params });
|
|
70
|
+
coords = [response.x, response.y, response.z];
|
|
71
|
+
}
|
|
72
|
+
if (!coords) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (ruler_awaiting_point.value === 1) {
|
|
77
|
+
ruler_point1.value = coords;
|
|
78
|
+
ruler_point2.value = undefined;
|
|
79
|
+
ruler_distance.value = undefined;
|
|
80
|
+
ruler_awaiting_point.value = 2;
|
|
81
|
+
} else {
|
|
82
|
+
ruler_point2.value = coords;
|
|
83
|
+
ruler_awaiting_point.value = 1;
|
|
84
|
+
}
|
|
85
|
+
await applyRuler();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function deactivateRuler() {
|
|
89
|
+
const { clearHoverHighlight } = useHybridViewerStore();
|
|
90
|
+
is_ruler_active.value = false;
|
|
91
|
+
clearHoverHighlight();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function clearRuler() {
|
|
95
|
+
ruler_point1.value = undefined;
|
|
96
|
+
ruler_point2.value = undefined;
|
|
97
|
+
ruler_distance.value = undefined;
|
|
98
|
+
ruler_awaiting_point.value = 1;
|
|
99
|
+
deactivateRuler();
|
|
100
|
+
const { remoteRender } = useHybridViewerStore();
|
|
101
|
+
const viewerStore = useViewerStore();
|
|
102
|
+
const schema = viewer_schemas.opengeodeweb_viewer.viewer.reset_ruler;
|
|
103
|
+
await viewerStore.request({ schema });
|
|
104
|
+
await remoteRender();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
is_ruler_active,
|
|
109
|
+
ruler_snap,
|
|
110
|
+
ruler_point1,
|
|
111
|
+
ruler_point2,
|
|
112
|
+
ruler_distance,
|
|
113
|
+
ruler_awaiting_point,
|
|
114
|
+
handleRulerClick,
|
|
115
|
+
applyRuler,
|
|
116
|
+
clearRuler,
|
|
117
|
+
deactivateRuler,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export { useHybridViewerRuler };
|