Please guide
Is this related to Uncaught RangeError: Invalid array length at Cesium3DTileset at async InitializeMaps ?
Its something else that cesium3DTileset is not loading with vite , just this is the issue.
I am stuck with it .
Hi @Zahid_Khan, we will need more information to understand your problem. Can you share a code snippet and the resulting error message?
Here is my code snippet
import React, { useState, useEffect, useRef, useMemo } from âreactâ;
import { useSelector, useDispatch } from âreact-reduxâ;
import {
Viewer,
Cesium3DTileset,
PointPrimitive,
PointPrimitiveCollection,
Entity,
PolylineGraphics,
Primitive,
Scene,
Camera,
ImageryLayer,
CameraFlyTo
} from âresiumâ;
import * as Cesium from âcesiumâ;
import has from âhasâ;
import { setAsset } from â../../../redux/actions/assetâ;
// import { setMapImage } from â../../../redux/actions/projectâ;
import isEmpty from â../../../utils/isEmptyâ;
import { useCameraCommandHandler } from â../../../utils/custom-hooksâ
import PreviewWindow from â./PreviewWindowâ;
import { is2d, is3d, isPhotorealistic } from â../../../utils/mapModesâ;
// import html2canvas from âhtml2canvasâ;
const imageryProvider3D = new Cesium.MapboxStyleImageryProvider({
styleId: âsatellite-v9â,
accessToken: â************************â,
});
const imageryProvider2D = new Cesium.MapboxStyleImageryProvider({
styleId: âoutdoors-v12â,
accessToken: â************************â,
});
window.CESIUM_BASE_URL = â/cesium/â;
let photoTileset, terrainProvider3D;
async function initializeMaps() {
terrainProvider3D = await Cesium.createWorldTerrainAsync();
photoTileset = await Cesium.createGooglePhotorealistic3DTileset();
}
(async () => {
await initializeMaps();
})();
let homeDestination;
const Map = props => {
const dispatch = useDispatch();
const [mapUrl, setMapUrl] = useState(ââ);
const [open, setOpen] = useState(false);
const [previewAsset, setPreviewAsset] = useState(ââ);
const [tilesetReady, setTilesetReady] = useState(false);
const [tileset, setTileset] = useState(ââ);
const [destination, setDestination] = useState(Cesium.Cartesian3.ONE);
const [primitives, setPrimitives] = useState({
geoOutline: null,
geoPlane: null,
appearanceOutline: null,
appearancePlane: null,
matrixOuline: null,
matrixPlane: null,
});
const viewerRef = useRef(null);
const { genInfo } = useSelector(state => state.report);
const { selectedAsset, selectedLat, selectedLon } = useSelector(state => state.asset);
const { project, selectedMapMode, assets, filters, captureMap } = useSelector(state => state.project);
const handleReady = (t) => {
console.log(âTileset ready state:â, {
tilesetObject: t,
readyState: t.ready,
rootTransform: t.root?.transform
});
setTileset(t);
console.log(âtileset : T ->â,t)
setTilesetReady(true);
// Debug: Check if tileset is in viewer
console.log(âViewer tilesets:â, viewerRef.current?.cesiumElement.scene.primitives.length);
if (viewerRef.current?.cesiumElement) {
viewerRef.current.cesiumElement.zoomTo(t);
}
};
useEffect(() => {
if (isEmpty(selectedAsset)) {
return;
}
const { lon, lat } = selectedAsset.referenceLoc;
const { GPSAltitude } = selectedAsset.metadata;
const index = GPSAltitude.indexOf(âmâ);
const height = Number(GPSAltitude.substring(0, index));
const origin = Cesium.Cartesian3.fromDegrees(lon, lat, height + 80);
handlePointClick(selectedAsset, origin);
}, [selectedAsset])
const handlePointClick = (asset, origin) => {
setPreviewAsset(asset);
setOpen(true);
if (!Cesium.Cartesian3.equals(origin, destination)) {
setDestination(origin);
setOpen(true);
setPreviewAsset(asset);
let loc = has(asset, 'referenceLoc') ? asset.referenceLoc : { lat: 0, lon: 0 };
dispatch(setAsset(asset, loc));
calculatePrimitivesGeometry(asset);
console.log("Point is Clicked")
}
};
const findPoint = (startPoint, angle) => {
const radiusEarthKm = 6371.01;
const distanceKm = 0.005;
let angleRad = Cesium.Math.toRadians(angle);
let distRatio = distanceKm / radiusEarthKm;
let distRatioSine = Math.sin(distRatio);
let distRatioCosine = Math.cos(distRatio);
let startLatRad = Cesium.Math.toRadians(startPoint.lat);
let startLonRad = Cesium.Math.toRadians(startPoint.lon);
let startLatCos = Math.cos(startLatRad);
let startLatSin = Math.sin(startLatRad);
let endLatRads = Math.asin(startLatSin * distRatioCosine + startLatCos * distRatioSine * Math.cos(angleRad));
let endLonRads =
startLonRad +
Math.atan2(
Math.sin(angleRad) * distRatioSine * startLatCos,
distRatioCosine - startLatSin * Math.sin(endLatRads),
);
return {
lat: Cesium.Math.toDegrees(endLatRads),
lon: Cesium.Math.toDegrees(endLonRads),
};
};
useEffect(() => {
initializeMaps();
if (has(project, âmapUrlâ) && !isEmpty(project.mapUrl)) {
setMapUrl(project.mapUrl);
}
}, );
useCameraCommandHandler(props.command, destination, setDestination, props.clear, homeDestination);
useEffect(() => {
initialDestination();
}, [selectedMapMode]);
const initialDestination = () => {
if (isEmpty(assets)) return;
const midway = assets.findIndex(
(a) =>
a.category === 'flightPic' &&
a.referenceLoc.lat !== 0 &&
a.referenceLoc.lon !== 0 &&
!isEmpty(a.referenceLoc.lat)
);
if (midway === -1) return;
if (!isEmpty(selectedAsset)) {
setPreviewAsset(selectedAsset);
setOpen(true);
} else {
setPreviewAsset('');
setOpen(false);
}
const { lon, lat } = assets[midway].referenceLoc;
const { GPSAltitude } = assets[midway].metadata;
const height = parseFloat(GPSAltitude);
const origin = Cesium.Cartesian3.fromDegrees(lon, lat, height + 150);
setDestination(origin);
homeDestination = origin;
};
const calculatePrimitivesGeometry = asset => {
console.log(âPrimitive Geometry Triggeredâ)
if (
((is3d(selectedMapMode) && tileset) || isPhotorealistic(selectedMapMode)) &&
!isEmpty(asset) &&
asset.category === 'flightPic' &&
!isEmpty(asset.referenceLoc.lat)
) {
const {
GPSAltitude,
GimbalPitchDegree,
GimbalRollDegree,
GimbalYawDegree,
ImageWidth,
ImageHeight,
FOV,
FocalLength,
} = asset.metadata;
console.log("Calcuted Primitive Geometry Not Triggered")
const { lon, lat } = asset.referenceLoc;
let index = GPSAltitude.indexOf('m');
const height = Number(GPSAltitude.substring(0, index));
const origin = Cesium.Cartesian3.fromDegrees(lon, lat, height);
let heading = Number(GimbalYawDegree);
let pitch = Number(GimbalPitchDegree);
let roll = Number(GimbalRollDegree);
const zeroPt = new Cesium.Cartesian3(0, 0, 0);
heading *= Math.PI / 180;
pitch *= Math.PI / 180;
roll *= Math.PI / 180;
// declare shortcuts
let til = pitch + Math.PI / 2;
roll *= -1;
let ch = Math.cos(heading);
let sh = Math.sin(heading);
let ct = Math.cos(til);
let st = Math.sin(til);
let cr = Math.cos(roll);
let sr = Math.sin(roll);
// determine local rot mat
let myrig = new Cesium.Cartesian3(ch * cr + sh * ct * sr, sh * cr * -1 + ch * ct * sr, st * sr);
let mydir = new Cesium.Cartesian3(sh * st, ch * st, ct * -1);
let myup = new Cesium.Cartesian3(sh * ct * cr + ch * sr * -1, ch * ct * cr + sh * sr, st * cr);
//transform local to ENU
let GD_transform = Cesium.Transforms.eastNorthUpToFixedFrame(
origin,
viewerRef.current?.cesiumElement.scene.globe.ellipsoid,
new Cesium.Matrix4(),
);
let GD_rotmat = Cesium.Matrix4.getMatrix3(GD_transform, new Cesium.Matrix3());
Cesium.Matrix3.multiplyByVector(GD_rotmat, myrig, myrig);
Cesium.Matrix3.multiplyByVector(GD_rotmat, mydir, mydir);
Cesium.Matrix3.multiplyByVector(GD_rotmat, myup, myup);
let rot = [myrig.x, myrig.y, myrig.z, mydir.x, mydir.y, mydir.z, myup.x, myup.y, myup.z];
// ----------------------------
let frustum = new Cesium.PerspectiveFrustum();
console.log("Frustum Just",frustum)
let fov = isEmpty(FOV) ? 60.0 : Number(FOV.split(' ')[0]);
frustum.fov = Cesium.Math.toRadians(fov);
let aspectWidth = isEmpty(ImageWidth) ? 4 : Number(ImageWidth);
let aspectHeight = isEmpty(ImageHeight) ? 3 : Number(ImageHeight);
frustum.aspectRatio = aspectWidth / aspectHeight;
frustum.near = 1.0;
let focalLengthIndex = FocalLength.indexOf('mm');
const focalLength = Number(FocalLength.substring(0, focalLengthIndex));
frustum.far = focalLength * 3;
let frustumGeometry = new Cesium.FrustumOutlineGeometry({
frustum,
origin: zeroPt,
orientation: { x: 0, y: 0, z: 0, w: 1 },
});
let frustumOutlineGeometryInstance = new Cesium.GeometryInstance({
geometry: frustumGeometry,
modelMatrix: [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 1.0)),
},
});
console.log("Frustum Geometry", frustumOutlineGeometryInstance)
let frustumGeometryInstance = new Cesium.GeometryInstance({
geometry: new Cesium.FrustumGeometry({
frustum,
origin: zeroPt,
orientation: { x: 0, y: 0, z: 0, w: 1 },
}),
modelMatrix: [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 0.0, 1.0, 0.2)),
},
});
const geoOutline = frustumOutlineGeometryInstance;
const appearanceOutline = new Cesium.PerInstanceColorAppearance({
closed: true,
flat: true,
});
const geoPlane = frustumGeometryInstance;
const appearancePlane = new Cesium.PerInstanceColorAppearance({
closed: true,
flat: true,
});
const matrixOuline = [
rot[0],
rot[1],
rot[2],
0,
rot[3],
rot[4],
rot[5],
0,
rot[6],
rot[7],
rot[8],
0,
origin.x,
origin.y,
origin.z,
1,
];
const matrixPlane = [
rot[0],
rot[1],
rot[2],
0,
rot[3],
rot[4],
rot[5],
0,
rot[6],
rot[7],
rot[8],
0,
origin.x,
origin.y,
origin.z,
1,
];
setPrimitives({
geoOutline,
geoPlane,
appearanceOutline,
appearancePlane,
matrixOuline,
matrixPlane,
});
}
};
useEffect(() => {
setPrimitives({
geoOutline: null,
geoPlane: null,
appearanceOutline: null,
appearancePlane: null,
matrixOuline: null,
matrixPlane: null,
});
}, [selectedMapMode]);
const contextOptions = useMemo(() => ({
webgl: {
preserveDrawingBuffer: true,
},
}), );
// useEffect(() => {
// if (!captureMap) return;
// // Check if viewer is initialized and fixedHeight is available
// const checkReady = () => {
// return (
// viewerRef.current &&
// viewerRef.current.cesiumElement &&
// viewerRef.current.cesiumElement.camera &&
// viewerRef.current.cesiumElement.scene &&
// genInfo?.fixedHeight !== null &&
// genInfo?.fixedHeight !== undefined
// );
// };
// // Callback Function
// const waitForReady = (callback, maxAttempts = 10, interval = 3000) => {
// let attempts = 0;
// const checkInterval = setInterval(() => {
// attempts++;
// if (checkReady()) {
// clearInterval(checkInterval);
// callback();
// } else if (attempts >= maxAttempts) {
// clearInterval(checkInterval);
// console.error(âMap or height value is taking too long to load. Please try again.â);
// }
// }, interval);
// };
// waitForReady(() => {
// const viewer = viewerRef.current.cesiumElement;
// const camera = viewer.camera;
// const scene = viewer.scene;
// // Store current view
// const currentPosition = camera.position.clone();
// const currentOrientation = {
// heading: camera.heading,
// pitch: camera.pitch,
// roll: camera.roll,
// };
// const currentFov = camera.frustum.fov;
// // Get current camera position to calculate height
// const currentCartographic = Cesium.Cartographic.fromCartesian(currentPosition);
// // Use dynamic fixedHeight
// const newCartographic = new Cesium.Cartographic(
// currentCartographic.longitude,
// currentCartographic.latitude,
// genInfo?.fixedHeight
// );
// const newPosition = Cesium.Cartesian3.fromRadians(
// newCartographic.longitude,
// newCartographic.latitude,
// newCartographic.height
// );
// // Set top-down view (pitch -90 degrees)
// camera.setView({
// destination: newPosition,
// orientation: {
// heading: 0, // North-facing
// pitch: -Cesium.Math.PI_OVER_TWO, // Straight down
// roll: 0
// }
// });
// // Apply fixed zoom percentage (2) with safety check
// const fixedZoomPercent = 2;
// const newFov = Math.min(
// Cesium.Math.PI - 0.01,
// Math.max(0.1, currentFov * fixedZoomPercent)
// );
// camera.frustum.fov = newFov;
// // Wait for scene to render
// scene.render();
// setTimeout(() => {
// const canvas = scene.canvas;
// canvas.toBlob(
// blob => {
// if (blob) {
// const imageUrl = URL.createObjectURL(blob);
// dispatch(setMapImage(imageUrl));
// // Restore original view
// camera.setView({
// destination: currentPosition,
// orientation: currentOrientation,
// });
// camera.frustum.fov = currentFov;
// }
// },
// âimage/pngâ,
// 0.9,
// );
// }, 1000);
// });
// }, [captureMap, genInfo?.fixedHeight]);
useEffect(() => {
console.log(âCurrent mapUrl:â, mapUrl);
}, [mapUrl]);
const terrainProvider = isPhotorealistic(selectedMapMode) ? undefined : terrainProvider3D;
return (
<Viewer
style={{ height: '100%', width: '100%' }}
homeButton={false}
geocoder={false}
sceneModePicker={false}
navigationHelpButton={false}
animation={false}
baseLayerPicker={false}
fullscreenButton={false}
timeline={false}
selectionIndicator={false}
infoBox={false}
ref={viewerRef}
>
<Scene
terrainProvider={terrainProvider}
debugShowFrustumPlanes={false}
mode={Cesium.SceneMode.SCENE3D}
/>
<ImageryLayer
imageryProvider={imageryProvider3D}
show={is3d(selectedMapMode)}
/>
<ImageryLayer
imageryProvider={imageryProvider2D}
show={is2d(selectedMapMode)}
/>
<Camera defaultZoomAmount={40}/>
<CameraFlyTo duration={2} destination={destination}/>
{
isPhotorealistic(selectedMapMode) && (
<Cesium3DTileset
url={photoTileset._url}
/>
)
}
<React.Fragment>
{is3d(selectedMapMode) && !isEmpty(mapUrl) && (
<React.Fragment>
<Cesium3DTileset
cacheBytes={3 * 1024 * 1024 * 1024} // 4 GB
maximumCacheOverflowBytes={3 * 1024 * 1024 * 1024} // 4 GB
maximumScreenSpaceError={6}
url={mapUrl}
onReady={handleReady}
/>
</React.Fragment>
)}
{((is3d(selectedMapMode) && tileset) || isPhotorealistic(selectedMapMode)) && (
<React.Fragment>
<Primitive
appearance={primitives.appearanceOutline}
geometryInstances={primitives.geoOutline}
modelMatrix={primitives.matrixOuline}
/>
<Primitive
appearance={primitives.appearancePlane}
geometryInstances={primitives.geoPlane}
modelMatrix={primitives.matrixPlane}
/>
</React.Fragment>
)}
<PointPrimitiveCollection>
{assets.map(a => {
if (a.category === 'flightPic' && !isEmpty(a.referenceLoc.lat)) {
const { lon, lat } = a.referenceLoc;
const { GPSAltitude } = a.metadata;
let index = GPSAltitude.indexOf('m');
const height = Number(GPSAltitude.substring(0, index));
const origin = Cesium.Cartesian3.fromDegrees(lon, lat, height);
if (previewAsset._id === a._id) {
let endPoint = '';
if (has(a.metadata, 'GimbalYawDegree')) {
const { GimbalYawDegree } = a.metadata;
let heading = Number(GimbalYawDegree);
endPoint = findPoint({ lat, lon }, heading);
}
return (
<React.Fragment key={a._id}>
<PointPrimitive
color={Cesium.Color.CORNFLOWERBLUE}
pixelSize={23}
position={origin}
onClick={() => handlePointClick(a, origin)}
/>
{is2d(selectedMapMode) && !isEmpty(endPoint) && (
<Entity>
<PolylineGraphics
positions={Cesium.Cartesian3.fromDegreesArray([lon, lat, endPoint.lon, endPoint.lat])}
width={15}
material={new Cesium.PolylineArrowMaterialProperty(Cesium.Color.CORNFLOWERBLUE)}
/>
</Entity>
)}
</React.Fragment>
);
} else {
return (
<PointPrimitive
key={a._id}
color={Cesium.Color.CORAL}
pixelSize={18}
position={origin}
onClick={() => handlePointClick(a, origin)}
/>
);
}
} else {
return null;
}
})}
<PreviewWindow asset={previewAsset} show={open} />
</PointPrimitiveCollection>
</React.Fragment>
</Viewer>
);
};
export default Map;
Hi @Zahid_Khan, thanks for the code snippet. What is the error message you are seeing from this code?
Not throwing any error , while uploading tileset , it successfully uploaded but its not rendering the 3D map after that .
Hi @Zahid_Khan, I understand the unexpected behavior with no error message can be frustrating.
The example snippet is pretty long and imports several third-party dependencies, so it would be difficult for me to reproduce it.
How about another approach: Start from the cesium vite example which should load a Cesium3DTileset
successfully (it uses an OSM buildings tileset). If that example works on your computer, then you could compare the setup of the example with your code to see what is different.
Thanks of reply it was proxy issue which i resolved later
server: {
proxy: {
â/apiâ: env.VITE_PORT_API_KEY,
â/tilesetsâ: env.VITE_PORT_API_KEY
},
},