首页  |  学习总览  |  ← 返回专题总览 进阶专题 14 · 3D 开发

CesiumJS 地理空间 3D 开发 🔥 热门

从基础地图到数字孪生,从坐标系转换到 3D Tiles,掌握 Web 地理空间开发核心技术
学习时长:约 25 小时 | 前置:JavaScript、WebGL 基础 | 产出:完整 Cesium 项目

一、CesiumJS 概述

什么是 CesiumJS?

CesiumJS 是一个开源 JavaScript 库,用于创建高性能、跨平台、跨浏览器的 3D 地球和地图应用。由 Analytical Graphics, Inc. (AGI) 开发,广泛用于 GIS、数字孪生、无人机、卫星等领域。

CesiumJS
WebGL 渲染
地理坐标系
3D Tiles
数据可视化
特性说明
开源免费Apache 2.0 协议,商用友好
WebGL 渲染基于 WebGL,GPU 加速
多数据源支持 WMS、WMTS、KML、GeoJSON、CZML 等
3D Tiles海量 3D 数据流式加载标准
坐标系支持WGS84、Web Mercator、地方坐标系
时间动态支持时间轴动画

二、环境搭建与基础

2.1 快速开始

// 安装
npm install cesium

// Vite 配置
// vite.config.js
import { defineConfig } from 'vite';
import cesium from 'cesium-vite-plugin';

export default defineConfig({
  plugins: [cesium()],
  resolve: {
    alias: {
      'cesium': 'cesium/Source/Cesium.js'
    }
  }
});

// 基础使用
import * as Cesium from 'cesium';

// 设置 Token(申请地址:https://cesium.com/ion/)
Cesium.Ion.defaultAccessToken = 'your_access_token';

// 创建 Viewer
const viewer = new Cesium.Viewer('cesiumContainer', {
  terrainProvider: Cesium.createWorldTerrain(),
  animation: false,         // 动画控件
  timeline: false,           // 时间轴
  baseLayerPicker: false,    // 图层选择
  geocoder: false,           // 地理编码
  homeButton: true,          // 主页按钮
  sceneModePicker: true,     // 场景模式
  navigationHelpButton: false,
  fullscreenButton: true,
  vrButton: false
});

// 定位到指定位置
viewer.camera.flyTo({
  destination: Cesium.Cartesian3.fromDegrees(116.397, 39.909, 15000000),
  orientation: {
    heading: Cesium.Math.toRadians(0),
    pitch: Cesium.Math.toRadians(-90),
    roll: 0
  }
});

2.2 Viewer 核心组件

组件说明
sceneScene 场景,管理 3D 世界
cameraCamera 相机,控制视角
canvasCanvas 画布,WebGL 渲染目标
clockClock 时钟,控制时间
dataSources数据源集合
entities实体集合
imageryLayers影像图层集合
terrainProvider地形提供者

三、坐标系与空间参考

3.1 常用坐标系

坐标系说明使用场景
WGS84 (EPSG:4326)经纬度坐标系GPS 定位、地理数据
Web Mercator (EPSG:3857)墨卡托投影地图瓦片、2D 地图
ECEF地心地固坐标系3D 空间计算
ENU东北天坐标系局部相对位置

3.2 坐标转换

// 经纬度 → 笛卡尔坐标
const cartesian = Cesium.Cartesian3.fromDegrees(
  116.397, // 经度
  39.909,  // 纬度
  100      // 高度(米)
);

// 经纬度数组 → 笛卡尔数组
const positions = Cesium.Cartesian3.fromDegreesArray([
  116.39, 39.90,
  116.40, 39.90,
  116.40, 39.91,
]);

// 笛卡尔坐标 → 经纬度
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
const lon = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
const height = cartographic.height;

// 屏幕坐标 → 世界坐标
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((event) => {
  const position = viewer.camera.pickEllipsoid(event.position);
  if (position) {
    const carto = Cesium.Cartographic.fromCartesian(position);
    console.log(`选中位置:${Cesium.Math.toDegrees(carto.longitude)}, ${Cesium.Math.toDegrees(carto.latitude)}`);
  }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

四、实体与数据可视化

4.1 Entity API

// 添加点
viewer.entities.add({
  name: '北京',
  position: Cesium.Cartesian3.fromDegrees(116.397, 39.909),
  point: {
    pixelSize: 10,
    color: Cesium.Color.RED,
    outlineColor: Cesium.Color.WHITE,
    outlineWidth: 2
  },
  label: {
    text: '北京',
    font: '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, -10)
  }
});

// 添加线
viewer.entities.add({
  polyline: {
    positions: Cesium.Cartesian3.fromDegreesArray([
      116.39, 39.90,
      121.47, 31.23,
      113.26, 23.13
    ]),
    width: 3,
    material: Cesium.Color.BLUE
  }
});

// 添加面
viewer.entities.add({
  polygon: {
    hierarchy: Cesium.Cartesian3.fromDegreesArray([
      116.39, 39.90,
      116.40, 39.90,
      116.40, 39.91,
      116.39, 39.91
    ]),
    material: Cesium.Color.GREEN.withAlpha(0.5),
    outline: true,
    outlineColor: Cesium.Color.BLACK
  }
});

// 添加 3D 模型
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(116.397, 39.909, 100),
  model: {
    uri: 'models/Cesium_Air.glb',
    minimumPixelSize: 128,
    maximumScale: 20000
  }
});

4.2 数据源

GeoJSON 加载

// 加载 GeoJSON
const dataSource = await Cesium.GeoJsonDataSource.load('data/china.geojson', {
  stroke: Cesium.Color.HOTPINK,
  fill: Cesium.Color.PINK.withAlpha(0.5),
  strokeWidth: 3
});
viewer.dataSources.add(dataSource);

