Cesium快速入门到精通系列教程二:添加地形与添加自定义地形、相机控制
一、添加地形与添加自定义地形
在 Cesium 1.93 中添加地形可以通过配置terrainProvider实现。Cesium 支持多种地形数据源,包括 Cesium Ion 提供的全球地形、自定义地形服务以及开源地形数据。下面介绍几种常见的添加地形的方法:
使用 Cesium Ion 全球地形服务
这是最简单的方式,需要一个 Cesium Ion 账户和访问令牌:
// 设置Cesium Ion访问令牌
Cesium.Ion.defaultAccessToken = '你的Cesium Ion令牌';// 初始化Viewer并启用全球地形
const viewer = new Cesium.Viewer('cesiumContainer', {terrainProvider: Cesium.createWorldTerrain({requestVertexNormals: true, // 启用地形光照requestWaterMask: true // 启用水面效果}),baseLayerPicker: false, // 可选:禁用默认图层选择器
});
添加自定义地形
1、从地理空间数据云下载数据:
数据资源->公开数据->DEM 数字高程数据
2、从cesiumlab下载工具进行数据转换:
安装下载的工具,比如当前版本cesiumlab4_4.0.8.exe;
打开工具,安装以下方式设置提交即可:
将以上生成的瓦片本地部署,部署的方式很多种,只要保证能通过url在线访问即可:
在代码中加载:
const viewer = new Cesium.Viewer('cesiumContainer', {terrainProvider: new Cesium.CesiumTerrainProvider({url: 'http://localhost:3000', // 替换为你的服务器地址requestVertexNormals: true, // 请求法线以支持地形光照requestWaterMask: true // 请求水掩码以支持水面效果})
});
// 配置自定义地形服务
const customTerrainProvider = new Cesium.CesiumTerrainProvider({url: 'http://localhost:3000', // 替换为你的服务器地址requestVertexNormals: true,requestWaterMask: true,isSct: true // 若为 SuperMap iServer 服务需设为 true [6](@ref)
});// 应用自定义地形
viewer.terrainProvider = customTerrainProvider;
常见问题排查
问题现象 | 解决方案 |
---|---|
地形加载失败 | 检查网络连接和 Cesium Ion 令牌 |
水体效果未显示 | 确认 requestWaterMask: true |
地形贴图模糊 | 增大 viewer.scene.maximumScreenSpaceError 值 |
内存泄漏 | 限制 viewer.scene.globe.tileCacheSize |
二、相机的方向和位置
在Cesium 1.93中,相机的方向和位置控制是三维场景交互的核心。
1、相机坐标系与关键概念
1.1 相机坐标系基础
将相机比喻成直立行走的人,镜头好比人的视野。
- 位置(Position):相机在三维空间中的笛卡尔坐标(Cartesian3),以地球质心为原点。
- 方向(Direction):相机的朝向,由视线向量(View Vector)表示,指向场景中的目标点。
- 上方向(Up Vector):相机的 “上方” 方向,默认与地球表面垂直(Z 轴正方向)。
- heading:绕Y轴旋转(正北为0°,向东为正方向)。
- pitch:绕X轴旋转(-90°为俯视地面,0°为平视,正值为仰视)。
- roll:绕Z轴旋转(默认0°,正值为右倾)。
- 参考系(Reference Frame):相机运动的参考坐标系,通常为ENU(东 - 北 - 上)或ECF(地心地固坐标系)。
const orientation = {heading: Cesium.Math.toRadians(0), // 正北pitch: Cesium.Math.toRadians(-90), // 俯视地面roll: 0.0
};
2、相机控制的核心方法
2.1 设置默认视角
// 设置Cesium默认视角
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(89.5, // 西边经度20.4, // 南边维度110.4, // 东边经度61.2) // 北边维度
2.2 setView:直接设置视角
特点:无动画,立即切换到目标位置和方向。
viewer.camera.setView({destination: position, // 目标位置(Cartesian3)orientation: orientation // 方向参数
});
const position = Cesium.Cartesian3.fromDegrees(116.3907917, 39.9158389, 500); // 故宫const orientation = {heading: Cesium.Math.toRadians(0), // 正北pitch: Cesium.Math.toRadians(-90), // 俯视地面roll: 0.0};viewer.camera.setView({destination: position,orientation});
2.3 flyTo:动画飞行至目标
特点:支持平滑过渡,可设置飞行时长、视角偏移等。
关键参数:
- duration:动画时间(秒)。
- pitchAdjustHeight:高度超过此值时自动调整俯仰角。
viewer.camera.flyTo({destination: position,orientation: orientation,duration: 5, // 5秒动画pitchAdjustHeight: -90 // 强制俯视地面
});
2.4 lookAt:视角锁定目标点
特点:相机位置固定,始终朝向目标点。
参数:target(目标点)和offset(偏移量,支持HeadingPitchRange)。
const center = Cesium.Cartesian3.fromDegrees(116.4, 39.9);
viewer.camera.lookAt(center, new Cesium.HeadingPitchRange(0, -Math.PI/2, 1000));
2.5 viewBoundingSphere:环绕目标区域
适用场景:室内或小范围模型浏览。
const boundingSphere = new Cesium.BoundingSphere(center, radius);
viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0, 0, 0));
2.6 方向控制的进阶应用
2.6.1 局部坐标系转换
使用Transforms.eastNorthUpToFixedFrame将局部坐标转换为全局坐标系:
const localPosition = new Cesium.Cartesian3(10, 20, 0);
const transform = Cesium.Transforms.eastNorthUpToFixedFrame(localPosition);
const globalPosition = Cesium.Matrix4.multiplyByPoint(transform, localPosition);
2.6.2 动态方向控制
通过事件监听实时更新相机方向:
viewer.scene.preRender.addEventListener(() => {const heading = viewer.camera.heading;const pitch = viewer.camera.pitch;console.log(`当前航向:${Cesium.Math.toDegrees(heading).toFixed(2)}°`);
});
2.6.3 实体跟随模式
使用trackedEntity让相机自动跟随移动目标:
viewer.trackedEntity = entity; // 实体ID或对象
2.6.4 多阶段飞行
viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(116.39, 39.90, 1000000),duration: 3,orientation: { heading: 0, pitch: -Math.PI/2, roll: 0 },complete: () => {// 第一阶段完成后触发第二阶段viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(116.40, 39.91, 500000),duration: 2,easingFunction: Cesium.EasingFunction.CUBIC_IN_OUT});}
});
效果:分阶段飞行,首阶段俯冲至地面,第二阶段缓升至目标点。
2.7 常见问题与注意事项
- 坐标系一致性
确保位置和方向参数在同一坐标系下(如WGS84)。若使用局部坐标,需通过变换矩阵转换。
- 俯仰角限制
默认俯仰角范围为[-π/2, π/2],超出可能导致视角异常。可通过viewer.camera.pitchLimits调整。
- 性能优化
频繁调用flyTo或setView时,建议合并连续操作,避免卡顿。
2.8 完整示例:相机环绕目标点
// 定义目标点(北京天安门)
const target = Cesium.Cartesian3.fromDegrees(116.397, 39.908, 50);// 设置相机初始位置和方向
viewer.camera.setView({destination: Cesium.Cartesian3.fromDegrees(116.397, 39.908, 1000),orientation: {heading: Cesium.Math.toRadians(0),pitch: Cesium.Math.toRadians(-30),roll: 0}
});// 启动环绕动画(每5秒绕目标一圈)
viewer.clock.onTick.addEventListener(() => {const time = Cesium.JulianDate.now(viewer.clock.currentTime);const angle = (time.secondsOfDay * 360) / 5; // 每5秒旋转360°viewer.camera.setView({destination: Cesium.Cartesian3.fromDegrees(116.397 + 10 * Math.cos(Cesium.Math.toRadians(angle)),39.908 + 10 * Math.sin(Cesium.Math.toRadians(angle)),1000),orientation: {heading: Cesium.Math.toRadians(angle),pitch: Cesium.Math.toRadians(-30),roll: 0}});
});
2.9 相机动画与相机动态交互
Cesium 1.93 实现镜头飞向故宫的完整示例,包含了基础的场景设置、相机飞行动画以及简单的交互控制。
<template><div id="cesiumContainer"></div><div class="controls"><button id="flyToPalaceBtn">飞向故宫</button><button id="flyToGreatWallBtn">飞向长城</button><button id="resetViewBtn">重置视角</button></div>
</template><script setup>
Cesium.Ion.defaultAccessToken = 'Cesium defaultAccessToken'
import { onMounted } from "vue";
import * as Cesium from "cesium";
import "./Widgets/widgets.css";window.CESIUM_BASE_URL = "/"; // 设置Cesium静态资源路径(public目录)onMounted(() => {// 初始化Viewerconst viewer = new Cesium.Viewer('cesiumContainer', {geocoder: false, //设置搜索框是否可见homeButton: false, // 返回初始位置键是否可见sceneModePicker: false, // 查看器选择模式选择键是否可见baseLayerPicker: false, // 图层选择键是否可见navigationHelpButton: false, // 帮助按钮是否可见animation: false, // 播放控制按钮是否可见timeline: false, // 时间轴是否可见fullscreenButton: false, // 全屏按钮是否可见terrainProvider: Cesium.createWorldTerrain()});// 故宫位置(经纬度和高度)const palacePosition = {destination: Cesium.Cartesian3.fromDegrees(116.3907917, 39.9158389, 500), // 经度、纬度、高度(米)orientation: {heading: Cesium.Math.toRadians(0.0), // 偏航角(向东)pitch: Cesium.Math.toRadians(-30.0), // 俯仰角(向下倾斜)roll: 0.0 // 翻滚角},duration: 5, // 飞行持续时间(秒)maximumHeight: 2000, // 飞行过程中最大高度(米)curveAmount: 0.5 // 飞行曲线弯曲程度(0-1)};// 长城位置(慕田峪段)const greatWallPosition = {destination: Cesium.Cartesian3.fromDegrees(116.6558, 40.4139, 500),orientation: {heading: Cesium.Math.toRadians(90.0),pitch: Cesium.Math.toRadians(-20.0),roll: 0.0},duration: 5,maximumHeight: 3000};// 初始视角const initialView = {destination: Cesium.Cartesian3.fromDegrees(116.3907917, 39.9158389, 15000),orientation: {heading: Cesium.Math.toRadians(0.0),pitch: Cesium.Math.toRadians(-30.0),roll: 0.0}};// 设置初始视角viewer.camera.setView(initialView);// 飞向故宫按钮事件document.getElementById('flyToPalaceBtn').addEventListener('click', function () {viewer.camera.flyTo(palacePosition);});// 飞向长城按钮事件document.getElementById('flyToGreatWallBtn').addEventListener('click', function () {viewer.camera.flyTo(greatWallPosition);});// 重置视角按钮事件document.getElementById('resetViewBtn').addEventListener('click', function () {viewer.camera.setView(initialView);});
})</script><style scoped>
* {margin: 0;padding: 0;
}#cesiumContainer {width: 100wh;height: 100vh;
}.controls {position: absolute;bottom: 20px;left: 50%;transform: translateX(-50%);display: flex;gap: 10px;z-index: 100;
}button {padding: 8px 16px;background-color: #007BFF;color: white;border: none;border-radius: 4px;cursor: pointer;font-size: 14px;
}button:hover {background-color: #0056b3;
}
</style>
相关文章:

