Skip to content

Commit

Permalink
feat(web): support for spatial id (#1331)
Browse files Browse the repository at this point in the history
Co-authored-by: mkumbobeaty <[email protected]>
  • Loading branch information
airslice and mkumbobeaty authored Jan 10, 2025
1 parent 9e409d9 commit 9441b7b
Show file tree
Hide file tree
Showing 15 changed files with 1,526 additions and 868 deletions.
2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
"@monaco-editor/react": "4.6.0",
"@popperjs/core": "2.11.8",
"@radix-ui/react-slot": "1.1.0",
"@reearth/core": "0.0.7-alpha.23",
"@reearth/core": "0.0.7-alpha.26",
"@rot1024/use-transition": "1.0.0",
"@sentry/browser": "7.77.0",
"@seznam/compose-react-refs": "1.0.6",
Expand Down
29 changes: 27 additions & 2 deletions web/src/beta/features/Visualizer/Crust/Plugins/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import useData from "./useData";
import useExtension from "./useExtension";
import useLayers from "./useLayers";
import useSketch from "./useSketch";
import useSpatialId from "./useSpatialId";
import useTimeline from "./useTimeline";
import useViewer from "./useViewer";

export default function ({
engineName,
mapRef,
mapAPIReady,
viewerProperty,
inEditor,
built,
Expand Down Expand Up @@ -145,6 +147,17 @@ export default function ({
onSketchTypeChange
});

const {
spatialIdPickSpace,
spatialIdExitPickSpace,
spatialIdEventsOn,
spatialIdEventsOff,
spatialIdEvents
} = useSpatialId({
mapRef,
mapAPIReady
});

const { pluginInstances, getExtensionList } = useExtension({
alignSystem,
floatingWidgets,
Expand Down Expand Up @@ -230,6 +243,12 @@ export default function ({
// sketch events
sketchEventsOn,
sketchEventsOff,
// spatialId
spatialIdPickSpace,
spatialIdExitPickSpace,
// spatialId events
spatialIdEventsOn,
spatialIdEventsOff,
// extension
getExtensionList
}),
Expand All @@ -242,7 +261,8 @@ export default function ({
cameraEvents,
timelineEvents,
layersEvents,
sketchEvents
sketchEvents,
spatialIdEvents
}),
[
engineName,
Expand Down Expand Up @@ -308,6 +328,10 @@ export default function ({
overrideSketchOptions,
sketchEventsOn,
sketchEventsOff,
spatialIdPickSpace,
spatialIdExitPickSpace,
spatialIdEventsOn,
spatialIdEventsOff,
getExtensionList,
overrideViewerProperty,
pluginInstances,
Expand All @@ -318,7 +342,8 @@ export default function ({
cameraEvents,
timelineEvents,
layersEvents,
sketchEvents
sketchEvents,
spatialIdEvents
]
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useCallback, useEffect, useMemo, useRef } from "react";

import {
SpatialIdEventType,
SpatialIdPickSpaceOptions
} from "../pluginAPI/types";
import { Props } from "../types";
import { events } from "../utils/events";

export default ({
mapRef,
mapAPIReady
}: Pick<Props, "mapRef" | "mapAPIReady">) => {
const spatialIdPickSpace = useCallback(
(options?: SpatialIdPickSpaceOptions) => {
mapRef?.current?.spatialId?.pickSpace(options);
},
[mapRef]
);

const spatialIdExitPickSpace = useCallback(() => {
mapRef?.current?.spatialId?.exitPickSpace();
}, [mapRef]);

const [spatialIdEvents, emit] = useMemo(
() => events<SpatialIdEventType>(),
[]
);

const spacePickEventBinded = useRef(false);
useEffect(() => {
if (
mapAPIReady &&
!spacePickEventBinded.current &&
mapRef?.current?.spatialId?.onSpacePick
) {
mapRef.current.spatialId.onSpacePick((e) => {
emit("spacePick", e);
});
spacePickEventBinded.current = true;
}
}, [emit, mapRef, mapAPIReady]);

const spatialIdEventsOn = useCallback(
<T extends keyof SpatialIdEventType>(
type: T,
callback: (...args: SpatialIdEventType[T]) => void,
options?: { once?: boolean }
) => {
return options?.once
? spatialIdEvents.once(type, callback)
: spatialIdEvents.on(type, callback);
},
[spatialIdEvents]
);

const spatialIdEventsOff = useCallback(
<T extends keyof SpatialIdEventType>(
type: T,
callback: (...args: SpatialIdEventType[T]) => void
) => {
return spatialIdEvents.off(type, callback);
},
[spatialIdEvents]
);

return {
spatialIdPickSpace,
spatialIdExitPickSpace,
spatialIdEventsOn,
spatialIdEventsOff,
spatialIdEvents
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ export function commonReearth({
// sketch events
sketchEventsOn,
sketchEventsOff,
// spatialId
spatialIdPickSpace,
spatialIdExitPickSpace,
// spatialId events
spatialIdEventsOn,
spatialIdEventsOff,
// extension
getExtensionList
}: {
Expand Down Expand Up @@ -166,6 +172,12 @@ export function commonReearth({
// sketch events
sketchEventsOn: GlobalThis["reearth"]["sketch"]["on"];
sketchEventsOff: GlobalThis["reearth"]["sketch"]["off"];
// spatialId
spatialIdPickSpace: GlobalThis["reearth"]["spatialId"]["pickSpace"];
spatialIdExitPickSpace: GlobalThis["reearth"]["spatialId"]["exitPickSpace"];
// spatialId events
spatialIdEventsOn: GlobalThis["reearth"]["spatialId"]["on"];
spatialIdEventsOff: GlobalThis["reearth"]["spatialId"]["off"];
// extension
getExtensionList: () => GlobalThis["reearth"]["extension"]["list"];
}): CommonReearth {
Expand Down Expand Up @@ -335,6 +347,16 @@ export function commonReearth({
on: sketchEventsOn,
off: sketchEventsOff
},
spatialId: {
get pickSpace() {
return spatialIdPickSpace;
},
get exitPickSpace() {
return spatialIdExitPickSpace;
},
on: spatialIdEventsOn,
off: spatialIdEventsOff
},
extension: {
get list() {
return getExtensionList();
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const REEATH_PLUGIN_API_VERSION = "2.0.0";
export const REEATH_PLUGIN_API_VERSION = "2.1.0";
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export * from "./modal";
export * from "./popup";
export * from "./extension";
export * from "./data";
export * from "./spatialId";
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Layers } from "./layers";
import { Modal } from "./modal";
import { Popup } from "./popup";
import { Sketch } from "./sketch";
import { SpatialId } from "./spatialId";
import { Timeline } from "./timeline";
import { UI } from "./ui";
import { Viewer } from "./viewer";
Expand All @@ -21,6 +22,7 @@ export declare type Reearth = {
readonly timeline: Timeline;
// functions
readonly sketch: Sketch;
readonly spatialId: SpatialId;
// layers
readonly layers: Layers;
// ui
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
export declare type SpatialId = {
pickSpace: (options?: SpatialIdPickSpaceOptions) => void;
exitPickSpace: () => void;
on: SpatialIdEvents["on"];
off: SpatialIdEvents["off"];
};

export declare type SpatialIdPickSpaceOptions = {
zoom?: number;
maxHeight?: number;
color?: string;
dataOnly?: boolean;
rightClickToExit?: boolean;
};

export declare type SpatialIdSpacePickProps = SpatialIdSpaceData;

export declare type SpatialIdSpaceData = {
id: string;
center: { lat: number; lng: number; alt?: number };
alt: number;
zoom: number;
zfxy: {
z: number;
f: number;
x: number;
y: number;
};
zfxyStr: string;
tilehash: string;
hilbertTilehash: string;
hilbertIndex: string;
vertices: [number, number, number][];
};

export declare type SpatialIdEventType = {
spacePick: [props: SpatialIdSpacePickProps];
};

export declare type SpatialIdEvents = {
readonly on: <T extends keyof SpatialIdEventType>(
type: T,
callback: (...args: SpatialIdEventType[T]) => void,
options?: { once?: boolean }
) => void;
readonly off: <T extends keyof SpatialIdEventType>(
type: T,
callback: (...args: SpatialIdEventType[T]) => void
) => void;
};
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export declare type InteractionModeType =
| "default"
| "move"
| "selection"
| "sketch";
| "sketch"
| "spatialId";

export declare type Viewer = {
readonly property: ViewerProperty | undefined;
Expand Down
6 changes: 6 additions & 0 deletions web/src/beta/features/Visualizer/Crust/Plugins/storybook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ export const context: Context = {
on: act("on"),
off: act("off")
},
spatialId: {
pickSpace: act("pickSpace"),
exitPickSpace: act("exitPickSpace"),
on: act("on"),
off: act("off")
},
layers: {
layers,
hide: act("layers.hide"),
Expand Down
1 change: 1 addition & 0 deletions web/src/beta/features/Visualizer/Crust/Plugins/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { Events } from "./utils/events";
export type Props = PropsWithChildren<{
engineName?: string;
mapRef?: RefObject<MapRef>;
mapAPIReady?: boolean;
viewerProperty?: ViewerProperty;
inEditor?: boolean;
built?: boolean;
Expand Down
3 changes: 3 additions & 0 deletions web/src/beta/features/Visualizer/Crust/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export type Props = {
inEditor?: boolean;
isBuilt?: boolean;
mapRef?: RefObject<MapRef>;
mapAPIReady?: boolean;
layers?: Layer[];
camera?: Camera;
selectedFeatureInfo?: SelectedFeatureInfo;
Expand Down Expand Up @@ -159,6 +160,7 @@ export default function Crust({
isEditable,
inEditor,
mapRef,
mapAPIReady,
selectedFeatureInfo,
externalPlugin,
layers,
Expand Down Expand Up @@ -274,6 +276,7 @@ export default function Crust({
<Plugins
engineName={engineName}
mapRef={mapRef}
mapAPIReady={mapAPIReady}
viewerProperty={viewerProperty}
built={isBuilt}
inEditor={inEditor}
Expand Down
16 changes: 13 additions & 3 deletions web/src/beta/features/Visualizer/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Camera } from "@reearth/beta/utils/value";
import { ViewerProperty, ComputedFeature, ComputedLayer } from "@reearth/core";
import { useCallback, useLayoutEffect, useMemo, useRef } from "react";
import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";

import { useVisualizerCamera } from "./atoms";
import { BuiltinWidgets } from "./Crust";
Expand All @@ -11,7 +11,8 @@ export default function useHooks({
ownBuiltinWidgets,
viewerProperty,
onCoreLayerSelect,
currentCamera
currentCamera,
handleCoreAPIReady
}: {
ownBuiltinWidgets?: (keyof BuiltinWidgets)[];
viewerProperty?: ViewerProperty;
Expand All @@ -21,6 +22,7 @@ export default function useHooks({
feature: ComputedFeature | undefined
) => void;
currentCamera?: Camera;
handleCoreAPIReady?: () => void;
}) {
const shouldRender = useMemo(() => {
const shouldWidgetAnimate = ownBuiltinWidgets?.some(
Expand Down Expand Up @@ -53,12 +55,20 @@ export default function useHooks({
};
}, [currentCamera, setVisualizerCamera]);

const [mapAPIReady, setMapAPIReady] = useState(false);
const onCoreAPIReady = useCallback(() => {
setMapAPIReady(true);
handleCoreAPIReady?.();
}, [handleCoreAPIReady]);

return {
shouldRender,
overriddenViewerProperty,
overrideViewerProperty,
storyWrapperRef,
visualizerCamera,
handleCoreLayerSelect
handleCoreLayerSelect,
mapAPIReady,
onCoreAPIReady
};
}
Loading

0 comments on commit 9441b7b

Please sign in to comment.