1.cesium 的基础知识篇

前言:cesium 的基本介绍

  • 概念:CesiumJS 是一套开源、基于 WebGL 的三维地球/地理空间可视化 JavaScript 库,专门用来在浏览器里搭建三维数字地球、GIS 三维场景;

  • 使用场景:航天航空、智能城市、无人机,使用cesium创建交互式Web应用程序,共享地理空间数据;

  • 核心标准:3D Tiles(三维瓦片,倾斜摄影、BIM、点云主流格式);

  • 特点:支持全球地形、影像、3D 模型、轨迹、管线、倾斜摄影;

1.初始化 cesium 应用与基础设置;

xml 复制代码
<template>
    <div ref="cesiumContainer" class="cesium-container"></div>
</template>
<script setup>
    import { ref, onMounted, onBeforeUnmount } from 'vue'
    // 导入 Cesium 所有 API
    import * as Cesium from 'cesium'
    // 自带控件样式(缩放按钮、比例尺、时间轴样式),不引入会按钮样式错乱 
    import 'cesium/Build/Cesium/Widgets/widgets.css'
    
    // 创建容器
    const cesiumContainer = ref(null);
    // 创建三维场景
    let viewer = null;

    onMounted(() => {
      // 01.设置cesium的Token
      Cesium.Ion.defaultAccessToken = "";
      // 02.设置cesium默认视角
      Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
         // 西边的经度、南边纬度、东边经度、北边纬度
         89.5, 20.4, 110.4, 61.2
      );
      // 03.初始化cesium程序
      var viewer = new Cesium.Viewer(cesiumContainer.value, {
          // 03.1.是否显示信息窗口
          infoBox: true,
          // 03.2.是否显示查询按钮
          geocoder: false,
          // 03.3.不显示home按钮
          homeButton: false,
          // 03.4.控制查看器的显示模式
          sceneModePicker: false,
          // 03.5.是否显示图层选择
          baseLayerPicker: false,
          // 03.6.是否显示帮助按钮
          navigationHelpButton: false,
          // 03.7.是否播放动画
          animation: false,
          // 03.8.是否显示时间轴
          timeline: false,
          // 03.9.是否显示全屏按钮
          fullscreenButton: false,
          // 03.10.设置天空盒子
          skyBox: new Cesium.SkyBox({
              sources: {
                positiveX: "public/texture/sky/px.jpg",
                negativeX: "public/texture/sky/nx.jpg",
                positiveY: "public/texture/sky/ny.jpg",
                negativeY: "public/texture/sky/py.jpg",
                positiveZ: "public/texture/sky/pz.jpg",
                negativeZ: "public/texture/sky/nz.jpg"
              },
          })
      });
      
      // 04.高德矢量地图
      let gdUrl = "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}";
      
      const amap = new Cesium.UrlTemplateImageryProvider({
            url: gdUrl,
            minimumLevel: 1,
            maximumLevel: 18,
            layer: "tdtVecBasicLayer",
            style: "default",
            format: "image/png",
            tileMatrixSetID: "GoogleMapsCompatible"
      });
      viewer.imageryLayers.addImageryProvider(amap);
      
      // 05.隐藏logo
      viewer.cesiumWidget.creditContainer.style.display = "none";
  })
  onBeforeUnmount(() => {
      if (viewer) {
          viewer.destroy()
          viewer = null
      }
  })
</script>

2.添加图层 - 高德地图

php 复制代码
/**
   *  高德地图:http://webrd02.is.autonavi.com/appmaptile?style=8&lang=zh_cn&size=1&scale=1&x={x}&y={y}&z={z}
   *  
   *  style=8	  标准矢量街道图            白底、灰色道路、省市 / 街道文字、POI 点位,日常导航普通电子地图
   *  style=7	  深色夜间矢量地图          黑底暗色地图,数字孪生大屏最常用
   *  style=6	  卫星航拍影像图            实景航拍照片,纯地面画面,不带文字
   * 
   *  lang=zh_cn           语言:中文
   *  size=1               瓦片尺寸:256×256像素
   *  scale=1              清晰度倍率:1倍(常规分辨率)
   *  x={x}&y={y}&z={z}    瓦片行列、缩放层级占位符
   **/
  const amap6 = new Cesium.UrlTemplateImageryProvider({
        url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
        minimumLevel: 1,
        maximumLevel: 18,
        layer: "tdtVecBasicLayer",
        style: "default",
        format: "image/png",
        tileMatrixSetID: "GoogleMapsCompatible"
  });
  const amap7 = new Cesium.UrlTemplateImageryProvider({
        url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
        minimumLevel: 1,
        maximumLevel: 18,
        layer: "tdtVecBasicLayer",
        style: "default",
        format: "image/png",
        tileMatrixSetID: "GoogleMapsCompatible"
  });

  const labelLayer6 = viewer.imageryLayers.addImageryProvider(amap6);
  const labelLayer7 = viewer.imageryLayers.addImageryProvider(amap7);
  
  labelLayer7.alpha = 0.5;

3.添加地形与添加自定义地形

php 复制代码
  // 01.添加cesium的地形
  Cesium.createWorldTerrainAsync({
      // 设置山脉的空间效果
      requestVertexNormals: true,
      // 设置水纹效果
      requestWaterMask: true
  }).then(terrainProvider => {
      viewer.terrainProvider = terrainProvider;
  }).catch(e => {
      console.log("地形加载异常", e);
  });
  
  // 02.添加自定义地形数据
  const terrainProvider = new Cesium.CesiumTerrainProvider({
      url: "/public/terrains/gz",
      requestVertexNormals: true,
      requestWaterMask: true,
  });
  viewer.terrainProvider = terrainProvider;

