从零搭起第一个三维地球
新建 Cesium 项目最容易卡住的地方不是 API,而是 Token。这一篇从空文件开始, 做出一个不依赖任何外部服务、打开就能转的三维地球。
准备两个文件
新建一个文件夹,里面放 index.html,内容如下。所有依赖都从 CDN 加载,
不需要 npm、不需要打包工具。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/cesium@1.121.0/Build/Cesium/Widgets/widgets.css">
<style>
html, body, #cesiumContainer { height: 100%; margin: 0; }
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script src="https://cdn.jsdelivr.net/npm/cesium@1.121.0/Build/Cesium/Cesium.js"></script>
<script>
var viewer = new Cesium.Viewer('cesiumContainer', {
baseLayer: false
});
</script>
</body>
</html>
这段代码只有一处关键:baseLayer: false。把这个参数删掉再刷新,
屏幕中央会出现一个一直旋转的加载提示,地球永远出不来。
为什么会一直转圈
new Cesium.Viewer(container) 在不传额外参数时,会尝试加载 Cesium ion 提供的
世界影像和世界地形。ion 需要访问令牌才能提供服务,没有配置
Cesium.Ion.defaultAccessToken 时,这些请求发不出去,页面就停在加载状态。
绕开它有两条路:一是注册 ion 账号拿 Token,二是干脆不要底图。 后者对很多场景已经够用——内部数据看板、卫星轨道示意、飞行轨迹回放, 这些都不需要卫星影像,只要一个球体作为空间参照。
只关影像不够。影像(imagery)和地形(terrain)是两条独立管线。
baseLayer: false 只管影像。如果后续给 Viewer 传了
terrain 或 terrainProvider,仍然可能触发 ion 请求。
让地球好看一点
关掉底图后,球体是默认的灰蓝色,边缘还有一圈大气光晕,背景是星空。 做展示型页面时通常要清掉这些:
var viewer = new Cesium.Viewer('cesiumContainer', {
baseLayer: false,
baseLayerPicker: false,
geocoder: false,
homeButton: false,
sceneModePicker: false,
navigationHelpButton: false,
animation: false,
timeline: false,
fullscreenButton: false,
infoBox: false,
selectionIndicator: false
});
var scene = viewer.scene;
scene.globe.baseColor = Cesium.Color.fromCssColorString('#1c2733');
scene.backgroundColor = Cesium.Color.fromCssColorString('#0e1116');
scene.skyBox.show = false;
scene.sun.show = false;
scene.moon.show = false;
scene.skyAtmosphere.show = false;
上面那一串 false 关掉的是 Viewer 自带的控件:图层选择器、地名搜索、
二三维切换、帮助按钮、时间轴、全屏按钮、信息框、选中框。
做纯展示时它们大多没用,留着只会挤占画面。
放一个点试试
Cartesian3.fromDegrees 把经纬度转成三维坐标,单位是米。
这里只给经度和纬度,高度默认取 0,也就是贴在地球表面。
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.391263, 39.907359),
point: {
pixelSize: 12,
color: Cesium.Color.fromCssColorString('#4d9bff'),
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2
},
label: {
text: '北京',
font: '500 12px sans-serif',
fillColor: Cesium.Color.WHITE,
pixelOffset: new Cesium.Cartesian2(0, -22),
disableDepthTestDistance: Number.POSITIVE_INFINITY
}
});
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(116.391263, 39.907359, 2000000),
duration: 1.5
});
disableDepthTestDistance: Number.POSITIVE_INFINITY 这一句经常被漏掉。
不写它的话,标签会被球体本身遮挡,转到背面就看不见了。
两个版本差异
Cesium 1.104 对 Viewer 的构造参数动过刀,网上大量教程还停留在旧写法, 照抄会不生效:
| 旧写法(1.104 之前) | 新写法(1.104 及之后) | 说明 |
|---|---|---|
imageryProvider | baseLayer | 接受 false 或一个 ImageryLayer |
Cesium.Ion.defaultAccessToken 自动加载 | baseLayer: false 显式关闭 | 不再默认走 ion |
terrainProvider | terrain 或保留 terrainProvider | 两者都能用,但别同时传 |
常见问题
页面白屏,控制台提示 Cesium is not defined
CDN 没加载成功。检查网络能否访问 cdn.jsdelivr.net,
或者把 Cesium 包下载到本地改成相对路径引用。
地球出来了,但没有地形起伏
因为没有地形服务。地形需要单独的 quantized-mesh 瓦片,Cesium ion 提供了一份, 也可以自建或用第三方服务。纯色球体没有高程数据,看起来就是光滑的。
想要影像底图但不想注册 ion
用公开瓦片服务替代。常见做法是给 baseLayer 传一个
Cesium.ImageryLayer,里面包一个 OpenStreetMapImageryProvider。
国内项目一般会用天地图或高德,这两者都需要单独申请 Key,并且涉及 GCJ-02 坐标偏移,
细节放在下一篇之后的数据章节里讲。
经纬志(2026)。《从零搭起第一个三维地球》。https://www.jingweizhi.com/cesium/tutorial/minimal-scene.html(访问日期 2026-11-03)。