Cesium快速入门到精通系列教程二:添加地形与添加自定义地形、相机控制
一、添加地形与添加自定义地形 在 Cesium 1.93 中添加地形可以通过配置terrainProvider实现。Cesium 支持多种地形数据源,包括 Cesium Ion 提供的全球地形、自定义地形服务以及开源地形数据。下面介绍几种常见的添加地形的方法: 使用 Cesium Ion 全球地…...
汽车零配件---ecu开发工厂学习
ecu成品制作工艺流程 一、PCB 设计与制作(打板) 工艺流程步骤 需求分析与电路设计 根据 ECU 功能(如发动机控制、变速箱控制)确定所需芯片(如 MCU、传感器接口芯片)、外围电路(如电源、通信接…...

python学习打卡day43
DAY 43 复习日 作业: kaggle找到一个图像数据集,用cnn网络进行训练并且用grad-cam做可视化 浙大疏锦行 数据集使用猫狗数据集,训练集中包含猫图像4000张、狗图像4005张。测试集包含猫图像1012张,狗图像1013张。以下是数据集的下…...

Microsoft Word使用技巧分享(本科毕业论文版)
小铃铛最近终于完成了毕业答辩后空闲下来了,但是由于学校没有给出准确地参考模板,相信诸位朋友们也在调整排版时感到头疼,接下来小铃铛就自己使用到的一些排版技巧分享给大家。 注:以下某些设置是根据哈尔滨工业大学(威…...

windows安装多个版本composer
一、需求场景 公司存在多个项目,有的项目比较老,需要composer 1.X版本才能使用 新的项目又需要composer 2.X版本才能使用 所以需要同时安装多个版本的composer二、下载多个版本composer #composer官网 https://getcomposer.org/download/三、放到指定目…...

【办公类-22-05】20250601Python模拟点击鼠标上传CSDN12篇
、 背景需求: 每周为了获取流量券,每天上传2篇,获得1500流量券,每周共上传12篇,才能获得3000和500的券。之前我用UIBOT模拟上传12篇。 【办公类-22-04】20240418 UIBOT模拟上传每天两篇,获取流量券,并删除内容_csdn 每日任务流量券-CSDN博客文章浏览阅读863次,点赞18…...

贪心算法应用:边着色问题详解
贪心算法应用:边着色问题详解 贪心算法是一种在每一步选择中都采取当前状态下最优的选择,从而希望导致结果是全局最优的算法策略。边着色问题是图论中的一个经典问题,贪心算法可以有效地解决它。下面我将从基础概念到具体实现,全…...
【蓝桥杯】包子凑数
包子凑数 题目描述 小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有 NN 种蒸笼,其中第 ii 种蒸笼恰好能放 AiAi 个包子。每种蒸笼都有非常多笼,可以认为是无限笼。 每当有顾客想买 XX 个包子,卖包子的大叔就会迅速选出若干…...

ck-editor5的研究 (2):对 CKEditor5 进行设计,并封装成一个可用的 vue 组件
前言 在上一篇文章中—— ck-editor5的研究(1):快速把 CKEditor5 集成到 nuxt 中 ,我仅仅是把 ckeditor5 引入到了 nuxt 中,功能还不算通用。 这一篇内容将会对其进行设计,并封装成可复用的 vue 组件&…...

Java-redis实现限时在线秒杀功能
1.使用redisson pom文件添加redisson <!--redisson--><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.23.4</version></dependency> 2.mysql数据库表设…...

simulink mask、sfunction和tlc的联动、接口
这里全部是讲的level2 sfunction(用m语言编写),基于matlab 2020a。 1.mask的参数操作 1)mask通过set_param和get_param这2个函数接口对mask里面定义的Parameters&Dialog的参数的大部分属性进行读写,一般是Value值…...

VMWare安装常见问题
如果之前安装过VMWare软件,只要是 15/16 版本的,可以正常使用的,不用卸载!!! 如果之前安装过,卸载了,一定要保证通过正常的渠道去卸载(通过控制面板卸载软件)…...
set_property LOC约束
##下列指令是用于清除自带GT CELL相关的LOC约束,或者覆盖 ##你需要把IP中自带的GT cell相关的LOC约束清除掉,或者覆盖掉 ##以下命令可以用来覆盖GT_CHANNEL的LOC约束, 在这条命令之后执行你自己的physical constraint: ##GT的channel的相关管脚有两种设计…...

【北邮 操作系统】第十二章 文件系统实现
一、文件的物理结构 1.1 文件块、磁盘块 类似于内存分页,磁盘中的存储单元也会被分为一个个“块/磁盘块/物理块”。很多操作系统中,磁盘块的大小与内存块、页面的大小相同 内存与磁盘之间的数据交换(即读/写操作、磁盘I/0)都是以“块”为单位进行的。即…...

Docker 插件生态:从网络插件到存储插件的扩展能力解析
Docker 容器技术以其轻量、快速、可移植的特性,迅速成为构建和部署现代应用的核心工具。然而,尽管 Docker Engine 自身功能强大,但在面对多样化的生产环境和复杂业务需求时,仅靠核心功能往往无法满足所有场景。 例如,跨主机的容器网络通信、异构存储系统的持久化数据管理…...

WordPress搜索引擎优化的最佳重定向插件:进阶指南
在管理网站时,我们经常需要调整网页地址或修复错误链接。这时,通过重定向不仅能有效解决这些问题,还能显著提升网站在搜索引擎中的排名。对于熟悉基础重定向插件的用户来说,一些功能更强大的工具可以帮助你更全面地管理网站&#…...

org.junit.runners.model.InvalidTestClassError:此类问题的解决
不知道大家是否遇见过以上这种情况,我也是今天被这个错误搞得很烦,后来通过网上查找资料终于找到了问题所在————就是简单的Test注解的错误使用 Test注解的注意情况 :1 权限必须是public 2 不能有参数 3 返回值类型是void 4 本类的其他的…...

用户管理页面(解决toggleRowSelection在dialog用不了的隐患,包含el-table的plus版本的组件)
新增/编辑/删除/分配角色,图片上传在此文章分类下另一个文章 1.重点分配角色: <template><!-- 客户资料 --><div class"pageBox"><elPlusTable :tableData"tableData" :tablePage"tablePage" onSi…...
打卡第35天:GPU训练以及类的Call方法
知识点回归: 1.CPU性能的查看:看架构代际、核心数、线程数 2.GPU性能的查看:看显存、看级别、看架构代际 3.GPU训练的方法:数据和模型移动到GPU device上 4.类的call方法:为什么定义前向传播时可以直接写作self.fc1(x)…...

Linux-GCC、makefile、GDB
GCC gcc -E test.c -o test.i预处理(-o指定文件名) gcc -S test.i -o test.s编译gcc -c test.s -o test.o汇编gcc test.o -o test链接(生成一个可执行程序的软连接) gcc test.c -o test一条指令可以完成以上所有内容 gcc *.c -I(大写的i) include由于在main.c中找不到当前文件…...

[MySQL初阶]MySQL(7) 表的内外连接
标题:[MySQL初阶]MySQL(7)表的内外连接 水墨不写bug 文章目录 一. 内连接 (INNER JOIN)二. 外连接 (OUTER JOIN)关键区别总结 三、 如何选择 在 MySQL 中,连接(JOIN)用于根据两个或多个表之间的相关列组合行。内连接(I…...
Spring Boot中Excel处理完全指南:从基础到高级实践
Excel处理基础知识 1.1 为什么需要在应用中处理Excel文件? 在企业应用开发中,Excel文件处理是一个非常常见的需求,主要用于以下场景: 数据导入:允许用户通过Excel上传批量数据到系统 数据导出:将系统数据…...
Windows下NVM的安装与使用
本文将介绍windows下nvm相关知识。 在不同的项目中可能会使用不同版本的Node.js,例如A项目中需要node>18;B项目中需要node>20。这时候就需要使用NVM切换不同的node版本。进而可以在同一台设备上使用多个node版本。 一、NVM是什么? n…...
Ubuntu挂起和休眠
Ubuntu挂起和休眠 1. 挂起(Suspend)2. 休眠(Hibernate)3. 混合挂起(Hybrid-Sleep)注意事项图形界面操作 在 Ubuntu 系统中,挂起(Suspend)和休眠(Hibernate&am…...

【R语言编程绘图-mlbench】
mlbench库简介 mlbench是一个用于机器学习的R语言扩展包,主要用于提供经典的基准数据集和工具,常用于算法测试、教学演示或研究场景。该库包含多个知名数据集,涵盖分类、回归、聚类等任务。 包含的主要数据集 BostonHousing 波士顿房价数据…...
云服务器部署Gin+gorm 项目 demo
更多个人笔记见: (注意点击“继续”,而不是“发现新项目”) github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note gitee 个人笔记仓库 https://gitee.com/harryhack/it_note 个人学习,学习过程中还会不断补充&…...
MySQL数据一致性守护者:pt-table-checksum原理与实战全解析
MySQL数据一致性守护者:pt-table-checksum原理与实战全解析 在MySQL主从复制环境中,数据一致性是DBA和运维人员最关心的问题之一。主从数据不一致可能导致业务逻辑错误、报表数据失真甚至系统故障。Percona Toolkit中的pt-table-checksum工具正是为解决这一痛点而生,它能够…...

检索器组件深入学习与使用技巧 BaseRetriever 检索器基类
1. BaseRetriever 检索器基类 在 LangChain 中,传递一段 query 并返回与这段文本相关联文档的组件被称为 检索器,并且 LangChain 为所有检索器设计了一个基类——BaseRetriever,该类继承了 RunnableSerializable,所以该类是一个 …...
Unity——QFramework工具 AciontKit时序动作执行系统
AciontKit 是一个时序动作执行系统。 游戏中,动画的播放、延时、资源的异步加载、网络请求等,这些全部都是时序任务,而 ActionKit,可以把这些任务全部整合在一起,使用统一的 API,来对他们的执行进行计划。…...

【Doris基础】Doris中的Replica详解:Replica原理、架构
目录 1 Replica基础概念 1.1 什么是Replica 1.2 Doris中的副本类型 2 Doris副本架构设计 2.1 副本分布机制 2.2 副本一致性模型 3 副本生命周期管理 3.1 副本创建流程 3.2 副本恢复机制 4 副本读写流程详解 4.1 写入流程与副本同步 4.2 查询流程与副本选择 5 副本…...