转自:http://www.cnblogs.com/fuckgiser/p/5824743.html

简述

前面我们从宏观上分析了Cesium的整体调度以及网格方面的内容,通过前两篇,读者应该可以比较清楚的明白一个Tile是怎么来的吧(如果还不明白全是我的错)。接下来,在前两篇的基础上,我们着重讨论一下地形相关的内容。

Cesium提供了TerrainProvider基类,该Provider负责每一个Tile对应的地形数据的构建,定义了一套地形Provider需要实现的接口和规范,但本身并不会参与其中的操作。这里列举一些关键的属性和函数:

  • tilingScheme

    • Provider内部地球网格的剖分方式,通常是WGS84坐标,也可以选择墨卡托坐标系
  • hasWaterMask
    • 是否支持水面效果
  • hasVertexNormals
    • 地形数据中是否包含法向量(光照是否支持)
  • heightmapTerrainQuality
    • 地形显示的精度,在上一篇中介绍的一个Tile占多少像素,其中这个参数作为调整系数
  • requestTileGeometry
    • Provider的对外接口,参数为Tile对应的XYZ,返回其对应的TerrainData,基类中为空实现。

如上就是TerrainProvider,基本都是空实现,仅仅提供了一套规范,在Cesium中有三个继承类,EllipsoidTerrainProvider和CesiumTerrainProvider,还有最新提供的ArcGisImageServerTerrainProvider。

详细介绍地形前我们先说明一下TileScheme、Terrain和Imagery之间的一个关联。TileScheme是坐标系,Cesium中目前支持WGS1984和墨卡托投影两种。Terrain和Imagery分别采用自己的TileScheme,比如目前Terrain默认采用WGS1984的坐标系,这和经纬高的真实数据更接近,而目前Imagery影像服务基本都是墨卡托投影(据我了解,只有天地图提供WGS84的影像服务)。

TileScheme Imagery(WGS1984) Imagery(Mercator)
Terrain(WGS1984) 坐标相同 坐标不同
Terrain(Mercator) 坐标不同 坐标相同

如上图,首先,Globe,也就是地球网格是根据TerrainProvider的TileScheme来划分的;其次,如果地形和影像之间采用不同的坐标系,则影像切片需要动态的转换为地形切片下对应的效果,也就是动态投影的过程,这个计算量是不可忽略的;

最后,在实际中,EllipsoidTerrainProvider支持WGS和Mercator两种坐标系,而CesiumTerrainProvider只能支持WGS一种,因此选择何种地形和影像来互相匹配,在性能上也是有差异的。

EllipsoidTerrainProvider

EllipsoidTerrainProvider是Globe默认采用的地形Provider,该Provider不支持水面,没有法向量,所以即使开启光照,对Tile也是无效的。

EllipsoidTerrainProvider功能弱爆了,那还有它存在的价值吗?答案是肯定的。它提供了一个全球范围内高度为0的地形,不需要额外的地形文件,就可以实时的自己来构建这个高度为0的Mesh。对那些没有网络环境,或网络不理想,或不需要地形的应用,EllipsoidTerrainProvider提供了最简单的,无需额外负担的地形数据来构网。

来看一下requestTileGeometry的实现:

原来EllipsoidTerrainProvider采用的高度图方式来构网,但buffer直接new出来,所以值都为0,而高宽为16,也就是把一个Tile的行列分为16*16。至于Cesium如何通过高度图构网的过程,我们在下一篇会介绍,本篇主要在于思路和流程的理解。如下是截取的XYZ为412的地形网格效果,是一个15*15的高度为0的网格:

另外,EllipsoidTerrainProvider有一个更为灵活的地方,TileScheme默认采用WGS84,但用户可以选择,这个在性能优化上还是值得考虑的,目前的影像服务绝大多数都是采用墨卡托,如果地形采用WGS84,如果所用的EllipsoidTerrainProvider内部坐标系是WGS84,这样就需要讲墨卡托的影像切片转换为WGS的切片的过程,所以,在这种情况下,反正怎么划分,最后的网格都没什么区别,索性让地形的TileScheme和影像的保持一致,性能会更好。理论上讲这个思路是正确的,但事实真的如此吗?因为这个牵扯到Imagery模块,我们在后面讲影像时再详细讨论。

ArcGisImageServerTerrainProvider

