@reearth/core 0.0.7-alpha.0 → 0.0.7-alpha.2

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.
Files changed (55) hide show
  1. package/dist/core.js +8865 -8890
  2. package/dist/core.umd.cjs +74 -74
  3. package/dist/index.d.ts +216 -212
  4. package/package.json +1 -1
  5. package/src/Map/ClusteredLayers/index.tsx +2 -2
  6. package/src/Map/Layer/index.tsx +3 -3
  7. package/src/Map/Layers/index.tsx +2 -2
  8. package/src/Map/Sketch/hooks.ts +46 -66
  9. package/src/Map/Sketch/index.tsx +2 -24
  10. package/src/Map/Sketch/preset.ts +2 -0
  11. package/src/Map/Sketch/types.ts +31 -0
  12. package/src/Map/hooks.ts +0 -4
  13. package/src/Map/index.tsx +8 -5
  14. package/src/Map/ref.ts +3 -7
  15. package/src/Map/types/index.ts +34 -216
  16. package/src/Map/types/viewerProperty.ts +215 -0
  17. package/src/Map/useTimelineManager.ts +5 -3
  18. package/src/Map/utils.ts +1 -43
  19. package/src/Visualizer/coreContext.tsx +1 -8
  20. package/src/Visualizer/hooks.ts +6 -75
  21. package/src/Visualizer/index.stories.tsx +4 -48
  22. package/src/Visualizer/index.tsx +8 -6
  23. package/src/Visualizer/useCoreAPI.ts +30 -0
  24. package/src/engines/Cesium/Feature/Ellipse/index.stories.tsx +1 -1
  25. package/src/engines/Cesium/Feature/Frustum/index.stories.tsx +1 -1
  26. package/src/engines/Cesium/Feature/Model/index.stories.tsx +1 -1
  27. package/src/engines/Cesium/Feature/Model/index.tsx +10 -9
  28. package/src/engines/Cesium/Feature/Polygon/index.stories.tsx +8 -6
  29. package/src/engines/Cesium/Feature/Raster/index.stories.tsx +2 -2
  30. package/src/engines/Cesium/Feature/Resource/index.stories.tsx +1 -1
  31. package/src/engines/Cesium/Feature/Tileset/hooks.ts +12 -11
  32. package/src/engines/Cesium/Feature/Tileset/index.stories.tsx +1 -1
  33. package/src/engines/Cesium/Feature/Tileset/index.tsx +4 -4
  34. package/src/engines/Cesium/Feature/index.tsx +5 -4
  35. package/src/engines/Cesium/Feature/utils.tsx +2 -2
  36. package/src/engines/Cesium/core/Globe.tsx +36 -68
  37. package/src/engines/Cesium/core/Imagery.test.ts +9 -9
  38. package/src/engines/Cesium/core/Imagery.tsx +17 -19
  39. package/src/engines/Cesium/core/Indicator/Indicator.tsx +8 -8
  40. package/src/engines/Cesium/hooks/useCamera.ts +135 -0
  41. package/src/engines/Cesium/{cameraLimiter.ts → hooks/useCameraLimiter.ts} +22 -45
  42. package/src/engines/Cesium/{useEngineRef.test.tsx → hooks/useEngineRef.test.tsx} +38 -34
  43. package/src/engines/Cesium/{useEngineRef.ts → hooks/useEngineRef.ts} +43 -41
  44. package/src/engines/Cesium/hooks/useExplicitRender.ts +65 -0
  45. package/src/engines/Cesium/hooks/useLayerDragDrop.ts +77 -0
  46. package/src/engines/Cesium/{VertexTerrainElevationMaterial.ts → hooks/useOverrideGlobeShader/VertexTerrainElevationMaterial.ts} +3 -2
  47. package/src/engines/Cesium/{useOverrideGlobeShader.ts → hooks/useOverrideGlobeShader/useOverrideGlobeShader.ts} +19 -16
  48. package/src/engines/Cesium/hooks/useViewerProperty.ts +90 -0
  49. package/src/engines/Cesium/hooks.ts +129 -365
  50. package/src/engines/Cesium/index.stories.tsx +1 -1
  51. package/src/engines/Cesium/index.tsx +60 -62
  52. package/src/engines/index.ts +1 -1
  53. package/src/mantle/compat/types.ts +7 -7
  54. /package/src/engines/Cesium/{JapanSeaLevelEllipsoid.ts → hooks/useOverrideGlobeShader/JapanSeaLevelEllipsoid.ts} +0 -0
  55. /package/src/engines/Cesium/{vertexTerrainElevationMaterial.glsl → hooks/useOverrideGlobeShader/vertexTerrainElevationMaterial.glsl} +0 -0
@@ -12,7 +12,7 @@ import { useRef } from "react";
12
12
  import type { CesiumComponentRef } from "resium";
