# cesium-加载3dTiles

# 3dTiles介绍

3D Tiles是一种开放的三维空间数据标准,其设计目的主要是为了提升大的三维场景中模型的加载和渲染速度。假如要在Web客户端渲染一个非常大的三维模型(如一个大城市的建筑模型),如果把模型全部下载到客户端并且进行渲染,这个过程所消耗的时间对于使用普通电脑的用户来说是不能接受的。然而,在绝大多数的用户交互式的三维场景中,都只需要渲染模型的一小部分,将三维模型全部加载并渲染是一种极大的资源浪费,3D Tiles为这个问题提供了一个很好的解决方案。将三维空间数据组织为3D Tiles格式,可以实现模型的按需加载和渲染,从而实现流畅的三维模型浏览体验。

参考 (opens new window)

# 3DTiles数据特点

  • 开放且灵活。作为一种开放式数据规范,3D Tiles的切片方案灵活可变,三维模型的切片大小和覆盖范围可以人为设置。此外,3D Tiles还能够适配三维空间中多种空间分区方案,包括KD树、四叉树、八叉树、普通网格,以及其他空间数据结构等。

  • 异质性支持。通过一组已定义的文件格式,可以将多种类型的三维地理空间要素(包括倾斜摄影数据、BIM/CAD数据、三维建筑模型、实例化要素和点云数据)转换为三维形式的单个数据集同时又允许多种不同格式标准的模型显示在同一个场景中。

  • 专为三维可视化设计。3D Tiles建立在gITF格式之上,并引入了三维图形领域的技术,3D Tiles 格式的基础就是树状模型对象的层次结构(hierarchical levels of deail.HLOD)。传统的细节层次模型会访问场景中所有对象或者节点,针对每一个节点判断是否符合值染的条件:而 HLOD具备层次结构,当不满足细化放染条件的时候,场最只会直染父级对象或节点,不会访同子节点,因此计算量相对较小。

    将大量三维模型预先处理成3D Tiles的格式,可以让浏览器端从请求数据到webGL直染数据的流程更快速和简单,减轻测览器端的处理压力。同时,因为三维模型预先处理成了分块的三维瓦片格式,所以也减少了WebGL 给制请求的数量。

  • 可交互。3D Tles支持交互旋转和样式的设置,在WebGL中优化后,三维瓦片支持对单个模型的交互,如高亮显示鼠标悬停位置的模型,或删除一个三维建筑模型。还支持对单个模型的材质修改,如根据建筑高度和年代,可以设置不同的显示效果面不需要重新更新代码。3D Tiles用于流式传输三维空间信息,包括建筑物、树木、点云和矢量数据等。

    var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
        url: '../data/3dtiles/tianjie/tileset.json', //数据地址
        maximumScreenSpaceError: 2,  //最大的屏幕空间误差
        maximumNumberOfLoadedTiles: 1000, //最大加载瓦片个数
        modelMatrix: m,//形状矩阵
    }));
1
2
3
4
5
6

首先指定一个url对数据进行检索,然后将对象添加到场景中。将tileset添加到scene.primitive而不是scene.entity ,3D Tiles不是Entity API的一部分。

maximumScreenSpaceError指定了一个视图中最大的屏幕空间误差,数字越低,视觉效果就越好。但高细节的视觉效果往往伴随着高性能运算成本。

# 3DTiles数据结构

3D Tiles的格式由两部分组成,一个是JSON格式的数据组织文件(tileset.json),另外是每个瓦片节点对应的模型文件,3D Tiles支持的模型文件格式有. b3dm、.i3dm、.pnts、.vctr、.cmpt五种。

3D Tiles模型文件类型

格式名称 说明
Batched 3D Model(*.b3dm) 用于具有不同几何、材质或贴图的异质模型网格
Instanced 3D Model( *.i3dm) 实例化的模型,应用同一个三维模型,用于树木等相同的地物可视化
Point Cloud( * .pnts) 用于点云数据的可视化
Vector Data( *.vetr) 用于矢量数据的可视化
Composite( *.cmpt) 上述几种格式的组合

# tileset.json

