3DTiles三维模型

1. 3DTiles 介绍​

2016 年,Cesium 团队借鉴传统 2DGIS 的地图规范:WMTS,借鉴图形学中的层次细节模型,打造出大规模的三维数据标准:3d-Tiles,中文译名:三维瓦片。

它在模型上利用了 gltf 渲染快的特点,对大规模的三维数据进行组织,包括层次细节模型、模型的属性数据、模型的层级数据等。

3D Tiles 是在 glTF 的基础上,加入了分层 LOD 的概念(可以把 3D Tiles 简单地理解为带有 LOD 的 glTF ),专门为流式传输和渲染海量 3D 地理空间数据而设计的,例如倾斜摄影、3D 建筑、BIM/CAD、实例化要素集和点云。它定义了一种数据分层结构和一组切片格式,用于渲染数据内容。3D Tiles 没有为数据的可视化定义明确的规则,客户可以按照自己合适的方式来可视化 3D 空间数据。同时,3D Tiles 也是 OGC 标准规范成员之一,可用于在台式机、Web 端和移动应用程序中实现与海量异构 3D 地理空间数据的共享、可视化、融合以及交互功能。

2. 3dTiles 数据示例及其加载

数据处理相关的,可以参看:各类三维模型转为 3DTiles 格式

2.1 3dTiles 数据示例​

首先,我从一个简单的 3D Tiles 数据示例说起,请看下面目录:

image

上图是一份 3dTiles 数据集在文件夹内的样子,层层打开可得以下特点:

  • 入口文件是tileset.json
  • 各级瓦片用文件夹来组织(类似套娃),目录中有零散的*.json文件
  • 叶子节点有*.b3dm、*.i3dm等格式

对这些数据的结构和详细介绍,我们下一节再详细解说,第一步,我们先学会怎么加载使用这个模型。

2.2 在平台中加载模型​

平台内加载 3dtiles 是使用 TilesetLayer 类。

3dTiles 至少有一个 tileset.json 文件,作为整个数据集的入口,在代码层面,我们拿到这个主瓦片集 JSON 文件(tileset.json)的 url 地址即可使用加载三维模型了。 如: http://data.mars3d.cn/3dtiles/qx-dyt/tileset.json

当我们拿到这个模型服务地址后:

  • (1)浏览器输入模型 url 地址验证下是否可以正常访问。
  • (2)打开模型参数调试编辑页面,在这个页面调试的模型 URL 输入框内输入模型 url 地址,并单击加载模型按钮。

image

  • (3)可以勾选深度检测来方便测试和调试模型高度

    image

  • (4)如果是人工模型,可以勾选“鼠标拖拽编辑”来手动拖拽模型的位置与地图上匹配。

  • (5)在该页面调整好所有参数后,单击“保存参数”按钮,保存的参数 json,会自动下载一个 json 文件。

    image

  • (6) 如果模型是初始化就加载的,可以打开项目的config.json文件,拷贝刚下载的 json 到 config.json 文件的 layers 参数中即可。

json

{"scene": {},"terrain": {},"basemaps": [], //已忽略其他参数"layers": [{"name": "模型名称","type": "3dtiles","url": "http://data.mars3d.cn/3dtiles/qx-dyt/tileset.json","maximumScreenSpaceError": 1,"maximumMemoryUsage": 1024,"position": { "alt": 452.9 },"center": {"lat": 34.216894,"lng": 108.959834,"alt": 591,"heading": 4,"pitch": -37},"show": true}]
}
  • (7)如果代码中直接使用TilesetLayer 类构造三维模型,可以将 json 中的参数拷贝到类参数中。

js

var tiles3dLayer = new mars3d.layer.TilesetLayer({url: 'http://data.mars3d.cn/3dtiles/qx-simiao/tileset.json',maximumScreenSpaceError: 16,maximumMemoryUsage: 1024,position: { alt: 452.9 },center: { lat: 34.216894, lng: 108.959834, alt: 591, heading: 4, pitch: -37 },flyTo: true
});
map.addLayer(tiles3dLayer);

运行效果

  • (8) 最后再说几个影响加载效率的关键参数:
  1. maximumScreenSpaceError

控制加载的精度,这个参数默认是 16,数值加大,能让最终成像变模糊

  1. maximumMemoryUsage

