Skip to content

3D Tiles 大规模三维地理空间数据的开放标准

什么是 3D Tiles?

简单理解:想象一下你要在手机上查看整个城市的三维模型,但手机内存有限装不下所有数据。3D Tiles 就像一个智能的"数据快递员":

  • 它把庞大的 3D 模型切成小块(瓦片)
  • 只加载你当前能看到的部分
  • 当你移动时,动态加载新区域
  • 离得远时显示简化版,离得近时显示精细版可以参考 3D Tiles 官方文档

核心优势

特性说明价值
分层细节根据视距动态加载不同精度模型平衡性能与视觉质量
空间索引基于四叉树/八叉树的瓦片组织实现高效视锥体剔除
流式传输按需加载可见区域数据降低初始加载时间
语义元数据保留要素级属性信息支持交互查询与分析
格式开放基于 glTF 标准,兼容主流 3D 生态确保长期可访问性

应用场景

  • 城市建模:加载百万级建筑模型
  • 地理信息:融合地形、影像与矢量数据
  • 工程 BIM:展示精细建筑构件与属性
  • 文化遗产:数字化文物与遗址保护
  • 工业仿真:工厂布局与设备管理
  • 元宇宙:构建大规模虚拟空间

与传统 3D 格式对比

格式优势劣势适用场景
3D Tiles流式加载、LOD 管理、空间索引规范复杂、生成工具依赖大规模地理空间数据
glTF/GLB轻量高效、生态成熟无内置 LOD 和空间索引单一场景模型
OBJ/FBX兼容性广、工具支持好体积大、不支持流式小型模型交换
Point Cloud点云数据原生支持可视化效果有限激光扫描数据

数据规范与结构

核心文件组成

一个完整的 3D Tiles 数据集包含:

  1. tileset.json - 数据集根描述文件

    • 元数据与全局属性
    • 瓦片层级结构定义
    • 扩展功能声明
  2. 瓦片内容文件 - 实际 3D 数据

    • glTF/GLB 模型
    • 点云数据(.pnts)
    • 复合瓦片(.cmpt)
  3. 元数据文件 - 属性定义与数据

    • 模式定义(schema.json)
    • 属性表(propertyTables)
    • 批量元数据(batchTable)

tileset.json 结构解析

json
{
  "asset": {
    "version": "1.1", // 规范版本
    "tilesetVersion": "1.0.0" // 数据集版本
  },
  "geometricError": 500, // 根节点几何误差
  "root": {
    "boundingVolume": {
      "region": [-180, -90, 180, 90, 0, 1000] // 经纬度范围+高度
    },
    "geometricError": 250, // 节点几何误差
    "refine": "REPLACE", // 细化方式:REPLACE/ADD
    "content": { "uri": "root.glb" }, // 瓦片内容
    "children": [
      /* 子瓦片 */
    ]
  },
  "extensions": {
    "3DTILES_metadata": {
      /* 元数据定义 */
    },
    "3DTILES_implicit_tiling": {
      /* 隐式瓦片配置 */
    }
  }
}

加载与配置

加载全球建筑

createOsmBuildingsAsync 为 Cesium OSM 建筑瓦片集创建一个 Cesium3DTileset 实例

展开代码
vue
<template>
  <div ref="cesiumContainer" class="container"></div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import * as Cesium from "cesium";
const cesiumContainer = ref(null);
let viewer = null;

// 天地图TOKEN
const token = "05be06461004055923091de7f3e51aa6";

onMounted(async () => {
  // 初始化Viewer
  viewer = new Cesium.Viewer(cesiumContainer.value, {
    geocoder: false, // 关闭地理编码搜索
    homeButton: false, // 关闭主页按钮
    sceneModePicker: false, // 关闭场景模式选择器
    baseLayerPicker: false, // 关闭底图选择器
    navigationHelpButton: false, // 关闭导航帮助
    animation: false, // 关闭动画控件
    timeline: false, // 关闭时间轴
    fullscreenButton: false, // 关闭全屏按钮
    baseLayer: false, // 关闭默认地图
  });
  // 清空logo
  viewer.cesiumWidget.creditContainer.style.display = "none";

  // 添加OSM建筑物数据
  const tileset = await Cesium.createOsmBuildingsAsync();
  viewer.scene.primitives.add(tileset);
  // 定位到北京天安门
  viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(116.3911, 39.9067, 500),
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-90),
      roll: Cesium.Math.toRadians(0),
    },
  });

  initMap();
});

