ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OSGB转3D Tiles全攻略:工具选型、转换流程与避坑指南

OSGB转3D Tiles全攻略:工具选型、转换流程与避坑指南 简介面向倾斜摄影数据处理与三维GIS开发者的OSGB转3dtile命令行工具用于将OSGB格式倾斜模型快速转换为Cesium、SuperMap等平台可加载的3dtiles数据解决Web端海量倾斜模型加载与调度难题。压缩包共178个文件约12.39MB以exe主程序为核心配齐动态库dll、坐标投影参数csv、地理坐标系wkt定义、数据格式定义xsd等覆盖常见坐标转换与瓦片生成所需组件解压后即可按命令行方式批处理转换。该工具基于GDAL体系通过gfs、csv等文件提供完整的投影与基准面信息可适配不同区域OSGB数据的坐标统一省去大量环境配置时间。目前已有578人学习下载适合需要在不依赖大型GIS平台的情况下自主完成OSGB切片、发布三维服务的测绘工程师与三维前端开发者。附带Tomcat部署查看思路可快速生成3dtile并验证效果。 最近被同一个问题问了好几次倾斜摄影数据跑完建模软件生成了一堆 OSGB 文件前端用 Cesium 拉不起来到底拿什么工具转 3dtile问的人里有搞无人机航测的有做数字孪生的也有刚接手实景三维项目被甲方赶着交活的。这个问题卡住过很多人因为 OSGB 和 3D Tiles 虽然都叫三维瓦片但设计思路完全不一样不是改个后缀就能糊弄过去的。这篇东西就把我实际跑通的转换流程、工具选型逻辑、还有踩过的一些坑完整写出来。适合三类人看一是手上有 OSGB 数据急着转给前端加载的建模人员二是要搭自动转换流程的研发三是想搞清楚转换原理避免乱试工具的初学者。看完你至少能判断一件事你手里的数据适合用哪条路线转转之前要准备什么转完怎么验证。1. 先搞清楚OSGB 和 3D Tiles 到底差在哪1.1 OSGB 不是一种格式而是一堆文件很多人第一次看到倾斜摄影成果时都会愣一下说好的 OSGB 数据怎么是一个塞满文件夹的目录这里要解释清楚OSGB 全称是 OpenSceneGraph Binary本质是场景图二进制格式但在实际生产里它通常以“一棵分块树”的形式存在。典型的倾斜摄影成果目录长这样Data/ ├── metadata.xml ├── Tile_000_000/ │ ├── Tile_000_000.osgb │ └── Tile_000_000_1.jpg ├── Tile_000_001/ │ ├── Tile_000_001.osgb │ └── ... └── Tile_001_000/ ├── Tile_001_000.osgb └── ...每一个Tile_xxx_yyy目录代表一个瓦片节点名字里的坐标是它在本地网格里的行列位置。节点内部是一个.osgb主文件里面包含这个瓦片的三角网格、材质、以及组织子节点的信息纹理可能是内嵌二进制也可能以 jpg/png 形式单独放在旁边。根目录的metadata.xml记录坐标系和模型原点这是最关键的文件之一。ContextCapture、iTwin Capture原 Smart3D这类建模软件导出 OSGB 时就是按照“根节点 LOD 子节点”的方式组织的。根节点是整片测区的粗模往下每一级细分直到贴近地面的高精度模型。前端要流畅浏览靠的就是这种多级细节层次结构。1.2 3D Tiles 解决的是“Web 端怎么调度”的问题3D Tiles 是 Cesium 团队提出、后来成为 OGC 社区标准的一种三维瓦片规范。它的核心不是某个具体模型格式而是一套“如何用 JSON 描述一棵三维空间树、然后按屏幕空间误差动态加载”的调度协议。最核心的文件是tileset.json它描述根节点、子节点、包围体、几何误差、内容路径、变换矩阵。一个简化版的tileset.json大概是这种感觉{ asset: { version: 1.0 }, geometricError: 500, root: { boundingVolume: { region: [1.2, 0.3, 1.3, 0.4, 0, 200] }, geometricError: 50, refine: REPLACE, content: { uri: Tile_000_000.b3dm }, children: [] } }浏览器里的 Cesium 加载时会不断计算“这个瓦片投到屏幕上的误差有多大”如果误差超过阈值就继续向下加载更精细的子节点否则就停在当前层级。这个机制跟 OSGB 的 LOD 思路很像但表达方式完全不同OSGB 的树结构隐藏在二进制文件内部而 3D Tiles 把树结构显式写成了 JSON。所以回到开头的问题为什么不能把.osgb文件直接扔给 Cesium因为 Cesium 根本不认识 OSGB 的二进制结构更不知道如何从根节点递归去找子节点。它只认 3D Tiles 规范里的 b3dm、pnts、i3dm 等瓦片格式以及外面的tileset.json。OSGB 数据要进入 Web 三维地球必须经过一次“翻译”。1.3 转换工具到底在帮你做什么理解了上面的差异你就能看懂所有转换工具的本质工作了。一次完整的 OSGB 转 3D Tiles大概要干这几件事解析每个瓦片的网格数据、材质、纹理把 OSGB 的场景图结构读出来把瓦片从原来的本地坐标或独立坐标系统一变换到目标坐标系通常是 EPSG:4490、EPSG:4326、EPSG:3857 等重新组织 LOD 树把“以目录和二进制文件表达的树”改造成“以 JSON 和独立瓦片文件表达的树”重写纹理必要时压缩纹理尺寸和格式控制输出体积写入tileset.json让 Cesium 能按规范逐级加载。这个过程不是简单的“解包再打包”还涉及坐标变换、纹理重采样、LOD 层级合并或拆分。很多时候你转出来的数据如果出现偏移、黑块、闪面问题往往不是工具坏了而是这些环节里某个参数没配对。2. 工具选型市面上的几条路线怎么挑2.1 四类转换路线横评我把目前能见到的 OSGB 转 3D Tiles 工具分成四类各有各的适用场景。第一类是商业桌面软件最典型的就是 CesiumLab。它界面友好点几下鼠标就能完成转换对小白极其友好内置了很多针对倾斜摄影的优化选项输出结果在 Cesium 里表现也稳。缺点是闭源批量自动化能力弱自定义空间有限而且部分高级功能需要付费授权。如果是偶尔转一两个小场景这条路最省心。第二类是图形化开源工具比如 Glaby 等。它们有的也能直接把 OSGB 拖进去转但更新频率和维护力度普遍不稳定遇到新版建模软件输出的数据可能解析失败。我一般不推荐把生产流程押在这种工具上玩玩可以正式项目担风险。第三类是命令行开源工具也是我目前最常用的路线。这一类工具以独立可执行文件或 CLI 程序的形式提供核心优点是可脚本化、可嵌入生产流程、参数透明。很多工具由测绘或三维领域的开发者在维护对 OSGB 的兼容性反而比商业软件更贴近实际需求。第四类是库/开发框架比如 py3dtiles。这种方式适合想自己写代码做二次开发的团队但 py3dtiles 对点云的支持比 OSGB 更完善你要拿它转大体积倾斜模型需要自己补不少胶水代码。2.2 我的选择逻辑命令行优先界面兜底我现在的习惯是正式生产环境优先用命令行工具遇到一次性小任务再用带界面的软件兜底。原因很简单命令行工具可以写进批处理脚本半夜挂机转大场景第二天起来看日志就行CesiumLab 这类 GUI 工具虽然简单但手工操作没法固化同样一个参数在不同项目里容易填错。以 GitHub 上常见的 OSGB 转 3D Tiles 工具为例不同作者维护的项目参数名可能略有差异但核心思路一致使用方式大多是./converter --input 输入目录 --output 输出目录 \ --srs 4490 --max-level 20 --thread 8 --texture-compress jpeg这里我先不绑定某一个具体项目因为你安装哪个工具后第一步永远是去看--help或 README参数名可能有差别。但下面这些概念是通用的输入目录、输出目录、坐标系、最大层级、线程数、纹理压缩方式。理解了它们任何工具到手上都能快速上手。个人建议如果只是转一个小区块、给甲方演示效果直接用 CesiumLab 这类带界面的工具可以大幅减少时间成本如果要做多测区批量处理、要接入自动发布流程一定要选命令行工具。3. 直接上手从 OSGB 到 3D Tiles 的完整转换流程3.1 转换前的数据体检拿到一批 OSGB 数据先别急着找转换工具先花五分钟确认三件事。第一目录里有没有metadata.xml没有它很多命令行工具读不到坐标系和原点转出来的模型位置大概率是错的。第二瓦片文件的目录结构是否完整有没有缺瓦片缺瓦片会导致输出树有空洞Cesium 加载时会出现局部塌陷。第三确认源数据坐标系是什么是 CGCS2000 还是西安80是经纬度还是投影坐标这决定了你在命令里填什么--srs参数。检查完之后我习惯先把输入数据做一次路径整理放到一个干净的目录避免路径里有中文、空格、特殊符号。某些转换工具对中文路径支持不好路径乱的时候会报一些莫名其妙的错排查起来很浪费时间。3.2 准备输入目录与环境假设你的数据解压后长这样/workspace/model/ ├── metadata.xml ├── Tile_000_000/ │ ├── Tile_000_000.osgb │ └── Tile_000_000_1.jpg ├── Tile_000_001/ │ └── ... └── Tile_001_000/ └── ...注意这里有个关键点命令行工具要你填的输入路径一般是这个包含 metadata.xml 的根目录而不是某一个具体的Tile_xxx_xxx子目录。之前有朋友把路径填到了某个瓦片目录里工具只能读到单独一个瓦片转出来的模型肉眼可见地丢了一大半。这是因为工具要从根目录递归遍历所有子瓦片如果只给一个子节点它没有上层信息可以回溯。环境上转换工具依赖还算简单。Windows 下直接解压或安装对应版本Linux 服务器下一般要保证有足够的磁盘空间和内存。我建议准备至少源数据 2 倍以上的磁盘余量因为临时文件、中间纹理、输出文件都会占空间。3.3 执行一条标准转换命令下面我以一条典型的 Linux 命令行操作为例参数名可能和某个具体工具不完全一样但含义通用。实际操作前先用--help确认./converter \ --input /workspace/model \ --output /workspace/out_3dtiles \ --srs 4490 \ --max-level 20 \ --thread 8 \ --texture-compress jpeg \ --rename-by-epsg分头解释一下这些参数都是干什么的。--srs 4490是目标坐标系。4490 是 CGCS2000 地理坐标系 EPSG 编码国内项目最常用。如果你的业务系统用 Web 墨卡托3857或者 WGS844326就改成对应编码。这里有个容易踩的坑很多工具假设输入数据的坐标系和metadata.xml里写的一致但实测中有的metadata.xml里坐标系信息是缺失或错误的这时候你需要额外指定输入坐标系参数常见的有--input-srs否则工具会按默认值解析导致坐标静默偏差。--max-level 20是最大 LOD 层级。建模软件导出的 OSGB 层级取决于输出设置这里设置 20 一般能覆盖绝大多数场景。如果设置得太小高精度瓦片会被丢弃模型变糊设置太大不会增加太多成本只是可能多生成冗余层级。--thread 8是转换线程数。这里很多人有个误区以为线程越多越快。实际上转换过程有两个瓶颈一个在磁盘 IO源瓦片文件要大量读取临时文件要写入磁盘带宽不够时加线程只会让硬盘更忙另一个在纹理压缩CPU 密集型但单瓦片内部不一定能并行充分。我实测下来8 线程在普通 NVMe 固态上已经能跑满16 线程的提升非常有限反而内存占用会明显上涨。--texture-compress jpeg是把纹理统一重采样成 JPEG 格式。OSGB 导出时纹理可能混合了 png、jpg尺寸也不统一。转换成 JPEG 可以显著压缩体积但要注意如果源纹理本身带有透明通道转成 JPEG 会让透明部分变黑底。如果你的模型里有大量树木、栏杆这类需要透明的物体建议选 webp 或保留 png 压缩。--rename-by-epsg是让工具自动把输出的tileset.json里坐标系统一按 EPSG 编码命名。这个参数非必需但建议开启能避免后续在 Cesium 里出现奇怪的坐标转换问题。如果你用的是 CesiumLab 这类带界面的工具对应的操作就是新建转换任务输入数据选择根目录输出格式选 3D Tiles坐标系选 CGCS2000纹理压缩选 JPEG层级上限选 20然后点开始。本质上是同一套参数。3.4 转换完成后的验证三板斧转换结束不等于能用了我每次都会做三件事验证输出。先看输出目录结构。一个正常的 3D Tiles 输出目录大致是/workspace/out_3dtiles/ ├── tileset.json ├── Tile_000_000/ │ ├── Tile_000_000.b3dm │ └── ... └── Tile_001_000/ ├── Tile_001_000.b3dm └── ...注意输出文件名大多保留了 OSGB 的瓦片命名规则但扩展名从.osgb变成了.b3dm有些工具会把所有瓦片平铺在一个目录有些仍然分目录这取决于工具实现不影响 Cesium 读取。核心是tileset.json必须存在并且它引用的瓦片路径和实际文件能对上。第二步是打开tileset.json看根节点的boundingVolume和transform确认坐标没有离谱到十几万公里之外。如果根节点 transform 里出现一堆天文数字多半是坐标变换没做对回头检查坐标系参数。第三步是用一个最简单的方式在 Cesium 里加载试试。本地起个静态文件服务npx serve /workspace/out_3dtiles -l 8080然后在页面里用Cesium.Cesium3DTileset.fromUrl(http://localhost:8080/tileset.json)加载。如果模型位置正确、纹理不黑、不闪面基本就能交付了。4. 生产环境里绕不开的优化点4.1 输出后的部署与加载方式转换完成的 3D Tiles 通常要放到 Web 服务器上供前端加载。这里有三个坑我反复遇到。第一个是 CORS 跨域问题如果你的页面在https://app.example.com瓦片在https://tiles.example.com服务器必须返回Access-Control-Allow-Origin头否则浏览器会把所有瓦片请求都拦截掉表现就是模型只加载第一层或者完全空白。排查方法很简单打开浏览器开发者工具看网络请求如果一堆红色 CORS 报错就是这里的问题。第二个是 gzip 压缩。tileset.json是小文件开 gzip 收益很大b3dm本身是二进制体压缩率有限但开了也没坏处。很多静态服务器默认只对文本类文件开 gzip对这种.json文件没问题但如果你的.b3dm文件没被识别为可压缩类型可能在传输层拖慢加载。第三个是并发加载量。一个大场景可能有几千个瓦片Cesium 会并发请求很多瓦片。如果服务器带宽有限建议在前端设置 tile 请求的限流或者用对象存储 CDN 扛流量。这个阶段和转换工具本身关系不大了但影响最终体验值得一提。4.2 纹理压缩和线程数的权衡纹理体积常常是 3D Tiles 体积的最大头。实测转一个 20GB 的 OSGB 数据纹理 jpeg 压缩到最大边 512 像素后输出可能只有 2GB 左右如果保持原始纹理尺寸输出可能 10GB 以上。这个差距在 Web 端是致命的因为浏览器不可能一次性加载 10GB 模型。但纹理也不能无限压。很多转换工具提供了--max-texture-size参数我建议优先从 512 开始试看近景是否糊糊了再提到 1024。对于大范围城市级模型512 通常够看对于需要近景展示的精细部件1024 更稳妥。一个区块一个区块调适合你的项目不要全局一把梭。线程数前面提过8 线程在多数机器上是甜点位。如果你只有 16GB 内存建议降到 4否则内存溢出会频繁打断转换。内存占用主要和纹理解码缓冲有关大纹理多线程容易把内存吃满。遇到中断时优先看日志里是“OutOfMemory”还是“Disk full”再对症调参。4.3 多测区数据怎么分批转、再合并倾斜摄影项目很少只有一个测区。多个测区分开飞行建模最后要合到同一个 3D Tiles 里展示。这里有两种做法。一种是每个测区单独转成独立的 3D Tiles然后在 Cesium 里加载多个Cesium3DTileset实例。这种最简单适合测区之间距离远、不需要无缝拼接的场景。缺点是层级切换时可能看到模型边缘“跳变”而且每个 tileset 有自己的 LOD 树无法统一优化。另一种是把多个测区先合并成一个大场景再转。很多专业用户会用建模软件先把模型merge 到一起或者用支持多输入的转换工具把多个根目录合并。这里要特别注意多个测区必须使用同一个坐标系基准而且瓦片重叠区域要处理好否则转出来的模型会出现互相插穿、重复面。我见过最离谱的一次是同一座楼在两个测区里各建了一遍合并后楼体出现重影切任何视角都闪面。如果工具不支持合并退而求其次的方案是用 Cesium 的clippingPolygons或者给每个 tileset 设置不同的maximumScreenSpaceError把边缘问题藏掉。这个属于前端技巧但对最终交付很管用。5. 常见问题与排查技巧实录5.1 问题速查表我把实际项目中遇到的高频问题整理成一张表按出现频率排序。现象常见原因排查与解决模型整体飞到几十万公里外坐标系没配对或 metadata.xml 缺失确认输入输出坐标系检查根节点 transform加载白屏、模型不出现跨域、路径错误、tileset.json 引用找不到瓦片看浏览器 Network 面板逐个请求检查 404 和 CORS模型黑色、纹理丢失纹理路径重写失败、纹理压缩格式不支持透明检查输出目录纹理文件是否存在透明贴图改用 webp/png转换中途内存溢出线程数过多、单瓦片纹理过大降低线程数限制 max-texture-size分批处理模型边缘有空洞源数据缺瓦片或 LOD 层级设置过低在源目录检查瓦片序列是否连续提高 max-level高层级加载时模型闪面多个测区重叠区域未处理检查源数据重叠情况用裁剪或多 tileset 方案转出来的 b3dm 文件巨大纹理未压缩或层级过多开纹理压缩检查 max-level 是否合理这张表基本覆盖了 90% 的问题。真正让新手崩溃的往往是第一行坐标飞了。它最阴险的地方在于转换工具本身不报错日志全部正常但模型就是不在它该在的地方。我现在的习惯是转换前先看metadata.xml里的坐标系声明再用 QGIS 或 GIS 软件打开源数据的包围盒确认数据真实位置再决定命令参数。5.2 三个容易被忽略的隐蔽坑第一个坑是临时目录空间不足。很多命令行工具都会在系统临时目录或你指定的--tmp-folder中写入大量中间文件而且不会及时清理。转换接近尾声时磁盘满了工具可能直接崩溃或输出一个残缺的tileset.json。解决方案是在转换命令里显式指定一个空间充足的临时目录转完手动删除中间文件。第二个坑是文件名大小写。Windows 上生成的数据拷贝到 Linux 服务器时某些瓦片文件名的大小写和tileset.json里写入的大小写不一致导致浏览器 404。这个问题在本地 Windows 上测试一切正常部署到 Linux 服务器才暴露。解决办法是转换前统一用小写文件名或者转换工具支持时开启大小写不敏感模式。第三个坑和最近圈子里流传的一些“转换神器”有关。大家都想省事网上经常有人分享那种打包好的压缩包比如我最近看到有人提的 baoli.rar 之类的资源包。说实话这类来源不明的转换包风险很高里面打包的工具版本老旧不说还可能夹带私货。工具要在生产服务器上跑给你的机器装上不该有的东西轻则数据泄露重则整个项目报废。我建议转换工具要么从官方仓库下载要么用知名开源项目的 Release 版不要用微信群和网盘里转来转去的“绿色版”。6. 最后一次实战我的固定套路每次拿到一批新的 OSGB 数据我现在的流程已经固定下来了先把数据目录结构和 metadata.xml 看一遍确认坐标系和瓦片完整性然后用命令行工具带着--srs 4490 --max-level 20 --thread 8 --texture-compress jpeg这套参数跑一个小区块做测试确认位置和纹理没问题最后再全量转换转完用本地静态服务器在 Cesium 里过一遍检查 LOD 切换和边缘情况。这套流程帮我挡掉了至少一半的返工问题。特别是“先用小区块测试”这一步很多人嫌麻烦直接全量跑结果转了 8 小时发现坐标错了白白浪费时间。我自己最早也是这样吃过亏的后来学乖了转换一个 20GB 场景之前先裁剪一小块试试水最多花十分钟能省一整晚。如果你现在手里正卡着一个转不好的项目我的建议是先别急着换工具换软件把你源目录的截图、metadata.xml 内容和失败日志拿来看一看大多数问题都出在这些不起眼的细节上。格式转换这活儿参数就那几个真正拉开差距的是对数据本身的理解。本文还有配套的精品资源点击获取
返回列表