这个参数默认是 512,也即是当几何体和纹理资源大于 512MB 的时候,Cesium 就会淘汰掉当前帧中没有 visited 的所有块,这个值其实很小,也是 cesium 为了避免资源占用过高的一个保障,不过上述我们也估算过最差情况下,没有做纹理 crn 压缩的情况下,这个值很容易被超过,导致很多人误以为 cesium 的淘汰没有效果。这个值如果设置的过小,导致 cesium 几乎每帧都在尝试淘汰数据,增加了遍历的时间,也同时增加了崩溃的风险。这个值如果设置的过大,cesium 的淘汰机制失效,那么容易导致显存超过显卡内存,也会导致崩溃。这个值应该处于最差视角下资源占用 和 显存最大量之间。建议显存大小的 50%左右,内存分配变小有利于倾斜摄影数据回收,提升性能体验。

  1. skipLevelOfDetail

这个参数默认值是 true,是 Cesium 在 1.5x 引入的一个优化参数,这个参数在金字塔数据加载中,可以跳过一些级别,这样整体的效率会高一些,数据占用也会小一些。 但是带来的异常是:

  1. 加载过程中闪烁,看起来像是透过去了,数据载入完成后正常。
  2. 有些异常的面片,这个还是因为两级 LOD 之间数据差异较大,导致的。 当这个参数设置 false,两级之间的变化更平滑,不会跳跃穿透,但是清晰的数据需要更长,而且还有个致命问题,一旦某一个 tile 数据无法请求到或者失败,导致一直不清晰。 所以我们建议:对于网络条件好,并且数据总量较小的情况下,可以设置 false,提升数据显示质量。
  1. preferLeaves

这个参数默认是 false,同等条件下,叶子节点会优先加载。但是 Cesium 的 tile 加载优先级有很多考虑条件,这个只是其中之一,如果 skipLevelOfDetail=false,这个参数几乎无意义。所以要配合 skipLevelOfDetail=true 来使用,此时设置 preferLeaves=true。这样我们就能最快的看见符合当前视觉精度的块,对于提升大数据以及网络环境不好的前提下有一点点改善意义。

3. 3D Tiles 数据结构​

3dTiles 是一种规范(要区分规范和实现的概念),在规范的指导下,各种资源文件可以是独立存在于硬盘中的目录、文件,也可以以二进制形式写入数据库中。

3dTiles 还有一个特点:那就是不记录模型数据(指三维模型的顶点、贴图材质、法线、颜色等信息),只记录各级“Tile”的逻辑关系(指 LOD 是如何组织的),以及“Tile”自己的属性信息(如房子的名称、建设年限、面积等)。

image

3.1 3D Tiles 支持的模型​

  • 城市建筑白膜:在拥有如 shp、kml 等格式的建筑物二维面边界坐标数据,和高度或楼层数属性信息,再通过工具转换为三维立体的白膜建筑物 3DTiles 模型。
  • 倾斜摄影:一般是无人机拍摄,拍摄的数据通过建模工具 ContextCapture Cente 等建模软件可以直接导出 3DTiles 格式。也可以通过 osgb 通用格式转 3DTiles 格式后在平台中使用。
  • 点云数据:一般是激光扫描后生产的数据,有 las、pts、ply 等格式。
  • 人工建模:数据来源于 3dmax、Maya 等建模软件建模,建好的三维模型导出为 dae 和 obj 数据后,再转换为 3DTiles 数据格式。
  • BIM 模型:数据来源于专业的 BIM 软件,常见的有 rvt 和 dgn 格式。

TIP

这些数据的原始格式都需要转换为 3dtiles 格式后,才能在平台加载使用。

3.2 LOD 树结构​

通过上面介绍,3dTiles 数据的入口文件是一个名叫tileset.json的文件,在这个 json 文件中 root 属性下通过 children 属性来关联子级节点*.json ,这样一层层关联到叶子节点(如*.b3dm等格式)。

image

树结构对于三维空间数据的组织有很大的优势。3dTiles 在空间上允许数据集使用如下几种树结构:

  • 四叉树:允许使用传统的均匀四叉树,也允许使用松散四叉树等变种(例如,允许子节点,即子瓦片允许存在空间范围重叠),常用于 建筑物(存在不可能严格切分的特点)。
  • 八叉树: 四叉树对在高度上不太好切分的数据比较适合,而如果追求极致的空间分割和分级(例如点云数据),那么八叉树更合适。八叉树也允许使用各种变种。
  • KD 树:
  • 格网结构:允许瓦片存在多个子瓦片,通常出现在倾斜摄影数据上,但是这会导致网络请求过多的问题。

