@reearth/core 0.0.7-alpha.31 → 0.0.7-alpha.33
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/dist/core.js +2443 -2377
- package/dist/core.umd.cjs +63 -63
- package/dist/index.d.ts +14 -1
- package/package.json +1 -1
- package/src/Map/Geoid/index.tsx +68 -0
- package/src/Map/Geoid/types.ts +8 -0
- package/src/Map/Sketch/hooks.ts +1 -1
- package/src/Map/SpatialId/constants.ts +5 -0
- package/src/Map/SpatialId/hooks.ts +114 -48
- package/src/Map/SpatialId/index.tsx +4 -1
- package/src/Map/SpatialId/types.ts +2 -2
- package/src/Map/SpatialId/utils.ts +3 -2
- package/src/Map/hooks.ts +4 -0
- package/src/Map/index.tsx +4 -0
- package/src/Map/ref.ts +9 -0
- package/src/Map/types/viewerProperty.ts +8 -0
- package/src/engines/Cesium/types.ts +1 -1
- /package/src/{Map/Sketch/utils.ts → utils/use-window-event.ts} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -374,7 +374,7 @@ export declare type Credit = {
|
|
|
374
374
|
html?: string;
|
|
375
375
|
};
|
|
376
376
|
|
|
377
|
-
declare type CursorType = "default" | "auto" | "help" | "pointer" | "grab" | "crosshair";
|
|
377
|
+
declare type CursorType = "default" | "auto" | "help" | "pointer" | "grab" | "crosshair" | "wait";
|
|
378
378
|
|
|
379
379
|
export declare type Data = {
|
|
380
380
|
type: DataType;
|
|
@@ -763,6 +763,17 @@ export declare type FrustumAppearance = {
|
|
|
763
763
|
length?: number;
|
|
764
764
|
};
|
|
765
765
|
|
|
766
|
+
export declare type GeoidProperty = {
|
|
767
|
+
server: {
|
|
768
|
+
url: string;
|
|
769
|
+
geoidProperty: string;
|
|
770
|
+
};
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
declare type GeoidRef = {
|
|
774
|
+
getGeoidHeight: (lat?: number, lng?: number) => Promise<number | undefined>;
|
|
775
|
+
};
|
|
776
|
+
|
|
766
777
|
export declare type Geometry = Point | LineString | Polygon_2 | MultiPoint | MultiLineString | MultiPolygon;
|
|
767
778
|
|
|
768
779
|
export declare type GeometryOptionsXYZ = {
|
|
@@ -1099,6 +1110,7 @@ export declare type MapRef = {
|
|
|
1099
1110
|
layers: WrappedRef<LayersRef>;
|
|
1100
1111
|
sketch: WrappedRef<SketchRef>;
|
|
1101
1112
|
spatialId?: WrappedRef<SpatialIdRef>;
|
|
1113
|
+
geoid: WrappedRef<GeoidRef>;
|
|
1102
1114
|
timeline?: TimelineManagerRef;
|
|
1103
1115
|
};
|
|
1104
1116
|
|
|
@@ -1794,6 +1806,7 @@ export declare type ValueTypes = {
|
|
|
1794
1806
|
|
|
1795
1807
|
export declare type ViewerProperty = {
|
|
1796
1808
|
globe?: GlobeProperty;
|
|
1809
|
+
geoid?: GeoidProperty;
|
|
1797
1810
|
terrain?: TerrainProperty;
|
|
1798
1811
|
scene?: SceneProperty;
|
|
1799
1812
|
tiles?: TileProperty[];
|
package/package.json
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
ForwardRefRenderFunction,
|
|
4
|
+
useCallback,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
useRef,
|
|
7
|
+
} from "react";
|
|
8
|
+
|
|
9
|
+
import { GeoidServer, GeoidRef } from "./types";
|
|
10
|
+
|
|
11
|
+
export type GeoidProps = {
|
|
12
|
+
geoidServer?: GeoidServer;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const MAX_GEOID_CACHE_SIZE = 1000;
|
|
16
|
+
|
|
17
|
+
const Geoid: ForwardRefRenderFunction<GeoidRef, GeoidProps> = ({ geoidServer }, ref) => {
|
|
18
|
+
const geoidCache = useRef<Map<string, number>>(new Map());
|
|
19
|
+
|
|
20
|
+
const getGeoidHeight = useCallback(
|
|
21
|
+
async (lng?: number, lat?: number): Promise<number | undefined> => {
|
|
22
|
+
if (!geoidServer?.url || !geoidServer?.geoidProperty) {
|
|
23
|
+
console.error("Geoid: Server is not set properly");
|
|
24
|
+
return Promise.resolve(undefined);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (lat === undefined || lng === undefined) {
|
|
28
|
+
console.error("Geoid: Invalid lat or lng");
|
|
29
|
+
return Promise.resolve(undefined);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const cache = geoidCache.current.get(`${lng},${lat}`);
|
|
33
|
+
if (cache) return Promise.resolve(cache);
|
|
34
|
+
|
|
35
|
+
return fetch(
|
|
36
|
+
geoidServer.url.replace("${lng}", lng.toString()).replace("${lat}", lat.toString()),
|
|
37
|
+
)
|
|
38
|
+
.then(res => {
|
|
39
|
+
return res.json().then((result: any) => {
|
|
40
|
+
if (!result) return undefined;
|
|
41
|
+
const geoid = Number(result[geoidServer?.geoidProperty]);
|
|
42
|
+
if (!isNaN(geoid)) {
|
|
43
|
+
const cache = geoidCache.current;
|
|
44
|
+
if (cache.size > MAX_GEOID_CACHE_SIZE) {
|
|
45
|
+
const firstKey = cache.keys().next().value;
|
|
46
|
+
if (firstKey) cache.delete(firstKey);
|
|
47
|
+
}
|
|
48
|
+
cache.set(`${lng},${lat}`, geoid);
|
|
49
|
+
return geoid;
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
});
|
|
53
|
+
})
|
|
54
|
+
.catch(e => {
|
|
55
|
+
console.error("Failed to fetch geoid height", e);
|
|
56
|
+
return undefined;
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
[geoidServer?.url, geoidServer?.geoidProperty],
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
useImperativeHandle(ref, () => ({
|
|
63
|
+
getGeoidHeight,
|
|
64
|
+
}));
|
|
65
|
+
return null;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default forwardRef(Geoid);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type GeoidServer = {
|
|
2
|
+
url: string; // URL of the geoid server. use ${lat} ${lng} for lat/lng placeholders. Example: "https://mock.com/api/altitude?lat=${lat}&lng=${lng}"
|
|
3
|
+
geoidProperty: string; // TODO: support json path
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export type GeoidRef = {
|
|
7
|
+
getGeoidHeight: (lat?: number, lng?: number) => Promise<number | undefined>;
|
|
8
|
+
};
|
package/src/Map/Sketch/hooks.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { v4 as uuidv4 } from "uuid";
|
|
|
16
16
|
import { InterpreterFrom, StateFrom } from "xstate";
|
|
17
17
|
|
|
18
18
|
import { ControlPointMouseEventHandler } from "../../engines/Cesium/Sketch";
|
|
19
|
+
import { useWindowEvent } from "../../utils/use-window-event";
|
|
19
20
|
import { InteractionModeType } from "../../Visualizer/interactionMode";
|
|
20
21
|
import { Feature, EngineRef, LayersRef, SketchRef } from "../types";
|
|
21
22
|
import { useGet } from "../utils";
|
|
@@ -34,7 +35,6 @@ import {
|
|
|
34
35
|
import usePluginSketchLayer from "./usePluginSketchLayer";
|
|
35
36
|
import useSketch from "./useSketch";
|
|
36
37
|
import useSketchFeature from "./useSketchFeature";
|
|
37
|
-
import { useWindowEvent } from "./utils";
|
|
38
38
|
|
|
39
39
|
import { OnLayerSelectType } from ".";
|
|
40
40
|
|
|
@@ -14,3 +14,8 @@ export const SPATIALID_DEFAULT_OPTIONS: Required<SpatialIdPickSpaceOptions> = {
|
|
|
14
14
|
verticalSpaceIndicatorColor: "#ffffff33",
|
|
15
15
|
verticalSpaceIndicatorOutlineColor: "#ffffff55",
|
|
16
16
|
};
|
|
17
|
+
|
|
18
|
+
export const SPATIALID_LATITUDE_RANGE = {
|
|
19
|
+
min: -85.0511,
|
|
20
|
+
max: 85.0511,
|
|
21
|
+
};
|
|
@@ -10,10 +10,12 @@ import {
|
|
|
10
10
|
} from "react";
|
|
11
11
|
import { v4 as uuid } from "uuid";
|
|
12
12
|
|
|
13
|
+
import { useWindowEvent } from "../../utils/use-window-event";
|
|
13
14
|
import { InteractionModeType } from "../../Visualizer";
|
|
15
|
+
import { GeoidRef } from "../Geoid/types";
|
|
14
16
|
import { EngineRef, MouseEventProps } from "../types";
|
|
15
17
|
|
|
16
|
-
import { SPATIALID_DEFAULT_OPTIONS } from "./constants";
|
|
18
|
+
import { SPATIALID_DEFAULT_OPTIONS, SPATIALID_LATITUDE_RANGE } from "./constants";
|
|
17
19
|
import {
|
|
18
20
|
SpatialIdRef,
|
|
19
21
|
SpatialIdSpacePickingState,
|
|
@@ -28,6 +30,7 @@ import { createSpatialIdSpace, getSpaceData, getVerticalLimits } from "./utils";
|
|
|
28
30
|
type Props = {
|
|
29
31
|
ref: ForwardedRef<SpatialIdRef>;
|
|
30
32
|
engineRef: RefObject<EngineRef>;
|
|
33
|
+
geoidRef: RefObject<GeoidRef>;
|
|
31
34
|
terrainEnabled?: boolean;
|
|
32
35
|
interactionMode?: InteractionModeType;
|
|
33
36
|
overrideInteractionMode?: (mode: InteractionModeType) => void;
|
|
@@ -37,6 +40,7 @@ type Props = {
|
|
|
37
40
|
export default ({
|
|
38
41
|
ref,
|
|
39
42
|
engineRef,
|
|
43
|
+
geoidRef,
|
|
40
44
|
terrainEnabled,
|
|
41
45
|
interactionMode,
|
|
42
46
|
overrideInteractionMode,
|
|
@@ -48,10 +52,14 @@ export default ({
|
|
|
48
52
|
const [verticalSpaceIndicator, setVerticalSpaceIndicator] =
|
|
49
53
|
useState<VerticalSpaceIndicatorType | null>(null);
|
|
50
54
|
const [coordinateSelector, setCoordinateSelector] = useState<CoordinateSelectorType | null>(null);
|
|
55
|
+
const lastCoordinateSelector = useRef<CoordinateSelectorType | null>(null);
|
|
51
56
|
const [spaceSelector, setSpaceSelector] = useState<SpatialIdSpaceType | null>(null);
|
|
57
|
+
const centerGeoidHeightRef = useRef<number | null>(null);
|
|
52
58
|
|
|
53
59
|
const [basePosition, setBasePosition] = useState<[number, number, number] | null>(null);
|
|
54
|
-
const [
|
|
60
|
+
const [baseCoordinateGeoid, setBaseCoordinateGeoid] = useState<[number, number, number] | null>(
|
|
61
|
+
null,
|
|
62
|
+
);
|
|
55
63
|
|
|
56
64
|
const [pickOptions, setPickOptions] =
|
|
57
65
|
useState<Required<SpatialIdPickSpaceOptions>>(SPATIALID_DEFAULT_OPTIONS);
|
|
@@ -65,7 +73,7 @@ export default ({
|
|
|
65
73
|
const allSpaces = [...(spatialIdSpaces ?? []), ...(spaceSelector ? [spaceSelector] : [])];
|
|
66
74
|
|
|
67
75
|
if (!allSpaces) return null;
|
|
68
|
-
|
|
76
|
+
|
|
69
77
|
const uniqueSpaces = allSpaces.reduce((acc, space) => {
|
|
70
78
|
if (
|
|
71
79
|
!acc.find(
|
|
@@ -111,9 +119,11 @@ export default ({
|
|
|
111
119
|
const finishPicking = useCallback(() => {
|
|
112
120
|
setState("idle");
|
|
113
121
|
setBasePosition(null);
|
|
114
|
-
|
|
122
|
+
setBaseCoordinateGeoid(null);
|
|
115
123
|
setSpaceSelector(null);
|
|
116
124
|
setCoordinateSelector(null);
|
|
125
|
+
lastCoordinateSelector.current = null;
|
|
126
|
+
centerGeoidHeightRef.current = null;
|
|
117
127
|
setVerticalSpaceIndicator(null);
|
|
118
128
|
overrideInteractionMode?.(
|
|
119
129
|
interactionModeRef.current === "spatialId"
|
|
@@ -125,29 +135,79 @@ export default ({
|
|
|
125
135
|
}, [overrideInteractionMode, engineRef]);
|
|
126
136
|
|
|
127
137
|
const handleMouseUp = useCallback(
|
|
128
|
-
(props: MouseEventProps) => {
|
|
138
|
+
async (props: MouseEventProps) => {
|
|
129
139
|
if (state === "idle") return;
|
|
130
140
|
if (tempSwitchToMoveMode.current) return;
|
|
131
141
|
|
|
132
142
|
// handle coordinate picking
|
|
133
143
|
if (state === "coordinate") {
|
|
134
|
-
if (
|
|
144
|
+
if (
|
|
145
|
+
!coordinateSelector ||
|
|
146
|
+
props.lat === undefined ||
|
|
147
|
+
props.lng === undefined ||
|
|
148
|
+
props.lat > SPATIALID_LATITUDE_RANGE.max ||
|
|
149
|
+
props.lat < SPATIALID_LATITUDE_RANGE.min
|
|
150
|
+
)
|
|
151
|
+
return;
|
|
135
152
|
|
|
136
|
-
setState("
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
153
|
+
setState("fetchingGeoid");
|
|
154
|
+
|
|
155
|
+
const { id, wsen, space } = createSpatialIdSpace(
|
|
156
|
+
props.lng,
|
|
157
|
+
props.lat,
|
|
158
|
+
0,
|
|
159
|
+
pickOptions.zoom,
|
|
160
|
+
0,
|
|
142
161
|
);
|
|
143
162
|
|
|
144
|
-
|
|
163
|
+
requestAnimationFrame(() => {
|
|
164
|
+
engineRef.current?.setCursor("wait");
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const [geoidHeight, centerGeoidHeight] = await Promise.all([
|
|
168
|
+
geoidRef.current?.getGeoidHeight(props.lng, props.lat),
|
|
169
|
+
geoidRef.current?.getGeoidHeight(space.center.lng, space.center.lat),
|
|
170
|
+
]);
|
|
171
|
+
|
|
172
|
+
setTimeout(() => {
|
|
173
|
+
engineRef.current?.setCursor("crosshair");
|
|
174
|
+
}, 100);
|
|
175
|
+
|
|
176
|
+
if (geoidHeight === undefined && centerGeoidHeight === undefined) {
|
|
177
|
+
setState("coordinate");
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// In most case the geoidHeight difference between click point and center is small
|
|
182
|
+
// The API is not that stable, it has NaN for some points for unknown reason
|
|
183
|
+
// Therefore we try use one another if one is NaN
|
|
184
|
+
const appliedGeoidHeight = geoidHeight ?? centerGeoidHeight ?? 0;
|
|
185
|
+
const appliedCenterGeoidHeight = centerGeoidHeight ?? geoidHeight ?? 0;
|
|
186
|
+
centerGeoidHeightRef.current = appliedCenterGeoidHeight;
|
|
187
|
+
|
|
188
|
+
setVerticalSpaceIndicator({
|
|
189
|
+
id,
|
|
190
|
+
wsen,
|
|
191
|
+
height: verticalLimits.top + appliedCenterGeoidHeight,
|
|
192
|
+
extrudedHeight: verticalLimits.bottom + appliedCenterGeoidHeight,
|
|
193
|
+
color: pickOptions.verticalSpaceIndicatorColor,
|
|
194
|
+
outlineColor: pickOptions.verticalSpaceIndicatorOutlineColor,
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
setBaseCoordinateGeoid([
|
|
198
|
+
props.lng,
|
|
199
|
+
props.lat,
|
|
200
|
+
(terrainEnabled ? props.height ?? 0 : 0) - appliedGeoidHeight,
|
|
201
|
+
]);
|
|
202
|
+
|
|
203
|
+
setBasePosition(engineRef.current?.toXYZ(props.lng, props.lat, props.height ?? 0) ?? null);
|
|
145
204
|
|
|
146
205
|
const initialSpaceSelectorSpace = createSpatialIdSpace(
|
|
147
206
|
props.lng,
|
|
148
207
|
props.lat,
|
|
149
|
-
terrainEnabled ? props.height ?? 0 : 0,
|
|
208
|
+
(terrainEnabled ? props.height ?? 0 : 0) - appliedGeoidHeight,
|
|
150
209
|
pickOptions.zoom,
|
|
210
|
+
appliedCenterGeoidHeight,
|
|
151
211
|
);
|
|
152
212
|
setSpaceSelector({
|
|
153
213
|
...initialSpaceSelectorSpace,
|
|
@@ -155,21 +215,11 @@ export default ({
|
|
|
155
215
|
outlineColor: pickOptions.outlineColor,
|
|
156
216
|
});
|
|
157
217
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
terrainEnabled ? props.height ?? 0 : 0,
|
|
162
|
-
pickOptions.zoom,
|
|
163
|
-
);
|
|
164
|
-
setVerticalSpaceIndicator({
|
|
165
|
-
id,
|
|
166
|
-
wsen,
|
|
167
|
-
height: verticalLimits.top,
|
|
168
|
-
extrudedHeight: verticalLimits.bottom,
|
|
169
|
-
color: pickOptions.verticalSpaceIndicatorColor,
|
|
170
|
-
outlineColor: pickOptions.verticalSpaceIndicatorOutlineColor,
|
|
171
|
-
});
|
|
218
|
+
lastCoordinateSelector.current = coordinateSelector;
|
|
219
|
+
setCoordinateSelector(null);
|
|
220
|
+
|
|
172
221
|
engineRef.current?.requestRender();
|
|
222
|
+
setState("floor");
|
|
173
223
|
} else if (state === "floor") {
|
|
174
224
|
if (!spaceSelector) return;
|
|
175
225
|
|
|
@@ -194,6 +244,7 @@ export default ({
|
|
|
194
244
|
state,
|
|
195
245
|
terrainEnabled,
|
|
196
246
|
engineRef,
|
|
247
|
+
geoidRef,
|
|
197
248
|
spaceSelector,
|
|
198
249
|
pickOptions,
|
|
199
250
|
verticalLimits,
|
|
@@ -208,19 +259,22 @@ export default ({
|
|
|
208
259
|
if (tempSwitchToMoveMode.current) return;
|
|
209
260
|
|
|
210
261
|
if (state === "coordinate") {
|
|
211
|
-
if (
|
|
262
|
+
if (
|
|
263
|
+
props.lat === undefined ||
|
|
264
|
+
props.lng === undefined ||
|
|
265
|
+
props.lat > SPATIALID_LATITUDE_RANGE.max ||
|
|
266
|
+
props.lat < SPATIALID_LATITUDE_RANGE.min
|
|
267
|
+
)
|
|
268
|
+
return;
|
|
212
269
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
terrainEnabled ? props.height ?? 0 : 0,
|
|
217
|
-
pickOptions.zoom,
|
|
218
|
-
);
|
|
270
|
+
// Coordinate Selector is clamp to ground, we can ignore height
|
|
271
|
+
// The space id is used to identify the selector only
|
|
272
|
+
const newSpace = createSpatialIdSpace(props.lng, props.lat, 0, pickOptions.zoom, 0);
|
|
219
273
|
|
|
220
|
-
if (newSpace.space.id === coordinateSelector?.
|
|
274
|
+
if (newSpace.space.id === coordinateSelector?.uid) return;
|
|
221
275
|
setCoordinateSelector({
|
|
222
276
|
id: uuid(),
|
|
223
|
-
|
|
277
|
+
uid: newSpace.space.id,
|
|
224
278
|
wsen: newSpace.wsen,
|
|
225
279
|
color: pickOptions.selectorColor,
|
|
226
280
|
});
|
|
@@ -229,7 +283,7 @@ export default ({
|
|
|
229
283
|
props.x === undefined ||
|
|
230
284
|
props.y === undefined ||
|
|
231
285
|
basePosition === null ||
|
|
232
|
-
|
|
286
|
+
baseCoordinateGeoid === null
|
|
233
287
|
)
|
|
234
288
|
return;
|
|
235
289
|
|
|
@@ -237,16 +291,17 @@ export default ({
|
|
|
237
291
|
engineRef.current?.getExtrudedHeight(basePosition, [props.x, props.y], true) ?? 0;
|
|
238
292
|
|
|
239
293
|
if (
|
|
240
|
-
|
|
241
|
-
|
|
294
|
+
baseCoordinateGeoid[2] + offset > verticalLimits.top ||
|
|
295
|
+
baseCoordinateGeoid[2] + offset < verticalLimits.bottom
|
|
242
296
|
)
|
|
243
297
|
return;
|
|
244
298
|
|
|
245
299
|
const newSpace = createSpatialIdSpace(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
300
|
+
baseCoordinateGeoid[0],
|
|
301
|
+
baseCoordinateGeoid[1],
|
|
302
|
+
baseCoordinateGeoid[2] + offset,
|
|
249
303
|
pickOptions.zoom,
|
|
304
|
+
centerGeoidHeightRef.current ?? 0,
|
|
250
305
|
);
|
|
251
306
|
|
|
252
307
|
if (newSpace.space.id === spaceSelector?.space.id) return;
|
|
@@ -262,29 +317,40 @@ export default ({
|
|
|
262
317
|
state,
|
|
263
318
|
spaceSelector,
|
|
264
319
|
basePosition,
|
|
265
|
-
|
|
320
|
+
baseCoordinateGeoid,
|
|
266
321
|
engineRef,
|
|
267
|
-
terrainEnabled,
|
|
268
322
|
pickOptions,
|
|
269
323
|
verticalLimits,
|
|
270
|
-
coordinateSelector?.
|
|
324
|
+
coordinateSelector?.uid,
|
|
271
325
|
],
|
|
272
326
|
);
|
|
273
327
|
|
|
274
|
-
const
|
|
328
|
+
const cancel = useCallback(() => {
|
|
275
329
|
if (state === "idle") return;
|
|
276
330
|
if (state === "coordinate" && pickOptions.rightClickToExit) {
|
|
277
331
|
finishPicking();
|
|
278
332
|
} else if (state === "floor") {
|
|
279
333
|
setSpaceSelector(null);
|
|
280
334
|
setBasePosition(null);
|
|
281
|
-
|
|
335
|
+
setBaseCoordinateGeoid(null);
|
|
282
336
|
setVerticalSpaceIndicator(null);
|
|
337
|
+
setCoordinateSelector(lastCoordinateSelector.current);
|
|
283
338
|
setState("coordinate");
|
|
339
|
+
centerGeoidHeightRef.current = null;
|
|
284
340
|
}
|
|
285
341
|
engineRef.current?.requestRender();
|
|
286
342
|
}, [state, pickOptions, engineRef, finishPicking]);
|
|
287
343
|
|
|
344
|
+
const handleMouseRightClick = useCallback(() => {
|
|
345
|
+
cancel();
|
|
346
|
+
}, [cancel]);
|
|
347
|
+
|
|
348
|
+
useWindowEvent("keydown", event => {
|
|
349
|
+
if (event.code === "Escape") {
|
|
350
|
+
cancel();
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
|
|
288
354
|
// bind mouse events
|
|
289
355
|
const eventsBinded = useRef(false);
|
|
290
356
|
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
VerticalSpaceIndicator,
|
|
7
7
|
} from "../../engines/Cesium/SpatialId";
|
|
8
8
|
import { InteractionModeType } from "../../Visualizer";
|
|
9
|
+
import { GeoidRef } from "../Geoid/types";
|
|
9
10
|
import { EngineRef } from "../types";
|
|
10
11
|
|
|
11
12
|
import useHooks from "./hooks";
|
|
@@ -13,6 +14,7 @@ import { SpatialIdRef } from "./types";
|
|
|
13
14
|
|
|
14
15
|
type SpatialIdProps = {
|
|
15
16
|
engineRef: RefObject<EngineRef>;
|
|
17
|
+
geoidRef: RefObject<GeoidRef>;
|
|
16
18
|
terrainEnabled?: boolean;
|
|
17
19
|
interactionMode?: InteractionModeType;
|
|
18
20
|
overrideInteractionMode?: (mode: InteractionModeType) => void;
|
|
@@ -20,7 +22,7 @@ type SpatialIdProps = {
|
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
const SpatialId: ForwardRefRenderFunction<SpatialIdRef, SpatialIdProps> = (
|
|
23
|
-
{ engineRef, terrainEnabled, interactionMode, overrideInteractionMode, onMount },
|
|
25
|
+
{ engineRef, geoidRef, terrainEnabled, interactionMode, overrideInteractionMode, onMount },
|
|
24
26
|
ref,
|
|
25
27
|
) => {
|
|
26
28
|
const {
|
|
@@ -32,6 +34,7 @@ const SpatialId: ForwardRefRenderFunction<SpatialIdRef, SpatialIdProps> = (
|
|
|
32
34
|
} = useHooks({
|
|
33
35
|
ref,
|
|
34
36
|
engineRef,
|
|
37
|
+
geoidRef,
|
|
35
38
|
terrainEnabled,
|
|
36
39
|
interactionMode,
|
|
37
40
|
overrideInteractionMode,
|
|
@@ -21,7 +21,7 @@ export type VerticalSpaceIndicatorType = {
|
|
|
21
21
|
|
|
22
22
|
export type CoordinateSelectorType = {
|
|
23
23
|
id: string;
|
|
24
|
-
|
|
24
|
+
uid: string;
|
|
25
25
|
wsen: [number, number, number, number];
|
|
26
26
|
color: string;
|
|
27
27
|
};
|
|
@@ -47,7 +47,7 @@ export type SpatialIdRef = {
|
|
|
47
47
|
onSpacePick: (cb: (space: SpatialIdSpaceData) => void) => void;
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
export type SpatialIdSpacePickingState = "idle" | "coordinate" | "floor";
|
|
50
|
+
export type SpatialIdSpacePickingState = "idle" | "coordinate" | "fetchingGeoid" | "floor";
|
|
51
51
|
|
|
52
52
|
export type SpatialIdSpaceData = {
|
|
53
53
|
id: string;
|
|
@@ -22,6 +22,7 @@ export const createSpatialIdSpace = (
|
|
|
22
22
|
lat: number,
|
|
23
23
|
alt: number,
|
|
24
24
|
zoom: number,
|
|
25
|
+
geoidHeight: number,
|
|
25
26
|
): SpatialIdSpaceType => {
|
|
26
27
|
const space = new Space({ lat, lng, alt }, zoom);
|
|
27
28
|
const { wsen, height, extrudedHeight } = getRectangeParamsFromSpace(space);
|
|
@@ -30,8 +31,8 @@ export const createSpatialIdSpace = (
|
|
|
30
31
|
id: uuid(),
|
|
31
32
|
space,
|
|
32
33
|
wsen,
|
|
33
|
-
height,
|
|
34
|
-
extrudedHeight,
|
|
34
|
+
height: height + geoidHeight,
|
|
35
|
+
extrudedHeight: extrudedHeight + geoidHeight,
|
|
35
36
|
};
|
|
36
37
|
};
|
|
37
38
|
|
package/src/Map/hooks.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { useImperativeHandle, useRef, type Ref, useState, useCallback, useEffect
|
|
|
2
2
|
|
|
3
3
|
import { SelectedFeatureInfo } from "../mantle";
|
|
4
4
|
|
|
5
|
+
import { GeoidRef } from "./Geoid/types";
|
|
5
6
|
import { type MapRef, mapRef } from "./ref";
|
|
6
7
|
import { SpatialIdRef } from "./SpatialId/types";
|
|
7
8
|
import type {
|
|
@@ -51,6 +52,7 @@ export default function ({
|
|
|
51
52
|
const layersRef = useRef<LayersRef>(null);
|
|
52
53
|
const sketchRef = useRef<SketchRef>(null);
|
|
53
54
|
const spatialIdRef = useRef<SpatialIdRef>(null);
|
|
55
|
+
const geoidRef = useRef<GeoidRef>(null);
|
|
54
56
|
const requestingRenderMode = useRef<RequestingRenderMode>(NO_REQUEST_RENDER);
|
|
55
57
|
|
|
56
58
|
useImperativeHandle(
|
|
@@ -61,6 +63,7 @@ export default function ({
|
|
|
61
63
|
layersRef,
|
|
62
64
|
sketchRef,
|
|
63
65
|
spatialIdRef,
|
|
66
|
+
geoidRef,
|
|
64
67
|
timelineManagerRef,
|
|
65
68
|
}),
|
|
66
69
|
[timelineManagerRef],
|
|
@@ -151,6 +154,7 @@ export default function ({
|
|
|
151
154
|
layersRef,
|
|
152
155
|
sketchRef,
|
|
153
156
|
spatialIdRef,
|
|
157
|
+
geoidRef,
|
|
154
158
|
selectedLayer,
|
|
155
159
|
requestingRenderMode,
|
|
156
160
|
handleLayerSelect,
|
package/src/Map/index.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import { forwardRef, useMemo, type Ref } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { INTERACTION_MODES } from "../Visualizer/interactionMode";
|
|
4
4
|
|
|
5
|
+
import Geoid from "./Geoid";
|
|
5
6
|
import useHooks, { MapRef } from "./hooks";
|
|
6
7
|
import Layers, { type Props as LayersProps } from "./Layers";
|
|
7
8
|
import Sketch, { SketchProps } from "./Sketch";
|
|
@@ -82,6 +83,7 @@ function MapFn(
|
|
|
82
83
|
layersRef,
|
|
83
84
|
sketchRef,
|
|
84
85
|
spatialIdRef,
|
|
86
|
+
geoidRef,
|
|
85
87
|
selectedLayer,
|
|
86
88
|
requestingRenderMode,
|
|
87
89
|
handleLayerSelect,
|
|
@@ -167,11 +169,13 @@ function MapFn(
|
|
|
167
169
|
<SpatialId
|
|
168
170
|
ref={spatialIdRef}
|
|
169
171
|
engineRef={engineRef}
|
|
172
|
+
geoidRef={geoidRef}
|
|
170
173
|
interactionMode={interactionMode}
|
|
171
174
|
terrainEnabled={!!props.property?.terrain?.enabled}
|
|
172
175
|
overrideInteractionMode={overrideInteractionMode}
|
|
173
176
|
onMount={handleSpatialIdMount}
|
|
174
177
|
/>
|
|
178
|
+
<Geoid ref={geoidRef} geoidServer={props.property?.geoid?.server} />
|
|
175
179
|
</Engine>
|
|
176
180
|
) : null;
|
|
177
181
|
}
|
package/src/Map/ref.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { RefObject } from "react";
|
|
2
2
|
|
|
3
|
+
import { GeoidRef } from "./Geoid/types";
|
|
3
4
|
import { SpatialIdRef } from "./SpatialId/types";
|
|
4
5
|
import type { EngineRef, LayersRef, SketchRef } from "./types";
|
|
5
6
|
import { TimelineManagerRef } from "./useTimelineManager";
|
|
@@ -10,6 +11,7 @@ export type MapRef = {
|
|
|
10
11
|
layers: WrappedRef<LayersRef>;
|
|
11
12
|
sketch: WrappedRef<SketchRef>;
|
|
12
13
|
spatialId?: WrappedRef<SpatialIdRef>;
|
|
14
|
+
geoid: WrappedRef<GeoidRef>;
|
|
13
15
|
timeline?: TimelineManagerRef;
|
|
14
16
|
};
|
|
15
17
|
|
|
@@ -141,17 +143,23 @@ const spatialIdRefKeys: FunctionKeys<SpatialIdRef> = {
|
|
|
141
143
|
onSpacePick: 1,
|
|
142
144
|
};
|
|
143
145
|
|
|
146
|
+
const geoidRefKeys: FunctionKeys<GeoidRef> = {
|
|
147
|
+
getGeoidHeight: 1,
|
|
148
|
+
};
|
|
149
|
+
|
|
144
150
|
export function mapRef({
|
|
145
151
|
engineRef,
|
|
146
152
|
layersRef,
|
|
147
153
|
sketchRef,
|
|
148
154
|
spatialIdRef,
|
|
155
|
+
geoidRef,
|
|
149
156
|
timelineManagerRef,
|
|
150
157
|
}: {
|
|
151
158
|
engineRef: RefObject<EngineRef>;
|
|
152
159
|
layersRef: RefObject<LayersRef>;
|
|
153
160
|
sketchRef: RefObject<SketchRef>;
|
|
154
161
|
spatialIdRef: RefObject<SpatialIdRef>;
|
|
162
|
+
geoidRef: RefObject<GeoidRef>;
|
|
155
163
|
timelineManagerRef?: TimelineManagerRef;
|
|
156
164
|
}): MapRef {
|
|
157
165
|
return {
|
|
@@ -159,6 +167,7 @@ export function mapRef({
|
|
|
159
167
|
layers: wrapRef(layersRef, layersRefKeys),
|
|
160
168
|
sketch: wrapRef(sketchRef, sketchRefKeys),
|
|
161
169
|
spatialId: wrapRef(spatialIdRef, spatialIdRefKeys),
|
|
170
|
+
geoid: wrapRef(geoidRef, geoidRefKeys),
|
|
162
171
|
timeline: timelineManagerRef,
|
|
163
172
|
};
|
|
164
173
|
}
|
|
@@ -37,6 +37,7 @@ export type SceneMode = "3d" | "2d" | "columbus";
|
|
|
37
37
|
|
|
38
38
|
export type ViewerProperty = {
|
|
39
39
|
globe?: GlobeProperty;
|
|
40
|
+
geoid?: GeoidProperty;
|
|
40
41
|
terrain?: TerrainProperty;
|
|
41
42
|
scene?: SceneProperty;
|
|
42
43
|
tiles?: TileProperty[];
|
|
@@ -56,6 +57,13 @@ export type GlobeProperty = {
|
|
|
56
57
|
depthTestAgainstTerrain?: boolean;
|
|
57
58
|
};
|
|
58
59
|
|
|
60
|
+
export type GeoidProperty = {
|
|
61
|
+
server: {
|
|
62
|
+
url: string;
|
|
63
|
+
geoidProperty: string;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
59
67
|
export type GlobeAtmosphereProperty = {
|
|
60
68
|
enabled?: boolean;
|
|
61
69
|
lightIntensity?: number;
|
|
File without changes
|