Skip to content

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 版本)。

安装完成后检查:

bash
node -v
npm -v

如果能输出版本号,说明安装成功。

2 通过 CDN 引入 Cesium

最快的方式是使用 CDN。

创建 index.html

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 安装

适合 工程化开发

bash
npm install cesium

在项目中引入:

javascript
import * as Cesium from "cesium";

如果使用构建工具(如 Vite / Webpack),需要配置 静态资源路径

二、Cesium 基础概念

Cesium 有几个核心对象,需要理解。

1 Viewer

Viewer 是 Cesium 的入口对象

它包含:

  • Scene
  • Camera
  • Imagery
  • Entity

创建 Viewer:

javascript
const viewer = new Cesium.Viewer("cesiumContainer");

这行代码会:

  • 创建 3D 地球
  • 加载默认影像
  • 初始化相机控制

2 Scene

Scene 表示 整个 3D 场景

javascript
const scene = viewer.scene;

Scene 管理:

  • 地球
  • 光照
  • 渲染

3 Camera

Camera 控制 视角和飞行

例如飞到北京:

javascript
viewer.camera.flyTo({
  destination: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 100000),
});

参数说明:

参数含义
longitude经度
latitude纬度
height高度

4 Entity

Entity 是 Cesium 的数据对象

例如添加一个点:

javascript
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(116.39, 39.9),
  point: {
    pixelSize: 10,
    color: Cesium.Color.RED,
  },
});

5 ImageryProvider

ImageryProvider 用于加载 地图影像

例如加载影像:

javascript
viewer.imageryLayers.addImageryProvider(
  new Cesium.UrlTemplateImageryProvider({
    url: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
  }),
);

三、入门实战:创建 3D 地球

下面构建一个 完整的 3D 地球示例

完整代码

html
<!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 使用本地服务器运行

bash
npx serve

3 浏览器打开

http://localhost:3000

你会看到:

  • 🌍 3D 地球
  • 📍 北京标记
  • 📷 相机飞行

四、中级进阶

1 加载 3D 模型(glTF)

Cesium 支持 glTF 模型

javascript
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(116.39, 39.9),
  model: {
    uri: "model.gltf",
    scale: 1,
  },
});

注意:

  • glTF 路径必须正确
  • 模型尺寸需要调整 scale

2 加载 GeoJSON

很多 GIS 数据是 GeoJSON。

javascript
Cesium.GeoJsonDataSource.load("data.geojson").then(function (dataSource) {
  viewer.dataSources.add(dataSource);
});

GeoJSON 示例:

json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [116.39, 39.9]
      }
    }
  ]
}

3 自定义材质

可以为对象设置材质。

javascript
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

javascript
viewer.dataSources.add(Cesium.KmlDataSource.load("city.kml"));

2 加载 CZML

CZML 用于 时间序列数据

例如卫星轨道。

javascript
viewer.dataSources.add(Cesium.CzmlDataSource.load("orbit.czml"));

3 实时数据可视化

可以通过 WebSocket 更新数据:

javascript
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

大量点位需要聚合:

javascript
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 开发者,甚至参与开源贡献,构建更复杂的 数字地球与城市可视化系统。 🌍🚀