八叉树

image

3.3 构成 3dtiles 的成员:Tile 瓦片​

瓦片对象会引用一个二进制的瓦片数据文件,目前这些文件有以下类型:

文件后缀名名称英文名称对应实际数据
b3dm批量三维模型Batch 3D Model传统三维建模数据、BIM 数据、倾斜摄影数据
i3dm实例三维模型Instance 3D Model一个模型多次渲染的数据,灯塔、树木、椅子等
pnts点云PointCloud点云数据
cmpt复合模型Component前三种数据的复合(允许一个 cmpt 文件内嵌多个其他类型的瓦片)

image

上面表格中的 b3dm 和 i3dm 格式是基于 glTF(一种专为高效传输 3D 内容而设计的开放性规范)构建的,它们的瓦片内容在二进制体中嵌入了 glTF 资源,包含模型的几何和纹理信息,而 pnts 格式却没有嵌入 glTF 资源。

3.4 单个 Tile 瓦片的内部构成​

在 3dTiles 中,模型数据是以 glb 的形式嵌入在瓦片文件中的(点云直接就写 xyz 和颜色信息了),模糊了二维中“要素”的概念,而且 gltf 规范看起来并没有所谓的“要素”的概念,仅仅是对 GPU 友好的 vertex、normal、texture 等信息。

瓦片引用的二进制文件有 4 种,即:b3dm、i3dm、pnts、cmpt。 除去 cmpt 这个复合类型不谈,前三种的瓦片二进制数据文件的大致字节布局结构见下图:

image

每一种瓦片二进制数据文件都有一个记录该瓦片的文件头信息,文件头包括若干个因瓦片不同而不太一致的数据信息,紧随其后的是两大数据表:FeatureTable(我翻译其为:要素表)、BatchTable(我翻译其为:批量表)。

这两个表既然是二进制的数据,尽管它名字里带“表”,但是却不是二维表格,它更多的是一些 键值 信息。

(1)FeatureTable 要素表: 记录渲染相关的数据​

在 b3dm 瓦片中,要素表记录这个批量模型瓦片中模型的个数,这个模型单体在人类逻辑上不可再分。

(在房屋级别来看,房子并不是单体,构造它的门、门把、窗户、屋顶、墙等才是模型单体;但是在模型壳子的普通表面建模数据中,房子就是一个简单的模型)

要素表还可以记录当前瓦片的中心坐标,以便 gltf 使用相对坐标,压缩顶点坐标数字的数据量。

在一个瓦片中,一个三维要素(GIS 中的通常叫法)= 一个模型(图形学、工业建模叫法) = 一个 BATCH(3dtiles 叫法)

要素表的结构:JSON 描述信息+要素表数据体

image

(2)BatchTable 批量表: 记录属性数据​

批量表就是所谓的模型属性表,批量表中每个属性数组的个数,就等于模型的个数,因为有多少个模型就对应多少个属性嘛!如果把批量表删除,那么 3dTiles 数据还能正常渲染。

批量表的结构:JSON 描述信息+批量表数据本体,与 要素表 很像,批量表也是由: 二进制的 JSON 文本头 + 二进制的数据体 构成的。如下图所示:

image

(3)四类类型对应的具体结构​

b3dm:

image

i3dm:与 b3dm 一致,文件头多了个 gltfFormat 属性。

image

pnts 不存在 gltf 模型,故结构如下:

image

cmpt:这是前三种的一种更灵活的组织,允许一个瓦片使用 cmpt 形式,组合多种瓦片,cmpt 瓦片可以内嵌任意个、任意类型的瓦片,b3dm、i3dm、pnts 均可。

image

(4)代码中如何查询瓦片的批量表​

我们通常在平台中使用 点击 事件,来获取一个 BATCH,即三维要素。在 API 中,这个被叫做:Cesium3DTileFeature。那么,这个 Cesium3DTileFeature 就能访问到它自己的批量表中的属性数据:

js

map.on(mars3d.EventType.click, function (event) {let feature = event.pickedObject;//下面只是演示解释底层实现,在平台中直接通过event.graphic.attr可以获取属性if (feature instanceof Cesium.Cesium3DTileFeature) {let propertyNames = feature.getPropertyNames();let length = propertyNames.length;for (var i = 0; i < length; ++i) {let propertyName = propertyNames[i];console.log(propertyName + ': ' + feature.getProperty(propertyName));}}
});

