其他分享
首页 > 其他分享> > M3D - 一个想突破又还有很多包袱的新生三维数据格式杂谈

M3D - 一个想突破又还有很多包袱的新生三维数据格式杂谈

作者:互联网

目录

都说 “一流企业定标准,二流企业卖品牌,三流企业卖产品,四流企业做项目”,在面向类 WebGL 技术的三维浏览器端渲染的大规模流式数据加载技术中,等到了 MapGIS 主导的 m3d 标准。

1 门派

这一份浓浓的武汉味似乎是想在继 Cesium 3d-Tiles、Esri i3s、超图 S3M 后再在三维市场分一杯羹。

在前言中,吴老爷子带路,洋洋洒洒的一队人。

2 几个术语简析

3 结构简析

image

结构的设计与 Esri i3s 略相类似,使用 Node 充当空间剖分的术语。

每份 m3d 数据,其根目录下有

3.1 空间剖分方式

规范中的术语是 “数据树形结构”,个人认为使用 空间剖分方式 更好,直观。

使用了三种常规三维数据结构,即空间八叉树、四叉树、KD树。

3.2 空间范围表示方式

以上两种常见空间范围体二选一。

其中,BoundingBox 使用的定义是 6 元素的 AABB 包围盒,即经纬高三轴的最值。

4 M3DDataInfo.mcj 类定义

描述整个 m3d 文件的 json 文件,它拥有如下顶层属性:

其中,BoundingVolume 在上文已提及,连同 PointField,在此简单使用 Rust 结构体定义:

struct BoundingVolume {
  boundingBox: BoundingBox,
  boundingSphere: BoundingSphere,
}

struct BoundingBox {
  left: f64,
  top: f64,
  right: f64,
  bottom: f64,
  minHeight: f64,
  maxHeight: f64,
}

struct BoundingSphere {
  center: Point,
  radius: f64,
}

struct Point {
  x: f64, 
  y: f64,
  z: f64,
}

struct Field {
  name: String,
  type: String,
  alias: String,
  size: i32,
}

其中,Field 的 type 字段可选值为 "bool""int16""uint16""int32""uint32""int64""uint64""float""double""wchar""text""date""time""timestamp"

5 NodeInfo.json 类定义

每个节点(node)的描述文件是一个 json 文件,它的顶层属性有:

其中,TileDataInfo 的类定义用 rust 表示可为:

struct TileDataInfo {
  tileData: Uri,
  geometry: Geometry,
  attribute: Attribute,
  texture: Uri,
  dataType: string, // 可选值 "Vector"、"TiltPhotography"、"Model"、"BIM"、"PointCloud"、"PipeLine"、"GeoModel"、"GeoGrid"、"GeoDrill"、"GeoSection",分别表示:矢量、倾斜、模型、BIM、点云、管线、地质体、地质体网格、地址钻孔、地质剖面
}

struct Geometry {
  blobType: string, // 可选值 "glb"、"glbx"
  url: string,
  geoCompressType: string, // 只能是 "draco"
  geometryType: string, // 可选值 "Point"、"Line"、"Polygon"、"Surface"、"Entity"
}

struct Attribute {
  attType: string, // 可选值 "json"、"bin"
  uri: string,
}

6 *.m3d 文件

文中对 m3d 的介绍在 7.4 节,就不复述了,主要提一点:

我觉得这个格式的提出是多余的,槽点最后再谈。

7. 地质模型几何结构定义

由于本部分(原文位于7.4.3节)在原文中较为详细,只捡几个点提一提。

7.1 钻孔模型几何结构定义

略。

7.2 地质剖面模型几何结构定义

剖面使用的是一个点列表表示的简单封闭三维线,这是有缺点的,因为不能表达多剖面的情况。

7.3 地质体模型几何结构定义

地质体在此处使用了多个索引三角面来定义,其实可以完全使用 glTF 来定义,只不过这里简化成了索引+顶点的形式。

7.4 网格模型几何结构

这部分的设计略显冗杂,有重复设计的嫌疑,没有优化。

8 属性文件的设计

属性文件的类型在 M3DDataInfo 对象中定义,见本文第 4 部分。

它使用 “属性记录(Record)” 来描述一个属性,又分了下列两个类定义:

struct Record {
  oid: long,
  rcdValues: Vec<RcdValue>,
}

struct RcdValue<T> {
  fldName: String,
  rcdValue: T
}

关于此部分的吐槽留到最后。

9 单体化的定义

m3d 标准使用一个叫 oidTable 的表,记录每个 “物件” 的单体信息。

具体做法是,对每个顶点进行设定值,例如房屋A设定每个顶点的值是1,那么就记录在 oidTable 中即可。

并由此扩展 glb 文件,构成 glbx 文件。

单开一小节吐槽

在 Cesium 提出的 glTF 扩展中,有一个更为接近此设计的扩充:glTF 中 Primitive 的定义增加一个 _BATCHID,使得顶点属性新增一个,与 POSITIONCOLOR 等同级别,使用此 _BATCHID 来区分顶点归属于哪个 batch。

利用 glTF 强大的扩展能力完全没必要 “扩展 glb 文件成 glbx”。

