
3D tiles are a powerful method for rendering large and complex 3D data sets on the web. They were developed as a solution to the challenges of displaying detailed 3D scenes in a browser, which traditionally required large amounts of data to be transferred and processed. 3D tiles break down the data into smaller, manageable pieces, allowing for efficient streaming, rendering, and interaction with the 3D scene. This makes it possible to create highly detailed and interactive visualizations without overwhelming the user’s device or network connection.
To get full source code for this tutorial, click here.
To check the live demo for this tutorial, click here.
The 3D Tiles specification, developed by Cesium, is an open standard for streaming 3D geospatial content. It enables the efficient streaming of massive 3D datasets to web browsers, mobile devices, and desktop applications.
To Integrate VueJS and CesiumJS, below is the nice tutorial:
Integrating Cesium Map with VueJS
Here is a step-by-step tutorial on how to convert a point cloud to 3D tiles and render it on a map using CesiumJS and Vue:
1. Install py3tiles:
py3dtiles is a Python library and command-line tool for working with 3D Tiles, an open standard for streaming massive heterogeneous 3D geospatial datasets. It allows you to convert various types of 3D data, such as point clouds, meshes, and geometries, into the 3D Tiles format for efficient streaming and visualization in web-based 3D mapping frameworks like CesiumJS.
|
1 |
pip install py3dtiles |
2. Prepare your point cloud data.
In this example, we are using the Clifton Suspension Bridge point cloud data in .laz format. We will process this lidar data into 3D tiles

