@reearth/core 0.0.7-alpha.30 → 0.0.7-alpha.32

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/index.d.ts CHANGED
@@ -374,9 +374,7 @@ export declare type Credit = {
374
374
  html?: string;
375
375
  };
376
376
 
377
- export declare type CursorType = "auto" | "grab" | "crosshair";
378
-
379
- declare type CursorType_2 = "default" | "auto" | "help" | "pointer" | "grab" | "crosshair";
377
+ declare type CursorType = "default" | "auto" | "help" | "pointer" | "grab" | "crosshair";
380
378
 
381
379
  export declare type Data = {
382
380
  type: DataType;
@@ -557,7 +555,7 @@ export declare type EngineRef = {
557
555
  type: SketchType;
558
556
  controlPoints: Position3d[];
559
557
  }) => LineString | Polygon_2 | MultiPolygon | Point | undefined;
560
- setCursor: (cursor: CursorType_2) => void;
558
+ setCursor: (cursor: CursorType) => void;
561
559
  flyTo: FlyTo;
562
560
  flyToBBox: (bbox: [number, number, number, number], options?: CameraOptions & {
563
561
  heading?: number;
@@ -1093,9 +1091,7 @@ declare const Map_2: ForwardRefExoticComponent< {
1093
1091
  engines?: Record<string, Engine> | undefined;
1094
1092
  engine?: string | undefined;
1095
1093
  onAPIReady?: (() => void) | undefined;
1096
- } & Omit<Props_2, "Feature" | "viewerProperty" | "selectionReason" | "delegatedDataTypes" | "clusterComponent" | "selectedLayerId"> & Omit<EngineProps, "onLayerSelect" | "selectedLayerId" | "layerSelectionReason"> & Omit<SketchProps, "engineRef" | "SketchComponent" | "layersRef"> & {
1097
- cursor?: CursorType | undefined;
1098
- } & RefAttributes<MapRef>>;
1094
+ } & Omit<Props_2, "Feature" | "viewerProperty" | "selectionReason" | "delegatedDataTypes" | "clusterComponent" | "selectedLayerId"> & Omit<EngineProps, "onLayerSelect" | "selectedLayerId" | "layerSelectionReason"> & Omit<SketchProps, "engineRef" | "SketchComponent" | "layersRef"> & RefAttributes<MapRef>>;
1099
1095
  export { Map_2 as Map }
1100
1096
 
1101
1097
  export declare type MapRef = {
@@ -1338,9 +1334,7 @@ export declare type Props = {
1338
1334
  engines?: Record<string, Engine>;
1339
1335
  engine?: string;
1340
1336
  onAPIReady?: () => void;
1341
- } & Omit<Props_2, "Feature" | "clusterComponent" | "selectionReason" | "delegatedDataTypes" | "selectedLayerId" | "viewerProperty"> & Omit<EngineProps, "onLayerSelect" | "layerSelectionReason" | "selectedLayerId"> & Omit<SketchProps, "layersRef" | "engineRef" | "SketchComponent"> & {
1342
- cursor?: CursorType;
1343
- };
1337
+ } & Omit<Props_2, "Feature" | "clusterComponent" | "selectionReason" | "delegatedDataTypes" | "selectedLayerId" | "viewerProperty"> & Omit<EngineProps, "onLayerSelect" | "layerSelectionReason" | "selectedLayerId"> & Omit<SketchProps, "layersRef" | "engineRef" | "SketchComponent">;
1344
1338
 
1345
1339
  declare type Props_2 = Omit<Props_3, "atomMap" | "isHidden" | "selectedLayerId"> & {
1346
1340
  selectedLayer?: {
@@ -1600,9 +1594,16 @@ export declare type Spacing = {
1600
1594
  declare type SpatialIdPickSpaceOptions = {
1601
1595
  zoom?: number;
1602
1596
  maxHeight?: number;
1603
- color?: string;
1597
+ minHeight?: number;
1604
1598
  dataOnly?: boolean;
1605
1599
  rightClickToExit?: boolean;
1600
+ color?: string;
1601
+ outlineColor?: string;
1602
+ groundIndicatorColor?: string;
1603
+ selectorColor?: string;
1604
+ selectorOutlineColor?: string;
1605
+ verticalSpaceIndicatorColor?: string;
1606
+ verticalSpaceIndicatorOutlineColor?: string;
1606
1607
  };
1607
1608
 
1608
1609
  declare type SpatialIdRef = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reearth/core",
3
- "version": "0.0.7-alpha.30",
3
+ "version": "0.0.7-alpha.32",
4
4
  "author": "Re:Earth contributors <community@reearth.io>",
5
5
  "license": "Apache-2.0",
6
6
  "description": "A library that abstracts a map engine as one common API.",
@@ -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
 
@@ -90,10 +90,16 @@ export default function ({
90
90
  const [type, updateType] = useState<SketchType | undefined>();
91
91
  const [from, updateFrom] = useState<"editor" | "plugin">("editor");
92
92
 
93
- const setType = useCallback((type: SketchType | undefined, from?: "editor" | "plugin") => {
94
- updateType(type);
95
- updateFrom(from ?? "editor");
96
- }, []);
93
+ const setType = useCallback(
94
+ (type: SketchType | undefined, from?: "editor" | "plugin") => {
95
+ updateType(type);
96
+ updateFrom(from ?? "editor");
97
+ if (type) {
98
+ engineRef.current?.setCursor("crosshair");
99
+ }
100
+ },
101
+ [engineRef],
102
+ );
97
103
 
98
104
  const [disableInteraction, setDisableInteraction] = useState(false);
99
105
 
@@ -611,6 +617,12 @@ export default function ({
611
617
  });
612
618
  }, [overrideInteractionMode]);
613
619
 
620
+ useEffect(() => {
621
+ if (!isEditing) {
622
+ overrideInteractionModeRef.current?.("default");
623
+ }
624
+ }, [isEditing]);
625
+
614
626
  return {
615
627
  state,
616
628
  isEditing,
@@ -0,0 +1,16 @@
1
+ import { SpatialIdPickSpaceOptions } from "./types";
2
+
3
+ export const SPATIALID_DEFAULT_OPTIONS: Required<SpatialIdPickSpaceOptions> = {
4
+ zoom: 20,
5
+ maxHeight: 4000,
6
+ minHeight: -1000,
7
+ dataOnly: false,
8
+ rightClickToExit: true,
9
+ color: "#00bebe44",
10
+ outlineColor: "#00bebe55",
11
+ groundIndicatorColor: "#00000066",
12
+ selectorColor: "#ff990099",
13
+ selectorOutlineColor: "#ff9900aa",
14
+ verticalSpaceIndicatorColor: "#ffffff33",
15
+ verticalSpaceIndicatorOutlineColor: "#ffffff55",
16
+ };
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  ForwardedRef,
3
+ RefObject,
3
4
  useCallback,
4
5
  useEffect,
5
6
  useImperativeHandle,
@@ -7,19 +8,23 @@ import {
7
8
  useRef,
8
9
  useState,
9
10
  } from "react";
10
- import { RefObject } from "use-callback-ref/dist/es5/types";
11
+ import { v4 as uuid } from "uuid";
11
12
 
13
+ import { useWindowEvent } from "../../utils/use-window-event";
12
14
  import { InteractionModeType } from "../../Visualizer";
13
15
  import { EngineRef, MouseEventProps } from "../types";
14
16
 
17
+ import { SPATIALID_DEFAULT_OPTIONS } from "./constants";
15
18
  import {
16
19
  SpatialIdRef,
17
20
  SpatialIdSpacePickingState,
18
21
  SpatialIdSpaceType,
19
22
  SpatialIdSpaceData,
20
23
  SpatialIdPickSpaceOptions,
24
+ VerticalSpaceIndicatorType,
25
+ CoordinateSelectorType,
21
26
  } from "./types";
22
- import { createSpatialIdFloorSpaces, createSpatialIdSpace, getSpaceData } from "./utils";
27
+ import { createSpatialIdSpace, getSpaceData, getVerticalLimits } from "./utils";
23
28
 
24
29
  type Props = {
25
30
  ref: ForwardedRef<SpatialIdRef>;
@@ -30,12 +35,6 @@ type Props = {
30
35
  onMount?: () => void;
31
36
  };
32
37
 
33
- export const SPATIALID_DEFAULT_ZOOM = 20;
34
- export const SPATIALID_DEFAULT_MAX_HEIGHT = 1000;
35
- export const SPATIALID_DEFAULT_COLOR = "#00bebe";
36
- export const SPATIALID_DEFAULT_DATA_ONLY = false;
37
- export const SPATIALID_DEFAULT_RIGHT_CLICK_TO_EXIT = true;
38
-
39
38
  export default ({
40
39
  ref,
41
40
  engineRef,
@@ -46,32 +45,66 @@ export default ({
46
45
  }: Props) => {
47
46
  const [state, setState] = useState<SpatialIdSpacePickingState>("idle");
48
47
 
49
- const [spatialIdSpaces, setSpatialIdSpaces] = useState<SpatialIdSpaceType[]>([]);
50
- const [floorSpaces, setFloorSpaces] = useState<SpatialIdSpaceType[]>([]);
51
- const [selectorSpace, setSelectorSpace] = useState<SpatialIdSpaceType | null>(null);
52
-
53
- const spaces = useMemo(() => {
54
- return [...spatialIdSpaces, ...floorSpaces, ...(selectorSpace ? [selectorSpace] : [])];
55
- }, [spatialIdSpaces, floorSpaces, selectorSpace]);
48
+ const [spatialIdSpaces, setSpatialIdSpaces] = useState<SpatialIdSpaceType[] | null>(null);
49
+ const [verticalSpaceIndicator, setVerticalSpaceIndicator] =
50
+ useState<VerticalSpaceIndicatorType | null>(null);
51
+ const [coordinateSelector, setCoordinateSelector] = useState<CoordinateSelectorType | null>(null);
52
+ const lastCoordinateSelector = useRef<CoordinateSelectorType | null>(null);
53
+ const [spaceSelector, setSpaceSelector] = useState<SpatialIdSpaceType | null>(null);
56
54
 
57
55
  const [basePosition, setBasePosition] = useState<[number, number, number] | null>(null);
58
56
  const [baseCoordinate, setBaseCoordinate] = useState<[number, number, number] | null>(null);
59
57
 
60
- const [pickOptions, setPickOptions] = useState<Required<SpatialIdPickSpaceOptions>>({
61
- zoom: SPATIALID_DEFAULT_ZOOM,
62
- maxHeight: SPATIALID_DEFAULT_MAX_HEIGHT,
63
- color: SPATIALID_DEFAULT_COLOR,
64
- dataOnly: SPATIALID_DEFAULT_DATA_ONLY,
65
- rightClickToExit: SPATIALID_DEFAULT_RIGHT_CLICK_TO_EXIT,
66
- });
58
+ const [pickOptions, setPickOptions] =
59
+ useState<Required<SpatialIdPickSpaceOptions>>(SPATIALID_DEFAULT_OPTIONS);
60
+
61
+ const verticalLimits = useMemo(
62
+ () => getVerticalLimits(pickOptions.maxHeight, pickOptions.minHeight, pickOptions.zoom),
63
+ [pickOptions.maxHeight, pickOptions.minHeight, pickOptions.zoom],
64
+ );
65
+
66
+ const groundIndicators = useMemo(() => {
67
+ const allSpaces = [...(spatialIdSpaces ?? []), ...(spaceSelector ? [spaceSelector] : [])];
68
+
69
+ if (!allSpaces) return null;
70
+ // find unique spaces by space.space.zfxy.z, space.space.zfxy.x, space.space.zfxy.y
71
+ const uniqueSpaces = allSpaces.reduce((acc, space) => {
72
+ if (
73
+ !acc.find(
74
+ s =>
75
+ s.space.zfxy.z === space.space.zfxy.z &&
76
+ s.space.zfxy.x === space.space.zfxy.x &&
77
+ s.space.zfxy.y === space.space.zfxy.y,
78
+ )
79
+ ) {
80
+ acc.push(space);
81
+ }
82
+ return acc;
83
+ }, [] as SpatialIdSpaceType[]);
84
+
85
+ if (uniqueSpaces.length === 0) return null;
86
+
87
+ return uniqueSpaces.map(space => {
88
+ const { wsen } = space;
89
+ return {
90
+ id: uuid(),
91
+ spaceId: space.space.id,
92
+ wsen,
93
+ color: pickOptions.groundIndicatorColor,
94
+ };
95
+ });
96
+ }, [spatialIdSpaces, spaceSelector, pickOptions.groundIndicatorColor]);
67
97
 
68
98
  const pickSpace = useCallback(
69
99
  (options?: SpatialIdPickSpaceOptions) => {
70
100
  setState("coordinate");
71
101
  setPickOptions(prev => ({ ...prev, ...options }));
72
102
  overrideInteractionMode?.("spatialId");
103
+ setTimeout(() => {
104
+ engineRef.current?.setCursor("crosshair");
105
+ }, 100);
73
106
  },
74
- [overrideInteractionMode],
107
+ [engineRef, overrideInteractionMode],
75
108
  );
76
109
 
77
110
  const interactionModeRef = useRef(interactionMode);
@@ -79,26 +112,30 @@ export default ({
79
112
 
80
113
  const finishPicking = useCallback(() => {
81
114
  setState("idle");
82
- setSelectorSpace(null);
83
115
  setBasePosition(null);
84
116
  setBaseCoordinate(null);
85
- setFloorSpaces([]);
117
+ setSpaceSelector(null);
118
+ setCoordinateSelector(null);
119
+ lastCoordinateSelector.current = null;
120
+ setVerticalSpaceIndicator(null);
86
121
  overrideInteractionMode?.(
87
122
  interactionModeRef.current === "spatialId"
88
123
  ? "default"
89
124
  : interactionModeRef.current ?? "default",
90
125
  );
126
+ engineRef.current?.setCursor("default");
91
127
  engineRef.current?.requestRender();
92
128
  }, [overrideInteractionMode, engineRef]);
93
129
 
94
- // handle events
95
130
  const handleMouseUp = useCallback(
96
131
  (props: MouseEventProps) => {
97
132
  if (state === "idle") return;
98
133
  if (tempSwitchToMoveMode.current) return;
99
134
 
135
+ // handle coordinate picking
100
136
  if (state === "coordinate") {
101
- if (!selectorSpace || props.lat === undefined || props.lng === undefined) return;
137
+ if (!coordinateSelector || props.lat === undefined || props.lng === undefined) return;
138
+
102
139
  setState("floor");
103
140
  setBaseCoordinate([props.lng, props.lat, terrainEnabled ? props.height ?? 0 : 0]);
104
141
  setBasePosition(
@@ -107,27 +144,48 @@ export default ({
107
144
  }) ?? null,
108
145
  );
109
146
 
110
- setSelectorSpace(prev =>
111
- prev ? { ...prev, type: "selector", color: pickOptions.color } : null,
147
+ lastCoordinateSelector.current = coordinateSelector;
148
+ setCoordinateSelector(null);
149
+
150
+ const initialSpaceSelectorSpace = createSpatialIdSpace(
151
+ props.lng,
152
+ props.lat,
153
+ terrainEnabled ? props.height ?? 0 : 0,
154
+ pickOptions.zoom,
112
155
  );
156
+ setSpaceSelector({
157
+ ...initialSpaceSelectorSpace,
158
+ color: pickOptions.color,
159
+ outlineColor: pickOptions.outlineColor,
160
+ });
113
161
 
114
- const floorSpaces = createSpatialIdFloorSpaces(
115
- selectorSpace.space,
116
- pickOptions.maxHeight,
117
- pickOptions.color,
162
+ const { id, wsen } = createSpatialIdSpace(
163
+ props.lng,
164
+ props.lat,
165
+ terrainEnabled ? props.height ?? 0 : 0,
166
+ pickOptions.zoom,
118
167
  );
119
- setFloorSpaces(floorSpaces);
168
+ setVerticalSpaceIndicator({
169
+ id,
170
+ wsen,
171
+ height: verticalLimits.top,
172
+ extrudedHeight: verticalLimits.bottom,
173
+ color: pickOptions.verticalSpaceIndicatorColor,
174
+ outlineColor: pickOptions.verticalSpaceIndicatorOutlineColor,
175
+ });
176
+ engineRef.current?.requestRender();
120
177
  } else if (state === "floor") {
121
- if (!selectorSpace) return;
178
+ if (!spaceSelector) return;
122
179
 
123
180
  const confirmedSpace: SpatialIdSpaceType = {
124
- ...selectorSpace,
125
- type: "confirmed",
181
+ ...spaceSelector,
182
+ id: uuid(),
126
183
  color: pickOptions.color,
184
+ outlineColor: pickOptions.outlineColor,
127
185
  };
128
186
 
129
187
  if (!pickOptions.dataOnly) {
130
- setSpatialIdSpaces(prev => [...prev, confirmedSpace]);
188
+ setSpatialIdSpaces(prev => (prev ? [...prev, confirmedSpace] : [confirmedSpace]));
131
189
  }
132
190
 
133
191
  finishPicking();
@@ -136,7 +194,16 @@ export default ({
136
194
  onSpacePickEvents.current.forEach(cb => cb(spaceData));
137
195
  }
138
196
  },
139
- [state, terrainEnabled, engineRef, selectorSpace, pickOptions, finishPicking],
197
+ [
198
+ state,
199
+ terrainEnabled,
200
+ engineRef,
201
+ spaceSelector,
202
+ pickOptions,
203
+ verticalLimits,
204
+ coordinateSelector,
205
+ finishPicking,
206
+ ],
140
207
  );
141
208
 
142
209
  const handleMouseMove = useCallback(
@@ -154,9 +221,13 @@ export default ({
154
221
  pickOptions.zoom,
155
222
  );
156
223
 
157
- if (newSpace.space.id === selectorSpace?.space.id) return;
158
-
159
- setSelectorSpace({ ...newSpace, type: "coordinate", color: pickOptions.color });
224
+ if (newSpace.space.id === coordinateSelector?.spaceId) return;
225
+ setCoordinateSelector({
226
+ id: uuid(),
227
+ spaceId: newSpace.space.id,
228
+ wsen: newSpace.wsen,
229
+ color: pickOptions.selectorColor,
230
+ });
160
231
  } else if (state === "floor") {
161
232
  if (
162
233
  props.x === undefined ||
@@ -166,40 +237,69 @@ export default ({
166
237
  )
167
238
  return;
168
239
 
169
- const height =
240
+ const offset =
170
241
  engineRef.current?.getExtrudedHeight(basePosition, [props.x, props.y], true) ?? 0;
171
242
 
172
- if (baseCoordinate[2] + height > pickOptions.maxHeight) return;
243
+ if (
244
+ baseCoordinate[2] + offset > verticalLimits.top ||
245
+ baseCoordinate[2] + offset < verticalLimits.bottom
246
+ )
247
+ return;
173
248
 
174
249
  const newSpace = createSpatialIdSpace(
175
250
  baseCoordinate[0],
176
251
  baseCoordinate[1],
177
- baseCoordinate[2] + height,
252
+ baseCoordinate[2] + offset,
178
253
  pickOptions.zoom,
179
254
  );
180
255
 
181
- if (newSpace.space.id === selectorSpace?.space.id || newSpace.space.zfxy.f < 0) return;
256
+ if (newSpace.space.id === spaceSelector?.space.id) return;
182
257
 
183
- setSelectorSpace({ ...newSpace, type: "selector", color: pickOptions.color });
258
+ setSpaceSelector({
259
+ ...newSpace,
260
+ color: pickOptions.selectorColor,
261
+ outlineColor: pickOptions.selectorOutlineColor,
262
+ });
184
263
  }
185
264
  },
186
- [state, selectorSpace, basePosition, baseCoordinate, engineRef, terrainEnabled, pickOptions],
265
+ [
266
+ state,
267
+ spaceSelector,
268
+ basePosition,
269
+ baseCoordinate,
270
+ engineRef,
271
+ terrainEnabled,
272
+ pickOptions,
273
+ verticalLimits,
274
+ coordinateSelector?.spaceId,
275
+ ],
187
276
  );
188
277
 
189
- const handleMouseRightClick = useCallback(() => {
278
+ const cancel = useCallback(() => {
190
279
  if (state === "idle") return;
191
280
  if (state === "coordinate" && pickOptions.rightClickToExit) {
192
281
  finishPicking();
193
282
  } else if (state === "floor") {
194
- setSelectorSpace(null);
283
+ setSpaceSelector(null);
195
284
  setBasePosition(null);
196
285
  setBaseCoordinate(null);
197
- setFloorSpaces([]);
286
+ setVerticalSpaceIndicator(null);
287
+ setCoordinateSelector(lastCoordinateSelector.current);
198
288
  setState("coordinate");
199
289
  }
200
290
  engineRef.current?.requestRender();
201
291
  }, [state, pickOptions, engineRef, finishPicking]);
202
292
 
293
+ const handleMouseRightClick = useCallback(() => {
294
+ cancel();
295
+ }, [cancel]);
296
+
297
+ useWindowEvent("keydown", event => {
298
+ if (event.code === "Escape") {
299
+ cancel();
300
+ }
301
+ });
302
+
203
303
  // bind mouse events
204
304
  const eventsBinded = useRef(false);
205
305
 
@@ -288,6 +388,10 @@ export default ({
288
388
  }, [onMount]);
289
389
 
290
390
  return {
291
- spaces,
391
+ spatialIdSpaces,
392
+ verticalSpaceIndicator,
393
+ coordinateSelector,
394
+ spaceSelector,
395
+ groundIndicators,
292
396
  };
293
397
  };
@@ -1,7 +1,10 @@
1
- import { forwardRef, ForwardRefRenderFunction } from "react";
2
- import { RefObject } from "use-callback-ref/dist/es5/types";
1
+ import { forwardRef, ForwardRefRenderFunction, RefObject } from "react";
3
2
 
4
- import SpatialIdSpace from "../../engines/Cesium/SpatialId";
3
+ import {
4
+ CoordinateIndicator,
5
+ SpatialIdSpace,
6
+ VerticalSpaceIndicator,
7
+ } from "../../engines/Cesium/SpatialId";
5
8
  import { InteractionModeType } from "../../Visualizer";
6
9
  import { EngineRef } from "../types";
7
10
 
@@ -20,7 +23,13 @@ const SpatialId: ForwardRefRenderFunction<SpatialIdRef, SpatialIdProps> = (
20
23
  { engineRef, terrainEnabled, interactionMode, overrideInteractionMode, onMount },
21
24
  ref,
22
25
  ) => {
23
- const { spaces } = useHooks({
26
+ const {
27
+ spatialIdSpaces,
28
+ verticalSpaceIndicator,
29
+ coordinateSelector,
30
+ spaceSelector,
31
+ groundIndicators,
32
+ } = useHooks({
24
33
  ref,
25
34
  engineRef,
26
35
  terrainEnabled,
@@ -28,9 +37,24 @@ const SpatialId: ForwardRefRenderFunction<SpatialIdRef, SpatialIdProps> = (
28
37
  overrideInteractionMode,
29
38
  onMount,
30
39
  });
31
- return spaces.length > 0
32
- ? spaces.map(space => <SpatialIdSpace key={space.id} space={space} />)
33
- : null;
40
+
41
+ return (
42
+ <>
43
+ {spatialIdSpaces &&
44
+ spatialIdSpaces.length > 0 &&
45
+ spatialIdSpaces.map(space => <SpatialIdSpace key={space.id} space={space} />)}
46
+ {groundIndicators &&
47
+ groundIndicators.length > 0 &&
48
+ groundIndicators.map(indicator => (
49
+ <CoordinateIndicator key={indicator.id} wsen={indicator.wsen} color={indicator.color} />
50
+ ))}
51
+ {verticalSpaceIndicator && <VerticalSpaceIndicator indicator={verticalSpaceIndicator} />}
52
+ {coordinateSelector && (
53
+ <CoordinateIndicator wsen={coordinateSelector.wsen} color={coordinateSelector.color} />
54
+ )}
55
+ {spaceSelector && <SpatialIdSpace space={spaceSelector} />}
56
+ </>
57
+ );
34
58
  };
35
59
 
36
60
  export default forwardRef(SpatialId);
@@ -6,16 +6,39 @@ export type SpatialIdSpaceType = {
6
6
  wsen: [number, number, number, number];
7
7
  height: number;
8
8
  extrudedHeight: number;
9
- type?: "selector" | "floor" | "coordinate" | "confirmed";
10
9
  color?: string;
10
+ outlineColor?: string;
11
+ };
12
+
13
+ export type VerticalSpaceIndicatorType = {
14
+ id: string;
15
+ wsen: [number, number, number, number];
16
+ height: number;
17
+ extrudedHeight: number;
18
+ color: string;
19
+ outlineColor: string;
20
+ };
21
+
22
+ export type CoordinateSelectorType = {
23
+ id: string;
24
+ spaceId: string;
25
+ wsen: [number, number, number, number];
26
+ color: string;
11
27
  };
12
28
 
13
29
  export type SpatialIdPickSpaceOptions = {
14
30
  zoom?: number;
15
31
  maxHeight?: number;
16
- color?: string;
32
+ minHeight?: number;
17
33
  dataOnly?: boolean;
18
34
  rightClickToExit?: boolean;
35
+ color?: string;
36
+ outlineColor?: string;
37
+ groundIndicatorColor?: string;
38
+ selectorColor?: string;
39
+ selectorOutlineColor?: string;
40
+ verticalSpaceIndicatorColor?: string;
41
+ verticalSpaceIndicatorOutlineColor?: string;
19
42
  };
20
43
 
21
44
  export type SpatialIdRef = {
@@ -1,7 +1,7 @@
1
- import { Space } from "@reearth/spatial-id-sdk";
2
1
  import { v4 as uuid } from "uuid";
3
2
 
4
- import { SPATIALID_DEFAULT_COLOR, SPATIALID_DEFAULT_MAX_HEIGHT } from "./hooks";
3
+ import { Space } from "@reearth/spatial-id-sdk";
4
+
5
5
  import { SpatialIdSpaceType, SpatialIdSpaceData } from "./types";
6
6
 
7
7
  const getRectangeParamsFromSpace = (space: Space) => {
@@ -35,34 +35,6 @@ export const createSpatialIdSpace = (
35
35
  };
36
36
  };
37
37
 
38
- export const createSpatialIdFloorSpaces = (
39
- space: Space,
40
- maxHeight = SPATIALID_DEFAULT_MAX_HEIGHT,
41
- color = SPATIALID_DEFAULT_COLOR,
42
- ) => {
43
- const floorSpaces: SpatialIdSpaceType[] = [];
44
- const { height, extrudedHeight } = getRectangeParamsFromSpace(space);
45
- const heightStep = extrudedHeight - height;
46
- for (let h = 0; h < maxHeight; h += heightStep) {
47
- const fSpace = new Space({ lat: space.center.lat, lng: space.center.lng, alt: h }, space.zoom);
48
- const {
49
- wsen: fWsen,
50
- height: fHeight,
51
- extrudedHeight: fExtrudedHeight,
52
- } = getRectangeParamsFromSpace(fSpace);
53
- floorSpaces.push({
54
- id: uuid(),
55
- space: fSpace,
56
- wsen: fWsen,
57
- height: fHeight,
58
- extrudedHeight: fExtrudedHeight,
59
- type: "floor",
60
- color,
61
- });
62
- }
63
- return floorSpaces;
64
- };
65
-
66
38
  export const getSpaceData = (space: Space): SpatialIdSpaceData => {
67
39
  return {
68
40
  id: space.id,
@@ -77,3 +49,16 @@ export const getSpaceData = (space: Space): SpatialIdSpaceData => {
77
49
  vertices: space.vertices3d(),
78
50
  };
79
51
  };
52
+
53
+ export const getVerticalLimits = (
54
+ maxHeigth: number,
55
+ minHeight: number,
56
+ zoom: number,
57
+ ): { top: number; bottom: number } => {
58
+ // lat/lng doesn't matter
59
+ const topSpace = new Space({ lat: 0, lng: 0, alt: maxHeigth }, zoom);
60
+ const bottomSpace = new Space({ lat: 0, lng: 0, alt: minHeight }, zoom);
61
+ const { height } = getRectangeParamsFromSpace(topSpace);
62
+ const { extrudedHeight } = getRectangeParamsFromSpace(bottomSpace);
63
+ return { top: height, bottom: extrudedHeight };
64
+ };
package/src/Map/hooks.ts CHANGED
@@ -14,7 +14,7 @@ import type {
14
14
  } from "./types";
15
15
  import useTimelineManager, { TimelineManagerRef } from "./useTimelineManager";
16
16
 
17
- import { CursorType, SketchEditingFeature } from ".";
17
+ import { SketchEditingFeature } from ".";
18
18
 
19
19
  export type { MapRef } from "./ref";
20
20
 
@@ -25,14 +25,12 @@ export const REQUEST_RENDER_ONCE = 1;
25
25
  export default function ({
26
26
  ref,
27
27
  timelineManagerRef,
28
- cursor,
29
28
  onLayerSelect,
30
29
  onMount,
31
30
  onAPIReady,
32
31
  }: {
33
32
  ref: Ref<MapRef>;
34
33
  timelineManagerRef?: TimelineManagerRef;
35
- cursor?: CursorType;
36
34
  onLayerSelect?: (
37
35
  layerId: string | undefined,
38
36
  featureId: string | undefined,
@@ -130,12 +128,6 @@ export default function ({
130
128
  timelineManagerRef,
131
129
  });
132
130
 
133
- useEffect(() => {
134
- if (cursor) {
135
- engineRef.current?.setCursor(cursor);
136
- }
137
- }, [cursor]);
138
-
139
131
  const [sketchEditingFeature, setSketchEditingFeature] = useState<
140
132
  SketchEditingFeature | undefined
141
133
  >();