用到了 Cesium3DTileFeature.getPropertyNames() 方法获取批量表中所有属性名,用了 Cesium3DTileFeature.getProperty(string Name) 来获取对应属性名的属性值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/911663.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/911663.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Golang Kratos 系列:业务分层的若干思考(一)

在使用 Kratos 框架开发云服务的过程中&#xff0c;渐渐理解和感受到“领域层”这个概念和抽象的强大之处&#xff0c;它可以将业务和存储细节解耦、将业务和开发初期频繁变更的API结构&#xff0c;让Mock单元测试变得更加容易、对细节的变化更鲁棒。让业务代码摆脱技术细节依赖…

深度优化OSS上传性能:多线程分片上传 vs 断点续传实战对比

1 卸载开头 对象存储服务&#xff08;OSS&#xff09;已成为现代应用架构的核心组件&#xff0c;但随着业务规模扩大&#xff0c;文件上传性能问题日益凸显。本文将深入探讨两种核心优化技术&#xff1a;多线程分片上传和断点续传&#xff0c;通过理论分析、代码实现和性能测试…

doris_工作使用整理

文章目录 前言一、doris整体情况二、doris的存储过程情况1.分类2. 同步物化视图3. 异步物化视图三,分区相关1.分区建的过多前言 提示:doris使用版本3.x 提示:以下是本篇文章正文内容,下面案例可供参考 一、doris整体情况 细节放大 二、doris的存储过程情况 1.分类 按…

左神算法之单辅助栈排序算法

目录 1. 题目2. 解释3. 思路4. 代码5. 总结 1. 题目 请编写一个程序&#xff0c;对一个栈里的整型数据&#xff0c;按升序进行排序&#xff08;即排序前栈里的数据是无序的&#xff0c;排序后最大元素位于栈顶&#xff09;。要求最多只能使用一个额外的栈存放临时数据&#xf…

使用Trae编辑器与MCP协议构建高德地图定制化服务

目录 一、使用Trae编辑器配置高德MCP Server 1.1 Trae介绍 1.2 从mcp.so中获取配置高德地图mcp server配置信息 1.3 高德地图开发者配置 1.4 添加Filesystem 到Trae 1.5 使用结果展示 1.6 MCP常见命令行工具和包管理说明 1.7 Function Call工具和MCP技术对比 二、本地…

【LLaMA-Factory 实战系列】三、命令行篇 - YAML 配置与高效微调 Qwen2.5-VL

【LLaMA-Factory 实战系列】三、命令行篇 - YAML 配置与高效微调 Qwen2.5-VL 1. 引言2. 为什么从 WebUI 转向命令行&#xff1f;3. 准备工作&#xff08;回顾&#xff09;4. 核心&#xff1a;创建并理解训练配置文件4.1 选择并复制基础模板4.2 逐一解析与修改配置文件4.3 参数详…

推荐:ToB销售B2B销售大客户营销大客户销售培训师培训讲师唐兴通讲销售技巧数字化销售销AI销售如何有效获取客户与业绩

站在AI浪潮之巅&#xff0c;重塑销售之魂 在AI时代&#xff0c;普通销售人员&#xff08;TOB、TOC&#xff09;除了传统的销售动作之外&#xff0c;还能做什么&#xff1f;怎么做&#xff1f; 这是《AI销冠》这本书想探讨的核心问题。 特别喜欢编辑老师总结的&#xff1a; 读者…

爬取小红书相关数据导入到excel

本期我们来进行实战,爬取小红书的相关数据导入到excel中,后续可进行些数据分析,今后或者已经在运营小红书的小伙伴应该比较喜欢这些数据。今天我们的主角是DrissionPage,相对于之前介绍的selenium省去了很多的配置,直接安装了就能使用。 DrissionPage 是一个基于 python …

c++面试题每日一学记录- C++对象模型与内存对齐深度原理详解

一、C++对象模型核心原理 1. 对象内存布局基础原理 设计哲学: 零开销原则:不为未使用的特性付出代价(如无虚函数则无vptr)兼容性:C结构体在C++中保持相同内存布局多态支持:通过虚函数表实现运行时动态绑定内存布局实现机制: 编译器处理步骤: 成员排列:严格按声明顺序…

Kafka 监控与调优实战指南(二)

