详解 Cesium的地形格式terrain

1 详解 Cesium .terrain 格式

在 3D 地理信息系统(GIS)和虚拟地球应用中,地形数据的处理至关重要。Cesium 作为一个强大的开源 JavaScript 库,支持多种地形数据格式,其中 .terrain 格式(量化网格)是最常用的格式之一。本文将深入解析 .terrain 格式,探讨其特点、工作原理及如何在 Cesium 中使用该格式。

生成地形工具

TilesBuilderTilesBuilder提供一个高效、兼容、优化的数据转换工具,一站式完成数据转换、数据发布、数据预览操作。

请添加图片描述

2 什么是 .terrain 格式?

.terrain 是一种专门为 Cesium 设计的地形数据格式,基于 量化网格(Quantized Mesh)技术。该格式通过将地形数据进行压缩和量化处理,大大减少了地形数据的存储空间,提升了加载和渲染性能。Cesium 使用这种格式来处理大型地形数据集,尤其是需要高效流式加载的地形切片(Tiles)。

3 量化网格(Quantized Mesh)简介

量化网格是一种高效的地形数据存储方式,它将地形高度数据(如 DEM 或数字高程模型)进行空间分割,将高程值通过量化压缩到较小的整数范围。这样做的好处是,减少了数据存储的大小,提升了处理速度。量化网格利用层次化的切片结构,使得系统可以根据用户的视图动态加载需要的地形部分。

请添加图片描述

3.1.terrain 格式的特点
  1. 高效的存储方式
    .terrain 格式通过量化和压缩技术将地形数据存储为二进制文件,使得大规模的地形数据能够高效地存储和传输。相比传统的地形数据格式(如高度图),.terrain 格式的文件体积较小,加载速度较快。

  2. 层次化切片结构
    .terrain 格式的数据被分成多个切片(tiles),每个切片代表地球表面某个区域的地形数据。每个切片的数据进一步被细分为更小的网格,每个网格包含多个地形点。切片的层次结构确保了在不同的缩放级别下,Cesium 只加载与视图相关的切片,进一步提高了性能。

  3. 适用于大规模数据集
    量化网格支持大范围、高精度的地形数据,例如,全球范围内的地形数据或某个大区域的详细地形模型。由于数据被切分为多个小块,它能够在不同的分辨率下进行渲染,适应不同级别的视图需求。

  4. 支持动态加载和流式传输
    .terrain 格式支持按需加载数据。这意味着当用户缩放或平移地图时,Cesium 会根据视图位置和缩放级别动态加载相应的地形切片,无需一次性加载整个地形数据集,从而减少了初始加载时间和内存占用。

3.2.terrain 格式的工作原理
  1. 地形数据的切片
    .terrain 格式通过将大范围的地形数据分割为许多小块(即切片),每个切片包含一个固定区域的地形数据。每个切片都有不同的细节级别(LOD,Level of Detail),当用户视角距离地形较近时,Cesium 会加载更高分辨率的切片;当视角较远时,加载较低分辨率的切片。
  2. 量化和压缩
    在每个切片内,地形高度值(如DEM数据)通过量化压缩为整数值,减小了数据的存储和传输开销。量化过程通常会使地形精度有所降低,但这种精度损失在大多数应用场景下是可以接受的,尤其是在大范围的地形渲染中,地形细节不会因为量化而明显丧失。
  3. 切片的传输和渲染
    Cesium 在客户端通过 TerrainProvider 来请求和加载 .terrain 文件中的切片数据。当用户浏览地图时,Cesium 会根据视图范围请求适当的切片进行渲染。随着用户视角的变化,Cesium 会动态加载新的切片,并卸载不再需要的切片,从而实现高效的地形加载。

4 Cesium .terrain 格式的二进制文件结构

Cesium 的 .terrain 格式是基于 量化网格(Quantized Mesh) 技术的,采用了一种高效的二进制文件结构来存储地形数据。这个结构通过将高程数据进行量化和压缩,使得数据体积大大缩小,同时确保渲染性能。

