OK, that tileset is definitely in a strange place. When you open the location editor with “Adjust Tileset Location” and click “Next”, it zooms to the tileset: You’ll see that it floats somewhere over Africa, and its (presumed) center is waaay off from where the actual data is.
If this was tiled from a LAS file with Cesium ion, then it strongly looks like something went wrong there. It’s hard to tell what exactly that was. Maybe there is something in the LAS file that suggested a different location…? If this was supposed to be investigated further, the it could be helpful if you could provide that LAS file. (Maybe some of this will then be moved to the “Cesium ion” section or tracked as an issue internally). If you can not share the LAS file, then maybe providing the output of tools like lasinfo could give further hints.
In any case, and in the meantime, there may be workarounds for that. You could
- adjust the tileset location at runtime, by setting the proper
tileset.modelMatrix
- ajdust the tileset JSON, to include this matrix as the
tile.transform
or the root tile
For the first approach:
The following sandcastle assumes that the tileset is hosted locally. (You could change the tileset creation to await Cesium.Cesium3DTileset.fromIonAssetId(3008393)
if you want to do this for your ion asset). The sandcastle examines the translation of the root node, and moves the tileset to the origin. Afterwards, you can additionally apply a transform to the tileset that was computed with eastNorthUpToFixedFrame
, to place it at a certain position on the globe:
const viewer = new Cesium.Viewer("cesiumContainer");
// Create the tileset in the viewer
const tileset = viewer.scene.primitives.add(
await Cesium.Cesium3DTileset.fromUrl(
"http://localhost:8003/tileset.json", {
debugShowBoundingVolume: true,
maximumScreenSpaceError: 8
})
);
// Fetch the center of the bounding box of the root tile
// (assuming that it is an oriented bounding box)
const center = tileset.root.boundingVolume.boundingVolume.center;
console.log("center:" + center);
const translation = Cesium.Cartesian3.negate(
center, new Cesium.Cartesian3());
const translationMatrix = Cesium.Matrix4.fromTranslation(
translation, new Cesium.Matrix4());
// Move the tileset to the origin
const matrix = Cesium.Matrix4.clone(Cesium.Matrix4.IDENTITY);
Cesium.Matrix4.multiply(matrix, translationMatrix, matrix);
console.log("transform " + Cesium.Matrix4.toArray(matrix));
// Move the tileset to a certain position on the globe
const transform = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-75.152408, 39.946975, 10)
);
Cesium.Matrix4.multiply(transform, matrix, matrix);
tileset.modelMatrix = matrix;
// Zoom to the tileset, with a small offset so that
// it is fully visible
const offset = new Cesium.HeadingPitchRange(
Cesium.Math.toRadians(-22.5),
Cesium.Math.toRadians(-22.5),
60.0
);
viewer.zoomTo(tileset, offset);
For the second approach:
You could add the following transform
in the root tile of the tileset JSON:
{
...
"root": {
"transform": [1,0,0,0,0,1,0,0,0,0,1,0,-379389.30500000005,-2048616.1500000001,-551.605,1],
"boundingVolume": ...
This will have the same effect visually, and you can then set the tileset.modelMatrix
to a transform that was computed with eastNorthUpToFixedFrame
as well.
You could also apply the full transform as the root transform
, so that you can load the tileset directly, and don’t have to manually adjust the transform afterwards. For that, however, it would be necessary to know the longitude/latitude of where the tileset is supposed to be located.
(If you know that, I can post the required matrix here as well).