Cesium 从入门到精通:实战指南
# 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
如果能输出版本号,说明安装成功。
# 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>
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
# 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),
});
2
3
参数说明:
| 参数 | 含义 |
|---|---|
| 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,
},
});
2
3
4
5
6
7
# 5 ImageryProvider
ImageryProvider 用于加载 地图影像。
例如加载影像:
viewer.imageryLayers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({
url: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
}),
);
2
3
4
5
# 三、入门实战:创建 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>
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# 运行步骤
1 创建 index.html
2 使用本地服务器运行
npx serve
3 浏览器打开
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,
},
});
2
3
4
5
6
7
注意:
- glTF 路径必须正确
- 模型尺寸需要调整 scale
# 2 加载 GeoJSON
很多 GIS 数据是 GeoJSON。
Cesium.GeoJsonDataSource.load("data.geojson").then(function (dataSource) {
viewer.dataSources.add(dataSource);
});
2
3
GeoJSON 示例:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [116.39, 39.9]
}
}
]
}
2
3
4
5
6
7
8
9
10
11
12
# 3 自定义材质
可以为对象设置材质。
viewer.entities.add({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray([
116, 39, 117, 39, 117, 40, 116, 40,
]),
material: Cesium.Color.BLUE.withAlpha(0.5),
},
});
2
3
4
5
6
7
8
# 常见问题
# 模型看不到
可能原因:
- 模型路径错误
- 高度不对
- 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,
},
});
};
2
3
4
5
6
7
8
9
10
# 4 性能优化
# LOD(层级细节)
远处加载低精度模型。
近处加载高精度模型。
# Clustering
大量点位需要聚合:
dataSource.clustering.enabled = true;
# 推荐项目结构
project
├ data
├ models
├ src
├ index.html
2
3
4
5
建议将项目托管到 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
↓
数字孪生系统
2
3
4
5
6
7
建议你多研究:
- Cesium Sandcastle 示例代码
- 开源项目
- 官方文档
如果持续练习,你可以逐步从 Cesium 初学者成长为 3D GIS 开发者,甚至参与开源贡献,构建更复杂的 数字地球与城市可视化系统。 🌍🚀