// 加载天地图
const initMap = () => {
  // 以下为天地图及天地图标注加载
  const tiandituProvider = new Cesium.WebMapTileServiceImageryProvider({
    url:
      "http://{s}.tianditu.gov.cn/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=" +
      token,
    layer: "img",
    style: "default",
    format: "tiles",
    tileMatrixSetID: "w", // 天地图使用 Web 墨卡托投影(EPSG:3857),需确保 tileMatrixSetID: "w"
    subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"], // 子域名
    maximumLevel: 18,
    credit: new Cesium.Credit("天地图影像"),
  });

  // 添加地理标注
  const labelProvider = new Cesium.WebMapTileServiceImageryProvider({
    url:
      "http://{s}.tianditu.gov.cn/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&tileMatrix={TileMatrix}&tileRow={TileRow}&tileCol={TileCol}&style=default&format=tiles&tk=" +
      token,
    layer: "img",
    style: "default",
    format: "tiles",
    tileMatrixSetID: "w",
    subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"], // 子域名轮询
    maximumLevel: 18,
    credit: new Cesium.Credit("天地图影像"),
  });
  // 天地图影像添加到viewer实例的影像图层集合中
  viewer.imageryLayers.addImageryProvider(tiandituProvider);
  // 天地图地理标注(后添加的会覆盖前面的)
  viewer.imageryLayers.addImageryProvider(labelProvider);
};
</script>
<style scoped>
.container {
  width: 100vw;
  height: 100vh;
}
</style>

OsmBuildings

基础加载流程

使用异步方法 Cesium.Cesium3DTileset.fromUrl(url, options) 加载 3D Tiles 数据集。

  • maximumScreenSpaceError: 最大屏幕空间误差,值越小越精细(默认 16)
展开代码
vue
<template>
  <div ref="cesiumContainer" class="container"></div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import * as Cesium from "cesium";
const cesiumContainer = ref(null);
let viewer = null;

onMounted(async () => {
  // 初始化Viewer
  viewer = new Cesium.Viewer(cesiumContainer.value, {
    geocoder: false, // 关闭地理编码搜索
    homeButton: false, // 关闭主页按钮
    sceneModePicker: false, // 关闭场景模式选择器
    baseLayerPicker: false, // 关闭底图选择器
    navigationHelpButton: false, // 关闭导航帮助
    animation: false, // 关闭动画控件
    timeline: false, // 关闭时间轴
    fullscreenButton: false, // 关闭全屏按钮
  });
  // 清空logo
  viewer.cesiumWidget.creditContainer.style.display = "none";

  // 添加3D Tileset
  const tileset = await Cesium.Cesium3DTileset.fromUrl(
    new URL("./models/Tileset/tileset.json", import.meta.url).href,
    {
      maximumScreenSpaceError: 16, // 最大屏幕空间误差
      maximumMemoryUsage: 512, // 最大内存使用量
      skipLevelOfDetail: true, // 跳过细节层级
      dynamicScreenSpaceError: true, // 动态屏幕空间误差
      dynamicScreenSpaceErrorDensity: 0.001, // 动态屏幕空间误差密度
    }
  );
  viewer.scene.primitives.add(tileset);
  viewer.zoomTo(tileset); // 缩放到3D Tileset
});
</script>
<style scoped>
.container {
  width: 100vw;
  height: 100vh;
}
</style>

3D Tileset 加载

关键配置参数

参数类型默认值说明性能影响
maximumScreenSpaceErrorNumber16最大屏幕空间误差
maximumMemoryUsageNumber512最大内存使用(MB)
skipLevelOfDetailBooleanfalse是否跳过中间 LOD
dynamicScreenSpaceErrorBooleanfalse动态误差计算
cullWithChildrenBoundsBooleantrue使用子瓦片边界剔除
preloadAncestorsBooleantrue预加载父瓦片
preloadSiblingsBooleanfalse预加载兄弟瓦片

加载状态监听

js
// 监听加载进度
tileset.loadProgress.addEventListener(function (
  numberOfPendingRequests,
  numberOfTilesProcessing
) {
  if (numberOfPendingRequests === 0 && numberOfTilesProcessing === 0) {
    console.log("Stopped loading");
    return;
  }

  console.log(
    `Loading: requests: ${numberOfPendingRequests}, processing: ${numberOfTilesProcessing}`
  );
});

高级功能应用

属性查询与交互

添加点击事件,当前点击的瓦片会变为黄色,并打印出该瓦片的属性。

js
viewer.screenSpaceEventHandler.setInputAction((click) => {
  const picked = viewer.scene.pick(click.position);
  if (picked instanceof Cesium.Cesium3DTileFeature) {
    // 当前点击为黄色
    picked.color = Cesium.Color.YELLOW;
    const properties = picked.getPropertyIds();
    // 获取属性并打印
    properties.forEach((name) => {
      console.log(`${name}: ${picked.getProperty(name)}`);
    });
  }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

3D Tiles 属性

添加调试面板

js
viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin);

样式表达与可视化

文档: Cesium3DTileStyle

js
tileset.style = new Cesium.Cesium3DTileStyle({
  color: {
    conditions: [
      ["${Height} >= 80", "color('purple')"], // 高楼红色
      ["${Height} >= 50", "color('red')"], // 中楼橙色
      ["${Height} >= 10", "color('green')"], // 低楼绿色
      ["true", "color('blue')"], // 其他蓝色
    ],
  },
});

3D Tiles 样式