Skip to main content

iTwin: Adding Design Context Using Cesium ion

Combining iTwin Platform with Cesium brings rich engineering metadata into geospatial visualizations, enabling infrastructure models to be explored both in their real-world location and with all the associated design intelligence, properties, and context. 

In this tutorial, you’ll add real-world context using Cesium ion. Global datasets like Cesium World Terrain or Google Photorealistic 3D Tiles provide accurate geospatial context, and infrastructure projects often require more site-specific data. That’s where Cesium ion reality modeling comes in: you can generate precise 3D context from drone-captured imagery. That’s what we’ll cover in this tutorial. In the next one, you’ll bring in the iTwin design model to complete the scene. The image below shows a preview of the final result—combining engineering data from a bridge project into a contextualized geospatial view. 

iTwin rail bridge design and Cesium ion reality modeling context visualized in CesiumJS.

You’ll learn how to:

  • Add contextual 3D data from photos using Cesium ion. 
  • Set up a CesiumJS app to load Cesium ion assets. 

Prerequisites

1Upload context data to Cesium ion

In this step, Cesium ion will use the provided photos to generate a reality model through 3D reconstruction. This takes approximately 50 minutes. 

If you prefer to skip the reconstruction, you can upload a pre-tiled reality model instead, available here

1 Download the bridge photo dataset.

2Go to https://ion.cesium.com to upload the photos.

Click My Assets. Click Add Data, then Add files.

iTwin Tutorial: Add Design Context Using Cesium ion. Click Add Data, then Add files.

Select Bridge.zip and click Open

Update Asset name (personal preference). For type of data, choose Photos (for 3D reconstruction).

iTwin tutorial: Add Design Context Using Cesium ion. For type of data, choose Photos (for 3D reconstruction).

Use the default Reconstruct models from photos settings.

iTwin tutorial: Add Design Context Using Cesium ion. Use the default Reconstruct models from photos settings.

Click Upload.

Information

Tiling may take 50 minutes or longer, depending on dataset size, upload speed, and current processing load on Cesium ion. It’s safe to step away while the model processes in the background.

3Once tiling is complete, you’ll see the asset on the Cesium globe. At the bottom of the right side of the preview, you’ll find the Cesium ion asset ID:

iTwin tutorial: Add Design Context Using Cesium ion. At the bottom of the right side of the preview, you’ll find the Cesium ion asset ID.

4Copy the asset ID for use during Step 3.

2Clone the starter app

You’ll use a prebuilt CesiumJS + iTwin starter app to visualize the bridge asset. 

1Clone the repository:

   git clone https://github.com/iTwin/itwin-cesium-tutorial-app.git

   cd cesium-itwin-tutorial-app 

2Install dependencies:

npm install

3Rename .env.example to .env; then open it in a text editor and add your own Cesium ion token:

VITE_ION_TOKEN="your_access_token" 

You can generate this from https://ion.cesium.com/tokens. Default permission settings will work for this tutorial, but for more information on permissions settings see our guide here

4Start the app:

npm run dev

5Open the app in your browser (default http://localhost:5173) and you should see the Cesium globe.

Information

Your app may run on a different port. Check the output of npm run dev to find the correct URL.

3Add the asset to the app

1In the cloned app repository, open src/main.js.  You’ll add the code from the next steps to the end of the main function.

Add a tileset to the application that references context data asset.  Be sure to replace "your-asset-id" with your Cesium ion asset ID from Step 1.

const railContextTileset = await Cesium.Cesium3DTileset.fromIonAssetId("your-asset-id");  // *** Replace your-asset-id *** 

2Add the tileset to the scene:

viewer.scene.primitives.add(railContextTileset); 

3Automatically zoom to the tileset once it’s ready:

viewer.zoomTo(railContextTileset); 

4Save the file and refresh the browser. You should now see the asset loaded on the globe.

iTwin tutorial: Add Design Context Using Cesium ion. You should now see the asset loaded on the globe. 

By default, Cesium World Terrain and your uploaded reality model may visually overlap, causing an unnatural doubling of the ground surface. To solve this, you'll use a clipping polygon to hide the terrain under the reality model footprint. 

4Clip reality data footprint from the terrain

You’ll load a GeoJSON file that defines the area to clip and apply it as a clipping region to the globe’s terrain. 

1Upload the footprint GeoJSON to Cesium ion.

We’ve prepared a GeoJSON file (RailContextFootprint.geojson) that outlines the exact boundaries of the reality model. Upload it to your Cesium ion account: 

Go to https://ion.cesium.com. Click My Assets, then Add Data > Add files. From there, select the RailContextFootprint.geojson file. Cesium ion automatically detects this as GeoJSON

iTwin tutorial: Add Design Context Using Cesium ion. Select the RailContextFootprint.geojson file. Cesium ion automatically detects this as GeoJSON. 

Click Upload.

After tiling completes, take note of the asset ID from the preview page—you’ll need it in the next step. 

2Add the clipping polygon in code. Open src/main.js and add the following code to the end of the main function. Be sure to replace geojson-asset-id in the first line with your own asset ID.

// Load a GeoJSON file with positions defining the reality model footprint 
const railContextBoundaryResource = await Cesium.IonResource.fromAssetId("geojson-asset-id"); // *** Replace geojson-asset-id *** 
const railContextBoundaryDataSource = await Cesium.GeoJsonDataSource.load(railContextBoundaryResource); 
 
let footprint = railContextBoundaryDataSource.entities.values.find((entity) => 
	Cesium.defined(entity.polygon), 
); 

// Add a clipping region based on the loaded reality model footprint 
const positions = footprint.polygon.hierarchy.getValue().positions; 
const clippingPolygons = new Cesium.ClippingPolygonCollection({ 
polygons: [ 
     new Cesium.ClippingPolygon({ 
          positions: positions, 
          }), 
     ],}); 
 
viewer.scene.globe.clippingPolygons = clippingPolygons; 

3Save your changes and refresh the browser. You should now see the terrain surface clipped away underneath the reality model, eliminating visual conflict and giving your scene a cleaner, more accurate appearance. 

iTwin tutorial: Add Design Context Using Cesium ion. You should now see the terrain surface clipped away underneath the reality model, eliminating visual conflict and giving your scene a cleaner, more accurate appearance. 

Next steps

You’ve successfully visualized contextual 3D data for an iTwin. This gives your design data meaningful location context. In the next tutorial, you’ll integrate design data into this same viewer to complete the iTwin visualization. 

If you want a deeper dive into creating reality models in Cesium ion, check out this tutorial on reconstruction.

Content and code examples at cesium.com/learn are available under the Apache 2.0 license. You can use the code examples in your commercial or non-commercial applications.