3. Convert the point cloud to 3D tiles using py3dtiles:
This command processes the specified point cloud data and transforms it into a format suitable for streaming and rendering in 3D mapping applications using the 3D Tiles standard.
|
1 |
py3dtiles convert pointcloud/Clifton_Suspension_Bridge.laz --out tiles/ --overwrite |
The command py3dtiles convert pointcloud/Clifton_Suspension_Bridge.laz --out tiles/ --overwrite performs the following actions:
- Input: Converts the point cloud data stored in the
Clifton_Suspension_Bridge.lazfile. - Output: Generates 3D Tiles format data as output.
- Output Directory: Stores the converted 3D Tiles data in the
tiles/directory. - Overwrite Flag: Overwrites existing data in the output directory if it already exists.
4. Create a new Vue project and integrate CesiumJS with it.
Follow below link to integrate CesiumJS with VueJS.
Integrating Cesium Map with VueJS
5. Update the App.vue file with the provided code:
Let’s break down the provided code to understand how it renders point cloud 3D tiles in CesiumJS using Vue.js:
- Vue Component Structure:
- The code starts with a Vue component structure that includes a template, script, and style sections.
- Import Statements:
- It imports necessary modules from Cesium and Vue, including
Viewer,Ion,OpenStreetMapImageryProvider,ImageryLayer,CesiumTerrainProvider,Cartesian3,Cesium3DTileset,Transforms,Matrix4,HeadingPitchRange, andHeadingPitchRoll.
- It imports necessary modules from Cesium and Vue, including
- Cesium Ion Access Token:
- Sets the Cesium Ion access token using
Ion.defaultAccessTokento enable access to Cesium’s global terrain and imagery.
- Sets the Cesium Ion access token using
- Global Variables:
- Declares a global variable
CESIUM_BASE_URLfor Cesium’s base URL, which is set to the path where CesiumJS assets are stored (static/cesiumin this case).
- Declares a global variable
- Vue Component Definition:
- Defines a Vue component named
AppusingdefineComponent.
- Defines a Vue component named
- Mounted Hook:
- Uses the
mountedlifecycle hook to initialize Cesium viewer and render the 3D tiles.
- Uses the
- Creating Cesium Viewer:
- Sets up an OpenStreetMap base layer and initializes a Cesium
Viewerinside thecesiumContainerdiv.
- Sets up an OpenStreetMap base layer and initializes a Cesium
- Setting Camera View:
- Sets the camera view to a specific position (
destination) and orientation (heading,pitch,roll) usingviewer.camera.setView().
- Sets the camera view to a specific position (
- Loading and Rendering 3D Tiles:
- Uses
Cesium3DTileset.fromUrlto load the 3D tileset from a specified URL ("static/tiles/tileset.json") and adds it to the viewer’s scene primitives.
- Uses
- Adjusting Tileset Position:
- Calculates a
transformmatrix usingTransforms.headingPitchRollToFixedFramebased on longitude, latitude, height, and orientation, and applies it to the tileset’smodelMatrixproperty.
- Calculates a
- Zooming to Tileset:
- Calls
viewer.zoomTo(tileset)to zoom and focus the camera on the loaded tileset.
- Calls
- Error Handling:
- Provides error handling for loading and creating the tileset.
- Styling:
- Includes basic styling for full-width and full-height display of the Cesium container (
cesiumContainer).
- Includes basic styling for full-width and full-height display of the Cesium container (
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
<template> <div id = "cesiumContainer" ></div> </template> <script lang="ts"> import { defineComponent } from 'vue' import { Viewer, Ion, OpenStreetMapImageryProvider, ImageryLayer, CesiumTerrainProvider, Cartesian3 } from "cesium"; import { Cesium3DTileset } from 'cesium'; import { Transforms } from 'cesium'; import { Matrix4 } from 'cesium'; import { HeadingPitchRange } from 'cesium'; import { HeadingPitchRoll } from 'cesium'; import { Terrain } from 'cesium'; import "cesium/Build/Cesium/Widgets/widgets.css"; Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwZjE0YjBiYy1iNjZiLTQ5ZWQtOTBmOS0yODQxZjYyMGQ0ZGIiLCJpZCI6MjY5MDcsImlhdCI6MTcxMzQzOTMxMH0.O4RDeS46mL3ABENB4wHIbiFPdCj8ze1xYPUrDrRVs1Y'; declare global { interface Window { CESIUM_BASE_URL: string; } } window.CESIUM_BASE_URL = 'static/cesium'; export default defineComponent({ name: 'App', async mounted() { let baseLayer = new ImageryLayer(new OpenStreetMapImageryProvider({ url: "https://tile.openstreetmap.org/" }), {}) let viewer = new Viewer("cesiumContainer", { baseLayer: baseLayer, terrain: Terrain.fromWorldTerrain(), }); viewer.camera.setView({ destination: new Cartesian3(1263093.7190924052, 5298125.807220887, 3311788.2669270574), orientation: { heading: 0.6291314004139439, pitch: -0.11972375171111294, roll: 6.283092953238719 } }); try { const tileset = await Cesium3DTileset.fromUrl( "static/tiles/tileset.json" ); viewer.scene.primitives.add(tileset); var longitude = -2.630805; var latitude = 51.453787; var height = 135; var cartesian = Cartesian3.fromDegrees(longitude, latitude, height); var transform = Transforms.headingPitchRollToFixedFrame(cartesian, new HeadingPitchRoll(0.65)); // tileset._root.transform = Matrix4.IDENTITY; tileset.modelMatrix = transform; viewer.zoomTo(tileset); } catch (error) { console.error(`Error creating tileset: ${error}`); } } }) </script> <style> html, body, #cesiumContainer, #app { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; font-family: sans-serif; } </style> |
In summary, this code sets up a Vue component to initialize a Cesium viewer, load and render a 3D tileset (point cloud in this case), set camera view and tileset position, and handle errors during the process. It combines Vue.js reactivity with CesiumJS’s powerful 3D rendering capabilities to visualize 3D geospatial data effectively.
6. Run the development server:

|
1 |
npm run dev |
Open the browser and navigate to http://127.0.0.1:5173/. You should see the 3D tiles rendering on the map.
3D tiles offer several advantages over traditional methods of rendering large 3D datasets on the web:
- Streaming: 3D tiles allow for efficient streaming of large datasets, enabling the browser to load only the data required to render the current view.
- Level of Detail (LOD): 3D tiles support LOD, which means that the data is rendered at varying levels of detail depending on the distance from the camera. This allows for efficient rendering and interaction with the scene.
- Progressive Loading: 3D tiles are loaded progressively, meaning that the most important data is loaded first, providing a smooth user experience.
- Standardized Format: The 3D Tiles specification is an open standard, which means that it is interoperable with various platforms and tools, making it easier to work with 3D data across different systems.
I hope this tutorial will create a good foundation for you. If you want tutorials on another GIS topic or you have any queries, please send an mail at contact@spatial-dev.guru.