五、Kafka 性能问题剖析 5.1 消息丢失 消息丢失是 Kafka 使用过程中较为严重的问题&#xff0c;可能由多种原因导致。在生产者端&#xff0c;如果配置不当&#xff0c;比如将acks参数设置为0&#xff0c;生产者发送消息后不会等待 Kafka broker 的确认&#xff0c;就继续发送…

Linux下SVN报错:Unable to connect to a repository at URL ‘svn://XXX‘

一、问题描述 Linux下通过SVN执行提交&#xff08;commit&#xff09;操作时报错&#xff1a;Unable to connect to a repository at URL svn://XXX&#xff1a; 二、解决方法 导致该问题的一个可能原因是远程仓库的URL发生变化了&#xff0c;即svn服务器的ip变更了。这时可…

Modbus 扫描 从站号、波特率

下载链接&#xff1a;https://pan.quark.cn/s/533ceb8e397d 下载链接: https://pan.baidu.com/s/1PQHn-MwfzrWgF2UrXQDoGg 提取码: 1111

Docker 容器通信与数据持久化

目录 简介 一、Docker 容器通信 1. Docker 网络模式 2. Bridge 模式 3. Host 模式 4. Container 模式 5. Overlay 模式 6. 端口映射&#xff1a;容器与外部的桥梁 7. 容器互联&#xff1a;从 --link 到自定义网络 二、Docker 数据持久化 1. 数据卷&#xff1a;Docke…

【教学类-89-08】20250624新年篇05——元宵节灯笼2CM黏贴边(倒置和正立数字 )

背景需求&#xff1a; 【教学类-89-06】20250220新年篇05——元宵节灯笼2CM黏贴边&#xff08;3边形到50边形&#xff0c;一页1图、2图、4图&#xff0c;适合不同水平&#xff0c;适合不同阶段&#xff09;-CSDN博客文章浏览阅读1.6k次&#xff0c;点赞35次&#xff0c;收藏27…

【DB2】SQL0104N An unexpected token “OCTETS“ was found following “……

db2创建表时报标题的错误&#xff0c;建表语句如下 db2 "CREATE TABLE YS.TEST_1(ID VARCHAR(64 OCTETS))"去掉octets就好了 经过测试&#xff0c;在9.7版本报错&#xff0c;在10.5.11没问题&#xff0c;怀疑版本差异导致 在官网查找资料&#xff0c;应该是10.5才…

暴雨以信创委员会成员单位身份参与南京专题活动

6月19日&#xff0c;中国电子工业标准化技术协会信息技术应用创新工作委员会&#xff08;简称信创工委会&#xff09;联合南京市工业和信息化局共同举办的“智启未来&#xff1a;AI赋能信息技术应用创新办公新势力”专题活动在南京成功举办。南京市工业和信息化局副局长代吉上、…

基于keepalived、vip实现高可用nginx (centos)

基于keepalived、vip实现高可用nginx &#xff08;centos&#xff09; 1、安装keepalived yum install keepalived2、选同一局域网空置ip作vip 我这里测试是&#xff1a; 主&#xff1a;192.168.163.134 副&#xff1a;192.168.163.135 vip&#xff1a;192.168.163.1403、ke…

使用 launch 启动 rviz2 并加载机器人模型

视频资料&#xff1a;《ROS 2机器人开发从入门到实践》6.2.2 在RViz中显示机器人_哔哩哔哩_bilibili 1、创建工作空间 chapt6_ws/src&#xff0c;创建包 fishrobot_description ros2 create fishrobot_description --build-type ament_cmake --license Apache-2.0 2、创建机器…

华为云Flexus+DeepSeek征文 | 基于CCE容器的AI Agent高可用部署架构与弹性扩容实践

华为云FlexusDeepSeek征文 | 基于CCE容器的AI Agent高可用部署架构与弹性扩容实践 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 总有一行代码&#xff0c;能点亮万千星辰。 &#x1f50d; 在技术的宇宙中&#xff0c;我愿做永不停歇的探索者。 …

Python学习Day41

学习来源&#xff1a;浙大疏锦行 知识回顾 数据增强卷积神经网络定义的写法batch归一化&#xff1a;调整一个批次的分布&#xff0c;常用与图像数据特征图&#xff1a;只有卷积操作输出的才叫特征图调度器&#xff1a;直接修改基础学习率 卷积操作常见流程如下&#xff1a; …