• Quick Start 快速入门
  • 启用地形照明和水体效果
  • 准备流式化地形
  • Terrain providers 地形提供器
  • 资源
  • 作业

7 - Adding Terrain - 添加地形

Cesium支持流式的、可视化的全球高程投影地形地势、水形数据,包括海洋、湖泊、河流、山峰、峡谷和其他能够被三维展示出来的且效果比二维好的地形数据。像图层数据一样,Cesium引擎会从一个服务器上请求流式地形数据,仅请求那些基于当前相机能看到的需要绘制的图层上的数据。

Cesium官方提供了一些地形数据集的例子,以及如何配置这些参数。

支持的地形数据格式

为了添加地形数据,我们需要创建一个CesiumTerrainProvider,提供一个url和一些配置,然后将这个provider赋值给viewer.terrainProvider

此处,我们可以使用Cesium WorldTerrianopen in new window图层,该图层由Cesium ion提供,在“My Assets”中是默认提供的。我们可以用createWorldTerrainAsync函数创建一个由Cesium ion提供服务的Cesium WorldTerrianopen in new window

<script type="module">
</script>
// Load Cesium World Terrain
viewer.terrainProvider = await Cesium.createWorldTerrainAsync({
    requestWaterMask: true, // required for water effects
    requestVertexNormals: true, // required for terrain lighting
});
const target = new Cesium.Cartesian3(
    -2489625.0836225147,
    -4393941.44443024,
    3882535.9454173897
);
const offset = new Cesium.Cartesian3(
    -6857.40902037546,
    412.3284835694358,
    2147.5545426812023
);
viewer.camera.lookAt(target, offset);
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);

requestWaterMaskrequestVertexNormals是可选的配置项,告诉Cesium是否需要请求额外的水、光数据。这两个选项默认是设为false的。

最终,既然我们有了地形数据,我们需要更多的线条来使得地形数据背后的objects能够正确地显示,只有最前面、最上面的objects才能是可见的。

// Enable depth testing so things behind the terrain disappear.
viewer.scene.globe.depthTestAgainstTerrain = true;

我们现在有地形数据和运动的水。纽约非常平坦,所以可以在上面的地形数据上自由的探索。举一个显而易见的例子,你可以跳转到更加崎岖的区域比如 Grand Canyon 或者 San Francisco。

img

CesiumJS支持对与水流相关的海洋、湖泊和河流以及全球高分辨率地形进行流式处理和可视化。查看山峰、山谷和其他地形特征,并拥抱三维数字地球。使用Cesium ionopen in new window流式化您自己的切片地形数据或高分辨率管理地形,如Cesium World Terrainopen in new window

Quick Start 快速入门

打开http://111.22.69.99:58080/cesium/Apps/Sandcastle的Hello Worldopen in new window示例。默认情况下,地球球体是WGS84 ellipsoidopen in new window。通过将terrainProvider选项传递给Viewer,指定不同的地形提供器。让我们使用Cesium世界地形:

Cesium.Ion.defaultAccessToken = 'your_access_token';
const viewer = new Cesium.Viewer("cesiumContainer", {
        animation: false, // 动画小组件
        baseLayerPicker: false, // 底图组件,选择三维数字地球的底图
        fullscreenButton: false, // 全屏组件
        vrButton: false, // VR模式
        geocoder: false, // 地理编码搜索组件
        homeButton: false, // 首页,点击之后将视图跳转到默认视角
        infoBox: false, // 信息框
        sceneModePicker: false, // 场景模式,切换2D、3D和Columbus Views(CV)模式
        selectionIndicator: false, // 是否显示选取指示器组件
        timeline: false, // 时间轴
        navigationHelpButton: false, // 帮助提示,如何操作数字地球
        navigationInstructionsInitiallyVisible: false,
        terrain: Cesium.Terrain.fromWorldTerrain(),
});
const target = new Cesium.Cartesian3(
    -2489625.0836225147,
    -4393941.44443024,
    3882535.9454173897
);
const offset = new Cesium.Cartesian3(
    -6857.40902037546,
    412.3284835694358,
    2147.5545426812023
);
viewer.camera.lookAt(target, offset);
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);

NOTE: 创建Cesium账号 NOTE: 本教程使用Cesium ion提供的地形。创建一个帐户以获取访问令牌(access token),以便在本教程中使用地形。在这里注册open in new window,上面的示例代码将自动更新为您的令牌。如果您已经有帐户,请登录open in new window

修改示例后,按F8运行该示例。缩放到山区,按住鼠标中键并拖动以倾斜到地平线视图。下图珠穆朗玛峰的样子:

img

随着我们的缩放越来越近,CesiumJS基于地球上哪些部分可见以及它们离得有多远来获得更高分辨率的地形。

地形和图像分别处理,任何图像提供者都可以与任何地形提供者一起使用。请参见Imagery Layers Tutorialopen in new window以管理图像。

启用地形照明和水体效果

Cesium世界地形还包括地形照明数据和水体效果所需的海岸线数据。默认情况下,此数据不会随地形图块一起发送。若要启用地形照明,请将requestVertexNormals设为true并开启全球光照。

