cesium 加载地形

打印 上一主题 下一主题

主题 877|帖子 877|积分 2631

1 加载cesium-ion地形

cesium-ion 是一个可扩展且安全的 3D 地理空间数据平台。它提供了 全球地形、影像图源和OSM建筑矢量等数据集。记住,因为地理数据的敏感性,一般正式项目开发时,都不会将自己的数据上传到该平台。不外在开发学习时,是一个很好的数据平台,我们可以注册使用它提供的数据服务。官网所在:Cesium ion – Cesium
1.1 注册cesium-ion账号



注册之后点击Access Tokens,已经默认提供了一个token, 你也可以自己注册新的token。
 


 
1.2 加载地形

cesium 提供了 createWorldTerrain 函数用来加载cesium-ion 提供的全球地形数据。使用示例如下:
  1. const accessToken = '你申请的token'
  2. Cesium.Ion.defaultAccessToken = accessToken;
  3. const terrainProvider = Cesium.createWorldTerrain({
  4.   requestVertexNormals: true,
  5.   requestWaterMask: true
  6. });
复制代码
2 加载 arcgis 地形

cesium 提供了 ArcGISTiledElevationTerrainProvider 类,来加载arcgis server 发布的地形服务。使用示例如下:
  1. const url = 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer'
  2. const terrainProvider = new Cesium.ArcGISTiledElevationTerrainProvider({
  3.   url: url,
  4.   requestWaterMask: true,
  5.   requestVertexNormals: true
  6. })
复制代码
3 加载离线地形

cesium 加载离线地形,需先下载DEM(高程数据)tif文件,然后像加载离线地图篇里一样,对离线的地形tif文件进行切片。只是这里的切片不能用QGIS切片,使用其他工具进行切片。
3.1 下载离线地形

参照使用QGIS对地形dem进行裁剪及归并篇的方法进行地形的下载和剪裁。
3.2 地形切片

cesium中使用的地形数据有格式要求,不能像离线地图篇那样直接使用QGIS切png瓦片,要使用其他工具,推荐使用cesiumlab,cesiumlab 是北京西部天下科技有限公司开发的一款数据处理软件,软件中大部分功能免费,高级功能收费。免费功能可以满意学习期间的数据处理任务,如果正式项目,没有专业的数据处理团队,建议购买高级功能。官网所在: 首页 地球可视化实行室.团队致力于提供基础应用开发,助力数字孪生从业者,开发相关业务。
地形数据处理如下:


处理完成后,切片效果如下:


我们可以在线检察切好后的显示效果




我们可以将切好的瓦片使用nginx 发布成静态服务,就可以使用了。cesium提供了CesiumTerrainProvider类来加载.terrain格式的瓦片地形数据,使用示例如下:
  1. cont url = 'http://47.107.93.79:8600/terrain/offline/'
  2. const terrainProvider = new Cesium.CesiumTerrainProvider({
  3.   url: url,
  4.   requestWaterMask: true,
  5.   requestVertexNormals: true
  6. })
复制代码
4 完备示例代码

TerrainLayer.vue
  1. <!--
  2. * @Description:
  3. * @Author: maizi
  4. * @Date: 2023-04-07 17:03:50
  5. * @LastEditTime: 2024-07-19 15:03:55
  6. * @LastEditors: maizi
  7. -->
  8. <template>
  9.   <div id="container">
  10.     <div class="pane_container">
  11.       <el-button size="small" @click="changeTerrain(0)">cesium-ion地形</el-button>
  12.       <el-button size="small" @click="changeTerrain(1)">ArcGis地形</el-button>
  13.       <el-button size="small" @click="changeTerrain(2)">离线地形</el-button>
  14.     </div>
  15.   </div>
  16. </template>
  17. <script>
  18. import * as MapWorks from './js/MapWorks'
  19. export default {
  20.   name: 'TerrainLayer',
  21.   data(){
  22.     return {
  23.       checked: false
  24.     }
  25.   },
  26.   mounted() {
  27.     this.init();
  28.   },
  29.   methods:{
  30.     init(){
  31.       let container = document.getElementById("container");
  32.       MapWorks.initMap(container)
  33.       MapWorks.addTdtLayer({
  34.         type: 'img_w'
  35.       })
  36.       MapWorks.addTdtLayer({
  37.         type: 'cia_w'
  38.       })
  39.       MapWorks.changeTerrain(0)
  40.     },
  41.     changeTerrain(index){
  42.       MapWorks.changeTerrain(index)
  43.     }
  44.   },
  45.   beforeDestroy(){
  46.     //实例被销毁前调用,页面关闭、路由跳转、v-if和改变key值
  47.     MapWorks.destroy();
  48.   }
  49. }
  50. </script>
  51. <style lang="scss" scoped>
  52. #container{
  53.   width: 100%;
  54.   height: 100%;
  55.   background: rgba(7, 12, 19, 1);
  56.   overflow: hidden;
  57.   background-size: 40px 40px, 40px 40px;
  58.   background-image: linear-gradient(hsla(0, 0%, 100%, 0.05) 1px, transparent 0), linear-gradient(90deg, hsla(0, 0%, 100%, 0.05) 1px, transparent 0);
  59.   .pane_container{
  60.     position: absolute;
  61.     left: 10px;
  62.     top: 50px;
  63.     padding: 10px 15px;
  64.     border-radius: 4px;
  65.     border: 1px solid rgba(128, 128, 128, 0.5);
  66.     color: #ffffff;
  67.     background: rgba(0, 0, 0, 0.4);
  68.     box-shadow: 0 3px 14px rgb(128 128 128 / 50%);
  69.     z-index: 2;
  70.   }
  71. }
  72. </style>
