点击查看:最新Cesium可视化系统实战视频课程

202502061653156ba984e8b7ad9d414381de8f65e19da0804Cesium 是一个强大的 WebGL 开源库,广泛应用于地理信息系统(GIS)和三维地图可视化领域。通过 Cesium,开发者可以轻松加载并展示 3D 模型,如飞机、车辆、建筑等。本文将基于上述代码,详细讲解如何使用 Cesium 加载 3D 模型,以及实现交互式模型选择。


一、基本概念

在 Cesium 中,3D 模型通常以 glTFGLB 格式加载。Cesium 提供了丰富的接口用于展示模型并进行交互操作。常见用途包括添加动画、调整模型位置和姿态、设置缩放比例等。

本文示例代码的功能包括:

  1. 初始化一个 Cesium Viewer。
  2. 加载不同的 3D 模型到场景中。
  3. 添加模型选择菜单,实现动态加载不同类型的模型。

二、代码结构概览

代码可以分为以下几个主要部分:

  1. 初始化 Cesium.Viewer
  2. 创建 createModel 函数,用于加载和定位模型。
  3. 配置模型选择菜单,动态选择加载模型。

三、初始化 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 属性指定模型文件的路径,minimumPixelSizemaximumScale 控制模型的大小和缩放行为。


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);

六、加载示例模型

上面的代码支持加载多种模型,例如:

  1. 飞机模型(Aircraft)
    • 路径:../SampleData/models/CesiumAir/Cesium_Air.glb
    • 高度:5000.0
  1. 无人机模型(Drone)
    • 路径:../SampleData/models/CesiumDrone/CesiumDrone.glb
    • 高度:150.0
  1. 地面车辆(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 应用、虚拟现实和三维地图开发提供了强大的支持。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注