cesium 加载地形

红小厨 2024-08-16 11:33:06 阅读 64

1 加载cesium-ion地形

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

1.1 注册cesium-ion账号

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

 

 

1.2 加载地形

cesium 提供了 createWorldTerrain 函数用来加载cesium-ion 提供的全球地形数据。使用示例如下:

<code>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 是北京西部世界科技有限公司开发的一款数据处理软件,软件中大部分功能免费,高级功能收费。免费功能可以满足学习期间的数据处理任务,如果正式项目,没有专业的数据处理团队,建议购买高级功能。官网地址: 首页 地球可视化实验室.团队致力于提供基础应用开发,助力数字孪生从业者,开发相关业务。

地形数据处理如下:

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

我们可以在线查看切好后的显示效果

我们可以将切好的瓦片使用nginx 发布成静态服务,就可以使用了。cesium提供了CesiumTerrainProvider类来加载.terrain格式的瓦片地形数据,使用示例如下:

<code>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">code>

<div class="pane_container">code>

<el-button size="small" @click="changeTerrain(0)">cesium-ion地形</el-button>code>

<el-button size="small" @click="changeTerrain(1)">ArcGis地形</el-button>code>

<el-button size="small" @click="changeTerrain(2)">离线地形</el-button>code>

</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>code>

#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 运行结果



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。