-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11678 from Tamrat-B/feature/i3s_bsl_support
Add support for Building Scene Layer (BSL) OGC I3S standard
- Loading branch information
Showing
31 changed files
with
5,625 additions
and
333 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
<meta | ||
name="viewport" | ||
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" | ||
/> | ||
<meta | ||
name="description" | ||
content="Add I3S Building Scene Layer from a service." | ||
/> | ||
<meta name="cesium-sandcastle-labels" content="DataSources" /> | ||
<title>I3S Building Scene Cesium Demo</title> | ||
<script type="text/javascript" src="../Sandcastle-header.js"></script> | ||
<script | ||
type="text/javascript" | ||
src="../../../Build/CesiumUnminified/Cesium.js" | ||
nomodule | ||
></script> | ||
<script type="module" src="../load-cesium-es6.js"></script> | ||
</head> | ||
|
||
<body | ||
class="sandcastle-loading" | ||
data-sandcastle-bucket="bucket-requirejs.html" | ||
> | ||
<style> | ||
@import url(../templates/bucket.css); | ||
#toolbar { | ||
background: rgba(42, 42, 42, 0.8); | ||
padding: 10px; | ||
border-radius: 4px; | ||
max-height: 100%; | ||
overflow-y: auto; | ||
} | ||
</style> | ||
<div id="cesiumContainer" class="fullSize"></div> | ||
<div id="loadingOverlay"> | ||
<h1>Loading...</h1> | ||
</div> | ||
<div id="toolbar"></div> | ||
<script id="cesium_sandcastle_script"> | ||
window.startup = async function (Cesium) { | ||
"use strict"; | ||
//Sandcastle_Begin | ||
// Cesium World Terrain height system doesn't match to I3S datasets height system in some locations even with geoid conversion. | ||
// Set ArcGIS Tiled Elevation Terrain gravity related height system to get closer results. | ||
const viewer = new Cesium.Viewer("cesiumContainer", { | ||
terrain: new Cesium.Terrain( | ||
Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( | ||
"https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" | ||
) | ||
), | ||
animation: false, | ||
timeline: false, | ||
orderIndependentTranslucency: false, | ||
msaaSamples: 4, // enables multisample antialiasing for improved visual quality | ||
}); | ||
|
||
// More datasets to tour can be added here... | ||
// The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. | ||
const tours = { | ||
"Turanga Library": | ||
"https://tiles.arcgis.com/tiles/cFEFS0EWrhfDeVw9/arcgis/rest/services/Turanga_Library/SceneServer", | ||
}; | ||
|
||
try { | ||
// Create i3s options to pass optional parameters useful for debugging and visualizing | ||
const i3sOptions = { | ||
adjustMaterialAlphaMode: true, // force the alpha mode to be set for transparent geometry | ||
showFeatures: true, // creates 3D object for each feature and allows to apply attributes filter | ||
applySymbology: true, // applies outlines based on the I3S layer renderer details | ||
calculateNormals: true, // generates flat normals if they are missing in I3S buffers | ||
}; | ||
|
||
// Create I3S data provider | ||
const i3sProvider = await Cesium.I3SDataProvider.fromUrl( | ||
tours["Turanga Library"], | ||
i3sOptions | ||
); | ||
|
||
Cesium.I3SBuildingSceneLayerExplorer("toolbar", i3sProvider); | ||
|
||
// Add the i3s layer provider as a primitive data type | ||
viewer.scene.primitives.add(i3sProvider); | ||
|
||
// Center camera on I3S once it's loaded | ||
const center = Cesium.Rectangle.center(i3sProvider.extent); | ||
center.height = 300.0; | ||
// Adjust camera height by the I3S BSL extent | ||
let bslLayer = i3sProvider.data; | ||
if (Cesium.defined(bslLayer.layers) && bslLayer.layers.length > 0) { | ||
bslLayer = bslLayer.layers[0]; | ||
} | ||
if ( | ||
Cesium.defined(bslLayer.fullExtent) && | ||
Cesium.defined(bslLayer.fullExtent.zmax) | ||
) { | ||
center.height += bslLayer.fullExtent.zmax; | ||
} | ||
const destination = Cesium.Ellipsoid.WGS84.cartographicToCartesian( | ||
center | ||
); | ||
viewer.camera.setView({ | ||
destination: destination, | ||
}); | ||
|
||
// Override home button to center the camera on I3S | ||
viewer.homeButton.viewModel._command = Cesium.createCommand( | ||
function () { | ||
viewer.camera.flyTo({ | ||
destination: destination, | ||
}); | ||
} | ||
); | ||
} catch (error) { | ||
console.error( | ||
`There was an error creating the I3S Data Provider: ${error}` | ||
); | ||
} | ||
|
||
// Information about the currently selected feature | ||
const selected = { | ||
feature: undefined, | ||
originalColor: new Cesium.Color(), | ||
}; | ||
|
||
// An entity object which will hold info about the currently selected feature for infobox display | ||
const selectedEntity = new Cesium.Entity(); | ||
// Show metadata in the InfoBox. | ||
viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( | ||
movement | ||
) { | ||
const selectedFeature = selected.feature; | ||
|
||
// Pick a new feature | ||
const pickedFeature = viewer.scene.pick(movement.position); | ||
if (selectedFeature === pickedFeature) { | ||
return; | ||
} | ||
|
||
// If a feature was previously selected, undo the highlight | ||
if (Cesium.defined(selected.feature)) { | ||
selected.feature.color = selected.originalColor; | ||
selected.feature = undefined; | ||
} | ||
|
||
if ( | ||
!Cesium.defined(pickedFeature) || | ||
!Cesium.defined(pickedFeature.content) || | ||
!Cesium.defined(pickedFeature.content.tile.i3sNode) | ||
) { | ||
viewer.selectedEntity = undefined; | ||
return; | ||
} | ||
|
||
// Highlight newly selected feature | ||
selected.feature = pickedFeature; | ||
Cesium.Color.clone(pickedFeature.color, selected.originalColor); | ||
pickedFeature.color = Cesium.Color.BLUE; | ||
|
||
const i3sNode = pickedFeature.content.tile.i3sNode; | ||
i3sNode.loadFields().then(function () { | ||
let description = "No attributes"; | ||
let name; | ||
|
||
const fields = i3sNode.getFieldsForFeature(pickedFeature.featureId); | ||
if (Object.keys(fields).length > 0) { | ||
description = | ||
'<table class="cesium-infoBox-defaultTable"><tbody>'; | ||
for (const fieldName in fields) { | ||
if (i3sNode.fields.hasOwnProperty(fieldName)) { | ||
description += `<tr><th>${fieldName}</th><td>`; | ||
description += `${fields[fieldName]}</td></tr>`; | ||
if (!Cesium.defined(name) && isNameProperty(fieldName)) { | ||
name = fields[fieldName]; | ||
} | ||
} | ||
} | ||
description += `</tbody></table>`; | ||
} | ||
if (!Cesium.defined(name)) { | ||
name = "unknown"; | ||
} | ||
selectedEntity.name = name; | ||
selectedEntity.description = description; | ||
viewer.selectedEntity = selectedEntity; | ||
}); | ||
}, | ||
Cesium.ScreenSpaceEventType.LEFT_CLICK); | ||
|
||
function isNameProperty(propertyName) { | ||
const name = propertyName.toLowerCase(); | ||
if ( | ||
name.localeCompare("name") === 0 || | ||
name.localeCompare("objname") === 0 || | ||
name.localeCompare("category") === 0 | ||
) { | ||
return true; | ||
} | ||
return false; | ||
} //Sandcastle_End | ||
}; | ||
if (typeof Cesium !== "undefined") { | ||
window.startupCalled = true; | ||
window.startup(Cesium).catch((error) => { | ||
"use strict"; | ||
console.error(error); | ||
}); | ||
Sandcastle.finishedLoading(); | ||
} | ||
</script> | ||
</body> | ||
</html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import Check from "./Check.js"; | ||
|
||
/** | ||
* Converts the value from sRGB color space to linear color space. | ||
* | ||
* @function | ||
* | ||
* @param {number} value The color value in sRGB color space. | ||
* @returns {number} Returns the color value in linear color space. | ||
* | ||
* @example | ||
* const srgbColor = [0.5, 0.5, 0.5]; | ||
* const linearColor = srgbColor.map(function (c) { | ||
* return Cesium.srgbToLinear(c); | ||
* }); | ||
*/ | ||
function srgbToLinear(value) { | ||
//>>includeStart('debug', pragmas.debug); | ||
Check.defined("value", value); | ||
//>>includeEnd('debug'); | ||
|
||
if (value <= 0.04045) { | ||
// eslint-disable-next-line no-loss-of-precision | ||
return value * 0.07739938080495356037151702786378; | ||
} | ||
return Math.pow( | ||
// eslint-disable-next-line no-loss-of-precision | ||
(value + 0.055) * 0.94786729857819905213270142180095, | ||
2.4 | ||
); | ||
} | ||
export default srgbToLinear; |
Oops, something went wrong.