@reearth/core 0.0.7-alpha.42 → 0.0.7-alpha.44
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 +1428 -1418
- package/dist/core.umd.cjs +30 -30
- package/package.json +1 -1
- package/src/Visualizer/hooks.ts +1 -1
- package/src/engines/Cesium/Feature/Tileset/hooks.ts +16 -8
- package/src/engines/Cesium/core/Imagery.test.ts +29 -11
- package/src/engines/Cesium/core/Imagery.tsx +11 -8
- package/src/engines/Cesium/core/presets.ts +19 -6
package/package.json
CHANGED
package/src/Visualizer/hooks.ts
CHANGED
|
@@ -82,7 +82,7 @@ export default function useHooks(
|
|
|
82
82
|
info: SelectedFeatureInfo | undefined,
|
|
83
83
|
) => {
|
|
84
84
|
const isSketchLayer =
|
|
85
|
-
selectedLayer.layer?.layer
|
|
85
|
+
selectedLayer.layer?.layer?.type === "simple" &&
|
|
86
86
|
selectedLayer.layer?.layer?.data?.isSketchLayer;
|
|
87
87
|
// Sketch layer feature has a fixed featureId, we need to exclude it from the skip condition
|
|
88
88
|
if (
|
|
@@ -177,7 +177,7 @@ const convertStyle = (val: any, convert: StyleProperty["convert"]) => {
|
|
|
177
177
|
|
|
178
178
|
const useFeature = ({
|
|
179
179
|
id,
|
|
180
|
-
|
|
180
|
+
tilesetRef,
|
|
181
181
|
idProperty,
|
|
182
182
|
layer,
|
|
183
183
|
viewer,
|
|
@@ -189,7 +189,7 @@ const useFeature = ({
|
|
|
189
189
|
isTilesetReady,
|
|
190
190
|
}: {
|
|
191
191
|
id?: string;
|
|
192
|
-
|
|
192
|
+
tilesetRef: MutableRefObject<Cesium3DTileset | undefined>;
|
|
193
193
|
idProperty?: string;
|
|
194
194
|
layer?: ComputedLayer;
|
|
195
195
|
viewer?: Viewer;
|
|
@@ -327,10 +327,10 @@ const useFeature = ({
|
|
|
327
327
|
handleTilesetLoadRef.current = handleTilesetLoad;
|
|
328
328
|
useEffect(
|
|
329
329
|
() =>
|
|
330
|
-
|
|
330
|
+
tilesetRef.current?.tileLoad.addEventListener((t: Cesium3DTile) =>
|
|
331
331
|
handleTilesetLoadRef.current(t),
|
|
332
332
|
),
|
|
333
|
-
[
|
|
333
|
+
[tilesetRef, isTilesetReady],
|
|
334
334
|
);
|
|
335
335
|
|
|
336
336
|
const handleTilesetUnload = useCallback(
|
|
@@ -346,10 +346,10 @@ const useFeature = ({
|
|
|
346
346
|
handleTilesetUnloadRef.current = handleTilesetUnload;
|
|
347
347
|
useEffect(
|
|
348
348
|
() =>
|
|
349
|
-
|
|
349
|
+
tilesetRef.current?.tileUnload.addEventListener((t: Cesium3DTile) =>
|
|
350
350
|
handleTilesetUnloadRef.current(t),
|
|
351
351
|
),
|
|
352
|
-
[
|
|
352
|
+
[tilesetRef, isTilesetReady],
|
|
353
353
|
);
|
|
354
354
|
|
|
355
355
|
useEffect(() => {
|
|
@@ -487,6 +487,8 @@ export const useHooks = ({
|
|
|
487
487
|
const shouldUseFeatureIndex = !disableIndexingFeature && !!idProperty;
|
|
488
488
|
|
|
489
489
|
const [isTilesetReady, setIsTilesetReady] = useState(false);
|
|
490
|
+
const [isTilesetCompReady, setIsTilesetCompReady] = useState(false);
|
|
491
|
+
const [isTilesetRefReady, setIsTilesetRefReady] = useState(false);
|
|
490
492
|
|
|
491
493
|
const prevPlanes = useRef(_planes);
|
|
492
494
|
const planes = useMemo(() => {
|
|
@@ -566,6 +568,7 @@ export const useHooks = ({
|
|
|
566
568
|
(tileset?.cesiumElement as any)[layerIdField] = layer.id;
|
|
567
569
|
}
|
|
568
570
|
tilesetRef.current = tileset?.cesiumElement;
|
|
571
|
+
setIsTilesetRefReady(!!tileset?.cesiumElement);
|
|
569
572
|
},
|
|
570
573
|
[id, layer?.id, featureIndex, shouldUseFeatureIndex],
|
|
571
574
|
);
|
|
@@ -602,7 +605,7 @@ export const useHooks = ({
|
|
|
602
605
|
|
|
603
606
|
useFeature({
|
|
604
607
|
id,
|
|
605
|
-
|
|
608
|
+
tilesetRef,
|
|
606
609
|
layer,
|
|
607
610
|
idProperty,
|
|
608
611
|
viewer,
|
|
@@ -806,13 +809,18 @@ export const useHooks = ({
|
|
|
806
809
|
|
|
807
810
|
const handleReady = useCallback(
|
|
808
811
|
(tileset: Cesium3DTileset) => {
|
|
809
|
-
|
|
812
|
+
setIsTilesetCompReady(true);
|
|
810
813
|
onLayerFetch?.({ properties: tileset.properties });
|
|
811
814
|
onLayerLoad?.({ layerId: layerIdRef.current });
|
|
812
815
|
},
|
|
813
816
|
[onLayerFetch, onLayerLoad],
|
|
814
817
|
);
|
|
815
818
|
|
|
819
|
+
useEffect(() => {
|
|
820
|
+
if (!isTilesetCompReady || !isTilesetRefReady) return;
|
|
821
|
+
setIsTilesetReady(true);
|
|
822
|
+
}, [isTilesetCompReady, isTilesetRefReady]);
|
|
823
|
+
|
|
816
824
|
useEffect(() => {
|
|
817
825
|
updateCredits?.();
|
|
818
826
|
return () => {
|
|
@@ -6,7 +6,7 @@ import { type Tile, useImageryProviders } from "./Imagery";
|
|
|
6
6
|
test("useImageryProviders", () => {
|
|
7
7
|
const provider = vi.fn(({ url }: { url?: string } = {}): any => ({ hoge: url }));
|
|
8
8
|
const provider2 = vi.fn(({ url }: { url?: string } = {}): any => ({ hoge2: url }));
|
|
9
|
-
const presets = { default: provider,
|
|
9
|
+
const presets = { default: provider, default_label: provider2 };
|
|
10
10
|
const { result, rerender } = renderHook(
|
|
11
11
|
({ tiles, cesiumIonAccessToken }: { tiles: Tile[]; cesiumIonAccessToken?: string }) =>
|
|
12
12
|
useImageryProviders({
|
|
@@ -14,23 +14,28 @@ test("useImageryProviders", () => {
|
|
|
14
14
|
presets,
|
|
15
15
|
cesiumIonAccessToken,
|
|
16
16
|
}),
|
|
17
|
-
{ initialProps: { tiles: [{ id: "1", type: "default" }] } },
|
|
17
|
+
{ initialProps: { tiles: [{ id: "1", type: "default" }], cesiumIonAccessToken: undefined } },
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
+
const typedRerender = rerender as (props: {
|
|
21
|
+
tiles: Tile[];
|
|
22
|
+
cesiumIonAccessToken?: string;
|
|
23
|
+
}) => void;
|
|
24
|
+
|
|
20
25
|
expect(result.current.providers).toEqual({ "1": ["default", undefined, { hoge: undefined }] });
|
|
21
26
|
expect(result.current.updated).toBe(true);
|
|
22
27
|
expect(provider).toBeCalledTimes(1);
|
|
23
28
|
const prevImageryProvider = result.current.providers["1"][2];
|
|
24
29
|
|
|
25
30
|
// re-render with same tiles
|
|
26
|
-
|
|
31
|
+
typedRerender({ tiles: [{ id: "1", type: "default" }] });
|
|
27
32
|
|
|
28
33
|
expect(result.current.providers).toEqual({ "1": ["default", undefined, { hoge: undefined }] });
|
|
29
34
|
expect(result.current.providers["1"][2]).toBe(prevImageryProvider); // 1's provider should be reused
|
|
30
35
|
expect(provider).toBeCalledTimes(1);
|
|
31
36
|
|
|
32
37
|
// update a tile URL
|
|
33
|
-
|
|
38
|
+
typedRerender({ tiles: [{ id: "1", type: "default", url: "a" }] });
|
|
34
39
|
|
|
35
40
|
expect(result.current.providers).toEqual({ "1": ["default", "a", { hoge: "a" }] });
|
|
36
41
|
expect(result.current.providers["1"][2]).not.toBe(prevImageryProvider);
|
|
@@ -40,7 +45,7 @@ test("useImageryProviders", () => {
|
|
|
40
45
|
const prevImageryProvider2 = result.current.providers["1"][2];
|
|
41
46
|
|
|
42
47
|
// add a tile with URL
|
|
43
|
-
|
|
48
|
+
typedRerender({
|
|
44
49
|
tiles: [
|
|
45
50
|
{ id: "2", type: "default" },
|
|
46
51
|
{ id: "1", type: "default", url: "a" },
|
|
@@ -56,7 +61,7 @@ test("useImageryProviders", () => {
|
|
|
56
61
|
expect(provider).toBeCalledTimes(3);
|
|
57
62
|
|
|
58
63
|
// sort tiles
|
|
59
|
-
|
|
64
|
+
typedRerender({
|
|
60
65
|
tiles: [
|
|
61
66
|
{ id: "1", type: "default", url: "a" },
|
|
62
67
|
{ id: "2", type: "default" },
|
|
@@ -72,7 +77,7 @@ test("useImageryProviders", () => {
|
|
|
72
77
|
expect(provider).toBeCalledTimes(3);
|
|
73
78
|
|
|
74
79
|
// delete a tile
|
|
75
|
-
|
|
80
|
+
typedRerender({
|
|
76
81
|
tiles: [{ id: "1", type: "default", url: "a" }],
|
|
77
82
|
cesiumIonAccessToken: "a",
|
|
78
83
|
});
|
|
@@ -85,18 +90,31 @@ test("useImageryProviders", () => {
|
|
|
85
90
|
expect(provider).toBeCalledTimes(4);
|
|
86
91
|
|
|
87
92
|
// update a tile type
|
|
88
|
-
|
|
89
|
-
tiles: [{ id: "1", type: "
|
|
93
|
+
typedRerender({
|
|
94
|
+
tiles: [{ id: "1", type: "default_label", url: "u" }],
|
|
90
95
|
cesiumIonAccessToken: "a",
|
|
91
96
|
});
|
|
92
97
|
|
|
93
98
|
expect(result.current.providers).toEqual({
|
|
94
|
-
"1": ["
|
|
99
|
+
"1": ["default_label", "u", { hoge2: "u" }],
|
|
95
100
|
});
|
|
96
101
|
expect(result.current.updated).toBe(true);
|
|
97
102
|
expect(provider).toBeCalledTimes(4);
|
|
98
103
|
expect(provider2).toBeCalledTimes(1);
|
|
99
104
|
|
|
100
|
-
|
|
105
|
+
// update a tile type to unexpected type
|
|
106
|
+
typedRerender({
|
|
107
|
+
tiles: [{ id: "1", type: "unexpected_type", url: "u" }],
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
expect(result.current.providers).toEqual({
|
|
111
|
+
// unexpected type is treated as "default"
|
|
112
|
+
"1": ["unexpected_type", "u", { hoge: "u" }],
|
|
113
|
+
});
|
|
114
|
+
expect(result.current.updated).toBe(true);
|
|
115
|
+
expect(provider).toBeCalledTimes(5);
|
|
116
|
+
expect(provider2).toBeCalledTimes(1);
|
|
117
|
+
|
|
118
|
+
typedRerender({ tiles: [] });
|
|
101
119
|
expect(result.current.providers).toEqual({});
|
|
102
120
|
});
|
|
@@ -8,7 +8,7 @@ import { isEqual } from "lodash-es";
|
|
|
8
8
|
import { useCallback, useMemo, useRef, useLayoutEffect, useState, useEffect } from "react";
|
|
9
9
|
import { ImageryLayer } from "resium";
|
|
10
10
|
|
|
11
|
-
import { tiles as tilePresets } from "./presets";
|
|
11
|
+
import { isValidPresetTileType, PresetTileType, tiles as tilePresets } from "./presets";
|
|
12
12
|
|
|
13
13
|
export type ImageryLayerData = {
|
|
14
14
|
id: string;
|
|
@@ -90,7 +90,7 @@ export function useImageryProviders({
|
|
|
90
90
|
tiles?: Tile[];
|
|
91
91
|
cesiumIonAccessToken?: string;
|
|
92
92
|
presets: {
|
|
93
|
-
[
|
|
93
|
+
[K in PresetTileType]: (opts?: {
|
|
94
94
|
url?: string;
|
|
95
95
|
cesiumIonAccessToken?: string;
|
|
96
96
|
heatmap?: boolean;
|
|
@@ -100,7 +100,7 @@ export function useImageryProviders({
|
|
|
100
100
|
}): { providers: Providers; updated: boolean } {
|
|
101
101
|
const newTile = useCallback(
|
|
102
102
|
(t: Tile, ciat?: string) =>
|
|
103
|
-
presets[t.type
|
|
103
|
+
presets[isValidPresetTileType(t.type) ? t.type : "default"]({
|
|
104
104
|
url: t.url,
|
|
105
105
|
cesiumIonAccessToken: ciat,
|
|
106
106
|
heatmap: t.heatmap,
|
|
@@ -113,11 +113,14 @@ export function useImageryProviders({
|
|
|
113
113
|
const tileKeys = tiles.map(t => t.id).join(",");
|
|
114
114
|
const prevTileKeys = useRef(tileKeys);
|
|
115
115
|
const prevProviders = useRef<Providers>({});
|
|
116
|
-
const zoomLevels = useMemo(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
const zoomLevels = useMemo(
|
|
117
|
+
() =>
|
|
118
|
+
tiles.map(t => {
|
|
119
|
+
if (t.id && t.zoomLevel) return { [t.id]: t.zoomLevel };
|
|
120
|
+
return;
|
|
121
|
+
}),
|
|
122
|
+
[tiles],
|
|
123
|
+
);
|
|
121
124
|
const prevZoomLevels = useRef(zoomLevels);
|
|
122
125
|
|
|
123
126
|
// Manage TileProviders so that TileProvider does not need to be recreated each time tiles are updated.
|
|
@@ -10,6 +10,22 @@ import {
|
|
|
10
10
|
|
|
11
11
|
import { JapanGSIOptimalBVmapLabelImageryProvider } from "./labels/JapanGSIOptimalBVmapVectorMapLabel/JapanGSIOptimalBVmapLabelImageryProvider";
|
|
12
12
|
|
|
13
|
+
const PRESET_TILE_TYPES = [
|
|
14
|
+
"default",
|
|
15
|
+
"default_label",
|
|
16
|
+
"default_road",
|
|
17
|
+
"open_street_map",
|
|
18
|
+
"black_marble",
|
|
19
|
+
"japan_gsi_standard",
|
|
20
|
+
"url",
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export type PresetTileType = (typeof PRESET_TILE_TYPES)[number];
|
|
24
|
+
|
|
25
|
+
export const isValidPresetTileType = (type: string | undefined): type is PresetTileType => {
|
|
26
|
+
return PRESET_TILE_TYPES.includes(type as PresetTileType);
|
|
27
|
+
};
|
|
28
|
+
|
|
13
29
|
export const tiles = {
|
|
14
30
|
default: ({ cesiumIonAccessToken } = {}) =>
|
|
15
31
|
IonImageryProvider.fromAssetId(IonWorldImageryStyle.AERIAL, {
|
|
@@ -26,8 +42,7 @@ export const tiles = {
|
|
|
26
42
|
open_street_map: () =>
|
|
27
43
|
new OpenStreetMapImageryProvider({
|
|
28
44
|
url: "https://tile.openstreetmap.org",
|
|
29
|
-
credit:
|
|
30
|
-
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
45
|
+
credit: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
31
46
|
}),
|
|
32
47
|
black_marble: ({ cesiumIonAccessToken } = {}) =>
|
|
33
48
|
IonImageryProvider.fromAssetId(3812, {
|
|
@@ -43,15 +58,13 @@ export const tiles = {
|
|
|
43
58
|
url
|
|
44
59
|
? new UrlTemplateImageryProvider({
|
|
45
60
|
url,
|
|
46
|
-
tileDiscardPolicy: heatmap
|
|
47
|
-
? new DiscardEmptyTileImagePolicy()
|
|
48
|
-
: undefined,
|
|
61
|
+
tileDiscardPolicy: heatmap ? new DiscardEmptyTileImagePolicy() : undefined,
|
|
49
62
|
minimumLevel: tile_zoomLevel?.[0],
|
|
50
63
|
maximumLevel: tile_zoomLevel?.[1],
|
|
51
64
|
})
|
|
52
65
|
: null,
|
|
53
66
|
} as {
|
|
54
|
-
[
|
|
67
|
+
[K in PresetTileType]: (opts?: {
|
|
55
68
|
url?: string;
|
|
56
69
|
cesiumIonAccessToken?: string;
|
|
57
70
|
heatmap?: boolean;
|