cesium地形瓦片(HeightMap)格式


參考資料:

cesium支持多種地形瓦片數據(GoogleEarthEnterpriseTerrainDataQuantizedMeshTerrainDataHeightmapTerrainData),這里不詳細敘述每一個,以下說的地形瓦片都是指HeightmapTerrainData

1、瓦片切分規則

地形瓦片(heightmap-1.0)格式的terrain瓦片集是根據TMS(瓦片地圖服務)global-geodetic(全球大地坐標)規則進行切分。

TMS特性簡述:

  • TMS中一個瓦片地圖(TileMap)由一組具有不同比例尺瓦片集(TileSet)組成,每個瓦片集由相同大小格式的規則瓦片平鋪而成。下一級的瓦片集由上一級的四叉分割而來(整個地圖就是個四叉樹結構)。

  • 對於一個瓦片地圖(TileMap)只能支持一個空間參考系(SRS)和一種圖像格式,如果需要支持多種就要做多個瓦片地圖。

  • 瓦片地圖具有邊界范圍(BoundingBox)和原點(Origin),原點是0,0瓦片的左下角(也是-1,-1瓦片的右上角),也就是軸向是向左向上。

TMS

global-geodetic切分規則:

  • 坐標系為WGS84大地坐標系(<SRS>EPSG:4326</SRS>

  • 對於任意級別(n),該級別瓦片集的瓦片像素分辨率為units-per-pixel = 0.703125/2^n

  • 0級為覆蓋全球的2個256x256像素大小(地理大小為180*180度)的圖塊,其Origin為-180,90

    global-geodetic

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的,瓦片集的信息如下。

    vr-theworld

2、.terrain瓦片格式分析

可以使用開源軟件 Cesium Terrain Builder 來對DEM數據切片,生成terrain瓦片。

對於TerrainTile的數據結構,可以查看代碼TerrainTile.hppTerrainTile.cpp,很清晰明了。

對於單個圖塊,為65x65大小,每個像素表示一個高度值,海拔值的計算規則為H=像素值*0.2-1000

每個高度值為16Bit的整數,排列順序為行-從西向東,列-從北向南,總的字節數為65*65*2=8450

相鄰圖塊直接關系大致如下圖所示,相鄰瓦片之間有一行或者一列的重合。

terrain-layout

對於一個.terrain圖塊,其經過gzip解壓后的數據(文檔里面說要瓦片數據要經過gzip壓縮,但是我在使用cesium測試的時候,是不經過壓縮的才能正確讀取),布局大致如下:

terrain-memory-layout

前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
});


免責聲明!

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



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