var viewer = new Cesium.Viewer('cesiumContainer', {
	terrainProvider: await Cesium.createWorldTerrainAsync({
    	requestVertexNormals: true, // required for terrain lighting
    }),
});
viewer.scene.globe.enableLighting = true;

使用requestWaterMask以类似的方式启用水体效果:

var viewer = new Cesium.Viewer('cesiumContainer', {
    terrainProvider: await Cesium.createWorldTerrainAsync({
        requestWaterMask: true
    })
});

缩放到有水的区域以查看效果。这里是旧金山湾:

img

随着时间的推移,水波波动和明亮的镜面反射太阳和月亮的光。通过使用 Globe.oceanNormalMapUrl用于创建波浪来自定义水效果。更改图像提供者也会影响水的外观,因为水的颜色与底层图像混合。改变图层提供器也会改变水体效果的呈现,因为水体的颜色会和底下的图层混合渲染。

请参阅http://111.22.69.99:58080/cesium/Apps/Sandcastle的地形示例open in new window,探索一些有趣的地形和水体效果区域。

准备流式化地形

Cesium World Terrainopen in new window: 高分辨世界地形,同时扩展支持地形照明和水体效果。Cesium World Terrain支持通过Cesium ion在线访问,也支持付费下载,离线访问。将它加入到Cesium应用中,将快速提高地形可视化效果。 Cesium World Terrain也可以通过on-premise获得。

Terrain providers 地形提供器

Cesium基于地形提供器支持请求地形的若干种方法。大多数地形提供器使用HTTP上的REST接口open in new window来请求地形切片。地形提供器根据请求的格式和地形数据的组织方式而有所不同。CesiumJS支持以下地形提供器:

  • CesiumTerrainProvider: 支持量化网格地形切片,针对地形流进行了优化。兼容Cesium ion所服务的地形和来自[3D tiling pipeline])(/3d-tiling-pipeline/terrain/)的输出数据。
  • GoogleEarthEnterpriseTerrainProvider: 支持由您的Google Earth Enterpriseopen in new window服务器生成的高程地图地形。
  • VRTheWorldTerrainProvider: 支持从VT MAK VR-TheWorld Serveropen in new window服务器请求的高度地图地形图。
  • EllipsoidTerrainProvider:按照程序创建椭球的表面。缺乏地形的真实外观,但不从服务器请求数据。

地形提供器的构造与图层提供器open in new window类似,如果服务器不支持跨域资源共享CORSopen in new window,则通常包括地形服务器的URL和可选的代理。

资源

查看http://111.22.69.99:58080/cesium/Apps/Sandcastle中的地形示例open in new window所有地形提供器的参考文档open in new window

Cesium加载地形数据:

主要接口:Cesium.CesiumProvider()

Cesium各类地形数据的加载

// cesium版本1.107.0之前的加载地形方式
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
    url: 'https://assets.agi.com/stk-terrain/world' 
});

cesium版本更新之后,删除了 viewer.terrainProvider 接口,其加载地形方式发生了改变:

第一种方式:调用Cesium.createWorldTerrainAsync()

// cesium版本1.107.0之后的加载地形方式
const addWorldTerrainAsync = async (viewer) => {
    try {
      const terrainProvider = await Cesium.createWorldTerrainAsync({
        requestWaterMask: true,
        requestVertexNormals: true,
      });
      viewer.terrainProvider = terrainProvider;
    } catch (error) {
      console.log(`Failed to add world imagery: ${error}`);
    }
  }
  addWorldTerrainAsync(viewer)
  viewer.scene.globe.enableLighting = true   // 对大气和雾启用实时动态照明效果
  // 启用深度测试,让地形后面的东西消失。为true实现高程遮挡(在没有地形时候也会有高程遮挡效果),为false则绘制与添加的图元均在地球顶部不会出现遮挡问题,按实际应用情况设置
  viewer.scene.globe.depthTestAgainstTerrain = true
  console.log(viewer.scene.imageryLayers === viewer.imageryLayers)
})

第二种方式:在创建Viewer时直接添加地形:

const viewer = new Cesium.Viewer('cesiumContainer', {
     terrain: new Cesium.Terrain.fromWorldTerrain({
     url: Cesium.IonResource.fromAssetId(3956),
     requestWaterMask: true,    // 请求水体效果所需要的海水波浪数据
     requestVertexNormals: true   // 请求地形照明数据
     })
  })

作业

  1. 加载使用Cesium.createWorldTerrainAsyn加载cesium ion的默认地形。

  2. 加载株洲市地形图和卫星影像底图( dem 和 arc_16.mbtiles )

    // cesium1.108版本后使用这个方法
    viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl(
    	"http://111.22.69.99:58080/cesium/Apps/SampleData/dem/zhuzhou/"
    )
    

image-20240320171206338

  1. (选做)参考天地图官方文档三维服务 - 天地图 帮助文档 (tianditu.gov.cn)open in new window,使用天地图地形图。
Last Updated:
Contributors: zly, star0891