{
  "asset": {
    "version": "1.0"
  },
  "extras": {
    "scenetree": "scenetree.json"
  },
  "geometricError": 3177.09515705891,
  "properties": null,
  "refine": "REPLACE",
  "root": {
    "boundingVolume": {
      "box": [
        4.65661287307739e-10,
        0.166235401295125,
        35.2569177309051,
        1588.54757852945,
        0,
        0,
        0,
        1181.13848758582,
        0,
        0,
        0,
        34.564118469134
      ]
    },
    "children": [
      {
        "boundingVolume": {
          "box": [
            0.124150419024886,
            0.0280173681455835,
            34.2241047454536,
            1588.36216882034,
            0,
            0,
            0,
            1181.1412862779,
            0,
            0,
            0,
            33.270950091015
          ]
        },
        "content": {
          "uri": "NoLod_0.b3dm"
        },
        "geometricError": 0.0,
        "refine": "REPLACE"
      }
    ],
    "geometricError": 3177.09515705891,
    "transform": [
      -0.895820508655044,
      -0.44441603962168,
      0.0,
      0.0,
      0.285099483582047,
      -0.57468214832474,
      0.767110626219003,
      0.0,
      -0.340916266455956,
      0.687193431374197,
      0.641514837818961,
      0.0,
      -2177436.70605816,
      4389113.54154921,
      4069934.44996518,
      1.0
    ]
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

asset是一个包含了整体tileset元数据属性的对象,其中version属性是定义3D Tiles 版本的字符串,版本号定义了tileset. json的JSON格式和瓦片格式的基础。tilesetVersion 属性是一个选填的字符串,用于定义特定应用中tileset的版本,可以用于更新tileset。

properties规定了瓦片集最大外包矩形地理空间范围,由经度、纬度、高度三个属性的最大值和最小值界定。

geometrieError定义了一个非负误差(以米为单位),在这个误差下瓦片集不被渲染。

root用于定义根瓦片,root.geometricError与最高层级tileset.json的geometricError不同。后者是整个瓦片集不被渲染的误差,前者是只有根瓦片被渲染的误差。

children定义子瓦片对象的数组。每个子瓦片都有boundingVolume,这个边界体被父瓦片的boundingVolume完全包围,通常子瓦片的geometricError要小于父瓦片的geometricError。对于叶子瓦片而言,子瓦片数组的长度为零。

# 具体代码

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Use correct character set. -->
    <meta charset="utf-8"/>
    <!-- Tell IE to use the latest, best version. -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
    <meta
            name="viewport"
            content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <title>cesium加载3Dtiles</title>
    <script src="../lib/Cesium-1.78/Build/Cesium/Cesium.js"></script>
    <style>
        @import url(../lib/Cesium-1.78/Build/Cesium/Widgets/widgets.css);

        html,
        body,
        #cesiumContainer {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
    //天地图token
    let TDT_tk = "token";
    //Cesium token
    let cesium_tk = "cesium token";
    //天地图影像
    let TDT_IMG_C = "http://{s}.tianditu.gov.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0" +
        "&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}" +
        "&style=default&format=tiles&tk=" + TDT_tk;

    //标注
    let TDT_CIA_C = "http://{s}.tianditu.gov.cn/cia_c/wmts?service=wmts&request=GetTile&version=1.0.0" +
        "&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}" +
        "&style=default&format=tiles&tk=" + TDT_tk;

    // 添加mapbox自定义地图实例
    let layer=new Cesium.MapboxStyleImageryProvider({
        url:'https://api.mapbox.com/styles/v1',
        username:'sungang',
        styleId: 'styleId',
        accessToken: 'accessToken',
        scaleFactor:true
    });
    //初始页面加载
    Cesium.Ion.defaultAccessToken = cesium_tk;
    let viewer = new Cesium.Viewer('cesiumContainer', {
        // baseLayerPicker: false,
        timeline: true,
        homeButton: true,
        fullscreenButton: true,
        infoBox: true,
        animation: true,
        shouldAnimate: true,
        imageryProvider: layer, //设置默认底图
    });

    //调用影响中文注记服务
    viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({
        url: TDT_CIA_C,
        layer: "tdtImg_c",
        style: "default",
        format: "tiles",
        tileMatrixSetID: "c",
        subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
        tilingScheme: new Cesium.GeographicTilingScheme(),
        tileMatrixLabels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"],
        maximumLevel: 50,
        show: false
    }))

    // cesium加载代码
    var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
        url: '../data/3dtiles/tianjie/tileset.json',
        modelMatrix: Cesium.Matrix4.fromArray(
            [0.9972458032561666, 0.04372029028528979, 0.05991113506964879, 0,
            -0.03623787897545647, 0.9920229449104262, -0.12073646051879428, 0,
            -0.06471185374661931, 0.11823287609043515, 0.9908750491338749, 0,
            -663.0794944260269, 1211.490494620055, 2974.1003134818748, 1]),
    }));
    viewer.flyTo(tileset);
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

实现效果

image-20220108153556029

上次更新时间: 2022年5月20日星期五上午11点16分