转自: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. JedisConnectionException: java.net.ConnectException: Connection refused

    出现问题 我遇到的一个问题,在连接redis的时候出现了错误!错误如下: JedisConnectionException: java.net.ConnectException: Connection ...

  2. python全栈开发之匿名函数和递归函数

    python 匿名函数和递归函数 python全栈开发,匿名函数,递归函数 匿名函数 lambda函数也叫匿名函数,即函数没有具体的名称.是为了解决一些功能很简单需求而设计的一句话函数.如下: #这段 ...

  3. Android中线程通信的方式

    Android 跨线程通信 android 中是不允许在主线程中进行 网络访问等事情的因为UI如果停止响应5秒左右的话整个应用就会崩溃,到Android4.0 以后 Google强制规定,与网络相关的 ...

  4. Python基础笔记(三)

    1. 循环与流程控制 (1) for myList1 = ["A", "B", "C", "D"] # 正序遍历 for ...

  5. luogu P2757 [国家集训队]等差子序列

    题目链接 luogu P2757 [国家集训队]等差子序列 题解 线段树好题 我选择暴力 代码 // luogu-judger-enable-o2 #include<cstdio> inl ...

  6. BZOJ.2142.礼物(扩展Lucas)

    题目链接 答案就是C(n,m1) * C(n-m1,m2) * C(n-m1-m2,m3)...(mod p) 使用扩展Lucas求解. 一个很简单的优化就是把pi,pi^ki次方存下来,因为每次分解 ...

  7. curl dns缓存设置

    CURLOPT_DNS_USE_GLOBAL_CACHE 启用时会启用一个全局的DNS缓存,此项为线程安全的,并且默认启用.CURLOPT_DNS_CACHE_TIMEOUT 设置在内存中保存DNS信 ...

  8. Codeforces Round #394 (Div. 2) E. Dasha and Puzzle 构造

    E. Dasha and Puzzle 题目连接: http://codeforces.com/contest/761/problem/E Description Dasha decided to h ...

  9. ios网络请求

    1.AFNetworking object 2.Alamofire swift

  10. IBM BR10i阵列卡配置Raid0/Raid1(转)

    说明:IBM的阵列卡无论多旧多新操作步骤都基本差不多. RAID1的步骤: 开机自检过程中出现ctrl+c提示,按ctrl+c进入LSI Logic Config Utility v6.10.02.0 ...