首页 > 其他分享 >详解 Cesium的地形格式terrain

详解 Cesium的地形格式terrain

时间:2024-11-20 11:43:22浏览次数:3  
标签:terrain bytes unsigned 地形 详解 Cesium 顶点

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提供一个高效、兼容、优化的数据转换工具,一站式完成数据转换、数据发布、数据预览操作。

请添加图片描述

标签:terrain,bytes,unsigned,地形,详解,Cesium,顶点
From: https://blog.csdn.net/ismartcube/article/details/143907441

相关文章

  • 软件架构五大模式详解
    本文包含软件架构的重要性、定义及其常见模式,架构对系统成功的影响,五种主要的架构模式及其最佳应用场景,评估优秀架构的关键质量属性。关注TechLead,复旦博士,分享云服务领域全维度开发技术。拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,复旦机器人智能实验室成员,国家......
  • 【拥抱AI】大模型文本质量的高级评估方法详解
    在文本生成任务中,高级评估方法旨在更深入地评估生成文本的质量,不仅仅是基于表面的相似度指标,而是从语义、语法、情感等多个维度进行全面评估。以下是一些常用的高级评估方法及其详细讲解。1.语义相似度评估1.1BERT和Sentence-BERT背景:BERT(BidirectionalEncoderRepr......
  • Gradle 8 使用教程:Maven 仓库导入、依赖管理与 TOML 配置详解
    Gradle是Java和Android项目中广泛使用的构建工具,以灵活和高效著称。然而,随着Gradle版本的迭代,它的配置方式也发生了变化。例如,Gradle8开始对一些老旧的配置方式进行优化,推荐新的DSL和工具,使构建脚本更具一致性和可维护性。本文将带你深入了解:Gradle8中如何导......
  • 【Linux】将python文件上传到GitHub(新版图文逐步详解)
    1.进入想要上传文件所在的文件夹,这里以如下图中目录下的t1为例2.输入如下命令,将当前目录变为git可以管理的目录gitinit3.将想要上传的文件添加到缓冲区gitaddt1.py出错了,查阅资料发现出现该提示是因为.gitignore文件中有规则将t1.py文件(或其所在目录)排除了,如果......
  • Python中的requests模块详解
    requests基础操作定义requests是一个基于网络请求的模块。可以使用程序模拟浏览器上网。环境安装pipinstallrequests编码流程指定url(相当于在浏览器地址栏输入一个网址)发起请求(相当于浏览器按下回车)获取响应数据(相当于浏览器请求到的数据/返回的页......
  • 超详细的ArrayList扩容过程(配合源码详解)
    首先,在调用add方法的时候,会去调用ensureCapacityInternal方法,传入一个参数minCapacity大小是size+1,也就是现在我们需要的数组的最小的大小。在ensureCapacityInternal方法中,先判断一下elementdata是不是初始空数组是的话就把minCapacity变更为默认容量也就是10,和传进......
  • FPGA 14 ,硬件开发板分类详解,FPGA开发板与普通开发板烧录的区别
    目录前言在嵌入式系统开发中,硬件开发板是工程师常用的工具之一。不同类型的开发板有不同的特点和用途,其中最常见的两大类是普通开发板和FPGA开发板。这里分享记录,这两类开发板的分类,并深入探讨它们在烧录过程中的具体区别,帮助我们更好地理解和选择适合自己的开发板。一. 开......
  • 事务的详解
    什么是事务?事务是逻辑上的一组操作,要么都执行,要么都不执行。另外,需要格外注意的是:事务能否生效数据库引擎是否支持事务是关键。比如常用的MySQL数据库默认使用支持事务的innodb引擎。但是,如果把数据库引擎变为myisam,那么程序也就不再支持事务了!事务最经典也经常被拿出......
  • 从0开始学习Linux——Shell编程详解【01】
    期目录:从0开始学习Linux——简介&安装从0开始学习Linux——搭建属于自己的Linux虚拟机从0开始学习Linux——文本编辑器从0开始学习Linux——Yum工具从0开始学习Linux——远程连接工具从0开始学习Linux——文件目录从0开始学习Linux——网络配置从0开始学习Linux——防......
  • WebSocket的应用:前后端详解与使用
    一、简介WebSocket是一种网络通信协议,它提供了在单个TCP连接上进行全双工通信的功能。在下面这个聊天应用示例中,WebSocket被用于实现实时的聊天功能,包括用户之间的消息发送、接收,用户状态管理以及其他相关的交互操作,为用户带来流畅的聊天体验。二、后端实现(一)模块引入与......