@reearth/core 0.0.7-alpha.32 → 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 +2102 -2041
- package/dist/core.umd.cjs +69 -69
- 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/SpatialId/constants.ts +5 -0
- package/src/Map/SpatialId/hooks.ts +99 -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/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
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -12,9 +12,10 @@ import { v4 as uuid } from "uuid";
|
|
|
12
12
|
|
|
13
13
|
import { useWindowEvent } from "../../utils/use-window-event";
|
|
14
14
|
import { InteractionModeType } from "../../Visualizer";
|
|
15
|
+
import { GeoidRef } from "../Geoid/types";
|
|
15
16
|
import { EngineRef, MouseEventProps } from "../types";
|
|
16
17
|
|
|
17
|
-
import { SPATIALID_DEFAULT_OPTIONS } from "./constants";
|
|
18
|
+
import { SPATIALID_DEFAULT_OPTIONS, SPATIALID_LATITUDE_RANGE } from "./constants";
|
|
18
19
|
import {
|
|
19
20
|
SpatialIdRef,
|
|
20
21
|
SpatialIdSpacePickingState,
|
|
@@ -29,6 +30,7 @@ import { createSpatialIdSpace, getSpaceData, getVerticalLimits } from "./utils";
|
|
|
29
30
|
type Props = {
|
|
30
31
|
ref: ForwardedRef<SpatialIdRef>;
|
|
31
32
|
engineRef: RefObject<EngineRef>;
|
|
33
|
+
geoidRef: RefObject<GeoidRef>;
|
|
32
34
|
terrainEnabled?: boolean;
|
|
33
35
|
interactionMode?: InteractionModeType;
|
|
34
36
|
overrideInteractionMode?: (mode: InteractionModeType) => void;
|
|
@@ -38,6 +40,7 @@ type Props = {
|
|
|
38
40
|
export default ({
|
|
39
41
|
ref,
|
|
40
42
|
engineRef,
|
|
43
|
+
geoidRef,
|
|
41
44
|
terrainEnabled,
|
|
42
45
|
interactionMode,
|
|
43
46
|
overrideInteractionMode,
|
|
@@ -51,9 +54,12 @@ export default ({
|
|
|
51
54
|
const [coordinateSelector, setCoordinateSelector] = useState<CoordinateSelectorType | null>(null);
|
|
52
55
|
const lastCoordinateSelector = useRef<CoordinateSelectorType | null>(null);
|
|
53
56
|
const [spaceSelector, setSpaceSelector] = useState<SpatialIdSpaceType | null>(null);
|
|
57
|
+
const centerGeoidHeightRef = useRef<number | null>(null);
|
|
54
58
|
|
|
55
59
|
const [basePosition, setBasePosition] = useState<[number, number, number] | null>(null);
|
|
56
|
-
const [
|
|
60
|
+
const [baseCoordinateGeoid, setBaseCoordinateGeoid] = useState<[number, number, number] | null>(
|
|
61
|
+
null,
|
|
62
|
+
);
|
|
57
63
|
|
|
58
64
|
const [pickOptions, setPickOptions] =
|
|
59
65
|
useState<Required<SpatialIdPickSpaceOptions>>(SPATIALID_DEFAULT_OPTIONS);
|
|
@@ -67,7 +73,7 @@ export default ({
|
|
|
67
73
|
const allSpaces = [...(spatialIdSpaces ?? []), ...(spaceSelector ? [spaceSelector] : [])];
|
|
68
74
|
|
|
69
75
|
if (!allSpaces) return null;
|
|
70
|
-
|
|
76
|
+
|
|
71
77
|
const uniqueSpaces = allSpaces.reduce((acc, space) => {
|
|
72
78
|
if (
|
|
73
79
|
!acc.find(
|
|
@@ -113,10 +119,11 @@ export default ({
|
|
|
113
119
|
const finishPicking = useCallback(() => {
|
|
114
120
|
setState("idle");
|
|
115
121
|
setBasePosition(null);
|
|
116
|
-
|
|
122
|
+
setBaseCoordinateGeoid(null);
|
|
117
123
|
setSpaceSelector(null);
|
|
118
124
|
setCoordinateSelector(null);
|
|
119
125
|
lastCoordinateSelector.current = null;
|
|
126
|
+
centerGeoidHeightRef.current = null;
|
|
120
127
|
setVerticalSpaceIndicator(null);
|
|
121
128
|
overrideInteractionMode?.(
|
|
122
129
|
interactionModeRef.current === "spatialId"
|
|
@@ -128,30 +135,79 @@ export default ({
|
|
|
128
135
|
}, [overrideInteractionMode, engineRef]);
|
|
129
136
|
|
|
130
137
|
const handleMouseUp = useCallback(
|
|
131
|
-
(props: MouseEventProps) => {
|
|
138
|
+
async (props: MouseEventProps) => {
|
|
132
139
|
if (state === "idle") return;
|
|
133
140
|
if (tempSwitchToMoveMode.current) return;
|
|
134
141
|
|
|
135
142
|
// handle coordinate picking
|
|
136
143
|
if (state === "coordinate") {
|
|
137
|
-
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;
|
|
138
152
|
|
|
139
|
-
setState("
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
153
|
+
setState("fetchingGeoid");
|
|
154
|
+
|
|
155
|
+
const { id, wsen, space } = createSpatialIdSpace(
|
|
156
|
+
props.lng,
|
|
157
|
+
props.lat,
|
|
158
|
+
0,
|
|
159
|
+
pickOptions.zoom,
|
|
160
|
+
0,
|
|
145
161
|
);
|
|
146
162
|
|
|
147
|
-
|
|
148
|
-
|
|
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);
|
|
149
204
|
|
|
150
205
|
const initialSpaceSelectorSpace = createSpatialIdSpace(
|
|
151
206
|
props.lng,
|
|
152
207
|
props.lat,
|
|
153
|
-
terrainEnabled ? props.height ?? 0 : 0,
|
|
208
|
+
(terrainEnabled ? props.height ?? 0 : 0) - appliedGeoidHeight,
|
|
154
209
|
pickOptions.zoom,
|
|
210
|
+
appliedCenterGeoidHeight,
|
|
155
211
|
);
|
|
156
212
|
setSpaceSelector({
|
|
157
213
|
...initialSpaceSelectorSpace,
|
|
@@ -159,21 +215,11 @@ export default ({
|
|
|
159
215
|
outlineColor: pickOptions.outlineColor,
|
|
160
216
|
});
|
|
161
217
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
terrainEnabled ? props.height ?? 0 : 0,
|
|
166
|
-
pickOptions.zoom,
|
|
167
|
-
);
|
|
168
|
-
setVerticalSpaceIndicator({
|
|
169
|
-
id,
|
|
170
|
-
wsen,
|
|
171
|
-
height: verticalLimits.top,
|
|
172
|
-
extrudedHeight: verticalLimits.bottom,
|
|
173
|
-
color: pickOptions.verticalSpaceIndicatorColor,
|
|
174
|
-
outlineColor: pickOptions.verticalSpaceIndicatorOutlineColor,
|
|
175
|
-
});
|
|
218
|
+
lastCoordinateSelector.current = coordinateSelector;
|
|
219
|
+
setCoordinateSelector(null);
|
|
220
|
+
|
|
176
221
|
engineRef.current?.requestRender();
|
|
222
|
+
setState("floor");
|
|
177
223
|
} else if (state === "floor") {
|
|
178
224
|
if (!spaceSelector) return;
|
|
179
225
|
|
|
@@ -198,6 +244,7 @@ export default ({
|
|
|
198
244
|
state,
|
|
199
245
|
terrainEnabled,
|
|
200
246
|
engineRef,
|
|
247
|
+
geoidRef,
|
|
201
248
|
spaceSelector,
|
|
202
249
|
pickOptions,
|
|
203
250
|
verticalLimits,
|
|
@@ -212,19 +259,22 @@ export default ({
|
|
|
212
259
|
if (tempSwitchToMoveMode.current) return;
|
|
213
260
|
|
|
214
261
|
if (state === "coordinate") {
|
|
215
|
-
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;
|
|
216
269
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
terrainEnabled ? props.height ?? 0 : 0,
|
|
221
|
-
pickOptions.zoom,
|
|
222
|
-
);
|
|
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);
|
|
223
273
|
|
|
224
|
-
if (newSpace.space.id === coordinateSelector?.
|
|
274
|
+
if (newSpace.space.id === coordinateSelector?.uid) return;
|
|
225
275
|
setCoordinateSelector({
|
|
226
276
|
id: uuid(),
|
|
227
|
-
|
|
277
|
+
uid: newSpace.space.id,
|
|
228
278
|
wsen: newSpace.wsen,
|
|
229
279
|
color: pickOptions.selectorColor,
|
|
230
280
|
});
|
|
@@ -233,7 +283,7 @@ export default ({
|
|
|
233
283
|
props.x === undefined ||
|
|
234
284
|
props.y === undefined ||
|
|
235
285
|
basePosition === null ||
|
|
236
|
-
|
|
286
|
+
baseCoordinateGeoid === null
|
|
237
287
|
)
|
|
238
288
|
return;
|
|
239
289
|
|
|
@@ -241,16 +291,17 @@ export default ({
|
|
|
241
291
|
engineRef.current?.getExtrudedHeight(basePosition, [props.x, props.y], true) ?? 0;
|
|
242
292
|
|
|
243
293
|
if (
|
|
244
|
-
|
|
245
|
-
|
|
294
|
+
baseCoordinateGeoid[2] + offset > verticalLimits.top ||
|
|
295
|
+
baseCoordinateGeoid[2] + offset < verticalLimits.bottom
|
|
246
296
|
)
|
|
247
297
|
return;
|
|
248
298
|
|
|
249
299
|
const newSpace = createSpatialIdSpace(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
300
|
+
baseCoordinateGeoid[0],
|
|
301
|
+
baseCoordinateGeoid[1],
|
|
302
|
+
baseCoordinateGeoid[2] + offset,
|
|
253
303
|
pickOptions.zoom,
|
|
304
|
+
centerGeoidHeightRef.current ?? 0,
|
|
254
305
|
);
|
|
255
306
|
|
|
256
307
|
if (newSpace.space.id === spaceSelector?.space.id) return;
|
|
@@ -266,12 +317,11 @@ export default ({
|
|
|
266
317
|
state,
|
|
267
318
|
spaceSelector,
|
|
268
319
|
basePosition,
|
|
269
|
-
|
|
320
|
+
baseCoordinateGeoid,
|
|
270
321
|
engineRef,
|
|
271
|
-
terrainEnabled,
|
|
272
322
|
pickOptions,
|
|
273
323
|
verticalLimits,
|
|
274
|
-
coordinateSelector?.
|
|
324
|
+
coordinateSelector?.uid,
|
|
275
325
|
],
|
|
276
326
|
);
|
|
277
327
|
|
|
@@ -282,10 +332,11 @@ export default ({
|
|
|
282
332
|
} else if (state === "floor") {
|
|
283
333
|
setSpaceSelector(null);
|
|
284
334
|
setBasePosition(null);
|
|
285
|
-
|
|
335
|
+
setBaseCoordinateGeoid(null);
|
|
286
336
|
setVerticalSpaceIndicator(null);
|
|
287
337
|
setCoordinateSelector(lastCoordinateSelector.current);
|
|
288
338
|
setState("coordinate");
|
|
339
|
+
centerGeoidHeightRef.current = null;
|
|
289
340
|
}
|
|
290
341
|
engineRef.current?.requestRender();
|
|
291
342
|
}, [state, pickOptions, engineRef, finishPicking]);
|
|
@@ -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;
|