cesium原理篇(三)--地形(1)【轉】


轉自: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中的細節。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM