3dTiles 数据规范详解[2] Tileset与Tile
2020-06-28 02:36
666 查看
> 转载请声明出处:全网@秋意正寒 https://www.cnblogs.com/onsummer/p/13128682.html
# 一、一个简单的3dTiles数据示例
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628023212965-1881585357.png)
上图是一份 3dTiles数据集在文件夹内的样子,层层打开可得以下特点:
- 入口文件是 `tileset.json`
- 各级瓦片用文件夹(目录)来组织
3dTiles 数据目前的具体文件实现,是一些零散的文件。
数据集的名称与所在文件夹的名称并无关系,数据集的名称写在入口文件中。
3dTiles至少有一个 `tileset.json` 文件,作为整个数据集的入口。它是一个 json 文件,描述了整个三维瓦片数据集,它记录的是上一节提及的“逻辑信息”,还包括一些其他的元数据。而“属性信息”、“嵌入的gltf模型” 则位于各个二进制瓦片文件中,这些二进制文件则由 `tileset.json` 中的瓦片中的 `uri` 来引用。
## 瓦片是什么?
瓦片,屋顶上的瓦片。古时候,盖房子,屋顶不能一次浇筑完工,也没有特定的“屋顶”零件,所以只好一片片瓦片盖上去(我瞎掰的)。
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628023240417-756840130.png)
瓦片切割了三维数据,允许三维数据进行细分。我们都知道网速是有限的,在加载超大规模的三维模型数据时,不可能把一个模型全部下载下来再渲染,那样等待的时间太慢了,但是一点一点出现,视野范围外的“瓦片”则干脆就不下载、渲染,性能、视觉都有提高。这就是瓦片的设计优点。
传统的二维地图瓦片,叫做 WMTS 或 TMS,这个 "T" 就是 `Tile` 的意思。
现在,你只要知道,3dTiles就是把空间进行切块,每个块叫做 “tile”,也即瓦片。至于怎么切的——待会介绍 tileset.json 时,会隆重介绍树结构。
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628023250071-257721572.png)
瓦片只有两种情况:叶子瓦片,非叶子瓦片。根瓦片也是非叶子瓦片。非叶子瓦片和叶子瓦片有什么区别呢?主要就是叶子瓦片不会再有孩子了(树结构的知识哈,不懂的建议去学习数据结构中的树)。
瓦片包含什么内容呢?本篇稍微靠后再仔细了解瓦片。
现在,我们先认识一下,描述整个 3dTiles 数据集的入口文件,也叫做三维瓦片数据集 —— tileset.json:
# 二、Tileset——(三维)瓦片数据集
通常,一个三维瓦片数据集(之后简称:一个3dtiles数据)的入口就是那个”tileset.json“,至于这个文件的名称可不可以改,暂时未作测试。
现在,我们先来研究研究 这个入口文件记录了哪些信息,拿一份最简单的 3dtiles数据来举例,该数据只有一个根瓦片(root),根瓦片再无子瓦片。
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628023313102-786143884.png)
root对象中有一个content,内有uri属性,其就记录了根瓦片的二进制数据文件的URL,这个URL是个相对路径,相对于 tileset.json 文件。
## ① 顶级属性概览
通过上面介绍,3dTiles数据的入口文件是一个名叫 `tileset.json` 的文件,而通常来说,这个json必须存在以下几个顶级对象:
- asset
- root
- geometricError
由于本人学识有限,目前不太清楚 `geometricError` 的精确含义,只知道这个数值的大小能控制 LOD 的显示隐藏,且这个数值父级瓦片一定比子级瓦片大。
`asset` 对象,记录了整个数据集的声明和归属数据,类似于数据声明,能在此写入 `version`、`tilesetVersion ` 等属性,当然也可以像上方的例子一样,写入生成工具、gltf朝向等信息。
`root` 对象,即这个数据集的根瓦片,每个3dTiles数据集必须有一个 `root` 对象。
至于 `tileset.json` 中其他的顶级对象,请查阅官方文档:[点我](https://github.com/CesiumGS/3d-tiles/blob/master/specification/schema/tileset.schema.json)
## ② root瓦片及其children
树结构对于三维空间数据的组织有很大的优势。3dTiles在空间上允许数据集使用如下几种树结构:
- 四叉树
- 八叉树
- KD树
- 格网结构
四叉树允许使用传统的均匀四叉树,也允许使用松散四叉树等变种(例如,允许子节点,即子瓦片允许存在空间范围重叠)。
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628023336509-1710488818.png)
上图为两个子瓦片在空间上存在部分重叠,照顾到了建筑物不可能严格切分的特点。
四叉树对在高度上不太好切分的数据比较适合,而如果追求极致的空间分割和分级(例如点云数据),那么八叉树更合适。
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628023345851-35392756.png)
八叉树也允许使用各种变种。
kd树比较难理解,在此不作展开,这也是一种有趣的空间结构分割的数据结构。
格网结构的树允许瓦片存在多个子瓦片:
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628023401171-92279387.png)
通常出现在倾斜摄影数据上,但是这会导致网络请求过多的问题。
## ③ 坐标系统
我们可以用简单的两位数、三位数:经纬度,还有一个高度来标识地球表面附近的任何一个点。经纬度的范围不超过三位数,而用米作单位的空间直角坐标系来描绘地球,数字太大,不好记忆。
在GIS中,WGS84就是一个用经纬度来标识空间坐标的“地理坐标系,Geographic Coordinate System”。
由于历史上对地球测量的技术不同,科学家制造了多个长半轴短半轴不太一样的“椭球”,来模拟地球的形状。目前,最具代表性的就是两个以地球质心为中心的椭球体:
- WGS84椭球体
- 中国国家2000椭球体(即CGCS2000)
基于椭球体,我们允许有多种不同的坐标系定义,WGS84坐标系其实并不太严谨。基于WGS84椭球(长短半轴等信息自行查询哈),可以使用球面坐标度量,即经纬度,还有一个从质心射向椭球面上的点的“椭球高度”射线,来记录第三维高度数据。
介绍了那么多,3dTiles其实采用的是WGS84椭球,但是并未采用经纬度记录数据:因为相对于精细三维模型来说,经纬度不足以提供足够精确的空间分割(要照顾图形显示问题)。所以,同样是那个形状,3dTiles使用了同一个WGS84椭球,但是更方便计算的坐标:空间直角坐标。
用经纬度记录数据的WGS84坐标系,WKID是4326,用地心为坐标原点的空间直角坐标来记录数据的坐标系,WKID是4979.
3dTiles 用的就是4979坐标系。
# 三、Tile——构成3dtiles的成员:瓦片
通常,瓦片对象会引用一个二进制的瓦片数据文件(也有例外,往下拉一点会说):
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628023446722-1276579601.png)
在1.0 版本的规范中,瓦片所引用的二进制的瓦片数据文件,有四种类型:
| 类型 | 英文名称 | 文件后缀名 |
| ------------ | ----------------- | ---------- |
| 批量三维模型 | Batch 3D Model | b3dm |
| 实例三维模型 | Instance 3D Model | i3dm |
| 点云 | PointCloud | pnts |
| 复合模型 | Component | cmpt |
这些不同的瓦片对应了些什么数据呢?本篇只贴一张各种数据类型的截图和信息对比表:
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628033646285-1641618470.png)
| 瓦片类型 | 对应实际数据 |
| -------- | ---------------------------------------------------------- |
| b3dm | 传统三维建模数据、BIM数据、倾斜摄影数据 |
| i3dm | 一个模型多次渲染的数据,灯塔、树木、椅子等 |
| pnts | 点云数据 |
| cmpt | 前三种数据的复合(允许一个cmpt文件内嵌多个其他类型的瓦片) |
关于这些二进制瓦片数据文件的数据结构如何,下一篇开始会详细展开。
现在,我们关注一下,瓦片对象的职能,也就是,它记录了啥信息:
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628023512595-606436569.png)
这是一个children下的第一个瓦片,观察不难得知,与root瓦片其实在属性上长得一模一样。
瓦片对象都有如下属性:
- boundingVolume:空间范围框,允许有box、sphere、region三种范围框,但是只能定义一种
- geometricError:几何误差
- content:瓦片内容,uri属性引用二进制瓦片数据文件。
- 其他属性:viewerRequestVolume、transform
没错,瓦片对象记录的就是瓦片的元数据,真正瓦片的本体数据在content所引用的二进制文件中。
## 瓦片还可以再引用 3dTiles 数据集!
我一再强调3dTiles十分灵活。
Tile不仅仅可以在其uri属性中引用 诸如 `.b3dm`、`.i3dm`、`.pnts`等二进制瓦片数据文件,还可以再引用一个 3dTiles!
![](https://img2020.cnblogs.com/blog/1097074/202006/1097074-20200628023533958-1307170550.png)
这是一份从osgb倾斜摄影数据转换而来的3dtiles数据,清晰可见在root瓦片的第一个child瓦片中,引用了另外一个json文件。这证明了两件事:
- 3dTiles的文件名可以不是tileset.json
- 3dTiles允许套娃
原则上,只要被引用的子一级3dtiles 不循环引用父级3dtiles,那么就OK(规范如是说)。
它真的很灵活!
---
下一节将展示二进制瓦片文件中的至关重要的一部分:两大数据表。
相关文章推荐
- Numpy中的tile()函数用法详解
- tf.tile()函数详解(附代码理解)
- 重新想象 Windows 8 Store Apps (36) - 通知: Tile 详解
- 重新想象 Windows 8 Store Apps (36) - 通知: Tile 详解
- 45度角Tile地图通过具体位置获得地图的行列数详解
- tf.tile详解(能懂版)
- JAVA jstack命令详解
- MySQL存储过程详解
- java移位运算符详解
- 详解python之多进程和进程池(Processing库)
- vue音乐播放器插件vue-aplayer的配置及其使用实例详解
- HSRP和VRRP工作原理详解
- @RequestBody, @ResponseBody 注解详解
- MySql表结构修改详解
- 基于C语言EOF与getchar()的使用详解
- linux下cat命令详解
- mmap详解
- Contiki Timers 详解
- 详解前端自动化工具gulp自动添加版本号
- C++中替代sprintf的std::ostringstream输出流详解