# GIS+BIM数字孪生DEMO技术方案
# 实现目标
虚实融合、创新驱动的原则,以虚拟服务现实、数据驱动治理为特征。
数字孪生城市集成数字化标识、自动化感知、网络化连接、普惠化计算、智能化控制、平台化服务等信息通信技术、新型测绘技术、地理信息技术、3D建模技术、仿真推演技术等综合技术支撑体系。实现城市全要素数字化和虚拟化、全状态实时化和可视化、运行管理协同化和智能化,实现物理城市与数字城市虚实交互、平行运转。
通过融合地理数据、模型数据、动态数据,综合应用23DGIS、WEBGL等技术,数字化和虚拟化特定区域内的关键城市信息,构建三维空间数据画像,实时呈现全域智能终端信息、城市运行效果、所有决策效果等,并可通过操控系统远程控制城市的运行状态。
# 数据构成
数据采集包括静态数据和动态数据:街景摄像、无人机倾斜摄影、雷达车扫描、卫星地图、GIS数据、BIM数据、物联网感知平台的实时运行监测数据等。实现从L1~L5的不同精度类型场景还原。
矢量GIS数据:天地图底图、行业数据(土地类型等);
栅格数据:卫星遥感影像数据、倾斜摄影数据;
BIM:不同精度类型、不同层次、不同部件的模型数据;
DEM数据;
监控数据:视频、图像、标识等;
# 实现效果
- 跨尺度无缝三维可视化:不同尺度的空间数据无缝切换;
- 室内外一体化可视化:坐标一致,相机视角一致;
- 动态数据可视化:海量流式数据呈现方式;
- 地上地下一体化可视化:地上地下无缝切换;
# 大场景
以三维GIS为基础,加载遥感影像、航拍模型、矢量数据、DEM数据,实现数据叠加、漫游、飞行、标识等功能。
体现地上地下一体化、动态数据可视化。
# 小场景
实景GIS与虚拟模型之间相互切换。
实现模型的全景浏览、室外和室内的相互切换、室内的漫游、室内监控数据展示、浏览等功能(体现室内外一体化可视化);
# 技术解决方案
通过融合二三维GIS和WEBGL技术实现城市关键要素信息的可视化,采用不同的可视化组件,充分利用其适合不同可视化场景的技术特点,实现跨尺度无缝可视化、室内外一体化可视化、地上地下一体化可视化及流式动态数据可视化的目标。
# 可视化技术路线
本项目采用的可视化组件主要包括Cesium、three.js、MapboxGL 等基于WebGL的可视化框架。

Cesium是基于JavaScript编写使用WebGL的地图引擎,支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区域,并提供良好的触摸支持,且支持绝大多数的浏览器和mobile。
Three.js是一个轻量级跨浏览器的WebGL JavaScript库,运行在浏览器中的3D引擎,用于在浏览器中创建和显示各种三维场景,包括摄影机、光影、材质等各种对象以及动画3D计算机图形。
Cesium和Three.js都是用于3D可视化的,且基于JavaScript构建的,它们有相似之处。Cesium的优势在于行星级渲染(大场景)和GIS功能,而Three.js提供广泛而易用的通用3D API功能,两者相结合可为新的WebGL体验开启了许多可能性。
Mapbox GL支持常规数据加载方式、矢量及栅格数据切片、基本GIS操作,且基于WebGL做了扩展,具有大数据展示优势;最新版本在3D可视化方面,相较OL、Leaflet等组件优势明显,且支持Camera、Sky、3D 地形渲染、高性能 DEM等功能。在可视化场景中,如果对于三维模型的需求不是很高,同时还要达到一个三维底图、倾斜底图或大场景模型的效果,数据量还要支持很高的情况下,选用Mapbox gl作为二三维GIS向精细化模型过渡、虚实可视化结合的解决方案。
# 系统技术架构
# 技术总体架构图

# 核心技术
# 模型制作
Threejs开发项目加载的模型,可能会比较大;模型三角形面数越多,一方面是threejs渲染模型的性能下降,另一方面是加载模型的时间比较长,影响体验。因为三维模型文件往往比较大,所以Web3D项目相比较普通的前端web项目,需要加载文件体积比较大,需要花费的时间自然比较多,加载时间比较长的情下,对于用户来说体验肯定不太好。

