Skip to content

Cesium简介与快速入门

Cesium概述

Cesium 是一个基于JavaScript开发的WebGL三维地球和地图可视化库。Cesium的主要特点包括:

  • 跨平台、跨浏览器:无需额外插件,即可在多种操作系统和浏览器上运行
  • 海量数据支持:Cesium定义了3D Tiles数据格式,支持大规模三维模型和地形数据的加载与渲染。
  • 丰富的地图模式:支持三维、二维和哥伦布视图(2.5D),提供多种地图和地形图层选择。
  • 交互功能:支持地址搜索、信息属性框等用户交互功能,以及全屏模型和WebVR虚拟现实体验。

Cesium应用场景

Cesium被广泛应用于多个领域,包括但不限于:

  • 交通管理:用于模拟交通流量,进行交通规划和分析。
  • 城市规划:辅助进行城市设计,展示城市规划的三维效果。
  • 城市管理:帮助城市管理者进行城市监控和应急响应规划。 地形仿真:在军事和地质研究中模拟地形环境,进行战术训练和地质分析。

安装 Cesium 其构建插件:

bash
pnpm add cesium
pnpm add vite-plugin-cesium

安装完成后,Cesium 的包已经准备好在项目中使用。但由于 Cesium 包含大量的 3D 资源文件,我们还需要对 Vite 进行一些配置,以便正确加载 Cesium 的静态资源。

配置 Vite 以支持 Cesium

要让 Vite 正确处理 Cesium 的静态资源,我们需要在vite.config.js中进行一些配置。

plugins:[] 中添加cesium()

js
import { defineConfig } from 'vite'
import cesium from 'vite-plugin-cesium'

export default defineConfig({
  plugins: [
    cesium()
  ]
})

main.ts中导入 Cesium 的样式文件:

js
import 'cesium/Build/Cesium/Widgets/widgets.css'

Cesium 地球组件案例

在 src/components 文件夹中创建一个新文件 CesiumMap.vue,并添加以下代码:

vue
<script setup lang="ts">
import * as Cesium from 'cesium'

let viewer: any = null
/**
 * 初始化地图
 */
async function initCesiumMap() {
  viewer = new Cesium.Viewer('map-container', {
    infoBox: false, // 右侧信息框
    selectionIndicator: false, // 选中状态
    scene3DOnly: false,
    timeline: false, // 时间轴控件
    animation: false, // 动画控件
    geocoder: false, // 搜索控件
    homeButton: false, // 主页控件
    sceneModePicker: false, // 投影控件
    baseLayerPicker: false, // 图层控件
    navigationHelpButton: false, // 帮助控件
    fullscreenButton: false, // 全屏控件
    sceneMode: Cesium.SceneMode.SCENE3D, // 3d/2d
    // baseLayer: false, //基础底图,使用天地图可设置为false
    shouldAnimate: false,
    navigationInstructionsInitiallyVisible: false,
    // terrainProvider: await Cesium.createWorldTerrainAsync({
    //   requestWaterMask: true, // 请求水面掩膜。这会使得地形数据中的水体区域呈现得更真实。
    //   requestVertexNormals: true, // 请求地形的顶点法线,这对于渲染光照和阴影效果非常重要
    // }),
  })
  viewer.cesiumWidget.creditContainer.style.display = 'none'

  // 设置视角;
  viewer.camera.setView({
    destination: new Cesium.Cartesian3(
      -2334853.404707261,
      4667065.28282889,
      3656985.516978565
    ),
    orientation: {
      heading: 0.06100902578996159,
      pitch: -1.300180753376774,
      roll: 0.0014934533703652164,
    },
  })

  viewer.scene.postProcessStages.fxaa.enabled = true

  viewer.scene.globe.depthTestAgainstTerrain = true
  viewer.scene.globe.ambientLightIntensity = 0.2
  viewer.scene.light.color = Cesium.Color.WHITE.withAlpha(1.0) // 设置方向光颜色
  viewer.scene.globe.enableLighting = true // 启用光照效果

  // 鼠标事件
  const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
  // 设置鼠标左键单击回调事件
  handler.setInputAction((e: any) => {
    // 首先移除之前添加的点
    // viewer.entities.removeAll();
    // 获取点击位置笛卡尔坐标
    const position = viewer.scene.pickPosition(e.position)
    // 将笛卡尔坐标转化为经纬度坐标
    const cartographic = Cesium.Cartographic.fromCartesian(position)
    const longitude = Cesium.Math.toDegrees(cartographic.longitude)
    const latitude = Cesium.Math.toDegrees(cartographic.latitude)
    const height = cartographic.height
    console.log(longitude, latitude, height)
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

  // 将原来鼠标中键倾斜视图修改为鼠标右键触发
  viewer.scene.screenSpaceCameraController.tiltEventTypes = [
    Cesium.CameraEventType.RIGHT_DRAG,
  ]
  // 将原来鼠标右键放大缩放修改为鼠标滚轮滚动
  viewer.scene.screenSpaceCameraController.zoomEventTypes = [
    Cesium.CameraEventType.WHEEL,
  ]

  // 添加底图天地图
  addTdtMap()
}
// 添加底图天地图
function addTdtMap() {
  viewer.imageryLayers.remove(viewer.imageryLayers.get(0))
  const token = '天地图密钥'
  viewer.imageryLayers.addImageryProvider(
    new Cesium.WebMapTileServiceImageryProvider({
      url: `http://t{s}.tianditu.gov.cn/img_w/wmts?tk=${token}`,
      layer: 'img',
      style: 'default',
      tileMatrixSetID: 'w',
      format: 'tiles',
      maximumLevel: 18,
      subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
    })
  )
}

onMounted(() => {
  initCesiumMap()
})
</script>

<template>
  <div id="map-container" class="cesium-container" />
</template>

<style lang="scss" scoped>
.cesium-container {
  width: 100%;
  height: 100%;
}
</style>

运行效果

empowerempower

使用默认的三维地形

new Cesium.Viewer中添加配置

js
{
  terrainProvider: await Cesium.createWorldTerrainAsync({
    requestWaterMask: true, // 请求水面掩膜。这会使得地形数据中的水体区域呈现得更真实。
    requestVertexNormals: true, // 请求地形的顶点法线,这对于渲染光照和阴影效果非常重要
  })
}

上文中注释起来了

运行效果:

empower