了解 .terrain 文件的二进制结构对于深度定制 Cesium 地形加载和理解底层实现是非常重要的。以下将详细解析 .terrain 格式的二进制文件结构。

4.1 .terrain 文件的整体结构

Cesium .terrain 文件的结构通常包括以下几个主要部分:

  1. 头部(Header)
  2. 切片信息(Tile Data)
  3. 顶点数据(Vertex Data)
  4. 索引数据(Index Data)
  5. 其他附加数据(如颜色、纹理、属性数据等)
4.1.1 头部(Header)

头部包含文件的基本信息,如瓦片的中心位置、海拔范围、包围球信息以及地平线遮挡点的坐标。

头部结构
struct QuantizedMeshHeader {
    double CenterX;  // 瓦片的中心点在地心固定坐标系中的 X 坐标。
    double CenterY;  // 瓦片的中心点在地心固定坐标系中的 Y 坐标。
    double CenterZ;  // 瓦片的中心点在地心固定坐标系中的 Z 坐标。
    float MinimumHeight;  // 瓦片区域内的最小高度。
    float MaximumHeight;  // 瓦片区域内的最大高度。
    double BoundingSphereCenterX;  // 瓦片的包围球中心点的 X 坐标。
    double BoundingSphereCenterY;  // 瓦片的包围球中心点的 Y 坐标。
    double BoundingSphereCenterZ;  // 瓦片的包围球中心点的 Z 坐标。
    double BoundingSphereRadius;  // 包围球的半径(单位:米)。
    double HorizonOcclusionPointX;  // 地平线遮挡点的 X 坐标(地心固定坐标系)。
    double HorizonOcclusionPointY;  // 地平线遮挡点的 Y 坐标。
    double HorizonOcclusionPointZ;  // 地平线遮挡点的 Z 坐标。
};
4.1.2 顶点数据(Vertex Data)

每个地形切片的顶点数据包含了地形的高度信息。Cesium 将地形分成多个网格,每个网格包含一个高度值。为了减少文件大小,Cesium 使用量化和压缩方法对高度数据进行处理。

顶点数据结构
  • 顶点数据包含描述瓦片三角网格中顶点位置的坐标和高度信息。顶点的坐标和高度值通过增量编码和 ZigZag 编码方式进行存储,以减少所需存储空间。

    顶点数据的结构如下:

    struct VertexData {
        unsigned int vertexCount;  // 顶点数量。
        unsigned short u[vertexCount];  // 水平方向坐标(经度)。
        unsigned short v[vertexCount];  // 垂直方向坐标(纬度)。
        unsigned short height[vertexCount];  // 顶点高度。
    };
    
    • uvheight 数组分别表示顶点的经度、纬度和高度。
    • 这些值使用 ZigZag 编码进行存储,以便高效表示小整数。

    解码这些数组的 JavaScript 示例代码如下:

    var u = 0, v = 0, height = 0;
    
    function zigZagDecode(value) {
        return (value >> 1) ^ (-(value & 1));
    }
    
    for (i = 0; i < vertexCount; ++i) {
        u += zigZagDecode(uBuffer[i]);
        v += zigZagDecode(vBuffer[i]);
        height += zigZagDecode(heightBuffer[i]);
    
        uBuffer[i] = u;
        vBuffer[i] = v;
        heightBuffer[i] = height;
    }
    

    每个解码后的 uv 值表示瓦片相对于边缘的水平和垂直位置,而 height 则表示该顶点的海拔。

4.1.3 索引数据(Index Data)

索引数据用于表示如何连接地形网格的顶点。Cesium 将每个切片的顶点数据分成三角形网格,这些三角形通过索引来定义。

索引数据结构
  • 索引数据定义了顶点如何连接成三角形。每个三角形由三个顶点组成,顶点通过索引连接。若瓦片包含超过 65536 个顶点,则使用 IndexData32 结构编码索引数据,否则使用 IndexData16 结构。

示例索引数据结构:

struct IndexData16 {
    unsigned int triangleCount;  // 三角形数量。
    unsigned short indices[triangleCount * 3];  // 构成三角形的顶点索引。
};