# 模型精简
模型和贴图数据是整个加载过程中最为“重量级”的数据。因此,我们应当从建模阶段就定好规范,在保证外观效果的前提下,尽量使用较为精简(面数较少)的模型。一般3D美术导出模型的时候,会进行减面操作,并导出模型的法线贴图,比如你只是加载一个机械零件模型(非批量),可以让3D美术进行减面然后导出法线贴图,这样的话在不影响曲面显示质量前提下,减少模型三角形面数,一方面可以降低模型文件大小提高网络传输性能,另一方面可以提高threejs渲染模型的渲染性能。
# 使用二进制格式
使用不同文件格式,文件的大小会有所不同,如果同一个模型,导出二进制.fbx大小要比文本格式的.obj文件要小1~2倍。常见的GLTF格式可以是文本格式,也可以使二进制格式,为了更好的传输性能可以选择二进制格式,.glTF打包转化为.glb二进制文件。
# 非二进制模型压缩
对于一些纯字符编码的模型,如 obj,dae 等,在服务端开启 gzip 压缩,可以带来较好的压缩比。
# 图片压缩
很多时候贴图文件往往大于模型。贴图尺寸也应该根据需要选取,不应该过大,一般最好不要超过 4k,保持 1024 或者 2048 较好。贴图也最好使用 2 的 n 次幂的尺寸。
# 前端
前端可视化页面是用户直接接触的,因此良好的前端可视化效果和交互效果是非常重要的。以下优化方式均为提升用户体验。

# 加载进度条
Web3D项目加载时间相对普通web页面时间比较长,如果用户一直等着,web页面没有什么反应,可能会关掉,这种情况下,可以在web页面放置一个进度条实时显示模型文件加载进度。
# 动态分批加载
如果一个场景中,有多个网格模型模型,比如室内设计效果展示,里面有沙发、椅子、电视等三维模型,这时候把这些模型分别单独建立一个文件,threejs可以按照一定的顺序分别先后加载这些单独的网格模型文件,然后插入到场景中。这样的话,用户可以以最快速度查看到场景中的部分模型,不用一直等待,没有什么反应,用户体验更好。
# 分包流式加载
对于大的场景,特别是 BIM 或者 GIS 场景,如果把所有模型全部加装完成了再展示,可能会让用户等待时间过久。所以,结合动态分批加载,可以采取分包流式加载的方式,每个包加载一部分的模型,加载解析完成后即丢到渲染主线程中进行渲染。这种方式在GIS中非常的常见,类似地图的瓦片加载服务。
想要达到这样的效果,一般会使用 worker 进行数据的加载和解析处理,这样保证了加载的线程和主线程是隔离的,不会产生加载解析模型过程中产生的 UI 卡顿。同时,如果我们想要达到并行加载和解析的效果,可以开多个 worker 进行多线程的同时加载解析工作。
# 使用LOD
LOD(Level of Details)技术指的是将场景中的模型按不同精度分为 N 套,按照模型与相机的距离远近,动态切换模型的精度,距离相机较近的模型采用精细模型展示,而距离相机较远的模型使用较为粗糙的模型进行展示。对于大的场景,使用 LOD 技术也是一个有效提升帧率的手段,可以有效减少整个场景中的渲染三角面数。
# 各种剔除
为了达到尽量减少 DrawCall 的目的,应当尽量的做好剔除工作,将最少的数据提交给 GPU 进行渲染。一般常见的剔除方式有视椎体剔除,背面剔除、遮挡剔除等。

# 视椎体剔除
一般是指只有在视椎体内的物体才能被渲染出来,不在视椎体内的物体将被剔除不作渲染。这也比较符合我们一般的视觉逻辑,不在可见范围内的物体,渲染了也看不见,纯粹属于性能浪费。一般是遍历视椎体的 6 个面,算出物体的中心到面的最小距离(带正负方向的)与包围球的半径做比较,如果小于半径,就表示在外面。
# 背面渲染剔除
一般来讲,渲染引擎大多会开启背面剔除。原生 webgl 中使用 gl.enable(gl.CULL_FACE); 来开启背面剔除。在 threejs 中可以使用 material 的 side 属性指定 front 进行单面渲染。
# 遮挡剔除
遮挡剔除是指在相机剔除后,在视野范围内仍然有许多物体直接有遮挡关系的,不需要进行渲染,虽然 gpu 有深度测试,会将有遮挡的物体进行剔除,但是我们仍然希望在提交 GPU 之前对遮挡关系进行判断,提前剔除掉一些东西,减少渲染压力。
# 内存管理优化
对于重型 webgl 应用,特别是 BIM、GIS 场景,有时候,我们需要加载多个大型模型,例如 cesium 还需要能够支持整个地球数据的加载。这就需要我们对内存有着较好的控制。
在不适用对象的时候,及时销毁对象,释放 JS 内存。同时对于模型数据,大量的顶点、法线等等 buffer 数据也是非常占用内存的。可以在 js 推送完数据之后,将这部分数据从内存中释放掉,从而降低 JS 的内存压力。对于 v8 引擎来说 32 位的 JS heap 最多能到 3.8G 左右,如果不及时释放内存,很容易内存爆掉,导致浏览器 crash。
# 后端
后端需要为前端提供模型文件服务、提供关系型数据服务、提供GIS空间分析服务;以及对大量模型数据和GIS数据进行组织和存储。为了保证以上服务的高可用,以及后端在高并发环境下依旧能正常提供高速的数据访问能力,后端服务的开发将使用微服务框架;数据存储将使用分布式框架,以保证数据存储的安全性和扩展性。
# 微服务框架
微服务是一种用于构建应用的架构方案。微服务架构有别于更为传统的单体式方案,可将应用拆分成多个核心功能。每个功能都被称为一项服务,可以单独构建和部署,这意味着各项服务在工作(和出现故障)时不会相互影响。

