点击查看:最新Cesium可视化系统实战视频课程
Cesium 是一个强大的 WebGL 开源库,广泛应用于地理信息系统(GIS)和三维地图可视化领域。通过 Cesium,开发者可以轻松加载并展示 3D 模型,如飞机、车辆、建筑等。本文将基于上述代码,详细讲解如何使用 Cesium 加载 3D 模型,以及实现交互式模型选择。
一、基本概念
在 Cesium 中,3D 模型通常以 glTF
或 GLB
格式加载。Cesium 提供了丰富的接口用于展示模型并进行交互操作。常见用途包括添加动画、调整模型位置和姿态、设置缩放比例等。
本文示例代码的功能包括:
- 初始化一个 Cesium Viewer。
- 加载不同的 3D 模型到场景中。
- 添加模型选择菜单,实现动态加载不同类型的模型。
二、代码结构概览
代码可以分为以下几个主要部分:
- 初始化
Cesium.Viewer
。 - 创建
createModel
函数,用于加载和定位模型。 - 配置模型选择菜单,动态选择加载模型。
三、初始化 Cesium Viewer
首先,初始化一个 Cesium.Viewer
对象,它是 Cesium 的核心对象,负责管理地图场景的渲染和交互。
javascript
const viewer = new Cesium.Viewer("cesiumContainer", {
infoBox: false, // 关闭信息框
selectionIndicator: false, // 关闭实体选择指示器
shadows: true, // 启用模型阴影
shouldAnimate: true, // 启用动画
});
参数说明
infoBox
: 控制是否显示实体的详细信息框。selectionIndicator
: 控制是否显示实体被选中的指示器。shadows
: 开启场景中的动态阴影效果。shouldAnimate
: 允许场景中存在的动画模型正常运行。
四、加载模型函数 createModel
1. 功能概述
createModel
是一个通用函数,用于加载 3D 模型到场景中,并设置模型的位置信息、朝向、缩放比例等。它还支持动态清除先前的实体,确保场景中只保留一个模型。
function createModel(url, height) {
// 清除场景中的所有实体
viewer.entities.removeAll();
// 定义模型的位置
const position = Cesium.Cartesian3.fromDegrees(
-123.0744619, // 经度
44.0503706, // 纬度
height // 高度(单位:米)
);
// 设置模型的方向
const heading = Cesium.Math.toRadians(135); // 方位角(度数转弧度)
const pitch = 0; // 俯仰角
const roll = 0; // 翻滚角
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
// 添加模型到场景
const entity = viewer.entities.add({
name: url, // 模型的名称
position: position, // 模型的位置
orientation: orientation, // 模型的朝向
model: {
uri: url, // 模型的路径
minimumPixelSize: 128, // 模型的最小像素尺寸
maximumScale: 20000, // 模型的最大缩放倍数
},
});
// 使相机跟随模型
viewer.trackedEntity = entity;
}
2. 关键部分详解
(1)位置计算
模型的位置由 Cesium.Cartesian3.fromDegrees
方法定义。它接收经度、纬度和高度(单位:米)作为参数,返回一个三维笛卡尔坐标值,表示模型在地球上的具体位置。
const position = Cesium.Cartesian3.fromDegrees(
-123.0744619, // 经度
44.0503706, // 纬度
height // 高度
);
(2)方向设置
通过 HeadingPitchRoll
设置模型的朝向:
- Heading(航向角): 模型在水平面上的旋转角度。
- Pitch(俯仰角): 模型的上下倾斜角度。
- Roll(滚转角): 模型的左右倾斜角度。
航向角需要用 Cesium.Math.toRadians
将角度值转换为弧度值。
javascript
const heading = Cesium.Math.toRadians(135);
const pitch = 0;
const roll = 0;
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
通过 Cesium.Transforms.headingPitchRollQuaternion
函数,将 HeadingPitchRoll
转换为四元数,最终用作模型的方向。
(3)模型加载
模型加载通过 viewer.entities.add
添加到场景中,uri
属性指定模型文件的路径,minimumPixelSize
和 maximumScale
控制模型的大小和缩放行为。
const entity = viewer.entities.add({
model: {
uri: url,
minimumPixelSize: 128,
maximumScale: 20000,
},
});
(4)相机跟随
通过 viewer.trackedEntity
,设置相机跟随模型,确保模型始终处于视野范围内。
五、模型选择菜单
通过配置菜单选项,允许用户动态选择加载的模型。代码中的 options
数组定义了多个模型选项,每个选项包含模型名称和对应的 onselect
回调函数。
const options = [
{
text: "Aircraft",
onselect: function () {
createModel("../SampleData/models/CesiumAir/Cesium_Air.glb", 5000.0);
},
},
{
text: "Drone",
onselect: function () {
createModel("../SampleData/models/CesiumDrone/CesiumDrone.glb", 150.0);
},
},
// 其他模型选项
];
添加菜单
通过 Sandcastle.addToolbarMenu
将选项加载为工具栏菜单,供用户选择不同的模型。
javascript
Sandcastle.addToolbarMenu(options);
六、加载示例模型
上面的代码支持加载多种模型,例如:
- 飞机模型(Aircraft):
-
- 路径:
../SampleData/models/CesiumAir/Cesium_Air.glb
- 高度:
5000.0
米
- 路径:
- 无人机模型(Drone):
-
- 路径:
../SampleData/models/CesiumDrone/CesiumDrone.glb
- 高度:
150.0
米
- 路径:
- 地面车辆(Ground Vehicle):
-
- 路径:
../SampleData/models/GroundVehicle/GroundVehicle.glb
- 高度:
0
米
- 路径:
通过选择不同的菜单项,调用对应的 onselect
方法动态加载模型。
七、完整代码
完整代码展示如下:
const viewer = new Cesium.Viewer("cesiumContainer", {
infoBox: false,
selectionIndicator: false,
shadows: true,
shouldAnimate: true,
});
function createModel(url, height) {
viewer.entities.removeAll();
const position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);
const heading = Cesium.Math.toRadians(135);
const pitch = 0;
const roll = 0;
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
const entity = viewer.entities.add({
name: url,
position: position,
orientation: orientation,
model: {
uri: url,
minimumPixelSize: 128,
maximumScale: 20000,
},
});
viewer.trackedEntity = entity;
}
const options = [
{ text: "Aircraft", onselect: () => createModel("../SampleData/models/CesiumAir/Cesium_Air.glb", 5000.0) },
{ text: "Drone", onselect: () => createModel("../SampleData/models/CesiumDrone/CesiumDrone.glb", 150.0) },
{ text: "Ground Vehicle", onselect: () => createModel("../SampleData/models/GroundVehicle/GroundVehicle.glb", 0) },
];
Sandcastle.addToolbarMenu(options);
八、运行效果
运行代码后,页面加载 Cesium 地图容器,用户可以通过菜单选择模型,动态加载到场景中。每次选择一个模型,场景会清除先前的模型并展示新模型。
九、总结
本文从代码解析、模型加载原理到菜单交互,详细讲解了如何使用 Cesium 加载 3D 模型。通过合理设置模型位置、方向和缩放参数,开发者可以轻松实现丰富的 3D 场景展示效果。这为 GIS 应用、虚拟现实和三维地图开发提供了强大的支持。