Cesium 从入门到精通:实战指南
引言
在 Web 可视化领域,如果你需要构建 3D 地球、数字孪生城市、卫星轨道可视化或 GIS 系统,有一个非常强大的工具——CesiumJS。
Cesium 是一个 开源的 JavaScript 3D 地图引擎,基于 WebGL 构建,能够在浏览器中渲染高性能的 3D 地球和空间数据。它最初由 Cesium 公司开发,现在被广泛用于:
- 🌍 GIS 地理信息系统
- 🛰 卫星轨道可视化
- 🏙 数字孪生城市
- 🚗 交通仿真系统
- 🌦 气象和环境数据可视化
- 🏗 城市规划和建筑展示
很多大型项目(例如智慧城市和数字地球平台)都会结合:
- CesiumJS
- Three.js
- Mapbox GL JS
共同构建复杂的 3D GIS 可视化系统。
本文面向 初学者到中级开发者,将从 环境搭建 → 基础概念 → 实战项目 → 高级应用 → 性能优化,一步一步带你掌握 Cesium,最终能够 独立开发一个 3D 地图项目。
一、环境准备
1 安装 Node.js 和 npm
首先安装 Node.js(推荐 LTS 版本)。
安装完成后检查:
node -v
npm -v如果能输出版本号,说明安装成功。
2 通过 CDN 引入 Cesium
最快的方式是使用 CDN。
创建 index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Cesium Demo</title>
<script src="https://unpkg.com/cesium/Build/Cesium/Cesium.js"></script>
<link
href="https://unpkg.com/cesium/Build/Cesium/Widgets/widgets.css"
rel="stylesheet"
/>
<style>
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script></script>
</body>
</html>3 通过 npm 安装
适合 工程化开发。
npm install cesium在项目中引入:
import * as Cesium from "cesium";如果使用构建工具(如 Vite / Webpack),需要配置 静态资源路径。
二、Cesium 基础概念
Cesium 有几个核心对象,需要理解。
1 Viewer
Viewer 是 Cesium 的入口对象。
它包含:
- Scene
- Camera
- Imagery
- Entity
创建 Viewer:
const viewer = new Cesium.Viewer("cesiumContainer");这行代码会:
- 创建 3D 地球
- 加载默认影像
- 初始化相机控制
2 Scene
Scene 表示 整个 3D 场景。
const scene = viewer.scene;Scene 管理:
- 地球
- 光照
- 渲染
3 Camera
Camera 控制 视角和飞行。
例如飞到北京:
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 100000),
});参数说明:
| 参数 | 含义 |
|---|---|
| longitude | 经度 |
| latitude | 纬度 |
| height | 高度 |
4 Entity
Entity 是 Cesium 的数据对象。
例如添加一个点:
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.39, 39.9),
point: {
pixelSize: 10,
color: Cesium.Color.RED,
},
});5 ImageryProvider
ImageryProvider 用于加载 地图影像。
例如加载影像:
viewer.imageryLayers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({
url: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
}),
);三、入门实战:创建 3D 地球
下面构建一个 完整的 3D 地球示例。
完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>3D Earth Demo</title>
<!-- 锁定到稳定版本,避免 API 变更导致报错 -->
<script src="https://unpkg.com/cesium@1.95.0/Build/Cesium/Cesium.js"></script>
<link
href="https://unpkg.com/cesium@1.95.0/Build/Cesium/Widgets/widgets.css"
rel="stylesheet"
/>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
}
#cesiumContainer {
width: 100%;
height: 100vh;
}
#toolbar {
position: absolute;
top: 10px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.6);
color: #fff;
padding: 8px 16px;
border-radius: 6px;
font-family: sans-serif;
font-size: 14px;
pointer-events: none;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<div id="toolbar">3D 地球演示 — 点击实体查看信息</div>
<script>
// -------------------------------------------------------
// 1. 使用 ArcGIS 公开影像服务(无需 Token)
// -------------------------------------------------------
const imageryProvider = new Cesium.ArcGisMapServerImageryProvider({
url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
});
// -------------------------------------------------------
// 2. 创建 Viewer
// terrainProvider 使用椭球体(无需 Cesium Ion Token)
// -------------------------------------------------------
const viewer = new Cesium.Viewer("cesiumContainer", {
imageryProvider: imageryProvider,
terrainProvider: new Cesium.EllipsoidTerrainProvider(),
baseLayerPicker: false,
geocoder: false,
homeButton: true,
sceneModePicker: true,
navigationHelpButton: false,
animation: false,
timeline: false,
fullscreenButton: true,
});
// 开启大气层 & 光照效果
viewer.scene.globe.enableLighting = true;
viewer.scene.skyAtmosphere.show = true;
// -------------------------------------------------------
// 3. 添加标注实体
// -------------------------------------------------------
const cities = [
{ name: "北京", lon: 116.39, lat: 39.9, color: Cesium.Color.YELLOW },
{ name: "上海", lon: 121.47, lat: 31.23, color: Cesium.Color.CYAN },
{ name: "广州", lon: 113.26, lat: 23.13, color: Cesium.Color.LIME },
{ name: "成都", lon: 104.06, lat: 30.67, color: Cesium.Color.ORANGE },
];
cities.forEach(({ name, lon, lat, color }) => {
viewer.entities.add({
name: name,
position: Cesium.Cartesian3.fromDegrees(lon, lat, 0),
point: {
pixelSize: 12,
color: color,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
label: {
text: name,
font: "bold 14px sans-serif",
fillColor: Cesium.Color.WHITE,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
outlineColor: Cesium.Color.BLACK,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -18),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
});
// -------------------------------------------------------
// 4. 镜头飞到初始视角(俯瞰中国)
// -------------------------------------------------------
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(105, 35, 6000000),
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-45),
roll: 0.0,
},
duration: 3,
});
// -------------------------------------------------------
// 5. 点击实体弹出信息框
// -------------------------------------------------------
viewer.screenSpaceEventHandler.setInputAction((click) => {
const picked = viewer.scene.pick(click.position);
if (Cesium.defined(picked) && Cesium.defined(picked.id)) {
viewer.selectedEntity = picked.id;
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
</script>
</body>
</html>运行步骤
1 创建 index.html 2 使用本地服务器运行
npx serve3 浏览器打开
http://localhost:3000你会看到:
- 🌍 3D 地球
- 📍 北京标记
- 📷 相机飞行
四、中级进阶
1 加载 3D 模型(glTF)
Cesium 支持 glTF 模型。
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.39, 39.9),
model: {
uri: "model.gltf",
scale: 1,
},
});注意:
- glTF 路径必须正确
- 模型尺寸需要调整 scale
2 加载 GeoJSON
很多 GIS 数据是 GeoJSON。
Cesium.GeoJsonDataSource.load("data.geojson").then(function (dataSource) {
viewer.dataSources.add(dataSource);
});GeoJSON 示例:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [116.39, 39.9]
}
}
]
}3 自定义材质
可以为对象设置材质。
viewer.entities.add({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray([
116, 39, 117, 39, 117, 40, 116, 40,
]),
material: Cesium.Color.BLUE.withAlpha(0.5),
},
});常见问题
模型看不到
可能原因:
- 模型路径错误
- 高度不对
- scale 太小
GeoJSON 不显示
可能原因:
- 坐标系不是 WGS84
- 文件路径错误
五、高级实战:城市模拟系统
一个典型项目可能包含:
- 城市建筑
- 实时数据
- 轨迹动画
1 加载 KML
viewer.dataSources.add(Cesium.KmlDataSource.load("city.kml"));2 加载 CZML
CZML 用于 时间序列数据。
例如卫星轨道。
viewer.dataSources.add(Cesium.CzmlDataSource.load("orbit.czml"));3 实时数据可视化
可以通过 WebSocket 更新数据:
socket.onmessage = function (event) {
const data = JSON.parse(event.data);
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(data.lon, data.lat),
point: {
pixelSize: 8,
},
});
};4 性能优化
LOD(层级细节)
远处加载低精度模型。
近处加载高精度模型。
Clustering
大量点位需要聚合:
dataSource.clustering.enabled = true;推荐项目结构
project
├ data
├ models
├ src
├ index.html建议将项目托管到 GitHub:
github.com/yourname/cesium-city-demo六、最佳实践和调试
常见错误
1 坐标系错误
Cesium 使用:
WGS84很多中国地图使用:
GCJ02需要转换。
2 性能瓶颈
避免:
一次加载 10 万 entity建议:
- 使用 primitive
- 使用 3D Tiles
WebGL 调试工具
推荐:
- Chrome WebGL Inspector
- Spector.js
学习资源
官方文档:
- CesiumJS 官方文档
示例平台:
- Cesium Sandcastle
社区:
- GitHub
- Cesium Forum
七、结语
通过本文,你已经学习了:
- 1 Cesium 环境搭建
- 2 核心概念(Viewer / Camera / Entity)
- 3 基础 3D 地球项目
- 4 GeoJSON 与 3D 模型加载
- 5 城市模拟系统开发
- 6 性能优化技巧
学习路径建议:
Cesium 基础
↓
GIS 数据处理
↓
3D Tiles
↓
数字孪生系统建议你多研究:
- Cesium Sandcastle 示例代码
- 开源项目
- 官方文档
如果持续练习,你可以逐步从 Cesium 初学者成长为 3D GIS 开发者,甚至参与开源贡献,构建更复杂的 数字地球与城市可视化系统。 🌍🚀