怀念夏天 发表于 2024-10-13 08:07:57

cesium 加载地形

1 加载cesium-ion地形

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


https://i-blog.csdnimg.cn/blog_migrate/e58c82bfad0eeb7695ad933a07795b77.png
注册之后点击Access Tokens,已经默认提供了一个token, 你也可以自己注册新的token。
 
https://i-blog.csdnimg.cn/blog_migrate/67997d9f9e822a1879c0d836a7ed7d0c.png

 
1.2 加载地形

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

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

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

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

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

https://i-blog.csdnimg.cn/blog_migrate/adad7854fe533bd9ad93144a910c3fd9.png
处理完成后,切片效果如下:

https://i-blog.csdnimg.cn/blog_migrate/d58dc1f2e29760514fbb20482671680f.png
我们可以在线检察切好后的显示效果

https://i-blog.csdnimg.cn/blog_migrate/b47fd2a2e092e5a9cb959967684f4029.png

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

TerrainLayer.vue
<!--
* @Description:
* @Author: maizi
* @Date: 2023-04-07 17:03:50
* @LastEditTime: 2024-07-19 15:03:55
* @LastEditors: maizi
-->

<template>
<div id="container">
    <div class="pane_container">
      <el-button size="small" @click="changeTerrain(0)">cesium-ion地形</el-button>
      <el-button size="small" @click="changeTerrain(1)">ArcGis地形</el-button>
      <el-button size="small" @click="changeTerrain(2)">离线地形</el-button>
    </div>
</div>
</template>

<script>
import * as MapWorks from './js/MapWorks'
export default {
name: 'TerrainLayer',
data(){
    return {
      checked: false
    }
},
mounted() {
    this.init();
},
methods:{
    init(){
      let container = document.getElementById("container");
      MapWorks.initMap(container)
      MapWorks.addTdtLayer({
      type: 'img_w'
      })
      MapWorks.addTdtLayer({
      type: 'cia_w'
      })
      MapWorks.changeTerrain(0)
    },
    changeTerrain(index){
      MapWorks.changeTerrain(index)
    }
},
beforeDestroy(){
    //实例被销毁前调用,页面关闭、路由跳转、v-if和改变key值
    MapWorks.destroy();
}
}
</script>

<style lang="scss" scoped>
#container{
width: 100%;
height: 100%;
background: rgba(7, 12, 19, 1);
overflow: hidden;
background-size: 40px 40px, 40px 40px;
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);
.pane_container{
    position: absolute;
    left: 10px;
    top: 50px;
    padding: 10px 15px;
    border-radius: 4px;
    border: 1px solid rgba(128, 128, 128, 0.5);
    color: #ffffff;
    background: rgba(0, 0, 0, 0.4);
    box-shadow: 0 3px 14px rgb(128 128 128 / 50%);
    z-index: 2;
}
}


</style> MapWorks.js
import GUI from 'lil-gui';
// 初始视图定位在中国
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(90, -20, 110, 90);
//天地图key
const key = '39673271636382067f0b0937ab9a9677'
// cesium-ion token
const accessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5NWZmOTNkYS1mZjQ4LTQwOGMtYjBjYy1iMmRiODEwNmJkNmQiLCJpZCI6MjM0NDksInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODMzNzc2NjJ9.658-LW_jNkEHQxyWWizR4FGdh7B9MbiV2WK_qUN6dEo'
const gui = new GUI();
const params = {
terrainExaggeration : 1.0,
}


let viewer = null;
let tileLayer = null

function initMap(container) {
viewer = new Cesium.Viewer(container, {
    animation: false,
    baseLayerPicker: false,
    fullscreenButton: false,
    geocoder: false,
    homeButton: false,
    infoBox: false,
    sceneModePicker: false,
    selectionIndicator: false,
    timeline: false,
    navigationHelpButton: false,
    scene3DOnly: true,
    orderIndependentTranslucency: false,
    contextOptions: {
      webgl: {
      alpha: true
      }
    }
})
viewer._cesiumWidget._creditContainer.style.display = 'none'
viewer.scene.fxaa = true
viewer.scene.postProcessStages.fxaa.enabled = true
if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
    // 判断是否支持图像渲染像素化处理
    viewer.resolutionScale = window.devicePixelRatio
}
// 移除默认影像
removeAll()
// 地形深度测试
viewer.scene.globe.depthTestAgainstTerrain = true
// 背景色
viewer.scene.globe.baseColor = new Cesium.Color(0.0, 0.0, 0.0, 0)
// 太阳光照
// viewer.scene.globe.enableLighting = true;


   //gui面板
   initGui()

   window.viewer = viewer
}

function initGui() {
let layerFolder = gui.addFolder('地形夸张')
layerFolder.add(params, 'terrainExaggeration', 0, 5).step(0.1).onChange(function (value) {
    viewer.scene.globe.terrainExaggeration =params.terrainExaggeration
})
}


function addTdtLayer(options) {
let url = `https://t{s}.tianditu.gov.cn/DataServer?T=${options.type}&x={x}&y={y}&l={z}&tk=${key}`
const layerProvider = new Cesium.UrlTemplateImageryProvider({
    url: url,
    subdomains: ['0','1','2','3','4','5','6','7'],
    tilingScheme: new Cesium.WebMercatorTilingScheme(),
    maximumLevel: 18
});
tileLayer = viewer.imageryLayers.addImageryProvider(layerProvider);
}

function changeTerrain(index) {
let url = null
let terrainProvider = null;
switch(index){
    case 0:   //cesium-ion
      Cesium.Ion.defaultAccessToken = accessToken;
      terrainProvider = Cesium.createWorldTerrain({
      requestVertexNormals: true,
      requestWaterMask: true
      });
      break;
    case 1:   //arcgis
      url = 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer'
      terrainProvider = new Cesium.ArcGISTiledElevationTerrainProvider({
      url: url,
      requestWaterMask: true,
      requestVertexNormals: true
      })
      break;
    case 2:   //离线地形
      url = 'http://47.107.93.79:8600/terrain/offline/'
      terrainProvider = new Cesium.CesiumTerrainProvider({
      url: url,
      requestWaterMask: true,
      requestVertexNormals: true
      })
      break;
}
viewer.terrainProvider = terrainProvider;



let destination = {
    x: -1252547.1676760237,
    y: 5349424.924241895,
    z: 3241966.5973322443
};
let orientation = {
    heading: 4.788130273160937,
    pitch: -0.33922935831056833,
    roll: 6.283013915050958
};
viewer.scene.camera.flyTo({
    destination: destination,
    orientation:orientation
});
}

function removeAll() {
viewer.imageryLayers.removeAll();
}

function destroy() {
viewer.entities.removeAll();
viewer.imageryLayers.removeAll();
viewer.destroy();
}

export {
initMap,
addTdtLayer,
changeTerrain,
destroy
}

5 运行效果


https://i-blog.csdnimg.cn/blog_migrate/104df72de3e75085003659969e7adf88.gif

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