另外,单体化也是一个伪命题。因为倾斜摄影模型仅仅是有外观的三角网模型,不具备精细模型和 GIS 要素的独立性,所以才提出 “单体化” 这种词。

在 GIS 数据、BIM 数据中就很少听说过这词,因为这两种数据本身就有着完备的物件独立信息。

如果模型建模时,有完整的地理要素的定义,其实就具备了单体化的信息,使用 GIS 中的 “要素” 完全可以区分开不同的物体。

10 Shared 文件夹

关于此文件夹没有过多的描述,只有不到 1/4 页纸。

它似乎是设计来存放公共数据的,用来提供 instance 能力。

11 RESTful 接口设计

11.1 数据信息获取服务:M3DData

url模板:<base-url>/services/<service-name>/M3dServer

例:

http://igserver.mapgis.com/igs/rest/services/wuhan-3d/M3dServer

调取方法是 HTTP GET,返回类型是 application/json

11.2 公共资源获取服务:M3DSharedResources

url模板:<m3d-data-url>/shared-resources

例:

http://igserver.mapgis.com/igs/rest/services/wuhan-3d/M3dServer/shared-resource

调取方法是 HTTP GET,返回类型是 application/octet-stream

11.3 根节点信息获取服务:M3DRootNodeInfo

11.4 其他服务

为什么写两个就不写了?

因为原文定义已经很详细了,无需复述。

12 优点

13 缺点

① 对 glTF 规范认知不全

没有充分阅读 glTF 规范

没有充分利用 glTF 强大的扩展能力

如无必要,勿增实体。glbx 是一种多余的设计。

② 文档定义缺陷

定义歧义

对于路径的定义,在原文见过 Uriurlstring 三种写法。

对于空间剖分的定义,在文件组织上,使用 Node 文件夹来组织,但是其下的各部分数据又使用 Tile 来定义,在原文第 3.2 节还专门说明了瓦片数据,却不见 Node 的详细定义;

在图1和图2中,对 Node 和 m3d 文件的组织十分困惑,Node<i> 目录应该是一个 Node,下面能挂载 N 个 m3d 文件;但是在原文 3.3 节中,每个瓦片下面挂 0 或 1 个 m3d 文件,却不见瓦片的定义,只见 tile data(瓦片数据) 的定义。

asset 属性按理说可以囊括 nameversionguiddataName 等属性的,却将他们分开,不知道设计上是否经过足够的考虑。

类型错误

在 M3DDataInfo 的类定义中,对于 version 字段的类型,表格里是 float,表格上面的 UML 类图又是 string,这种低级错误应该在校对的时候修正。

UML 描述不够完整

属性的默认值、属性的可选性未指出。

属性拼写不规范

例如 geoCompressType,此属性是 Geometry 类下的,按理说就不需要 geo 前缀,只需保留 compressType 即可。

还有 attType,该简写的地方简写,此处就不该简写,它是 Attribute 对象的一个属性,所以它应该是 type

RcdValue 对象应该完整的命名为 RecordValue,且其 rcdValue 应简单命名为 value,它的类型还出现了模糊不清的定义,因为没有人知道 value 是什么值类型。

驼峰命名法、下划线命名法混用就不说了。

③ 标准里太多 “专有” 词汇

④ 对一些属性未完全解释

14 槽点

① ArcGIS Server REST接口风格味道太重

在原文的第 8 部分体现的十分明显,RESTful 风格其实完全没有必要设计如此冗杂的 URL 模板。

② 对数据的行业层级和结构层级混淆

数据的结构层级是与行业无关的,例如 “矢量” 是一种概念,矢量数据可以囊括二维图形、三维图形数据,完全可以描述几何部分。

行业层级必须基于结构层级去定义,才有物质基础,这一点马克思老爷子早就总结好了。如果一个行业的数据对其底层的结构不清楚,例如单提 “BIM数据”,不提是什么格式,不提它的结构,那也只能是谈判桌上的词,落实不下来,谈不了什么自主创新。

③ 使用商业压缩格式 rar,使用过多的压缩格式

若为开放标准,而使用半封闭的 rar 格式,则必须在服务端多准备一个 rar 解压的程序。

zip、7z 作为存储时能有效减少体积,但是文章中并未提及这两种压缩方式的压缩等级、压缩与解压缩的性能开销,如果因为这些延长了文件 IO 的时间,那是得不偿失的。

这一点是 i3s 的资源 gzip 法则占优,因为浏览器天生支持 gzip,并且开销不算很大。

④ 扩展性不佳

若将来要新增气象数据或时态数据,没有留有冗余的设计。

15 个人总结

定义这种类型的数据规范,不仅要有足够充足的行业一线实践经历,还要在 Web 可视化领域有足够的底层技术积累。

从技术和数据的视角做定义,才具备完整的可实施性和一般适配性。

M3D 的提出丰富了我国对三维数据规范的标准库,但是现在缺实现,生态不足,推广几乎没有,如何让各行各业买账,还需要走相当长的路,务必脚踏实地,方可行百里路。

标签:文件,M3D,定义,glTF,杂谈,数据格式,m3d,数据,string
来源: https://www.cnblogs.com/onsummer/p/14652462.html