微服务的优势:
- 复杂度可控:通过对共享业务服务更细粒度的拆分,一个服务只需关注一个特定的业务领域,并通过定义良好的接口清晰表述服务边界。由于体积小、复杂度低,开发、维护会更加简单。
- 技术选型更灵活:每个微服务都由不同的团队来维护,所以可以结合业务特性自由选择技术栈。
- 可扩展性更强:可以根据每个微服务的性能要求和业务特点来对服务进行灵活扩展,比如通过增加单个服务的集群规模,提升部署了该服务的节点的硬件配置。
- 独立部署:由于每个微服务都是一个独立运行的进程,所以可以实现独立部署。当某个微服务发生变更时不需要重新编译部署整个应用,并且单个微服务的代码量比较小,使得发布更加高效。
- 容错性:在微服务架构中,如果某一个服务发生故障,我们可以使故障隔离在单个服务中。其他服务可以通过重试、降级等机制来实现应用层面的容错。
基于服务注册和发现中心使用微服务网关,进行负载均衡,提高前端数据接口访问的并发量,保证服务的高可用性。
# GIS空间分析服务

PostGIS在对象关系型数据库PostgreSQL (opens new window)上增加了存储管理空间数据的能力,相当于Oracle的spatial部分。PostGIS最大的特点是符合并且实现了OpenGIS的一些规范,是最著名的开源GIS数据库。
GeoTools是一个开放源代码Java库,提供用于地理空间数据的工具。
GeoMesa是一种开源工具套件,可在分布式计算系统上进行大规模地理空间查询和分析。GeoMesa在Accumulo,HBase,Google Bigtable和Cassandra数据库之上提供了时空索引,用于大量存储点,线和面数据。GeoMesa还通过在Apache Kafka之上分层空间语义来提供时空数据的近实时流处理。通过GeoServer,GeoMesa促进了通过标准OGC(开放地理空间联盟)API和协议(例如WFS和WMS)与各种现有地图客户端的集成。GeoMesa支持Apache Spark进行自定义分布式地理空间分析。
# 文件缓存
因为Web3D项目的模型文件、3dTiles文件等数据,具有数据量大、单文件数据尺寸大、文件不经常修改等特点,后台提供数据时可以使用数据缓存策略。开启数据缓存策略后,在项目第一次加载的时候,所有的静态文件会进行加载并缓存到客户端中,重新打开时不会再去请求那些已经缓存的文件。缩短用户加载模型等数据的时间,提升用户体验,减小服务器的带宽和并发压力。
# 文件存储

- 大文件存储:针对单个文件很大的模型数据可以使用GridFS、HDFS进行分布式存储,提高文件的访问速度和数据可靠性。
- 小文件存储:针对文件尺寸不大,但数量多的情况,可以使用mongoDB进行分布式文件存储,比如三维模型的切片文件(3dtitles)、栅格数据的瓦片数据。
- 矢量文件存储:ShapeFile文件等矢量GIS数据使用PostgreSQL+PostGIS进行存储。
- 关系型数据存储:二维关系型数据存储使用PostgreSQL。
- 热点数据存储:对于高频热点访问数据,可以使用内存数据库Redis进行存储。
MongoDB的文件存储方式可看成一个大的哈希表,其中文件名作为键,文件内容作为值被保存。它可将一个大文件分割成多个较小的文件。当BIM+GIS集成过程中形成的各种基础信息存储到MongoDB数据库后会被分割成许多块,每块仅保存一个主题空间的数据。这为有效保存较大的文件对象提供可能,如遥感影像、全景地图和视频等。
MongoDB数据库可管理百亿级的三维切片数据,并具有高并发能力,响应时间达到秒级,适用于大规模数字城市三维场景的应用。将BIM+GIS集成数据存储在MongoDB中,可实现三维切片数据的分布式存储,为智慧城市基础大数据的管理提供技术支撑。