// 加载 KML
const kmlDataSource = await Cesium.KmlDataSource.load('data/example.kml');
viewer.dataSources.add(kmlDataSource);

// 加载 CZML(时间动态数据)
const czmlDataSource = await Cesium.CzmlDataSource.load('data/example.czml');
viewer.dataSources.add(czmlDataSource);

五、3D Tiles 大规模数据

5.1 3D Tiles 概述

3D Tiles 是 OGC 社区标准,用于流式传输大规模异构 3D 地理空间数据。

倾斜摄影
点云
BIM 模型
矢量数据

5.2 加载 3D Tiles

// 加载 3D Tiles
const tileset = await Cesium.Cesium3DTileset.fromUrl('https://example.com/tileset.json');
viewer.scene.primitives.add(tileset);

// 定位到模型
viewer.zoomTo(tileset);

// 设置样式
tileset.style = new Cesium.Cesium3DTileStyle({
  color: {
    conditions: [
      ["\${Height} >= 100", "color('red')"],
      ["\${Height} >= 50", "color('orange')"],
      ['true', "color('blue')"]
    ]
  }
});

// 监听加载完成
tileset.allTilesLoaded.addEventListener(() => {
  console.log('所有瓦片加载完成');
});

六、相机与飞行控制

6.1 相机控制

// 设置视角
viewer.camera.setView({
  destination: Cesium.Cartesian3.fromDegrees(116.397, 39.909, 5000),
  orientation: {
    heading: Cesium.Math.toRadians(0),   // 朝向
    pitch: Cesium.Math.toRadians(-45),    // 俯仰
    roll: 0                                 // 翻滚
  }
});

// 飞行到指定位置
viewer.camera.flyTo({
  destination: Cesium.Cartesian3.fromDegrees(116.397, 39.909, 5000),
  duration: 3, // 飞行时间(秒)
  maximumHeight: 10000,
  complete: () => { console.log('飞行完成'); }
});

// 飞行到实体
viewer.flyTo(entity, {
  duration: 2,
  offset: new Cesium.HeadingPitchRange(
    Cesium.Math.toRadians(0),
    Cesium.Math.toRadians(-45),
    1000
  )
});

// 原地旋转
viewer.clock.onTick.addEventListener(() => {
  viewer.camera.rotate(Cesium.Math.toRadians(0.1));
});

七、高级特效与场景

7.1 天气与大气

// 设置大气效果
viewer.scene.globe.enableLighting = true;  // 启用光照
viewer.scene.fog.enabled = true;             // 雾效
viewer.scene.skyAtmosphere.hueShift = -0.0;
viewer.scene.skyAtmosphere.saturationShift = 0.1;
viewer.scene.skyAtmosphere.brightnessShift = -0.1;

// 太阳位置(基于时间)
viewer.scene.globe.enableLighting = true;

7.2 后处理效果

// 高亮轮廓
const outlineBlue = new Cesium.PostProcessStageLibrary.createSilhouetteStage();
viewer.scene.postProcessStages.add(outlineBlue);

八、性能优化

优化策略

策略说明
3D Tiles使用 3D Tiles 替代普通模型,支持 LOD
实例化Primitive API 比 Entity 性能更好
视锥剔除自动剔除视野外的对象
按需加载根据相机距离加载不同精度
Web Worker复杂计算放到 Worker 中
纹理压缩使用 KTX2 等压缩格式
// 使用 Primitive API 提升性能
const instance = new Cesium.GeometryInstance({
  geometry: new Cesium.RectangleGeometry({
    rectangle: Cesium.Rectangle.fromDegrees(116.39, 39.90, 116.40, 39.91),
    vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
  }),
  attributes: {
    color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED.withAlpha(0.5))
  }
});

viewer.scene.primitives.add(new Cesium.Primitive({
  geometryInstances: instance,
  appearance: new Cesium.PerInstanceColorAppearance()
}));

九、数字孪生实战架构

完整数字孪生系统架构

┌─────────────────────────────────────────────────┐
│                   前端展示层                       │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐            │
│  │ CesiumJS │ │ Three.js│ │  图表    │            │
│  └─────────┘ └─────────┘ └─────────┘            │
├─────────────────────────────────────────────────┤
│                   数据接入层                       │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐            │
│  │ IoT 数据 │ │ GIS 数据 │ │ 业务数据 │            │
│  └─────────┘ └─────────┘ └─────────┘            │
├─────────────────────────────────────────────────┤
│                   服务层                           │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐            │
│  │ 3D Tiles │ │ WebSocket│ │  API    │            │
│  └─────────┘ └─────────┘ └─────────┘            │
└─────────────────────────────────────────────────┘

十、面试高频问题

Q1:CesiumJS 和 Google Earth 有什么区别?
查看答案 ▼

CesiumJS 是开源库,可以嵌入网页;Google Earth 是独立应用。CesiumJS 更适合开发定制化的 3D 地理应用,支持自定义数据源和交互逻辑。

Q2:3D Tiles 和传统模型加载有什么区别?
查看答案 ▼
  • 数据量级:3D Tiles 支持 GB 级数据,传统模型通常 MB 级
  • 加载方式:3D Tiles 按需加载(LOD),传统模型一次性加载
  • 精度控制:3D Tiles 根据距离自动切换精度
  • 标准:3D Tiles 是 OGC 标准,通用性强
Q3:CesiumJS 性能优化的关键点?
查看答案 ▼
  • 使用 Primitive API 替代 Entity API
  • 3D Tiles 替代普通模型
  • 合理使用 requestRenderMode 减少渲染
  • 纹理压缩(KTX2/Basis)
  • 视锥剔除和遮挡剔除
  • Web Worker 处理数据解析