struct IndexData32 {
    unsigned int triangleCount;  // 三角形数量。
    unsigned int indices[triangleCount * 3];  // 构成三角形的顶点索引。
};
4.1.4 边缘索引(Edge Indices)

边缘索引用于描述瓦片边缘上的顶点,这些顶点对邻接瓦片的无缝连接非常重要。边缘索引分为两种类型:

  • 16 位边缘索引:适用于顶点数量小于 65536 的瓦片。
  • 32 位边缘索引:适用于顶点数量超过 65536 的瓦片。
struct EdgeIndices16 {
    unsigned int westVertexCount;
    unsigned short westIndices[westVertexCount];
    unsigned int southVertexCount;
    unsigned short southIndices[southVertexCount];
    unsigned int eastVertexCount;
    unsigned short eastIndices[eastVertexCount];
    unsigned int northVertexCount;
    unsigned short northIndices[northVertexCount];
};

struct EdgeIndices32 {
    unsigned int westVertexCount;
    unsigned int westIndices[westVertexCount];
    unsigned int southVertexCount;
    unsigned int southIndices[southVertexCount];
    unsigned int eastVertexCount;
    unsigned int eastIndices[eastVertexCount];
    unsigned int northVertexCount;
    unsigned int northIndices[northVertexCount];
};

这些边缘索引能够帮助渲染过程中处理瓦片之间的接缝,尤其是在拼接不同层次的瓦片时,避免出现可见的缝隙。

4.1.5 可选扩展(Optional Extensions)

Quantized Mesh 格式支持扩展,允许为地形数据增加额外的信息,例如每个顶点的法线、海岸线水域数据、或瓦片的元数据。扩展数据以特定的结构格式追加到瓦片文件的末尾:

  • 扩展类型包括:
    • Oct-Encoded Per-Vertex Normals:每个顶点的法线,用 16 位编码表示。
    • Water Mask:用于表示瓦片中的水域(0 表示陆地,255 表示水域)。
    • Metadata:附加的 JSON 元数据,描述瓦片的其他信息
struct ExtensionHeader {
    unsigned char extensionId;  // 扩展的唯一标识符。
    unsigned int extensionLength;  // 扩展数据的长度。
};
4.2 二进制结构总结

以下是 .terrain 文件典型二进制结构的详细,包含字段和对应的字节数:

结构字段类型字节数说明
1. 头部信息 (QuantizedMeshHeader)CenterXdouble8 bytes瓦片中心的地心固定坐标系 X 坐标
CenterYdouble8 bytes瓦片中心的地心固定坐标系 Y 坐标
CenterZdouble8 bytes瓦片中心的地心固定坐标系 Z 坐标
MinimumHeightfloat4 bytes瓦片区域的最小高度
MaximumHeightfloat4 bytes瓦片区域的最大高度
BoundingSphereCenterXdouble8 bytes包围球中心的 X 坐标
BoundingSphereCenterYdouble8 bytes包围球中心的 Y 坐标
BoundingSphereCenterZdouble8 bytes包围球中心的 Z 坐标
BoundingSphereRadiusdouble8 bytes包围球的半径
HorizonOcclusionPointXdouble8 bytes地平线遮挡点的 X 坐标
HorizonOcclusionPointYdouble8 bytes地平线遮挡点的 Y 坐标
HorizonOcclusionPointZdouble8 bytes地平线遮挡点的 Z 坐标
2. 顶点数据 (VertexData)vertexCountunsigned int4 bytes顶点数量
u[vertexCount]unsigned short[]2 bytes/值顶点的水平坐标(经度),每个顶点 2 字节
v[vertexCount]unsigned short[]2 bytes/值顶点的垂直坐标(纬度),每个顶点 2 字节
height[vertexCount]unsigned short[]2 bytes/值顶点的高度,每个顶点 2 字节
3. 索引数据 (Index Data)triangleCountunsigned int4 bytes三角形的数量
indices[triangleCount * 3]unsigned short[] (16位)2 bytes/索引16 位的三角形顶点索引,每个索引 2 字节
indices[triangleCount * 3]unsigned int[] (32位)4 bytes/索引32 位的三角形顶点索引,每个索引 4 字节
4. 边缘索引 (Edge Indices)westVertexCountunsigned int4 bytes西边顶点数量
westIndices[westVertexCount]unsigned short[] (16位)2 bytes/索引西边顶点索引,每个索引 2 字节
southVertexCountunsigned int4 bytes南边顶点数量
southIndices[southVertexCount]unsigned short[] (16位)2 bytes/索引南边顶点索引,每个索引 2 字节
eastVertexCountunsigned int4 bytes东边顶点数量
eastIndices[eastVertexCount]unsigned short[] (16位)2 bytes/索引东边顶点索引,每个索引 2 字节
northVertexCountunsigned int4 bytes北边顶点数量
northIndices[northVertexCount]unsigned short[] (16位)2 bytes/索引北边顶点索引,每个索引 2 字节
5. 扩展数据 (Extension Data)extensionIdunsigned char1 byte扩展标识符
extensionLengthunsigned int4 bytes扩展数据长度
扩展数据示例OctEncodedVertexNormalsunsigned char[]2 bytes/值每个顶点的法线(16 位 xy 编码),每个法线 2 字节
WaterMaskunsigned char[256 * 256]256 * 256 bytes水域掩模数据,0 为陆地,255 为水域,256x256 像素,每个像素 1 字节
Metadataunsigned int, char[]4 bytes + jsonLength存储元数据的 JSON 数据,JSON 长度为 jsonLength,4 字节用于存储 JSON 长度,后跟 JSON 数据

