目錄html
參考資料:git
cesium支持多種地形瓦片數據(GoogleEarthEnterpriseTerrainData、QuantizedMeshTerrainData、HeightmapTerrainData),這裏不詳細敘述每個,如下說的地形瓦片都是指HeightmapTerrainData。github
地形瓦片(heightmap-1.0)格式的terrain瓦片集是根據TMS(瓦片地圖服務)global-geodetic(全球大地座標)規則進行切分。數據結構
TMS特性簡述:佈局
TMS中一個瓦片地圖(TileMap)由一組具備不一樣比例尺瓦片集(TileSet)組成,每一個瓦片集由相同大小格式的規則瓦片平鋪而成。下一級的瓦片集由上一級的四叉分割而來(整個地圖就是個四叉樹結構)。測試
瓦片地圖具備邊界範圍(BoundingBox)和原點(Origin),原點是0,0
瓦片的左下角(也是-1,-1
瓦片的右上角),也就是軸向是向左向上。ui
global-geodetic切分規則:code
座標系爲WGS84大地座標系(<SRS>EPSG:4326</SRS>
)htm
對於任意級別(n
),該級別瓦片集的瓦片像素分辨率爲units-per-pixel = 0.703125/2^n
blog
0級爲覆蓋全球的2個256x256像素大小(地理大小爲180*180度)的圖塊,其Origin爲-180,90
。
heightmap 1.0 特定規則:
全部圖塊都具備後綴名.terrain
。
圖塊大小爲65x65
像素大小,實際上圖塊的最後一行和最後一列是相鄰的 東邊/南邊 圖塊的第一行/第一列。由於其大小不是256x256
,因此其對應級別的分辨率也有所不一樣。
圖塊獲取URL示例以下:
對於頂級的兩個圖塊:
- (-180°, -90°) - (0 °, 90 °) -
/path/tilesets/terrain/smallterrain/0/0/0.terrain
- ( 0°, -90 °) - (180 °, 90 °) -
/path/tilesets/terrain/smallterrain/0/1/0.terrain
往下一級的8個圖塊:
- (-180°,-90°) - ( -90°, 0°) -
/path/tilesets/terrain/smallterrain/1/0/0.terrain
- ( -90°,-90°) - ( 0°, 0°) -
/path/tilesets/terrain/smallterrain/1/1/0.terrain
- ( 0°,-90°) - ( 90°, 0°) -
/path/tilesets/terrain/smallterrain/1/2/0.terrain
- ( 90°,-90°) - ( 180°, 0°) -
/path/tilesets/terrain/smallterrain/1/3/0.terrain
- (-180°, 0°) - ( -90°, 90°) -
/path/tilesets/terrain/smallterrain/1/0/1.terrain
- ( -90°, 0°) - ( 0°, 90°) -
/path/tilesets/terrain/smallterrain/1/1/1.terrain
- ( 0°, 0°) - ( 90°, 90°) -
/path/tilesets/terrain/smallterrain/1/2/1.terrain
- ( 90°, 0°) - (180 °, 90 °) -
/path/tilesets/terrain/smallterrain/1/3/1.terrain
能夠參考一下 http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/ ,它的圖塊大小是32x32
的,瓦片集的信息以下。
可使用開源軟件 Cesium Terrain Builder 來對DEM數據切片,生成terrain瓦片。
對於TerrainTile
的數據結構,能夠查看代碼TerrainTile.hpp、TerrainTile.cpp,很清晰明瞭。
對於單個圖塊,爲65x65大小,每一個像素表示一個高度值,海拔值的計算規則爲H=像素值*0.2-1000
。
每一個高度值爲16Bit的整數,排列順序爲行-從西向東,列-從北向南,總的字節數爲65*65*2=8450
。
相鄰圖塊直接關係大體以下圖所示,相鄰瓦片之間有一行或者一列的重合。
對於一個.terrain圖塊,其通過gzip
解壓後的數據(文檔裏面說要瓦片數據要通過gzip壓縮,可是我在使用cesium測試的時候,是不通過壓縮的才能正確讀取),佈局大體以下:
前8540字節是高度數據,每一個高度數據爲2字節的小端表示的16位帶符號整數。
緊跟其後的一個字節是子塊掩碼,用於標識當前塊的子塊是否存在。
再以後是1個或者256*256個字節的水域掩碼,若是所有是水域(0)或者陸地(255),那麼就是一個字節,若是混合了水域和陸地,那麼就是256x256個字節,每一個字節表示該像素位置是水域(0)仍是陸地(255)。
cesium裏解析terrain瓦片數據(解壓縮後的)的示例代碼:
var buffer = ... var heightBuffer = new Uint16Array(buffer, 0, that._heightmapWidth * that._heightmapWidth); var childTileMask = new Uint8Array(buffer, heightBuffer.byteLength, 1)[0]; var waterMask = new Uint8Array(buffer, heightBuffer.byteLength + 1, buffer.byteLength - heightBuffer.byteLength - 1); var terrainData = new Cesium.HeightmapTerrainData({ buffer : heightBuffer, width : 65, height : 65, childTileMask : childTileMask, waterMask : waterMask });