@reearth/core 0.0.7-alpha.64 → 0.0.7-alpha.66
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 +6738 -6679
- package/dist/core.umd.cjs +100 -100
- package/package.json +1 -1
- package/src/engines/Cesium/Feature/Tileset/hooks.ts +113 -20
- package/src/engines/Cesium/Feature/Tileset/index.tsx +7 -14
- package/src/engines/Cesium/Feature/index.tsx +17 -5
package/package.json
CHANGED
|
@@ -23,7 +23,15 @@ import {
|
|
|
23
23
|
createGooglePhotorealistic3DTileset,
|
|
24
24
|
} from "cesium";
|
|
25
25
|
import { pick } from "lodash-es";
|
|
26
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
MutableRefObject,
|
|
28
|
+
useCallback,
|
|
29
|
+
useEffect,
|
|
30
|
+
useLayoutEffect,
|
|
31
|
+
useMemo,
|
|
32
|
+
useRef,
|
|
33
|
+
useState,
|
|
34
|
+
} from "react";
|
|
27
35
|
import { CesiumComponentRef, useCesium } from "resium";
|
|
28
36
|
|
|
29
37
|
import type {
|
|
@@ -490,12 +498,53 @@ export const useHooks = ({
|
|
|
490
498
|
|
|
491
499
|
const [style, setStyle] = useState<Cesium3DTileStyle>();
|
|
492
500
|
const { url, type, idProperty, googleMapApiKey, provider } = useData(layer);
|
|
501
|
+
const cesiumIonAccessToken =
|
|
502
|
+
typeof meta?.cesiumIonAccessToken === "string" ? meta.cesiumIonAccessToken : undefined;
|
|
493
503
|
const shouldUseFeatureIndex = !disableIndexingFeature && !!idProperty;
|
|
494
504
|
|
|
495
505
|
const [isTilesetReady, setIsTilesetReady] = useState(false);
|
|
496
506
|
const [isTilesetCompReady, setIsTilesetCompReady] = useState(false);
|
|
497
507
|
const [isTilesetRefReady, setIsTilesetRefReady] = useState(false);
|
|
498
508
|
|
|
509
|
+
const reearthGooglePhotorealisticUrl = useMemo(
|
|
510
|
+
() =>
|
|
511
|
+
customProvider?.layers?.providers?.find(
|
|
512
|
+
p => p.id === "reearth_google_photorealistic_3d_tiles",
|
|
513
|
+
)?.url,
|
|
514
|
+
[customProvider],
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
const tilesetKey = useMemo(
|
|
518
|
+
() =>
|
|
519
|
+
generateIDWithMD5(
|
|
520
|
+
JSON.stringify({
|
|
521
|
+
type,
|
|
522
|
+
url,
|
|
523
|
+
tileset,
|
|
524
|
+
provider,
|
|
525
|
+
googleMapApiKey,
|
|
526
|
+
reearthGooglePhotorealisticUrl,
|
|
527
|
+
cesiumIonAccessToken:
|
|
528
|
+
type === "osm-buildings" ||
|
|
529
|
+
(type === "google-photorealistic" && (provider === "cesium-ion" || !googleMapApiKey))
|
|
530
|
+
? cesiumIonAccessToken
|
|
531
|
+
: undefined,
|
|
532
|
+
}),
|
|
533
|
+
),
|
|
534
|
+
[
|
|
535
|
+
type,
|
|
536
|
+
url,
|
|
537
|
+
tileset,
|
|
538
|
+
provider,
|
|
539
|
+
googleMapApiKey,
|
|
540
|
+
reearthGooglePhotorealisticUrl,
|
|
541
|
+
cesiumIonAccessToken,
|
|
542
|
+
],
|
|
543
|
+
);
|
|
544
|
+
const currentTilesetKeyRef = useRef(tilesetKey);
|
|
545
|
+
currentTilesetKeyRef.current = tilesetKey;
|
|
546
|
+
const tilesetRefKeyRef = useRef<string | undefined>(undefined);
|
|
547
|
+
|
|
499
548
|
const prevPlanes = useRef(_planes);
|
|
500
549
|
const planes = useMemo(() => {
|
|
501
550
|
if (
|
|
@@ -563,20 +612,25 @@ export const useHooks = ({
|
|
|
563
612
|
|
|
564
613
|
const ref = useCallback(
|
|
565
614
|
(tileset: CesiumComponentRef<Cesium3DTilesetType> | null) => {
|
|
566
|
-
|
|
567
|
-
|
|
615
|
+
const cesiumElement = tileset?.cesiumElement;
|
|
616
|
+
if (tilesetKey !== currentTilesetKeyRef.current) {
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
if (cesiumElement) {
|
|
620
|
+
attachTag(cesiumElement, {
|
|
568
621
|
layerId: layer?.id || id,
|
|
569
622
|
featureIndex: shouldUseFeatureIndex ? featureIndex : undefined,
|
|
570
623
|
appearanceType: "3dtiles",
|
|
571
624
|
});
|
|
572
625
|
}
|
|
573
|
-
if (layer?.id &&
|
|
574
|
-
(
|
|
626
|
+
if (layer?.id && cesiumElement) {
|
|
627
|
+
(cesiumElement as any)[layerIdField] = layer.id;
|
|
575
628
|
}
|
|
576
|
-
tilesetRef.current =
|
|
577
|
-
|
|
629
|
+
tilesetRef.current = cesiumElement;
|
|
630
|
+
tilesetRefKeyRef.current = cesiumElement ? tilesetKey : undefined;
|
|
631
|
+
setIsTilesetRefReady(!!cesiumElement);
|
|
578
632
|
},
|
|
579
|
-
[id, layer?.id, featureIndex, shouldUseFeatureIndex],
|
|
633
|
+
[id, layer?.id, featureIndex, shouldUseFeatureIndex, tilesetKey],
|
|
580
634
|
);
|
|
581
635
|
|
|
582
636
|
const selectedFeatureIdsRef = useRef<string[]>([]);
|
|
@@ -584,6 +638,20 @@ export const useHooks = ({
|
|
|
584
638
|
selectedFeatureColorRef.current = selectedFeatureColor;
|
|
585
639
|
const [selectedFeatureColorMap] = useState(() => new Map<string, Color>());
|
|
586
640
|
|
|
641
|
+
// The Cesium3DTileset child remounts when tilesetKey changes, while this hook stays mounted.
|
|
642
|
+
useLayoutEffect(() => {
|
|
643
|
+
setIsTilesetCompReady(false);
|
|
644
|
+
setIsTilesetReady(false);
|
|
645
|
+
if (tilesetRefKeyRef.current !== tilesetKey) {
|
|
646
|
+
tilesetRef.current = undefined;
|
|
647
|
+
tilesetRefKeyRef.current = undefined;
|
|
648
|
+
setIsTilesetRefReady(false);
|
|
649
|
+
}
|
|
650
|
+
featureIndex.records.clear();
|
|
651
|
+
selectedFeatureIdsRef.current = [];
|
|
652
|
+
selectedFeatureColorMap.clear();
|
|
653
|
+
}, [tilesetKey, featureIndex, selectedFeatureColorMap]);
|
|
654
|
+
|
|
587
655
|
useEffect(() => {
|
|
588
656
|
if (!tilesetRef.current || !shouldUseFeatureIndex || !isTilesetReady) return;
|
|
589
657
|
Object.assign(tilesetRef.current, {
|
|
@@ -759,12 +827,7 @@ export const useHooks = ({
|
|
|
759
827
|
|
|
760
828
|
// For Re:Earth provider, use the custom URL from customProvider or layer data
|
|
761
829
|
if (provider === "reearth") {
|
|
762
|
-
|
|
763
|
-
const customUrl = customProvider?.layers?.providers?.find(
|
|
764
|
-
p => p.id === "reearth_google_photorealistic_3d_tiles",
|
|
765
|
-
)?.url;
|
|
766
|
-
|
|
767
|
-
return customUrl || url || null;
|
|
830
|
+
return reearthGooglePhotorealisticUrl || url || null;
|
|
768
831
|
}
|
|
769
832
|
|
|
770
833
|
// Otherwise load via Google API key or Cesium Ion.
|
|
@@ -772,11 +835,13 @@ export const useHooks = ({
|
|
|
772
835
|
try {
|
|
773
836
|
if (provider === "cesium-ion" || !googleMapApiKey) {
|
|
774
837
|
const resource = await IonResource.fromAssetId(2275207, {
|
|
775
|
-
accessToken:
|
|
838
|
+
accessToken: cesiumIonAccessToken,
|
|
776
839
|
});
|
|
777
840
|
return resource;
|
|
778
841
|
}
|
|
779
|
-
const tileset = await createGooglePhotorealistic3DTileset({
|
|
842
|
+
const tileset = await createGooglePhotorealistic3DTileset({
|
|
843
|
+
key: googleMapApiKey,
|
|
844
|
+
});
|
|
780
845
|
return tileset.resource;
|
|
781
846
|
} catch (error) {
|
|
782
847
|
console.error(`Error loading Photorealistic 3D Tiles tileset: ${error}`);
|
|
@@ -785,7 +850,15 @@ export const useHooks = ({
|
|
|
785
850
|
};
|
|
786
851
|
|
|
787
852
|
return loadTileset();
|
|
788
|
-
}, [
|
|
853
|
+
}, [
|
|
854
|
+
type,
|
|
855
|
+
isVisible,
|
|
856
|
+
googleMapApiKey,
|
|
857
|
+
cesiumIonAccessToken,
|
|
858
|
+
provider,
|
|
859
|
+
reearthGooglePhotorealisticUrl,
|
|
860
|
+
url,
|
|
861
|
+
]);
|
|
789
862
|
|
|
790
863
|
const tilesetUrl = useMemo((): string | Resource | Promise<Resource> | null => {
|
|
791
864
|
if (!isVisible) return null;
|
|
@@ -803,7 +876,7 @@ export const useHooks = ({
|
|
|
803
876
|
// OSM Buildings — only available via Cesium Ion.
|
|
804
877
|
if (type === "osm-buildings") {
|
|
805
878
|
return IonResource.fromAssetId(96188, {
|
|
806
|
-
accessToken:
|
|
879
|
+
accessToken: cesiumIonAccessToken,
|
|
807
880
|
}); // https://github.com/CesiumGS/cesium/blob/main/packages/engine/Source/Scene/createOsmBuildings.js#L53
|
|
808
881
|
}
|
|
809
882
|
|
|
@@ -813,7 +886,7 @@ export const useHooks = ({
|
|
|
813
886
|
}
|
|
814
887
|
|
|
815
888
|
return null;
|
|
816
|
-
}, [type, isVisible, googleMapPhotorealisticResource, url, tileset,
|
|
889
|
+
}, [type, isVisible, googleMapPhotorealisticResource, url, tileset, cesiumIonAccessToken]);
|
|
817
890
|
|
|
818
891
|
const imageBasedLighting = useMemo(() => {
|
|
819
892
|
if (
|
|
@@ -854,11 +927,29 @@ export const useHooks = ({
|
|
|
854
927
|
|
|
855
928
|
const handleReady = useCallback(
|
|
856
929
|
(tileset: Cesium3DTileset) => {
|
|
930
|
+
if (tilesetKey !== currentTilesetKeyRef.current) {
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
857
933
|
setIsTilesetCompReady(true);
|
|
858
934
|
onLayerFetch?.({ properties: tileset.properties });
|
|
859
935
|
onLayerLoad?.({ layerId: layerIdRef.current });
|
|
860
936
|
},
|
|
861
|
-
[onLayerFetch, onLayerLoad],
|
|
937
|
+
[onLayerFetch, onLayerLoad, tilesetKey],
|
|
938
|
+
);
|
|
939
|
+
|
|
940
|
+
const handleError = useCallback(
|
|
941
|
+
(error: unknown) => {
|
|
942
|
+
if (tilesetKey !== currentTilesetKeyRef.current) {
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
tilesetRef.current = undefined;
|
|
946
|
+
tilesetRefKeyRef.current = undefined;
|
|
947
|
+
setIsTilesetCompReady(false);
|
|
948
|
+
setIsTilesetRefReady(false);
|
|
949
|
+
setIsTilesetReady(false);
|
|
950
|
+
console.error("Error loading Cesium 3D Tileset:", error);
|
|
951
|
+
},
|
|
952
|
+
[tilesetKey],
|
|
862
953
|
);
|
|
863
954
|
|
|
864
955
|
useEffect(() => {
|
|
@@ -874,6 +965,7 @@ export const useHooks = ({
|
|
|
874
965
|
}, [type, updateCredits]);
|
|
875
966
|
|
|
876
967
|
return {
|
|
968
|
+
tilesetKey,
|
|
877
969
|
tilesetUrl,
|
|
878
970
|
ref,
|
|
879
971
|
style,
|
|
@@ -883,5 +975,6 @@ export const useHooks = ({
|
|
|
883
975
|
builtinBoxProps,
|
|
884
976
|
imageBasedLighting,
|
|
885
977
|
handleReady,
|
|
978
|
+
handleError,
|
|
886
979
|
};
|
|
887
980
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo, type JSX } from "react";
|
|
2
2
|
import { Cesium3DTileset } from "resium";
|
|
3
3
|
|
|
4
4
|
import type { Cesium3DTilesAppearance, ComputedLayer } from "../../..";
|
|
@@ -37,6 +37,7 @@ function Tileset({
|
|
|
37
37
|
property ?? {};
|
|
38
38
|
const boxId = `${layer?.id}_box`;
|
|
39
39
|
const {
|
|
40
|
+
tilesetKey,
|
|
40
41
|
tilesetUrl,
|
|
41
42
|
ref,
|
|
42
43
|
style,
|
|
@@ -46,6 +47,7 @@ function Tileset({
|
|
|
46
47
|
builtinBoxProps,
|
|
47
48
|
imageBasedLighting,
|
|
48
49
|
handleReady,
|
|
50
|
+
handleError,
|
|
49
51
|
} = useHooks({
|
|
50
52
|
id,
|
|
51
53
|
boxId,
|
|
@@ -72,6 +74,7 @@ function Tileset({
|
|
|
72
74
|
return !isVisible || !tilesetUrl ? null : (
|
|
73
75
|
<>
|
|
74
76
|
<Cesium3DTileset
|
|
77
|
+
key={tilesetKey}
|
|
75
78
|
ref={ref}
|
|
76
79
|
url={tilesetUrl}
|
|
77
80
|
customShader={
|
|
@@ -88,8 +91,10 @@ function Tileset({
|
|
|
88
91
|
colorBlendMode={colorBlendModeFor3DTile(colorBlendMode)}
|
|
89
92
|
imageBasedLighting={imageBasedLighting}
|
|
90
93
|
onReady={handleReady}
|
|
94
|
+
onError={handleError}
|
|
91
95
|
debugWireframe={showWireframe}
|
|
92
96
|
debugShowBoundingVolume={showBoundingVolume}
|
|
97
|
+
showCreditsOnScreen
|
|
93
98
|
/>
|
|
94
99
|
{builtinBoxProps && (
|
|
95
100
|
<Box
|
|
@@ -110,19 +115,7 @@ function Tileset({
|
|
|
110
115
|
);
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
export default
|
|
114
|
-
Tileset,
|
|
115
|
-
(prev, next) =>
|
|
116
|
-
prev.id === next.id &&
|
|
117
|
-
prev.isVisible === next.isVisible &&
|
|
118
|
-
prev.property === next.property &&
|
|
119
|
-
prev.layer?.layer === next.layer?.layer &&
|
|
120
|
-
prev.viewerProperty === next.viewerProperty &&
|
|
121
|
-
prev.meta === next.meta &&
|
|
122
|
-
prev.evalFeature === next.evalFeature &&
|
|
123
|
-
prev.onComputedFeatureFetch === next.onComputedFeatureFetch &&
|
|
124
|
-
prev.onFeatureDelete === next.onFeatureDelete,
|
|
125
|
-
);
|
|
118
|
+
export default Tileset;
|
|
126
119
|
|
|
127
120
|
export const config: FeatureComponentConfig = {
|
|
128
121
|
noFeature: true,
|
|
@@ -112,7 +112,19 @@ export default function Feature({
|
|
|
112
112
|
displayType.every(k => components[k][1].noFeature && !components[k][1].noLayer);
|
|
113
113
|
const useTransition = !!layer?.transition?.useTransition;
|
|
114
114
|
const cacheable = !data?.updateInterval && !useTransition;
|
|
115
|
-
const
|
|
115
|
+
const dataSourceKey = useMemo(
|
|
116
|
+
() =>
|
|
117
|
+
generateIDWithMD5(
|
|
118
|
+
JSON.stringify({
|
|
119
|
+
type: data?.type,
|
|
120
|
+
url: data?.url,
|
|
121
|
+
layers: data?.layers,
|
|
122
|
+
provider: data?.provider,
|
|
123
|
+
googleMapApiKey: data?.serviceTokens?.googleMapApiKey,
|
|
124
|
+
}),
|
|
125
|
+
),
|
|
126
|
+
[data?.type, data?.url, data?.layers, data?.provider, data?.serviceTokens?.googleMapApiKey],
|
|
127
|
+
);
|
|
116
128
|
|
|
117
129
|
const { requestRender } = useContext();
|
|
118
130
|
// TODO: Find a way to wait updating the entity
|
|
@@ -139,7 +151,7 @@ export default function Feature({
|
|
|
139
151
|
!(sketchEditingFeature?.layerId === layer.id && sketchEditingFeature?.feature?.id === f?.id);
|
|
140
152
|
|
|
141
153
|
const componentId =
|
|
142
|
-
|
|
154
|
+
dataSourceKey +
|
|
143
155
|
generateIDWithMD5(
|
|
144
156
|
`${layer.id}_${
|
|
145
157
|
f?.id ?? ""
|
|
@@ -221,9 +233,9 @@ export default function Feature({
|
|
|
221
233
|
layer?.layer?.type === "simple" && !!layer?.layer?.["3dtiles"]?.specularEnvironmentMaps;
|
|
222
234
|
|
|
223
235
|
// "noFeature" component should be recreated when the following value is changed.
|
|
224
|
-
// data
|
|
236
|
+
// data source, Cesium Ion token, isVisible
|
|
225
237
|
const key =
|
|
226
|
-
|
|
238
|
+
dataSourceKey +
|
|
227
239
|
generateIDWithMD5(
|
|
228
240
|
`${
|
|
229
241
|
layer?.id || ""
|
|
@@ -243,7 +255,7 @@ export default function Feature({
|
|
|
243
255
|
})}
|
|
244
256
|
</>
|
|
245
257
|
);
|
|
246
|
-
}, [areAllDisplayTypeNoFeature, displayType, layer, isHidden,
|
|
258
|
+
}, [areAllDisplayTypeNoFeature, displayType, layer, isHidden, dataSourceKey, props]);
|
|
247
259
|
|
|
248
260
|
return (
|
|
249
261
|
<>
|