Cesium加载地形

[复制链接]
发表于 2025-11-9 17:55:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Cesium的地形泉源大抵可以分为两种,一种是由Cesium官方提供的数据源,一种是第三方的数据源,官方源依赖于Cesium Assets,假如设置了AccessToken后,就可以直接使用Cesium的地形静态构造方法来获取数据源CesiumTerrainProvider.fromIonAssetId,AssetId来自于你本身的Assets库中的id。别的一种则可以通过CesiumTerrainProvider.fromUrl 来实现加载第三方的地形服务。
    下面的代码是从上一章节中的代码根本上实现的,集成了下拉选择地形服务的功能。
    代码中的各个key,不再移除了,方便诸位复现功能,假如须要正式发布,请自行更换,各个key随时大概到期或被整理。
  

  • 须要注意的是,对于第三方地形服务部门,我是使用了本身发布的地形服务,怎样制作发布,网上有很多教程,一样寻常来说发布后的所在是如许的,末了以layer.json竣事,但是在cesium中使用的时间,须要去掉末了的layer.json,由于Cesium会主动增补。
  1. http://127.0.0.1:9004/tile/terrain/2zxJPMEE/layer.json
复制代码


  • 我使用的是cesiumlab发布的,另有一个labtoken参数,着实完备的是【…2zxJPMEE/layer.json?labtoken=xx】,这种环境,也是要去掉layer.json后再使用。
  • 还须要注意,在cesium 1.104版本后,地形构造器改为了使用静态方法来获取,而且是异步的,具体的可查察代码中的switchTerrain 方法
  1. <template>
  2.   <div>
  3.     <div
  4.         ref="cesiumContainer"
  5.         id="cesiumContainer"
  6.         class="cesium-container"
  7.         style="width: 100%; height: 100vh;"
  8.     >
  9.       
  10.     </div>
  11.     <!--地形切换 -->
  12.     <div class="layer-switcher">
  13.       <label for="baseMap">选择底图:</label>
  14.       <select id="baseMap" v-model="selectedBaseMap" @change="switchBaseMap">
  15.         <option value="cesium">Cesium 默认</option>
  16.         <option value="tianditu">天地图</option>
  17.         <option value="gaode">高德地图</option>
  18.         <option value="baidu">百度地图</option>
  19.       </select>
  20.     </div>
  21.     <!-- 地形切换 -->
  22.     <div class="terrain-switcher">
  23.       <label for="terrain">选择地形:</label>
  24.       <select id="terrain" v-model="selectedTerrain" @change="switchTerrain">
  25.         <option value="none">无地形</option>
  26.         <option value="cesium">Cesium 官方地形</option>
  27.         <option value="custom">第三方/自定义地形</option>
  28.       </select>
  29.     </div>
  30.   </div>
  31. </template>
  32. <script setup>
  33. import { onMounted, ref, reactive } from 'vue';
  34. import {
  35.   BingMapsImageryProvider,
  36.   BingMapsStyle,
  37.   Cartesian3,
  38.   Color,
  39.   HeadingPitchRange,
  40.   Ion,
  41.   Viewer,
  42.   EllipsoidTerrainProvider,
  43.   CesiumTerrainProvider
  44. } from "cesium";
  45. import "cesium/Build/Cesium/Widgets/widgets.css";
  46. import CustomBaiduImageryProvider from "../cesium-extensions/BaiduImageryProvider.js";
  47. import { AMapImageryProvider,BaiduImageryProvider,TdtImageryProvider }  from '@cesium-china/cesium-map'
  48. import * as Cesium from "cesium";
  49. const cesiumContainer = ref(null)
  50. const viewer = ref(null)
  51. const selectedBaseMap = ref('cesium')
  52. // 地形下拉框选项
  53. const selectedTerrain = ref('none');
  54. // 定义各个底图的 ImageryProvider
  55. const imageryProviders = reactive({
  56.   cesium: [new BingMapsImageryProvider({
  57.     url: 'https://dev.virtualearth.net',
  58.     key: 'Rrke5RPh9hmJ32QZoFzP~_KI12m_pz_KbnGoZFmxVFg~Ai7_QidoqYPrWY7Kf1-GR8g9tY5C7BtbjAxOYpeoJNL4Hj66qSgWNOEAZSAlJKFC', // Cesium默认使用Bing Maps,需要替换为你的密钥
  59.     mapStyle: BingMapsStyle.AERIAL,
  60.   })],
  61.   tianditu: [new TdtImageryProvider({
  62.     style: 'vec', //style: vec、cva、img、cia、ter
  63.     key:'8af054001cff0f120a2e21c69b4f8c00', // 需去天地图申请
  64.   }),new TdtImageryProvider({
  65.     style: 'cva', //style: vec、cva、img、cia、ter
  66.     key:'8af054001cff0f120a2e21c69b4f8c00', // 需去天地图申请
  67.   })],
  68.   gaode: [new AMapImageryProvider({
  69.     style: 'img', // style: img、elec、cva
  70.     crs: 'WGS84' // 使用84坐标系,默认为:GCJ02
  71.   }),
  72.     new AMapImageryProvider({
  73.     style: 'cva', // style: img、elec、cva
  74.     crs: 'WGS84' // 使用84坐标系,默认为:GCJ02
  75.   })],
  76.   // 使用cesium-map 组件实现
  77.   /*baidu: [new BaiduImageryProvider({
  78.     url:"http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1",
  79.     style: 'normal', // style: img、vec、normal、dark
  80.     crs: 'WGS84' // 使用84坐标系,默认为:BD09
  81.   })],*/
  82.   // 自定义百度地图提供器
  83.   baidu:[new CustomBaiduImageryProvider()]
  84. })
  85. onMounted(() => {
  86.   // 设置 Cesium Ion 访问令牌
  87.   Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhNmQ5NDYyNi1lZTdhLTRiYTItODFiZi1mYzNiYWNjNDFjMzgiLCJpZCI6NTk3MTIsImlhdCI6MTY2MDE4MDAyNX0.bDTaHEah0hRjUyJWz0hyxIL0Fg63awPXV26OmQ5MCdM'; // 替换为你的访问令牌
  88.   viewer.value = new Viewer('cesiumContainer', {
  89.     animation: false, // 移除动画控件
  90.     timeline: false, // 移除时间轴控件
  91.     geocoder: false, // 移除地理编码控件
  92.     homeButton: false, // 移除主页按钮
  93.     sceneModePicker: false, // 移除场景模式选择器
  94.     selectionIndicator: false, // 移除选择指示器
  95.     fullscreenButton: false, // 移除全屏按钮
  96.     vrButton: false, // 移除 VR 按钮
  97.     // 默认不设置 terrainProvider,即使用椭球体
  98.     terrainProvider: new EllipsoidTerrainProvider(),// 默认无地形
  99.   });
  100.   // 添加默认实体或其他初始化操作
  101.   const tiananmenEntity = viewer.value.entities.add({
  102.     position: Cartesian3.fromDegrees(116.397128, 39.916527),
  103.     point: { pixelSize: 10, color: Color.RED },
  104.     name: '天安门',
  105.   })
  106.   viewer.value.flyTo(tiananmenEntity,{
  107.     duration: 3, // 飞行时间,单位秒
  108.     offset: new HeadingPitchRange(
  109.         0, // Heading,航向角,0表示正北方向
  110.         Cesium.Math.toRadians(-80), // Pitch,俯仰角,负值表示向下俯视
  111.         405000 // Range,距离目标的距离,增加此值以提高视角高度
  112.     )
  113.   })
  114. });
  115. const switchBaseMap = () => {
  116.   // 移除当前的底图图层
  117.   if (viewer.value && viewer.value.imageryLayers.length > 0) {
  118.     viewer.value.imageryLayers.removeAll()
  119.   }
  120.   let newProviders = imageryProviders[selectedBaseMap.value] || [];
  121.   
  122.   for (let i = 0; i < newProviders.length; i++) {
  123.     viewer.value.imageryLayers.addImageryProvider(newProviders[i])
  124.   }
  125.   
  126. }
  127. // ------------------ 方法:地形切换 -------------------
  128. const switchTerrain = async () => {
  129.   if (!viewer.value) return;
  130.   if (selectedTerrain.value === 'none') {
  131.     viewer.value.terrainProvider = new EllipsoidTerrainProvider();
  132.   } else if (selectedTerrain.value === 'cesium') {
  133.     // 从 Ion assetId 加载官方地形
  134.     viewer.value.terrainProvider = await CesiumTerrainProvider.fromIonAssetId(1, {
  135.       // requestVertexNormals: true,
  136.       // requestWaterMask: true,
  137.     });
  138.   } else if (selectedTerrain.value === 'custom') {
  139.     // 从自定义 URL 加载
  140.     viewer.value.terrainProvider = await CesiumTerrainProvider.fromUrl(
  141.         'http://127.0.0.1:9004/tile/terrain/2zxJPMEE?labtoken=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiItMSxUaHUgQXByIDE4IDE1OjMwOjU3IENTVCAyMDI0In0.j_YKsCRsIQtpgOWfFvMwAP65Rlx9uXyVte_xkE95Vdo',
  142.         {
  143.           requestVertexNormals: false,
  144.           // requestWaterMask: true,
  145.         }
  146.     )
  147.   }
  148. };
  149. </script>
  150. <style>
  151. .cesium-container {
  152.   width: 100%;
  153.   height: 100%;
  154.   position: relative;
  155. }
  156. /* 隐藏页面底部的 Cesium logo 和数据归属 */
  157. .cesium-viewer .cesium-widget-credits {
  158.   display: none !important; /* 隐藏整个 Cesium 控件 */
  159. }
  160. /* 隐藏 右上角的 Imagery 和 Navigation instructions */
  161. .cesium-viewer .cesium-viewer-toolbar {
  162.   display: none !important; /* 隐藏工具栏 */
  163. }
  164. .layer-switcher {
  165.   position: absolute;
  166.   top: 10px;
  167.   left: 10px;
  168.   background: rgba(42, 42, 42, 0.8);
  169.   padding: 10px;
  170.   border-radius: 4px;
  171.   color: white;
  172.   z-index: 1;
  173. }
  174. .layer-switcher select {
  175.   margin-left: 5px;
  176.   padding: 2px 5px;
  177.   border-radius: 2px;
  178.   border: none;
  179. }
  180. /* 地形切换器样式,可以放在旁边或者下方 */
  181. .terrain-switcher {
  182.   position: absolute;
  183.   top: 60px;
  184.   left: 10px;
  185.   background: rgba(42, 42, 42, 0.8);
  186.   padding: 10px;
  187.   border-radius: 4px;
  188.   color: white;
  189.   z-index: 10;
  190. }
  191. .terrain-switcher select {
  192.   margin-left: 5px;
  193.   padding: 2px 5px;
  194.   border-radius: 2px;
  195.   border: none;
  196. }
  197. </style>
复制代码
源码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表