复制代码
MapWorks.js
  1. import GUI from 'lil-gui';
  2. // 初始视图定位在中国
  3. Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(90, -20, 110, 90);
  4. //天地图key
  5. const key = '39673271636382067f0b0937ab9a9677'
  6. // cesium-ion token
  7. const accessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5NWZmOTNkYS1mZjQ4LTQwOGMtYjBjYy1iMmRiODEwNmJkNmQiLCJpZCI6MjM0NDksInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODMzNzc2NjJ9.658-LW_jNkEHQxyWWizR4FGdh7B9MbiV2WK_qUN6dEo'
  8. const gui = new GUI();
  9. const params = {
  10.   terrainExaggeration : 1.0,
  11. }
  12. let viewer = null;
  13. let tileLayer = null
  14. function initMap(container) {
  15.   viewer = new Cesium.Viewer(container, {
  16.     animation: false,
  17.     baseLayerPicker: false,
  18.     fullscreenButton: false,
  19.     geocoder: false,
  20.     homeButton: false,
  21.     infoBox: false,
  22.     sceneModePicker: false,
  23.     selectionIndicator: false,
  24.     timeline: false,
  25.     navigationHelpButton: false,
  26.     scene3DOnly: true,
  27.     orderIndependentTranslucency: false,
  28.     contextOptions: {
  29.       webgl: {
  30.         alpha: true
  31.       }
  32.     }
  33.   })
  34.   viewer._cesiumWidget._creditContainer.style.display = 'none'
  35.   viewer.scene.fxaa = true
  36.   viewer.scene.postProcessStages.fxaa.enabled = true
  37.   if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
  38.     // 判断是否支持图像渲染像素化处理
  39.     viewer.resolutionScale = window.devicePixelRatio
  40.   }
  41.   // 移除默认影像
  42.   removeAll()
  43.   // 地形深度测试
  44.   viewer.scene.globe.depthTestAgainstTerrain = true
  45.   // 背景色
  46.   viewer.scene.globe.baseColor = new Cesium.Color(0.0, 0.0, 0.0, 0)
  47.   // 太阳光照
  48.   // viewer.scene.globe.enableLighting = true;
  49.    //gui面板
  50.    initGui()
  51.    window.viewer = viewer
  52. }
  53. function initGui() {
  54.   let layerFolder = gui.addFolder('地形夸张')
  55.   layerFolder.add(params, 'terrainExaggeration', 0, 5).step(0.1).onChange(function (value) {
  56.     viewer.scene.globe.terrainExaggeration =params.terrainExaggeration
  57.   })
  58. }
  59. function addTdtLayer(options) {
  60.   let url = `https://t{s}.tianditu.gov.cn/DataServer?T=${options.type}&x={x}&y={y}&l={z}&tk=${key}`
  61.   const layerProvider = new Cesium.UrlTemplateImageryProvider({
  62.     url: url,
  63.     subdomains: ['0','1','2','3','4','5','6','7'],
  64.     tilingScheme: new Cesium.WebMercatorTilingScheme(),
  65.     maximumLevel: 18
  66.   });
  67.   tileLayer = viewer.imageryLayers.addImageryProvider(layerProvider);
  68. }
  69. function changeTerrain(index) {
  70.   let url = null
  71.   let terrainProvider = null;
  72.   switch(index){
  73.     case 0:   //cesium-ion
  74.       Cesium.Ion.defaultAccessToken = accessToken;
  75.       terrainProvider = Cesium.createWorldTerrain({
  76.         requestVertexNormals: true,
  77.         requestWaterMask: true
  78.       });
  79.       break;
  80.     case 1:   //arcgis
  81.       url = 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer'
  82.       terrainProvider = new Cesium.ArcGISTiledElevationTerrainProvider({
  83.         url: url,
  84.         requestWaterMask: true,
  85.         requestVertexNormals: true
  86.       })
  87.       break;
  88.     case 2:   //离线地形
  89.       url = 'http://47.107.93.79:8600/terrain/offline/'
  90.       terrainProvider = new Cesium.CesiumTerrainProvider({
  91.         url: url,
  92.         requestWaterMask: true,
  93.         requestVertexNormals: true
  94.       })
  95.       break;
  96.   }
  97.   viewer.terrainProvider = terrainProvider;
  98.   let destination = {
  99.     x: -1252547.1676760237,
  100.     y: 5349424.924241895,
  101.     z: 3241966.5973322443
  102.   };
  103.   let orientation = {
  104.     heading: 4.788130273160937,
  105.     pitch: -0.33922935831056833,
  106.     roll: 6.283013915050958
  107.   };
  108.   viewer.scene.camera.flyTo({
  109.     destination: destination,
  110.     orientation:orientation
  111.   });
  112. }
  113. function removeAll() {
  114.   viewer.imageryLayers.removeAll();
  115. }
  116. function destroy() {
  117.   viewer.entities.removeAll();
  118.   viewer.imageryLayers.removeAll();
  119.   viewer.destroy();
  120. }
  121. export {
  122.   initMap,
  123.   addTdtLayer,
  124.   changeTerrain,
  125.   destroy
  126. }
复制代码
5 运行效果




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

怀念夏天

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表