Skip to content

Commit

Permalink
Merge pull request #9634 from Tamrat-B/cesium_i3s_support
Browse files Browse the repository at this point in the history
Added I3S data source support in Cesium
  • Loading branch information
lilleyse authored Oct 17, 2022
2 parents e580be5 + bb23732 commit 92a6063
Show file tree
Hide file tree
Showing 17 changed files with 6,499 additions and 5 deletions.
176 changes: 176 additions & 0 deletions Apps/Sandcastle/gallery/I3S 3D Object Layer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<!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 3D Object Layer from a service."
/>
<meta name="cesium-sandcastle-labels" content="DataSources" />
<title>I3S Consumption 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);
</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 = function (Cesium) {
"use strict";
//Sandcastle_Begin
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: new Cesium.createWorldTerrain(),
animation: false,
timeline: false,
});
// 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 = {
"San Francisco":
"https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_3DObjects_1_7/SceneServer/layers/0",
};
// Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based
// height systems (Cesium World Terrain).
// If this is not specified, or the URL is invalid no geoid conversion will be applied.
// The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model
const geoidService = new Cesium.ArcGISTiledElevationTerrainProvider({
url:
"https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer",
});
// Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing
const cesium3dTilesetOptions = {
skipLevelOfDetail: false,
debugShowBoundingVolume: false,
};
const i3sOptions = {
url: tours["San Francisco"],
traceFetches: false, // for tracing I3S fetches
geoidTiledTerrainProvider: geoidService, // pass the geoid service
cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset
};

// Create I3S data provider
const i3sProvider = new Cesium.I3SDataProvider(i3sOptions);

// Center camera on I3S once it's loaded
i3sProvider.readyPromise.then(function () {
const center = Cesium.Rectangle.center(i3sProvider.extent);
center.height = 10000.0;
viewer.camera.setView({
destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center),
});
});

// Add the i3s layer provider as a primitive data type
viewer.scene.primitives.add(i3sProvider);
// 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
) {
// Pick a new feature
const pickedFeature = viewer.scene.pick(movement.position);
if (!Cesium.defined(pickedFeature)) {
return;
}

const pickedPosition = viewer.scene.pickPosition(movement.position);

if (
Cesium.defined(pickedFeature.content) &&
Cesium.defined(pickedFeature.content.tile.i3sNode)
) {
const i3sNode = pickedFeature.content.tile.i3sNode;
i3sNode.loadFields().then(function () {
const geometry = i3sNode.geometryData[0];
if (pickedPosition) {
const location = geometry.getClosestPointIndexOnTriangle(
pickedPosition.x,
pickedPosition.y,
pickedPosition.z
);
let description = "No attributes";
let name;
if (
location.index !== -1 &&
geometry.customAttributes.featureIndex
) {
console.log(
`pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}`
);
const featureIndex =
geometry.customAttributes.featureIndex[location.index];
if (Object.keys(i3sNode.fields).length > 0) {
description =
'<table class="cesium-infoBox-defaultTable"><tbody>';
for (const fieldName in i3sNode.fields) {
if (i3sNode.fields.hasOwnProperty(fieldName)) {
const field = i3sNode.fields[fieldName];
description += `<tr><th>${field.name}</th><td>`;
description += `${field.values[featureIndex]}</td></tr>`;
console.log(
`${field.name}: ${field.values[featureIndex]}`
);
if (
!Cesium.defined(name) &&
isNameProperty(field.name)
) {
name = field.values[featureIndex];
}
}
}
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
) {
return true;
}
return false;
}
//Sandcastle_End
if (typeof Cesium !== "undefined") {
window.startupCalled = true;
window.startup(Cesium);
}
};
</script>
</body>
</html>
Binary file added Apps/Sandcastle/gallery/I3S 3D Object Layer.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
176 changes: 176 additions & 0 deletions Apps/Sandcastle/gallery/I3S Feature Picking.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<!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="Pick features from an I3S 3D Object Layer."
/>
<meta name="cesium-sandcastle-labels" content="DataSources, Showcases" />
<title>I3S Feature Picking 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);
</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 = function (Cesium) {
"use strict";
//Sandcastle_Begin
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: new Cesium.createWorldTerrain(),
animation: false,
timeline: false,
});
// 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 = {
"New York":
"https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/NYC_Attributed_v17/SceneServer",
};
// Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based
// height systems (Cesium World Terrain).
// If this is not specified, or the URL is invalid no geoid conversion will be applied.
// The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model
const geoidService = new Cesium.ArcGISTiledElevationTerrainProvider({
url:
"https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer",
});
// Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing
const cesium3dTilesetOptions = {
skipLevelOfDetail: false,
debugShowBoundingVolume: false,
};
const i3sOptions = {
url: tours["New York"],
traceFetches: false, // for tracing I3S fetches
geoidTiledTerrainProvider: geoidService, // pass the geoid service
cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset
};

// Create I3S data provider
const i3sProvider = new Cesium.I3SDataProvider(i3sOptions);

// Center camera on I3S once it's loaded
i3sProvider.readyPromise.then(function () {
const center = Cesium.Rectangle.center(i3sProvider.extent);
center.height = 10000.0;
viewer.camera.setView({
destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center),
});
});

// Add the i3s layer provider as a primitive data type
viewer.scene.primitives.add(i3sProvider);
// 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
) {
// Pick a new feature
const pickedFeature = viewer.scene.pick(movement.position);
if (!Cesium.defined(pickedFeature)) {
return;
}

const pickedPosition = viewer.scene.pickPosition(movement.position);

if (
Cesium.defined(pickedFeature.content) &&
Cesium.defined(pickedFeature.content.tile.i3sNode)
) {
const i3sNode = pickedFeature.content.tile.i3sNode;
i3sNode.loadFields().then(function () {
const geometry = i3sNode.geometryData[0];
if (pickedPosition) {
const location = geometry.getClosestPointIndexOnTriangle(
pickedPosition.x,
pickedPosition.y,
pickedPosition.z
);
let description = "No attributes";
let name;
if (
location.index !== -1 &&
geometry.customAttributes.featureIndex
) {
console.log(
`pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}`
);
const featureIndex =
geometry.customAttributes.featureIndex[location.index];
if (Object.keys(i3sNode.fields).length > 0) {
description =
'<table class="cesium-infoBox-defaultTable"><tbody>';
for (const fieldName in i3sNode.fields) {
if (i3sNode.fields.hasOwnProperty(fieldName)) {
const field = i3sNode.fields[fieldName];
description += `<tr><th>${field.name}</th><td>`;
description += `${field.values[featureIndex]}</td></tr>`;
console.log(
`${field.name}: ${field.values[featureIndex]}`
);
if (
!Cesium.defined(name) &&
isNameProperty(field.name)
) {
name = field.values[featureIndex];
}
}
}
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
) {
return true;
}
return false;
}
//Sandcastle_End
if (typeof Cesium !== "undefined") {
window.startupCalled = true;
window.startup(Cesium);
}
};
</script>
</body>
</html>
Binary file added Apps/Sandcastle/gallery/I3S Feature Picking.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 92a6063

Please sign in to comment.