5.如何在 Cesium 中使用 .terrain 格式

在 Cesium 中,.terrain 格式的地形数据通常通过 CesiumTerrainProvider 来加载。这个提供者可以连接到远程的 Cesium 服务器或加载本地的 .terrain 文件。以下是如何在 Cesium 中加载 .terrain 数据的示例代码:

// 创建Cesium Viewer
const viewer = new Cesium.Viewer('cesiumContainer', {
    terrainProvider: Cesium.createWorldTerrain() // 使用Cesium官方的地形服务
});

// 设置本地地形数据
const terrainProvider = new Cesium.CesiumTerrainProvider({
    url : './path/to/terrain'  // .terrain文件所在的路径
});

viewer.terrainProvider = terrainProvider;

在这个示例中,Cesium.createWorldTerrain() 是 Cesium 提供的默认地形服务,它使用 .terrain 格式的数据。你也可以使用本地的 .terrain 文件,或者通过指定 URL 来加载自定义的地形数据。

.terrain 格式的应用场景

  1. 全球地形渲染
    .terrain 格式非常适合处理全球范围的地形数据。通过量化网格技术,Cesium 可以在不牺牲性能的情况下展示全球地形,支持流式加载不同区域的地形数据。

  2. 高精度地形建模
    对于需要高精度地形细节的应用,例如城市建模、灾难模拟、科学可视化等,.terrain 格式提供了有效的存储和加载机制,可以在保证性能的前提下,展示高质量的地形数据。

  3. 地理信息系统(GIS)
    .terrain 格式适用于大规模地理信息系统中的地形数据展示。例如,城市规划、环境监测和交通模拟等领域的 GIS 应用可以从中受益。

总结

Cesium 的 .terrain 格式(量化网格)是一个高效的地形数据存储和加载解决方案。通过量化压缩、层次化切片和动态加载等技术,它能够处理大规模地形数据,并保证高效的加载和渲染性能。对于需要全球范围或大区域、高精度地形数据的应用,.terrain 格式提供了理想的支持。

随着 Cesium 的发展,.terrain 格式将继续在地理信息系统、3D 地图和虚拟现实等领域发挥重要作用。了解和掌握 .terrain 格式的使用,可以帮助开发者更好地构建高效的地形渲染应用,提升用户体验。

生成地形工具

TilesBuilderTilesBuilder提供一个高效、兼容、优化的数据转换工具,一站式完成数据转换、数据发布、数据预览操作。

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值