13
13
  import { vi, expect, test, afterEach } from "vitest";
14
14
 
15
- import type { EngineRef, Clock } from "..";
15
+ import type { EngineRef, Clock } from "../../..";
16
16
 
17
17
  import useEngineRef from "./useEngineRef";
18
18
 
@@ -57,86 +57,86 @@ test("bind mouse events", () => {
57
57
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
58
58
 
59
59
  result.current.current?.onDoubleClick(mockMouseEventCallback);
60
- expect(result.current.current?.mouseEventCallbacks.doubleclick[0]).toBe(mockMouseEventCallback);
60
+ expect(result.current.current?.mouseEventCallbacks.doubleClick[0]).toBe(mockMouseEventCallback);
61
61
 
62
- result.current.current?.mouseEventCallbacks.doubleclick[0]?.(props);
62
+ result.current.current?.mouseEventCallbacks.doubleClick[0]?.(props);
63
63
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(2);
64
64
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
65
65
 
66
66
  result.current.current?.onMouseDown(mockMouseEventCallback);
67
- expect(result.current.current?.mouseEventCallbacks.mousedown[0]).toBe(mockMouseEventCallback);
67
+ expect(result.current.current?.mouseEventCallbacks.mouseDown[0]).toBe(mockMouseEventCallback);
68
68
 
69
- result.current.current?.mouseEventCallbacks.mousedown[0]?.(props);
69
+ result.current.current?.mouseEventCallbacks.mouseDown[0]?.(props);
70
70
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(3);
71
71
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
72
72
 
73
73
  result.current.current?.onMouseUp(mockMouseEventCallback);
74
- expect(result.current.current?.mouseEventCallbacks.mouseup[0]).toBe(mockMouseEventCallback);
74
+ expect(result.current.current?.mouseEventCallbacks.mouseUp[0]).toBe(mockMouseEventCallback);
75
75
 
76
- result.current.current?.mouseEventCallbacks.mouseup[0]?.(props);
76
+ result.current.current?.mouseEventCallbacks.mouseUp[0]?.(props);
77
77
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(4);
78
78
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
79
79
 
80
80
  result.current.current?.onRightClick(mockMouseEventCallback);
81
- expect(result.current.current?.mouseEventCallbacks.rightclick[0]).toBe(mockMouseEventCallback);
81
+ expect(result.current.current?.mouseEventCallbacks.rightClick[0]).toBe(mockMouseEventCallback);
82
82
 
83
- result.current.current?.mouseEventCallbacks.rightclick[0]?.(props);
83
+ result.current.current?.mouseEventCallbacks.rightClick[0]?.(props);
84
84
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(5);
85
85
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
86
86
 
87
87
  result.current.current?.onRightDown(mockMouseEventCallback);
88
- expect(result.current.current?.mouseEventCallbacks.rightdown[0]).toBe(mockMouseEventCallback);
88
+ expect(result.current.current?.mouseEventCallbacks.rightDown[0]).toBe(mockMouseEventCallback);
89
89
 
90
- result.current.current?.mouseEventCallbacks.rightdown[0]?.(props);
90
+ result.current.current?.mouseEventCallbacks.rightDown[0]?.(props);
91
91
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(6);
92
92
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
93
93
 
94
94
  result.current.current?.onRightUp(mockMouseEventCallback);
95
- expect(result.current.current?.mouseEventCallbacks.rightup[0]).toBe(mockMouseEventCallback);
95
+ expect(result.current.current?.mouseEventCallbacks.rightUp[0]).toBe(mockMouseEventCallback);
96
96
 
97
- result.current.current?.mouseEventCallbacks.rightup[0]?.(props);
97
+ result.current.current?.mouseEventCallbacks.rightUp[0]?.(props);
98
98
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(7);
99
99
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
100
100
 
101
101
  result.current.current?.onMiddleClick(mockMouseEventCallback);
102
- expect(result.current.current?.mouseEventCallbacks.middleclick[0]).toBe(mockMouseEventCallback);
102
+ expect(result.current.current?.mouseEventCallbacks.middleClick[0]).toBe(mockMouseEventCallback);
103
103
 
104
- result.current.current?.mouseEventCallbacks.middleclick[0]?.(props);
104
+ result.current.current?.mouseEventCallbacks.middleClick[0]?.(props);
105
105
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(8);
106
106
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
107
107
 
108
108
  result.current.current?.onMiddleDown(mockMouseEventCallback);
109
- expect(result.current.current?.mouseEventCallbacks.middledown[0]).toBe(mockMouseEventCallback);
109
+ expect(result.current.current?.mouseEventCallbacks.middleDown[0]).toBe(mockMouseEventCallback);
110
110
 
111
- result.current.current?.mouseEventCallbacks.middledown[0]?.(props);
111
+ result.current.current?.mouseEventCallbacks.middleDown[0]?.(props);
112
112
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(9);
113
113
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
114
114
 
115
115
  result.current.current?.onMiddleUp(mockMouseEventCallback);
116
- expect(result.current.current?.mouseEventCallbacks.middleup[0]).toBe(mockMouseEventCallback);
116
+ expect(result.current.current?.mouseEventCallbacks.middleUp[0]).toBe(mockMouseEventCallback);
117
117
 
118
- result.current.current?.mouseEventCallbacks.middleup[0]?.(props);
118
+ result.current.current?.mouseEventCallbacks.middleUp[0]?.(props);
119
119
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(10);
120
120
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
121
121
 
122
122
  result.current.current?.onMouseMove(mockMouseEventCallback);
123
- expect(result.current.current?.mouseEventCallbacks.mousemove[0]).toBe(mockMouseEventCallback);
123
+ expect(result.current.current?.mouseEventCallbacks.mouseMove[0]).toBe(mockMouseEventCallback);
124
124
 
125
- result.current.current?.mouseEventCallbacks.mousemove[0]?.(props);
125
+ result.current.current?.mouseEventCallbacks.mouseMove[0]?.(props);
126
126
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(11);
127
127
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
128
128
 
129
129
  result.current.current?.onMouseEnter(mockMouseEventCallback);
130
- expect(result.current.current?.mouseEventCallbacks.mouseenter[0]).toBe(mockMouseEventCallback);
130
+ expect(result.current.current?.mouseEventCallbacks.mouseEnter[0]).toBe(mockMouseEventCallback);
131
131
 
132
- result.current.current?.mouseEventCallbacks.mouseenter[0]?.(props);
132
+ result.current.current?.mouseEventCallbacks.mouseEnter[0]?.(props);
133
133
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(12);
134
134
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
135
135
 
136
136
  result.current.current?.onMouseLeave(mockMouseEventCallback);
137
- expect(result.current.current?.mouseEventCallbacks.mouseleave[0]).toBe(mockMouseEventCallback);
137
+ expect(result.current.current?.mouseEventCallbacks.mouseLeave[0]).toBe(mockMouseEventCallback);
138
138
 
139
- result.current.current?.mouseEventCallbacks.mouseleave[0]?.(props);
139
+ result.current.current?.mouseEventCallbacks.mouseLeave[0]?.(props);
140
140
  expect(mockMouseEventCallback).toHaveBeenCalledTimes(13);
141
141
  expect(mockMouseEventCallback).toHaveBeenCalledWith(props);
142
142
 
@@ -188,10 +188,11 @@ test("zoom", async () => {
188
188
  return engineRef;
189
189
  });
190
190
 
191
- const commons = await import("./common");
191
+ const commons = await import("../common");
192
+ const zoom = vi.spyOn(commons, "zoom");
192
193
 
193
194
  result.current.current?.zoomIn(10);
194
- expect(commons.zoom).toHaveBeenCalledTimes(1);
195
+ expect(zoom).toHaveBeenCalledTimes(1);
195
196
  expect(commons.zoom).toHaveBeenCalledWith(
196
197
  {
197
198
  viewer,
@@ -221,6 +222,7 @@ test("call orbit when camera focuses on center", async () => {
221
222
  rotateUp: vi.fn(),
222
223
  look: vi.fn(),
223
224
  move: vi.fn(),
225
+ getPickRay: vi.fn(),
224
226
  positionCartographic: new Cartesian3(),
225
227
  },
226
228
  mode: SceneMode.SCENE3D,
@@ -247,15 +249,14 @@ test("call orbit when camera focuses on center", async () => {
247
249
  return [engineRef, cesium] as const;
248
250
  });
249
251
 
250
- const commons = await import("./common");
252
+ const commons = await import("../common");
253
+ const getCenterCamera = vi.spyOn(commons, "getCenterCamera");
251
254
 
252
255
  const [engineRef, cesium] = result.current;
253
256
 
254
257
  engineRef.current?.orbit(90);
255
- expect(commons.getCenterCamera).toHaveBeenCalled();
256
- expect(cesium.current.cesiumElement?.scene.camera.rotateLeft).toHaveBeenCalled();
257
- expect(cesium.current.cesiumElement?.scene.camera.rotateUp).toHaveBeenCalled();
258
- expect(cesium.current.cesiumElement?.scene.camera.lookAtTransform).toHaveBeenCalledTimes(2);
258
+ expect(getCenterCamera).toHaveBeenCalled();
259
+ expect(cesium.current.cesiumElement?.scene.camera.lookAtTransform).toHaveBeenCalledTimes(1);
259
260
  });
260
261
 
261
262
  test("call orbit when camera does not focus on center", async () => {
@@ -268,6 +269,7 @@ test("call orbit when camera does not focus on center", async () => {
268
269
  rotateUp: vi.fn(),
269
270
  look: vi.fn(),
270
271
  move: vi.fn(),
272
+ getPickRay: vi.fn(),
271
273
  positionWC: new Cartesian3(),
272
274
  positionCartographic: new Cartesian3(),
273
275
  },
@@ -294,12 +296,13 @@ test("call orbit when camera does not focus on center", async () => {
294
296
  return [engineRef, cesium] as const;
295
297
  });
296
298
 
297
- const commons = await import("./common");
299
+ const commons = await import("../common");
300
+ const getCenterCamera = vi.spyOn(commons, "getCenterCamera");
298
301
 
299
302
  const [engineRef, cesium] = result.current;
300
303
 
301
304
  engineRef.current?.orbit(90);
302
- expect(commons.getCenterCamera).toHaveBeenCalled();
305
+ expect(getCenterCamera).toHaveBeenCalled();
303
306
  expect(cesium.current.cesiumElement?.scene.camera.look).toHaveBeenCalledTimes(2);
304
307
  expect(cesium.current.cesiumElement?.scene.camera.lookAtTransform).toHaveBeenCalledTimes(2);
305
308
  });
@@ -314,6 +317,7 @@ test("orbit on 2D mode", async () => {
314
317
  rotateUp: vi.fn(),
315
318
  look: vi.fn(),
316
319
  move: vi.fn(),
320
+ getPickRay: vi.fn(),
317
321
  positionWC: new Cartesian3(),
318
322
  positionCartographic: new Cartesian3(),
319
323
  },
@@ -4,11 +4,9 @@ import { ClockStep, JulianDate, Math as CesiumMath } from "cesium";
4
4
  import { useImperativeHandle, Ref, RefObject, useMemo, useRef } from "react";
5
5
  import { CesiumComponentRef } from "resium";
6
6
 
7
- import type { EngineRef, MouseEventProps, Feature, ComputedFeature } from "..";
8
- import { MouseEventCallbacks, TickEventCallback } from "../../Map";
9
- import { SketchType } from "../../Map/Sketch/types";
10
- import { Position2d, Position3d } from "../../types";
11
-
7
+ import type { EngineRef, MouseEventProps, Feature, ComputedFeature } from "../..";
8
+ import { MouseEventCallbacks, TickEventCallback, SketchType } from "../../../Map";
9
+ import { Position2d, Position3d } from "../../../types";
12
10
  import {
13
11
  getLocationFromScreen,
14
12
  flyTo,
@@ -34,11 +32,11 @@ import {
34
32
  cartesianToLatLngHeight,
35
33
  getExtrudedHeight,
36
34
  getOverriddenScreenSpaceCameraOptions,
37
- } from "./common";
38
- import { attachTag, getTag } from "./Feature";
39
- import { PickedFeature, pickManyFromViewportAsFeature } from "./pickMany";
40
- import { createGeometry } from "./Sketch/createGeometry";
41
- import { CursorType } from "./types";
35
+ } from "../common";
36
+ import { attachTag, getTag } from "../Feature";
37
+ import { PickedFeature, pickManyFromViewportAsFeature } from "../pickMany";
38
+ import { createGeometry } from "../Sketch/createGeometry";
39
+ import { CursorType } from "../types";
42
40
  import {
43
41
  convertCesium3DTileFeatureProperties,
44
42
  convertEntityDescription,
@@ -46,7 +44,7 @@ import {
46
44
  convertObjToComputedFeature,
47
45
  findEntity,
48
46
  findFeaturesFromLayer,
49
- } from "./utils/utils";
47
+ } from "../utils/utils";
50
48
 
51
49
  export default function useEngineRef(
52
50
  ref: Ref<EngineRef>,
@@ -55,18 +53,18 @@ export default function useEngineRef(
55
53
  const cancelCameraFlight = useRef<() => void>();
56
54
  const mouseEventCallbacks = useRef<MouseEventCallbacks>({
57
55
  click: [],
58
- doubleclick: [],
59
- mousedown: [],
60
- mouseup: [],
61
- rightclick: [],
62
- rightdown: [],
63
- rightup: [],
64
- middleclick: [],
65
- middledown: [],
66
- middleup: [],
67
- mousemove: [],
68
- mouseenter: [],
69
- mouseleave: [],
56
+ doubleClick: [],
57
+ mouseDown: [],
58
+ mouseUp: [],
59
+ rightClick: [],
60
+ rightDown: [],
61
+ rightUp: [],
62
+ middleClick: [],
63
+ middleDown: [],
64
+ middleUp: [],
65
+ mouseMove: [],
66
+ mouseEnter: [],
67
+ mouseLeave: [],
70
68
  wheel: [],
71
69
  });
72
70
  const tickEventCallback = useRef<TickEventCallback[]>([]);
@@ -239,6 +237,8 @@ export default function useEngineRef(
239
237
  setView: camera => {
240
238
  const viewer = cesium.current?.cesiumElement;
241
239
  if (!viewer || viewer.isDestroyed()) return false;
240
+ if (camera.lat === undefined || camera.lng === undefined || camera.height === undefined)
241
+ return false;
242
242
  const scene = viewer.scene;
243
243
  if (camera.lng || camera.lat || camera.height) {
244
244
  const xyz = Cesium.Cartesian3.fromDegrees(camera.lng, camera.lat, camera.height);
@@ -539,13 +539,15 @@ export default function useEngineRef(
539
539
  const oldTransform = Cesium.Matrix4.clone(camera.transform);
540
540
 
541
541
  const center = getCenterCamera({ camera, scene });
542
- // Get fixed frame from center to globe ellipsoid.
543
- const frame = Cesium.Transforms.eastNorthUpToFixedFrame(
544
- center || camera.positionWC,
545
- scene.globe.ellipsoid,
546
- );
542
+ if (center || camera.positionWC) {
543
+ // Get fixed frame from center to globe ellipsoid.
544
+ const frame = Cesium.Transforms.eastNorthUpToFixedFrame(
545
+ center || camera.positionWC,
546
+ scene.globe.ellipsoid,
547
+ );
547
548
 
548
- camera.lookAtTransform(frame);
549
+ camera.lookAtTransform(frame);
550
+ }
549
551
 
550
552
  if (viewer.scene.mode !== Cesium.SceneMode.SCENE3D) {
551
553
  camera.move(
@@ -675,40 +677,40 @@ export default function useEngineRef(
675
677
  mouseEventCallbacks.current.click.push(cb);
676
678
  },
677
679
  onDoubleClick: (cb: (props: MouseEventProps) => void) => {
678
- mouseEventCallbacks.current.doubleclick.push(cb);
680
+ mouseEventCallbacks.current.doubleClick.push(cb);
679
681
  },
680
682
  onMouseDown: (cb: (props: MouseEventProps) => void) => {
681
- mouseEventCallbacks.current.mousedown.push(cb);
683
+ mouseEventCallbacks.current.mouseDown.push(cb);
682
684
  },
683
685
  onMouseUp: (cb: (props: MouseEventProps) => void) => {
684
- mouseEventCallbacks.current.mouseup.push(cb);
686
+ mouseEventCallbacks.current.mouseUp.push(cb);
685
687
  },
686
688
  onRightClick: (cb: (props: MouseEventProps) => void) => {
687
- mouseEventCallbacks.current.rightclick.push(cb);
689
+ mouseEventCallbacks.current.rightClick.push(cb);
688
690
  },
689
691
  onRightDown: (cb: (props: MouseEventProps) => void) => {
690
- mouseEventCallbacks.current.rightdown.push(cb);
692
+ mouseEventCallbacks.current.rightDown.push(cb);
691
693
  },
692
694
  onRightUp: (cb: (props: MouseEventProps) => void) => {
693
- mouseEventCallbacks.current.rightup.push(cb);
695
+ mouseEventCallbacks.current.rightUp.push(cb);
694
696
  },
695
697
  onMiddleClick: (cb: (props: MouseEventProps) => void) => {
696
- mouseEventCallbacks.current.middleclick.push(cb);
698
+ mouseEventCallbacks.current.middleClick.push(cb);
697
699
  },
698
700
  onMiddleDown: (cb: (props: MouseEventProps) => void) => {
699
- mouseEventCallbacks.current.middledown.push(cb);
701
+ mouseEventCallbacks.current.middleDown.push(cb);
700
702
  },
701
703
  onMiddleUp: (cb: (props: MouseEventProps) => void) => {
702
- mouseEventCallbacks.current.middleup.push(cb);
704
+ mouseEventCallbacks.current.middleUp.push(cb);
703
705
  },
704
706
  onMouseMove: (cb: (props: MouseEventProps) => void) => {
705
- mouseEventCallbacks.current.mousemove.push(cb);
707
+ mouseEventCallbacks.current.mouseMove.push(cb);
706
708
  },
707
709
  onMouseEnter: (cb: (props: MouseEventProps) => void) => {
708
- mouseEventCallbacks.current.mouseenter.push(cb);
710
+ mouseEventCallbacks.current.mouseEnter.push(cb);
709
711
  },
710
712
  onMouseLeave: (cb: (props: MouseEventProps) => void) => {
711
- mouseEventCallbacks.current.mouseleave.push(cb);
713
+ mouseEventCallbacks.current.mouseLeave.push(cb);
712
714
  },
713
715
  onWheel: (cb: (props: MouseEventProps) => void) => {
714
716
  mouseEventCallbacks.current.wheel.push(cb);
@@ -0,0 +1,65 @@
1
+ import { Viewer } from "cesium";
2
+ import { MutableRefObject, RefObject, useCallback, useEffect, useRef } from "react";
3
+ import { CesiumComponentRef } from "resium";
4
+
5
+ import { RequestingRenderMode, ViewerProperty } from "../../../Map";
6
+ import { FORCE_REQUEST_RENDER, NO_REQUEST_RENDER, REQUEST_RENDER_ONCE } from "../../../Map/hooks";
7
+
8
+ export default ({
9
+ cesium,
10
+ requestingRenderMode,
11
+ isLayerDragging,
12
+ shouldRender,
13
+ property,
14
+ }: {
15
+ cesium: RefObject<CesiumComponentRef<Viewer>>;
16
+ requestingRenderMode?: MutableRefObject<RequestingRenderMode>;
17
+ isLayerDragging?: boolean;
18
+ shouldRender?: boolean;
19
+ property?: ViewerProperty;
20
+ }) => {
21
+ // explicit rendering
22
+ const explicitRender = useCallback(() => {
23
+ const viewer = cesium.current?.cesiumElement;
24
+ if (!requestingRenderMode?.current || !viewer || viewer.isDestroyed()) return;
25
+ viewer.scene.requestRender();
26
+ if (requestingRenderMode.current === REQUEST_RENDER_ONCE) {
27
+ requestingRenderMode.current = NO_REQUEST_RENDER;
28
+ }
29
+ }, [cesium, requestingRenderMode]);
30
+
31
+ const explicitRenderRef = useRef<() => void>();
32
+
33
+ useEffect(() => {
34
+ explicitRenderRef.current = explicitRender;
35
+ }, [explicitRender]);
36
+
37
+ useEffect(() => {
38
+ const viewer = cesium.current?.cesiumElement;
39
+ if (!viewer || viewer.isDestroyed()) return;
40
+ return viewer.scene.postUpdate.addEventListener(() => {
41
+ explicitRenderRef.current?.();
42
+ });
43
+ }, [cesium]);
44
+
45
+ // render one frame when scene property changes
46
+ useEffect(() => {
47
+ if (requestingRenderMode) {
48
+ requestingRenderMode.current = REQUEST_RENDER_ONCE;
49
+ }
50
+ }, [property, requestingRenderMode]);
51
+
52
+ // force render when timeline is animating or is shouldRender
53
+ useEffect(() => {
54
+ const viewer = cesium.current?.cesiumElement;
55
+ if (!viewer || viewer.isDestroyed()) return;
56
+ if (requestingRenderMode) {
57
+ requestingRenderMode.current =
58
+ isLayerDragging || shouldRender
59
+ ? FORCE_REQUEST_RENDER
60
+ : requestingRenderMode.current === REQUEST_RENDER_ONCE
61
+ ? REQUEST_RENDER_ONCE
62
+ : NO_REQUEST_RENDER;
63
+ }
64
+ }, [cesium, isLayerDragging, shouldRender, requestingRenderMode]);
65
+ };
@@ -0,0 +1,77 @@
1
+ import { Cartesian3, Entity, Viewer } from "cesium";
2
+ import CesiumDnD, { Context } from "cesium-dnd";
3
+ import { RefObject, useCallback, useEffect, useRef } from "react";
4
+ import { CesiumComponentRef } from "resium";
5
+
6
+ import { LatLng } from "../../../utils";
7
+ import { isDraggable, isSelectable } from "../common";
8
+ import { getTag } from "../Feature";
9
+ import { convertCartesian3ToPosition } from "../utils/utils";
10
+
11
+ export default ({
12
+ cesium,
13
+ isLayerDraggable,
14
+ onLayerDrag,
15
+ onLayerDrop,
16
+ }: {
17
+ cesium: RefObject<CesiumComponentRef<Viewer>>;
18
+ isLayerDraggable?: boolean;
19
+ onLayerDrag?: (layerId: string, featureId: string | undefined, position: LatLng) => void;
20
+ onLayerDrop?: (
21
+ layerId: string,
22
+ featureId: string | undefined,
23
+ position: LatLng | undefined,
24
+ ) => void;
25
+ }) => {
26
+ // enable Drag and Drop Layers
27
+ const handleLayerDrag = useCallback(
28
+ (e: Entity, position: Cartesian3 | undefined, _context: Context): boolean | void => {
29
+ const viewer = cesium.current?.cesiumElement;
30
+ if (!viewer || viewer.isDestroyed() || !isSelectable(e) || !isDraggable(e)) return false;
31
+
32
+ const pos = convertCartesian3ToPosition(cesium.current?.cesiumElement, position);
33
+ if (!pos) return false;
34
+
35
+ const tag = getTag(e);
36
+ if (!tag) return false;
37
+
38
+ onLayerDrag?.(tag.layerId || "", tag.featureId, pos);
39
+ },
40
+ [cesium, onLayerDrag],
41
+ );
42
+
43
+ const handleLayerDrop = useCallback(
44
+ (e: Entity, position: Cartesian3 | undefined): boolean | void => {
45
+ const viewer = cesium.current?.cesiumElement;
46
+ if (!viewer || viewer.isDestroyed()) return false;
47
+
48
+ const tag = getTag(e);
49
+ const pos = convertCartesian3ToPosition(cesium.current?.cesiumElement, position);
50
+ onLayerDrop?.(tag?.layerId || "", tag?.featureId || "", pos);
51
+
52
+ return false; // let apollo-client handle optimistic updates
53
+ },
54
+ [cesium, onLayerDrop],
55
+ );
56
+
57
+ const cesiumDnD = useRef<CesiumDnD>();
58
+ useEffect(() => {
59
+ const viewer = cesium.current?.cesiumElement;
60
+ if (!viewer || viewer.isDestroyed()) return;
61
+ cesiumDnD.current = new CesiumDnD(viewer, {
62
+ onDrag: handleLayerDrag,
63
+ onDrop: handleLayerDrop,
64
+ dragDelay: 1000,
65
+ initialDisabled: !isLayerDraggable,
66
+ });
67
+ return () => {
68
+ if (!viewer || viewer.isDestroyed()) return;
69
+ cesiumDnD.current?.disable();
70
+ };
71
+ }, [cesium, isLayerDraggable, handleLayerDrag, handleLayerDrop]);
72
+
73
+ return {
74
+ handleLayerDrag,
75
+ handleLayerDrop,
76
+ };
77
+ };
@@ -1,7 +1,8 @@
1
1
  import { Ellipsoid, Material } from "cesium";
2
2
 
3
- import { createColorMapImage } from "./Feature/HeatMap/colorMap";
4
- import { turboColorMap } from "./Feature/HeatMap/constants";
3
+ import { createColorMapImage } from "../../Feature/HeatMap/colorMap";
4
+ import { turboColorMap } from "../../Feature/HeatMap/constants";
5
+
5
6
  import { JapanSeaLevelEllipsoid } from "./JapanSeaLevelEllipsoid";
6
7
  import source from "./vertexTerrainElevationMaterial.glsl?raw";
7
8
 
@@ -8,15 +8,15 @@ import { Viewer, Globe, Material, Cartesian3 } from "cesium";
8
8
  import { RefObject, useCallback, useEffect, useMemo, useRef } from "react";
9
9
  import { CesiumComponentRef } from "resium";
10
10
 
11
- import { TerrainProperty } from "..";
12
- import { useImmutableFunction } from "../../hooks/useRefFunction";
13
- import { StringMatcher } from "../../utils/StringMatcher";
14
-
15
- import { createColorMapImage } from "./Feature/HeatMap/colorMap";
16
- import GlobeFSDefinitions from "./Shaders/OverriddenShaders/GlobeFS/Definitions.glsl?raw";
17
- import HeatmapForTerrainFS from "./Shaders/OverriddenShaders/GlobeFS/HeatmapForTerrain.glsl?raw";
18
- import IBLFS from "./Shaders/OverriddenShaders/GlobeFS/IBL.glsl?raw";
19
- import { PrivateCesiumGlobe } from "./types";
11
+ import { TerrainProperty } from "../../..";
12
+ import { useImmutableFunction } from "../../../../hooks/useRefFunction";
13
+ import { StringMatcher } from "../../../../utils/StringMatcher";
14
+ import { createColorMapImage } from "../../Feature/HeatMap/colorMap";
15
+ import GlobeFSDefinitions from "../../Shaders/OverriddenShaders/GlobeFS/Definitions.glsl?raw";
16
+ import HeatmapForTerrainFS from "../../Shaders/OverriddenShaders/GlobeFS/HeatmapForTerrain.glsl?raw";
17
+ import IBLFS from "../../Shaders/OverriddenShaders/GlobeFS/IBL.glsl?raw";
18
+ import { PrivateCesiumGlobe } from "../../types";
19
+
20
20
  import { VertexTerrainElevationMaterial } from "./VertexTerrainElevationMaterial";
21
21
 
22
22
  const defaultMatcher = new StringMatcher()
@@ -122,17 +122,19 @@ const useIBL = ({
122
122
 
123
123
  const useTerrainHeatmap = ({
124
124
  cesium,
125
- terrain: {
126
- heatmapType,
127
- heatmapMaxHeight,
128
- heatmapMinHeight,
129
- heatmapLogarithmic,
130
- heatmapColorLUT,
131
- } = {},
125
+ terrain,
132
126
  }: {
133
127
  cesium: RefObject<CesiumComponentRef<Viewer>>;
134
128
  terrain: TerrainProperty | undefined;
135
129
  }) => {
130
+ const {
131
+ type: heatmapType,
132
+ maxHeight: heatmapMaxHeight,
133
+ minHeight: heatmapMinHeight,
134
+ logarithmic: heatmapLogarithmic,
135
+ colorLUT: heatmapColorLUT,
136
+ } = terrain?.elevationHeatMap ?? {};
137
+
136
138
  const isCustomHeatmapEnabled = useMemo(() => heatmapType === "custom", [heatmapType]);
137
139
 
138
140
  const shaderForTerrainHeatmap = useMemo(
@@ -206,6 +208,7 @@ export const useOverrideGlobeShader = ({
206
208
  enableLighting,
207
209
  });
208
210
 
211
+ // Terrain Heatmap is actually a built-in feature for globe, it renders as a heatmap using terrain height data.
209
212
  const { isCustomHeatmapEnabled, shaderForTerrainHeatmap } = useTerrainHeatmap({
210
213
  cesium,
211
214
  terrain,
@@ -0,0 +1,90 @@
1
+ import { Cartesian3, Color, DirectionalLight, SceneMode, SunLight, Viewer } from "cesium";
2
+ import { RefObject, useMemo } from "react";
3
+ import { CesiumComponentRef } from "resium";
4
+
5
+ import { ViewerProperty } from "../..";
6
+
7
+ // TODO: move all viewer property -> resium component prop logic here (from the gerneal long Cesium/hooks file)
8
+ export default ({
9
+ cesium,
10
+ property,
11
+ }: {
12
+ cesium: RefObject<CesiumComponentRef<Viewer>>;
13
+ property?: ViewerProperty;
14
+ }) => {
15
+ const sceneLight = useMemo(() => {
16
+ let light;
17
+ if (property?.scene?.light?.type === "sunLight") {
18
+ light = new SunLight({
19
+ color: property.scene?.light?.color
20
+ ? Color.fromCssColorString(property.scene.light.color)
21
+ : undefined,
22
+ intensity: property.scene?.light?.intensity,
23
+ });
24
+ } else if (property?.scene?.light?.type === "directionalLight") {
25
+ light = new DirectionalLight({
26
+ direction: new Cartesian3(
27
+ property?.scene?.light?.direction?.[0] ?? 1,
28
+ property?.scene?.light?.direction?.[1] ?? 0,
29
+ property?.scene?.light?.direction?.[2] ?? 0,
30
+ ),
31
+ color: property.scene?.light?.color
32
+ ? Color.fromCssColorString(property.scene.light.color)
33
+ : undefined,
34
+ intensity: property.scene?.light?.intensity,
35
+ });
36
+ } else {
37
+ light = cesium.current?.cesiumElement?.scene.light;
38
+ if (light) {
39
+ light.color = property?.scene?.light?.color
40
+ ? Color.fromCssColorString(property.scene.light.color)
41
+ : light.color;
42
+ light.intensity = property?.scene?.light?.intensity
43
+ ? property.scene.light.intensity
44
+ : light.intensity;
45
+ }
46
+ }
47
+ return light;
48
+ }, [
49
+ cesium,
50
+ property?.scene?.light?.type,
51
+ property?.scene?.light?.color,
52
+ property?.scene?.light?.direction,
53
+ property?.scene?.light?.intensity,
54
+ ]);
55
+
56
+ const sceneBackgroundColor = useMemo(
57
+ () =>
58
+ property?.scene?.backgroundColor
59
+ ? Color.fromCssColorString(property.scene.backgroundColor)
60
+ : undefined,
61
+ [property?.scene?.backgroundColor],
62
+ );
63
+
64
+ const sceneMsaaSamples = useMemo(() => {
65
+ // TODO: FXAA doesn't support alpha blending in Cesium, so we will enable FXAA when this is fixed.
66
+ // viewer.scene.postProcessStages.fxaa.enabled = property?.render?.antialias === "high";
67
+ return property?.render?.antialias === "extreme"
68
+ ? 8
69
+ : property?.render?.antialias === "high"
70
+ ? 6
71
+ : property?.render?.antialias === "medium"
72
+ ? 4
73
+ : 1;
74
+ }, [property?.render?.antialias]);
75
+
76
+ const sceneMode = useMemo(() => {
77
+ return property?.scene?.mode === "2d"
78
+ ? SceneMode.SCENE2D
79
+ : property?.scene?.mode === "columbus"
80
+ ? SceneMode.COLUMBUS_VIEW
81
+ : SceneMode.SCENE3D;
82
+ }, [property?.scene?.mode]);
83
+
84
+ return {
85
+ sceneLight,
86
+ sceneBackgroundColor,
87
+ sceneMsaaSamples,
88
+ sceneMode,
89
+ };
90
+ };