Skip to content

Commit 1823cb5

Browse files
authored
fix: 3dtiles style lost when using style url and click on features (#99)
1 parent d573166 commit 1823cb5

3 files changed

Lines changed: 73 additions & 40 deletions

File tree

example/testLayers/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { LAND_USE, LSLD_SAPPORO, LSLD_NIJIMA } from "./mvt";
88
import { OSM_BUILDINGS } from "./osm_buildings";
99
import { THREEDTILES_KUMAGAYA_LOD2 } from "./threedtiles_lod2";
1010
import { THREEDTILES_SIMPLE } from "./threedtiles_simple";
11+
import { THREEDTILES_SIMPLE_WITH_STYLE_URL } from "./threedtiles_simple_with_style_url";
1112

1213
export const TEST_LAYERS: Layer[] = [
1314
LAND_USE,
@@ -18,6 +19,7 @@ export const TEST_LAYERS: Layer[] = [
1819
GOOGLE_PHOTOREALISTIC_3DTILES,
1920
OSM_BUILDINGS,
2021
THREEDTILES_SIMPLE,
22+
THREEDTILES_SIMPLE_WITH_STYLE_URL,
2123
THREEDTILES_KUMAGAYA_LOD2,
2224
CZML_SIMPLE,
2325
];
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Layer } from "@reearth/core";
2+
3+
export const THREEDTILES_SIMPLE_WITH_STYLE_URL: Layer = {
4+
id: "3dtiles_simple_with_style_url",
5+
type: "simple",
6+
data: {
7+
type: "3dtiles",
8+
url: "https://assets.cms.plateau.reearth.io/assets/4f/702958-5009-4d6b-a2e0-157c7e573eb2/13100_tokyo23-ku_2022_3dtiles _1_1_op_bldg_13101_chiyoda-ku_lod2_no_texture/tileset.json",
9+
},
10+
"3dtiles": {
11+
styleUrl:
12+
"https://assets.cms.reearth.io/assets/07/5374e9-5b67-49e8-9791-dfc4af86b824/simple_3dtiles_style.json",
13+
},
14+
};

src/engines/Cesium/Feature/Tileset/hooks.ts

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ const useFeature = ({
187187
onComputedFeatureFetch,
188188
shouldUseFeatureIndex,
189189
isTilesetReady,
190+
useExternalStyle,
190191
}: {
191192
id?: string;
192193
tilesetRef: MutableRefObject<Cesium3DTileset | undefined>;
@@ -199,6 +200,7 @@ const useFeature = ({
199200
selectedFeatureIdsRef: MutableRefObject<string[]>;
200201
shouldUseFeatureIndex?: boolean;
201202
isTilesetReady: boolean;
203+
useExternalStyle?: boolean;
202204
}) => {
203205
const cachedFeaturesRef = useRef<CachedFeature[]>([]);
204206
const cachedCalculatedLayerRef = useRef(layer);
@@ -220,49 +222,51 @@ const useFeature = ({
220222

221223
const computedFeature = evalFeature(layer, { ...feature?.feature, properties });
222224

223-
const style = computedFeature?.["3dtiles"];
225+
if (!useExternalStyle) {
226+
const style = computedFeature?.["3dtiles"];
224227

225-
COMMON_STYLE_PROPERTIES.forEach(({ name, convert }) => {
226-
const val = convertStyle(style?.[name], convert);
227-
228-
if (name === "color") {
229-
// Reset color to default so that new style could update all.
230-
raw.color = DEFAULT_FEATURE_COLOR;
228+
COMMON_STYLE_PROPERTIES.forEach(({ name, convert }) => {
229+
const val = convertStyle(style?.[name], convert);
231230

232-
// Apply color from style.
233-
if (val !== undefined) {
234-
raw.color = val;
231+
if (name === "color") {
232+
// Reset color to default so that new style could update all.
233+
raw.color = DEFAULT_FEATURE_COLOR;
234+
235+
// Apply color from style.
236+
if (val !== undefined) {
237+
raw.color = val;
238+
}
239+
240+
// Apply color for selected feature.
241+
if (isFeatureSelected && typeof layer["3dtiles"]?.selectedFeatureColor === "string") {
242+
raw.color = toColor(layer["3dtiles"]?.selectedFeatureColor) ?? val;
243+
}
244+
} else {
245+
if (val !== undefined) {
246+
raw[name] = val;
247+
}
235248
}
249+
});
236250

237-
// Apply color for selected feature.
238-
if (isFeatureSelected && typeof layer["3dtiles"]?.selectedFeatureColor === "string") {
239-
raw.color = toColor(layer["3dtiles"]?.selectedFeatureColor) ?? val;
240-
}
241-
} else {
242-
if (val !== undefined) {
243-
raw[name] = val;
244-
}
251+
if (raw instanceof Cesium3DTilePointFeature) {
252+
POINT_STYLE_PROPERTIES.forEach(({ name, convert }) => {
253+
const val = convertStyle(style?.[name], convert);
254+
if (val !== undefined) {
255+
raw[name] = val;
256+
}
257+
});
245258
}
246-
});
247-
248-
if (raw instanceof Cesium3DTilePointFeature) {
249-
POINT_STYLE_PROPERTIES.forEach(({ name, convert }) => {
250-
const val = convertStyle(style?.[name], convert);
251-
if (val !== undefined) {
252-
raw[name] = val;
253-
}
254-
});
255-
}
256259

257-
if ("style" in raw) {
258-
raw.style = new Cesium3DTileStyle(
259-
// TODO: Convert value if it's necessary
260-
MODEL_STYLE_PROPERTIES.reduce((res, { name, convert }) => {
261-
const val = convertStyle(style?.[name as keyof typeof style], convert);
262-
if (val === undefined) return res;
263-
return { ...res, [name]: val };
264-
}, {}),
265-
);
260+
if ("style" in raw) {
261+
raw.style = new Cesium3DTileStyle(
262+
// TODO: Convert value if it's necessary
263+
MODEL_STYLE_PROPERTIES.reduce((res, { name, convert }) => {
264+
const val = convertStyle(style?.[name as keyof typeof style], convert);
265+
if (val === undefined) return res;
266+
return { ...res, [name]: val };
267+
}, {}),
268+
);
269+
}
266270
}
267271

268272
attachTag(feature.raw, {
@@ -276,7 +280,7 @@ const useFeature = ({
276280
}
277281
return;
278282
},
279-
[evalFeature, layerId, viewer, shouldUseFeatureIndex, selectedFeatureIdsRef],
283+
[evalFeature, layerId, viewer, shouldUseFeatureIndex, selectedFeatureIdsRef, useExternalStyle],
280284
);
281285

282286
const handleTilesetLoad = useCallback(
@@ -615,6 +619,7 @@ export const useHooks = ({
615619
selectedFeatureIdsRef,
616620
shouldUseFeatureIndex,
617621
isTilesetReady,
622+
useExternalStyle: !!styleUrl,
618623
});
619624

620625
const [terrainHeightEstimate, setTerrainHeightEstimate] = useState(0);
@@ -730,11 +735,23 @@ export const useHooks = ({
730735
}
731736
(async () => {
732737
const res = await fetch(styleUrl);
733-
if (!res.ok) return;
734-
setStyle(new Cesium3DTileStyle(await res.json()));
738+
if (!res.ok) {
739+
console.warn("Failed to fetch style from:", styleUrl);
740+
return;
741+
}
742+
const styleData = await res.json();
743+
const newStyle = new Cesium3DTileStyle(styleData);
744+
setStyle(newStyle);
735745
})();
736746
}, [styleUrl]);
737747

748+
// Apply style to tileset when both external style and tileset are ready
749+
useEffect(() => {
750+
if (style && tilesetRef.current && isTilesetReady) {
751+
tilesetRef.current.style = style;
752+
}
753+
}, [style, isTilesetReady]);
754+
738755
const googleMapPhotorealisticResource = useMemo(() => {
739756
if (type !== "google-photorealistic" || !isVisible) return null;
740757

0 commit comments

Comments
 (0)