我们下来在看看年轻的ArcGIS的地形,这个可以说是一个真实的(凹凸的)高度图,原理和EllipsoidTerrainProvider如出一辙,因此同样的不支持法线,水面,但可以选择TileScheme,与EllipsoidTerrainProvider不一样之处在于每一个切片会根据ArcGIS规范请求一张图片,该图片中的像素对应的值就是该像素对应的高度,真的是名副其实的高度图。我们来看看ArcGisImageServerTerrainProvider的requestTileGeometry实现:

如上,不同于EllipsoidTerrainProvider,ArcGisImageServerTerrainProvider需要根据当前的XYZ获取对应的范围bbox,然后向ArcGIS
World Elevation Image
Services请求对应该范围的一个_heightmapWidth*_heightmapWidth大小的高度图。heightmapWidth默认为65,可想而知该网格会比较密。

遗憾的是,根据Cesium提供的url,我本机无法访问,所以看不到效果,如果对这个感兴趣,可以参考之前的一篇文章《ArcGIS Earth数据小析》,两者应该是同源的。

CesiumTerrainProvider

最后,就轮到了CesiumTerrainProvider,在该Provider中支持两种地形格式,一种是高度图,一种则是TIN网格的STK地形。我们一一道来。

createHeightmapTerrainData

这个是Cesium提供的高度图方式,和ArcGIS的很相似,目前Cesium已经废弃,确实在技术上,高度图有很多缺陷,我们在介绍完STK的TIN效果后,大家就一目了然。

这个就不用介绍了吧,和前面的一模一样,效果如下,相比EllipsoidTerrainProvider,同一个XYZ(412)这个比较密,因为这次确实有高度了,而不是清一色的0:

另外,Cesium的高度图支持水面效果,水面涉及到渲染层面,我们会在影像渲染中涉及这个问题。

createQuantizedMeshTerrainData

Cesium厉害的指出就在于目前采用STK的地形服务,这个地形的难度和技术细节已经无法在这一个章节内一一道来了,我们也主要说思路,后面单独一个章节来具体的说一下。支持。Cesium通过QuantizedMeshTerrainData封装了STK地形数据格式,它的优点是支持水面和法线,同时数据量比较小。个人认为STK的地形数据代表目前最好的TIN地形生成技术,没有之一,相比之下,高度图的形式可能更容易在应用层面解决问题,但在技术角度不值得一提。

当然,下载STK的数据思路和高度图的一直,也是根据XYZ请求一个Terrain文件,返回值是一个arraybuffer,不过这一次,不是用HeightmapTerrainData来封装,而是用QuantizedMeshTerrainData,本篇不讨论QuantizedMeshTerrainData细节,先看看同一个Tile(412)下的效果图:

可见STK的地形网格看上去很简单,甚至比EllipsoidTerrainProvider还要稀疏,那为什么还能具有如此多的优点呢,现卖个关子,下回分解。

回顾

本文主要介绍了目前Cesium支持的三种TerrainProvider的相关细节,每一个Tile切片,对应不同的TerrainProvider,地形数据会封装成HeightMapTerrainData或者QuantizedMeshTerrainData对象。

下两篇,我们详细介绍高度图,也就是HeightMapTerrainData和QuantizedMeshTerrainData中的细节。

