3DTiles介绍
3DTiles是一种面向网格化、可展示的大规模三维空间数据格式,专门为流式传输和渲染海量3D地理空间数据而设计的,用于存储和管理基于网格的三维模型数据。其数据结构基于B3DM和PNTS格式,可以支持多个级别的LOD,并使用Tilesets(瓦片集合)来组织和管理数据。3DTiles具有以下特点:
- 支持大规模、高精度的三维模型数据展示。
- 采用标准的json格式描述数据结构和元数据。
- 使用DRACO和LZMA等压缩算法,提高数据传输和存储效率。
- 支持多级别的LOD,并支持快速开启、关闭不同级别的数据层。
3DTiles数据结构
在3DTiles中,一个瓦片集(Tileset)是由一组瓦片(Tile)按照空间数据结构(树状结构)组织而成的,它至少包含一个用于描述瓦片集的JSON文件(包含瓦片集的元数据和瓦片对象),其中每一个瓦片对象可以引用下面的其中一种格式,用于渲染瓦片内容:
b3dm和i3dm格式是基于glTF构建的,它们的瓦片内容在二进制体中嵌入了glTF资源,包含模型的几何和纹理信息;pnts格式则没有嵌入glTF资源。 在3DTiles数据结构,Tileset(瓦片集)是3DTiles的主要管理单元,包括Tileset全局信息、Tileset资源路径、Tileset根Tile等。每个Tileset包含多个Tile,表示不同的数据层级和视野级别,每个Tile内部又包含多个子Tile。最底层的Tile可包含具体的3D模型数据,称为Leaf Tile。
Cesium中与3DTiles相关的类
1.Cesium3DTileset类
Cesium3DTileset类是3DTiles数据的主要管理类,负责加载和渲染Tileset。Cesium3DTileset类允许该3D瓦片集的多个3D瓦片在不同的细节级别之间互相切换,从而实现在不同距离和观察角度下提供适当的细节。该类还提供了一个易于使用的接口来控制3D瓦片集的可见性、样式、位置和旋转等方面,以及管理预加载、缓存和卸载等功能,可用于开发高效、可靠且具有交互性的3D地球应用程序。
常用属性:
url
:3D瓦片数据的URL地址。modelMatrix
:该3D瓦片集的模型矩阵。boundingSphere
:3D瓦片集的边界球体(bounding sphere),用于计算和处理可见性和碰撞检测等。root
:3D瓦片集的根瓦片(root tile)。ready
: 一个Boolean类型的属性,用于指示3D瓦片是否已准备好渲染。
常用方法:
destroy()
:销毁3D瓦片及其内容。getProperty(name)
:根据属性名称获取3D瓦片的属性值。setProperty(name, value)
:设置3D瓦片的属性值。hasProperty(name)
:判断3D瓦片是否包含指定名称的属性。makeStyleDirty()
:通知3D瓦片集需要重新应用样式。show
:设置3D瓦片集的可见性。
2.Cesium3DTileStyle类
Cesium3DTileStyle是用于指定和应用3D瓦片集的样式的类;它可以控制3D瓦片的颜色、点大小、标签风格和文本内容等;它可以对3D瓦片进行分类和着色,以及创建基于属性(如高度、分类或时间)的动态样式。
常用属性:
color
:3D瓦片的颜色,可以是rgba、rgb或16进制颜色值。pointSize
:3D瓦片中点的大小。labelStyle
:3D瓦片中的标签的样式。labelText
:3D瓦片中标签的文本内容。show
:3D瓦片的可见性。style
:3D瓦片的所有样式属性。
3.Cesium3DTileContent类
Cesium3DTileContent是用于表示单个3D瓦片的内容和几何信息的类。它可以使用Cesium3DTileContent类来设置和获取3D瓦片中存储的几何和元数据属性,并将其应用于3D瓦片中的3D对象。
常用属性
featuresLength
:3D瓦片内容中包含的要素数量。pointsLength
:3D瓦片内容中包含的点数量。trianglesLength
:3D瓦片内容中包含的三角形数量。geometryByteLength
:3D瓦片内容的几何数据字节长度。texturesByteLength
:3D瓦片内容的纹理数据字节长度。
常用方法
hasProperty(batchId,name)
:检查3D瓦片内容中是否存在具有指定名称的属性值。该方法需要两个参数:batchId
:要检查属性的要素在批处理表中的索引。name
:要检查的属性名称。
该方法将返回一个布尔值,指示在批量表的指定批量ID上下文中,是否存在指定属性。
该方法主要用于动态创建和应用3D瓦片样式,使用3D瓦片内容的hasProperty
方法可以检查3D瓦片是否具有指定名称的属性,以便选择性地应用样式。例如,可以检查3D瓦片中是否存在“height”属性,然后根据条件对3D瓦片进行分类和着色,或启动特定的动画效果。
getFeature(batchId)
:获取批处理表中指定索引的要素的属性值集合。该方法需要一个参数:batchId
:要获取属性的要素在批处理表中的索引。
该方法将返回一个包含指定要素的所有属性值的JavaScript对象,这些属性值位于批量表对象中,并且属性的键的名称与其在批量表中的名称相同。
该方法主要用于在Cesium中与3D瓦片交互和操作。除了获取批量表中的属性值之外,还可以使用此方法将元数据附加到要素上,以支持元数据功能。例如,在调用此方法之后,可以将附加的元数据名称和值存储在要素对象中,然后、在应用特定的3D瓦片样式、动态筛选查询或者其他与要素交互的操作中使用这些元数据属性。
注意,如果尝试获取不存在的批处理ID的要素属性,则该方法将返回 undefined
。同时,如果要获取的要素具有不完整或错误的属性数据,则该方法可能会返回错误或部分属性数据。
4. Cesium3DTileFeature类
Cesium3DTileFeature类用于表示3D瓦片中的单个要素(feature)及其相关属性。
常用属性
color
:颜色属性,用于设置3D瓦片要素的颜色。颜色支持RGBA(红/绿/蓝/透明通道)格式,它可以是一个数组,数组的结构为[red, green, blue, alpha],每个值的范围为0到1之间。Cesium3DTileFeature类允许设置颜色以覆盖3D瓦片的默认颜色。featureId
:要素ID属性,它是一个任意类型的值,用来定义3D瓦片中的每个要素的唯一标识符。开发人员可以使用这个属性来追踪特定的3D瓦片要素,并在需要时选择性地对其进行操作。polylinePositions
:存储要素的线位置的属性(如果存在)。该属性用于3D瓦片中的线型要素,并包含一组数值数组,用于指定该要素的线型样式的位置。每个数值数组都被解释为一个Cartesian3坐标。primitive
:与要素相关的图元对象,可以用于检索要素的几何图形信息和进行交互操作。该属性允许开发人员直接访问3D瓦片中的要素及其相关属性数据。tileset
:与要素相关的3D瓦片集对象。该属性用于获取要素所在的3D瓦片集对象,以便进行交互操作和操作。
常用方法
getProperty(name)
:获取要素在批量表中的具有指定名称的属性值。setProperty(name, value)
:设置指定名称的属性值。hasProperty(name)
:检查要素在批量表中是否具有指定名称的属性。
5.Cesium3DTile类
Cesium3DTile类用于表示3D瓦片数据。
常用属性
boundingSphere
:一个包含3D瓦片的最小球型边界体。该属性用于裁剪和优化3D瓦片的显示性能。boundingSphere由边界盒计算得到,并可以通过调用update()
方法来更新它。children
:一个包含所有子瓦片的数组。每个子瓦片都是Cesium3DTile实例。当3D瓦片的内容对象包含多个数组时,它们通常将为每个数组创建子瓦片来管理这些数组。computedTransform
:一个包含从父瓦片到当前瓦片的4x4矩阵的数组。该矩阵用于将当前瓦片的内容对象转换为父瓦片的坐标系。computedTransform在更新瓦片转换矩阵时被重新计算。如果瓦片没有父瓦片,则computedTransform为单位矩阵。content
:3D瓦片的内容对象,通常包含地理信息和属性数据等相关信息。geometricError
:3D瓦片的几何误差,表示3D瓦片的最大距离误差。Cesium使用这个属性来计算3D瓦片的显示优先级和细节层次。extras
:一个包含3D瓦片的任意附加数据的对象。Cesium3DTile中的extras属性允许开发人员存储和访问与瓦片相关联的任何额外数据。parent
:一个指向父瓦片的指针。父瓦片是当前瓦片的直接上级。如果当前瓦片没有父瓦片,则parent属性将为null。transform
:一个从模型坐标系到世界坐标系的4x4矩阵。该矩阵用于将3D瓦片内容对象从模型坐标系转换为世界坐标系。transform矩阵通常在加载3D瓦片时通过调用update()
方法计算得到。tileset
:与3D瓦片关联的3D瓦片集对象。
Cesium中加载3DTiles数据的示例
代码语言:javascript复制 try {
const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(75343);
viewer.scene.primitives.add(tileset);
} catch (error) {
console.log(`Error loading tileset: ${error}`);
}
viewer.scene.globe.depthTestAgainstTerrain = true;