Reputation: 21
I am new to CesiumJS, but have the following code which focuses on Southern San Francisco and I have also drawn a red rectangle on top of the 3D World Terrain
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- Include the CesiumJS JavaScript and CSS files -->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.119/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.119/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
<div id="cesiumContainer"></div>
<script type="module">
// Your access token can be found at: https://ion.cesium.com/tokens.
// This is the default access token from your ion account
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI4MjViMDdiOC02OTBlLTQyYjgtOTcyYy02YTYzNjczNDgxN2QiLCJpZCI6MjI2NDQ1LCJpYXQiOjE3MjAxMDMzNjV9.tSVOLKfyeiR0kn1e0G13O2PA6E8dLU3J6531muHF16g';
// Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
const viewer = new Cesium.Viewer('cesiumContainer', {
terrain: Cesium.Terrain.fromWorldTerrain(),
});
// Fly the camera to San Francisco at the given longitude, latitude, and height.
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(-122.4175, 37.655, 400),
orientation: {
heading: Cesium.Math.toRadians(0.0),
pitch: Cesium.Math.toRadians(-15.0),
}
});
const geoJsonMountainPolygon = {
type: "Feature",
properties: {},
geometry: {
type: "Polygon",
coordinates: [[
[-122.5, 37.6],
[-122.4, 37.6],
[-122.4, 37.7],
[-122.5, 37.7],
[-122.5, 37.6]
]]
}
};
const mountainPolygonEntity = viewer.entities.add({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray([
-122.5, 37.6,
-122.4, 37.6,
-122.4, 37.7,
-122.5, 37.7,
-122.5, 37.6
]),
material: Cesium.Color.RED.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK
}
});
</script>
</div>
</body>
</html>
However, what I am wondering is - does CesiumJS have the capability to manipulate the elevation of the terrain? E.g. exaggerate it further, flatten it, etc?
I have been trying to write code to write a custom tile provider where the terrain is flattened if the tiles fall within the red rectangle that I've drawn
customTerrainProvider.requestTileGeometry = function(x, y, level, request) {
const rectangle = Cesium.EllipsoidTilingScheme.tileXYToRectangle(x, y, level);
const cartographicPosition = Cesium.Rectangle.center(rectangle);
const isInMountainPolygon = Cesium.Cartesian3.fromDegrees(cartographicPosition.longitude, cartographicPosition.latitude);
if (Cesium.PolygonPipeline.insidePolygon(isInMountainPolygon, geoJsonMountainPolygon.geometry.coordinates[0])) {
return Cesium.EllipsoidTerrainProvider.prototype.getLevelMaximumGeometricError(level);
} else {
// Call the original method to get the default terrain data
return Cesium.EllipsoidTerrainProvider.prototype.requestTileGeometry.call(this, x, y, level, request)
.then(function(terrainData) {
// Add custom terrain manipulation logic here
terrainData.interpolateHeight = function (rectangle, longitude, latitude) {
// Custom logic to flatten terrain to desired elevation
return Cesium.Cartesian3.fromRadians(longitude, latitude, desiredElevation);
};
return terrainData;
});
}
};
But that is just resulting in Cesium pointing to the sky ...
I've noticed Cesium World Bathymetry has a slider which can exaggerate the bathymetry https://cesium.com/blog/2024/01/29/cesium-world-bathymetry-in-cesiumjs/ - is there any way I could implement something similar for the 3D World Terrain? Or this https://sandcastle.cesium.com/?src=3D%20Tiles%20Vertical%20Exaggeration.html ??
Upvotes: 1
Views: 144