cesium原理篇(三)--地形(1)【转】的更多相关文章

  1. Cesium原理篇:3最长的一帧之地形(2:高度图)

           这一篇,接着上一篇,内容集中在高度图方式构建地球网格的细节方面.        此时,Globe对每一个切片(GlobeSurfaceTile)创建对应的TileTerrain类,用来维 ...

  2. Cesium原理篇:5最长的一帧之影像

    如果把地球比做一个人,地形就相当于这个人的骨骼,而影像就相当于这个人的外表了.之前的几个系列,我们全面的介绍了Cesium的地形内容,详见: Cesium原理篇:1最长的一帧之渲染调度 Cesium原 ...

  3. Cesium原理篇:7最长的一帧之Entity(下)

    上一篇,我们介绍了当我们添加一个Entity时,通过Graphics封装其对应参数,通过EntityCollection.Add方法,将EntityCollection的Entity传递到DataSo ...

  4. Cesium原理篇:3最长的一帧之地形(1)

    前面我们从宏观上分析了Cesium的整体调度以及网格方面的内容,通过前两篇,读者应该可以比较清楚的明白一个Tile是怎么来的吧(如果还不明白全是我的错).接下来,在前两篇的基础上,我们着重讨论一下地形 ...

  5. Cesium原理篇:4Web Workers剖析

    JavaScript是单线程的,又是异步的,而最新的HTML5中,通过Web Workers可以在JS中支持多线程开发.这是几个意思?异步还是单线程,这怎么理解?Web Workers又是什么原理?实 ...

  6. Cesium原理篇:3最长的一帧之地形(3:STK)

    有了之前高度图的基础,再介绍STK的地形相对轻松一些.STK的地形是TIN三角网的,基于特征值,坦白说,相比STK而言,高度图属于淘汰技术,但高度图对数据的要求相对简单,而且支持实时构建网格,STK具 ...

  7. Cesium原理篇:3最长的一帧之地形(4:重采样)

           地形部分的原理介绍的差不多了,但之前还有一个刻意忽略的地方,就是地形的重采样.通俗的讲,如果当前Tile没有地形数据的话,则会从他父类的地形数据中取它所对应的四分之一的地形数据.打个比方 ...

  8. Cesium原理篇:7最长的一帧之Entity(上)

    之前的最长的一帧系列,我们主要集中在地形和影像服务方面.简单说,之前我们都集中在地球是怎么造出来的,从这一系列开始,我们的目光从GLOBE上解放出来,看看球面上的地物是如何渲染的.本篇也是先开一个头, ...

  9. Cesium原理篇:2最长的一帧之网格划分

    上一篇我们从宏观上介绍了Cesium的渲染过程,本章延续上一章的内容,详细介绍一下Cesium网格划分的一些细节,包括如下几个方面: 流程 Tile四叉树的构建 LOD 流程 首先,通过上篇的类关系描 ...

随机推荐

  1. DPDK+OpenvSwitch-centos7.4安装

    系统版本 [root@controller ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) DPDK版本: dpdk- ...

  2. 如何用dat批处理文件关闭某端口对应程序-Windows自动化命令

    如何用dat批处理文件关闭某端口对应程序? 网上找到的大部分都是手动操作,第一步先查出端口,第二步在根据上一步查到的端口手动去关闭进程.但我的需求不是这样的,我需要全自动处理.用于 dubbo 服务进 ...

  3. BZOJ4175 : 小G的电话本

    用后缀树统计出出现了x次的本质不同的子串的个数,最后再乘以x,得到一个多项式. 这个多项式常数项为0,但是一次项不为0. 于是把整个多项式除以一次项,通过多项式求ln和多项式求exp求出它的幂. 最后 ...

  4. Lua打印table树形结构

    --这是quick中的工具,作用就是打印Lua中强大的table的结构, 当table的嵌套层级比较多的时候,这个工具非常方便,开发中必备的工具.--具体使用方法:local debug = requ ...

  5. 【转】Mapped Statements collection does not contain value for解决

    最近一直在弄springMVC+mybatis的整合,因为接触到这个框架之后发现这个框架确实要比ssh好得多所以我自己也在配置这个框架.但是在配置的过程中我遇到了一些问题,这些问题当我配置完成之后访问 ...

  6. Bugzilla Error message: couldn't create child process: 720003: index.cgi

    two steps is try to fix this issue. 1. Turn off the windowns firewall 2. Register the perl to the sy ...

  7. CodeSmith 基础用法和例子

    〇.            前言 一.            工具设置 CodeSmith默认是不支持中文的,那么我们必须要先设置使其支持中文显示,保存.并且要能够在生成文件中支持中文. [Tools ...

  8. Understanding the STM32F0's GPIO

    Understanding the STM32F0's GPIO This is the first part of the GPIO tutorial for the STM32F0Discover ...

  9. android adb命令 unable to connect to 192.168.1.155:5555

    如果使用有线网络无法用adb connect命令连接设备的话,可以选择使用无线wifi来连接. 首先在android设备上装一个叫做Adb Wireless的软件,打开wifi,然后打开adb wir ...

  10. Xcode工程文件打不开:cannot be opened because the project file cannot be parsed

    svn更新代码后,打开xcode工程文件,会出现  xxx..xcodeproj  cannot be opened because the project file cannot be parsed ...