山海鲸可视化

GIS融合之路(一)技术选型CesiumJS/loaders.gl/iTowns

image.png

大家好,我是山海鲸的技术负责人。今天来和大家分享一下山海鲸可视化在数字孪生系统当中对 GIS 系统的整合之路,大家可以移步视频中看一下目前的整合效果: GIS 与数字孪生-山海鲸可视化视频教程

熟悉山海鲸的朋友应该知道,山海鲸可视化在 3.0 之后,在软件内部整合了一个 3D 场景编辑组件-城市大师。城市大师当中不仅实现了体积云天空,Lensflare,雨雪天气,高度指数雾等等特效,也整合了模型库,PBR 材质编辑,植被笔刷,标记点,热力图等等非常好用的 3D 编辑功能。经过了一年时间的加班打磨,作为技术负责人的我终于觉得可以躺下来好好喝杯咖啡了。然而,天不遂人愿,咱们做 TOB 的人有一个永远的诅咒,那就是软件的开发永远跟不上客户的需求变动的速度。在接触大客户的过程中,GIS 系统不断被提及。特别是大部分智慧城市项目,几乎都有自己的测绘数据,DEM,DOM,倾斜摄影等数据,都需要接入到山海鲸的可视化系统当中。

问题来了,到底怎么才能把这些 GIS 数据接入到山海鲸当中,还能共享城市大师中所有的功能呢?

如果是一家没有技术追求的公司,那肯定是 CesiumJS 拿来用。但是我们不一样啊,作为一个有理想的技术负责人,渲染都不愿意用成熟游戏引擎,要自己来实现。更何况 GIS 这种纯粹功能的东西,必须要自己写啊。想到这,当然是说干就干:先搞清楚这些 GIS 名词是啥。

经过一番仔细研究和认真研判(对,就是搜索了几个关键词),最终发现自己还是太年轻。GIS 行业的人都不上网的吗?咋没有一个大神出来写一篇 GIS 从入门到精通呢?这些词这么多,咋解释的文章这么少,还全是抄来抄去的。要不先看看 CesiumJS 代码吧,再次经过一番仔细研究和认真研判,发现自研道路道阻且长,作为一个有理智的技术负责人,此时应为整个团队着想,果断放弃自研道路。
image.png

三种方式

目前根据搜索到的信息,有三条路可以走(由于我们采用的 Webgl 引擎相对小众且做了大量修改,所以搜索时基本都只能搜索 ThreeJS 的相关内容,因此下面我用 CesiumJS 和 ThreeJS 的整合方式来代表和我们的引擎的整合方式):

1.整合 CesiumJS 到系统中

优势:CesiumJS 的非常成熟,几乎支持了大部分常用的 GIS 协议,且性能优化较好
劣势:CesiumJS 自己实现了底层的渲染功能,无法直接嫁接到我们的渲染引擎当中。

2.给 iTown 写一个中间件

优势:iTown 底层是基于 Threejs 的,起码能看懂,好嫁接
劣势:iTown 本身不成熟,即使整合成功可能会面临额外工作

3.使用 loaders.gl 加载成功后,直接写入渲染引擎

优势:开发起来自由灵活,类似自研
劣势:对 tiles 的加载几乎需要自己实现。

最终,考虑到最终客户对于稳定性的需求,以及研发时间的限制,决定选择 CesiumJS 整合这条路径。然后经过一番深入的研究发现这条路实际也是道阻且长,网上仅搜索到了几篇文章谈到了 ThreeJS 和 CesiumJS 的整合方式。
(1) 直接将两个 Canvas 叠加到一起,并同步相机实现。这种实现方式远不能满足我们深度整合的需求。
(2) 采用 CesiumJS 的 DrawCommand 来实现 ThreeJS 的渲染底层,这种方式整合程度更深,但我们本身已经在自己的渲染引擎中做了太多的定制,几乎不可能在这个时候迁移到 CesiumJS 的 DrawCommand 当中去。

那么有没有既不需要动目前的渲染引擎底层,又不至于像是两个 Canvas 这种非常浅的整合方式呢?当然是有的。
实际上,无论是 CesiumJS 还是类似 ThreeJS,他们底层目前都是基于 WebGL/WebGL2 绘制到 Canvas 来实现的(WebGPU 还远没有成熟),那么我们是不是可以直接在一个 Canvas 让 CesiumJS 先画,ThreeJS 后画呢?答案显然是可以的。但是我们依然会面临非常多的整合问题和技术难关,这个我在后面的系列文章中会逐一给大家解释。