4.坐标系与坐标系数值转换

javascript 复制代码
// 06.坐标系数值转换
// 06.1.屏幕坐标系统:二维的笛卡尔坐标系    Cartesian2类型
// 06.2.地理坐标系统:WGS-84坐标系         Cartographic类型:经度 纬度 高度
// 06.3.笛卡尔空间直角坐标系:             Cartesian3类型

// 1.角度与弧度的转换
var radians = Cesium.Math.toRadians(90);
console.log("1.角度 - 弧度" ,radians);

// 2.弧度转角度
var degrees = Cesium.Math.toDegrees(2 * Math.PI);
console.log("2.弧度 - 角度" , degrees);

// 3.将经纬度转为笛卡尔坐标
var cartesian3 = Cesium.Cartesian3.fromDegrees(
   // 经度
   89.5,
   // 纬度
   20.4,
   // 高度
   100
);
console.log("3.经纬度 - 笛卡尔空间" , cartesian3);

// 4.将笛卡尔坐标转为经纬度
var cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
console.log("4.笛卡尔空间 - 经纬度" , cartographic);

5.相机的方向和位置

  • setView:瞬间到达指定位置和视角
  • flyto:让相机飞往某个地方
less 复制代码
  // 05.1.设置相机的视角位置 
  
  // 05.1.天安门广场的经纬度位置信息 
  var position = Cesium.Cartesian3.fromDegrees(116.393428, 39.90923, 100);

  // 05.2.设置天安门广场的视角
  // viewer.camera.setView({
  //     // 指定相机位置
  //     destination: position,
  //     // 指定相机视角
  //     orientation: {
  //         // 指定相机的朝向,偏航角
  //         heading: Cesium.Math.toRadians(0),
  //         // 指定相机的俯仰角,0度是竖直向上,-90度是向下
  //         pitch: Cesium.Math.toRadians(-20),
  //         // 指定相机的滚转角,翻滚角
  //         roll: 0
  //     }
  // });

  // 05.3.flyto让相机飞往某个地方
  viewer.camera.flyTo({
      destination: position,
      orientation: {
          heading: Cesium.Math.toRadians(0),
          pitch: Cesium.Math.toRadians(-20),
          roll: 0
      }
  });
  
  // 05.4.通过按键移动相机
  document.addEventListener("keydown", (e) => {
      // 获取相机离地面的高度
      var height = viewer.camera.positionCartographic.height;
      // 移动距离
      var moveRate = height / 100;
      
      if (e.key == "w") {
        // 设置相机向前移动
        viewer.camera.moveForward(moveRate);
      } else if (e.key == "s") {
        // 设置相机向后移动
        viewer.camera.moveBackward(moveRate);
      } else if (e.key == "a") {
        // 设置相机向左移动
        viewer.camera.moveLeft(moveRate);
      } else if (e.key == "d") {
        // 设置相机向右移动
        viewer.camera.moveRight(moveRate);
      } else if (e.key == "q") {
        // 设置相机向左旋转相机
        viewer.camera.lookLeft(Cesium.Math.toRadians(0.1));
      } else if (e.key == "e") {
        // 设置相机向右旋转相机
        viewer.camera.lookRight(Cesium.Math.toRadians(0.1));
      } else if (e.key == "r") {
        // 设置相机向上旋转相机
        viewer.camera.lookUp(Cesium.Math.toRadians(0.1));
      } else if (e.key == "f") {
        // 设置相机向下旋转相机
        viewer.camera.lookDown(Cesium.Math.toRadians(0.1));
      } else if (e.key == "g") {
        // 向左逆时针翻滚
        viewer.camera.twistLeft(Cesium.Math.toRadians(0.1));
      } else if (e.key == "h") {
        // 向右顺时针翻滚
        viewer.camera.twistRight(Cesium.Math.toRadians(0.1));
      }
});
相关推荐
粥里有勺糖21 分钟前
视野修炼-技术周刊第130期 | 光影效果
前端·javascript·github
小岛前端35 分钟前
AI Skills 已经封神,但新的问题却越来越严重!
前端·后端·github
拖孩39 分钟前
一个人 + AI 做的小程序,上线 15 天赚了 10 块 5
前端·后端·微信小程序
用户939838294159940 分钟前
安卓自动化脚本热更新怎么做?不重新打包 APK 也能更新代码
前端
猫七先生1 小时前
在 React 里用 PMTiles 自托管底图
前端
tanghonghanhaoli1 小时前
【图书翻译】有意义的游戏设计:桌面游戏的方法论与心理学(第1、2章)
前端·游戏·ui
光影少年1 小时前
react native打包优化、包体积瘦身、离线包/热更新方案
前端·react native·react.js
Cache技术分享1 小时前
504. Java 反射 - 创建一个简单的依赖注入框架
前端·后端
_codeOH1 小时前
# 手把手复刻 DeepSeek 官网效果:玻璃拟态 + WebGL 流体 + Spring 动画,一篇讲透
前端
名字还没想好☜1 小时前
Next.js 用 cookies()/headers() 读请求信息:动态渲染触发、缓存失效与在 Server Action 里读写 cookie
前端·javascript·缓存·react·next.js·app router