前言
作为一家自动驾驶前端,需要做一些炫酷的车辆HMI,3D可视化监控等。经常接触一些gis 和 webgl的框架是避免不了的。但是我司的无人驾驶和市面上大家所熟知的特斯拉,小鹏,蔚来这些还是不同的。主线科技大部分的业务是在港口,大家知道一般港口,政企这类的项目为了网络安全,一般是不允许接入外网的。所以一个公共库要解决多种业务场景(公网内网),不依赖外网可离线部署这一点非常重要。
一开始我们使用openlayers,离线使用,地图加载,geojson图形加载编辑,出色的性能都很符合我们的业务。但是openlayers只有2D显示,如果我们要做一个炫酷的3D的可视化地图这是远远不够的。那有没有既能符合我们业务,又有炫酷3D显示的方案吗?答案是肯定的,咱们接着往下看。
技术选型
框架需求
- 开源
- 可离线部署使用。
- 支持各种地图服务加载。
- 支持geojson。
- 支持3D显示,glb/gltf 模型显示、编辑。
- 出色的性能和已拓展性。
- 平滑的学习曲线。
- 良好的社区,issue修复速度。
已知的webgl && Gis框架
- Mapbox-gl.js
- Cesium.js
- Deck.gl
- MapTalks.js
- Three.js
值得一提的是three.js本身不属于gis,但是可以通过一些手段来实现我们的业务需求。而且mapbox和 maptalks 1.0.0以下版本,都算是外挂three.js实现的3D显示。综合我们的框架需求,我们最终选择了MapTalks。
MapTalks
MapTalks简介
首先要说的是MapTalks是由国人独立研发的WebGL三维地图。在国外地图框架霸榜,国内魔改开源卖钱的大环境下,能做出这样的成绩实属不易,仅凭这份勇气都值得我们点个赞。
MapTalks优势
- 性能优化:独立的底层实现保证了拥有更多的性能优化手段。
- 呈现效果:基于PBR的材质系统,让三维地图的呈现效果拥有了无限的可能。
- MapTalks是基于开放数据格式构建的,不会让用户受限于特定的数据格式或服务。
MapTalks新旧版本对比
v1.0.0版本相比旧版,除了性能大幅度提升,还增加了很多新的功能和特性:
比如GeoJSONVectorTileLayer,3dtitle等,最重要的一点是这一次自身添加了对3D模型的渲染,包括hdr全局环境光,天空盒,天气效果,常用后处理泛光抗锯齿 空间反射 动画等等。老版本是通过社区一个热心大佬基于three.js实现的这些功能,性能和效果也是相当的出色,当然在新版本也得以了保留。 详情请查阅maptalks.three: deyihu.github.io/maptalks.th…
这就体现了MapTalks的另一个优点。版本升级这么大,但是API还兼容老版本的(@three.js 好好学学!)这对于项目升级迭代无疑减少了大量的时间。以下就是我司业务对新老版本的使用的一个简单对比,新特性新功能远不于此,更多详情请查看官方文档:maptalks.com/
MapTalks配套工具
MapTalks IDE MapTalks: 集成设计环境,三维地图场景设计软件
MapTalks Designer: 矢量底图的配色软件
目前处于公测阶段,大家可以免费尝鲜。后期可能要收费吧,毕竟人家是要吃饭的。你可以理解这就是个低代码平台,动动手指就能轻松实现各种特效,哪怕你不懂代码,也可以!
优化两三事
即使再好的框架,也会因为使用不当导致你的项目达不到预期效果。尤其在webgl这类的项目,性能优化是重中之重。一个不留神,CPU,GPU消耗和温度都上去了,效果再牛逼机器挺不住了。下面我就说一下我们的优化策略和一些注意事项。
- 首先第一步打开开发者选项性能监视器。一旦出现cpu暴涨;JS堆大小,DOM接点只增不减的情况,那一定要格外注意,这会导致你的页面崩溃。可能是你的代码出现了问题,要认真断点排查
-
linux环境,假如你的生产环境是linux。千万注意显卡驱动是否正常,或者规定生产环境的硬件配置和系统版本。因为运行webgl项目时,浏览器会调用显卡资源,当你显卡驱动不正常时浏览器webgl就报错,项目大概率会出现运行不起来会是卡死情况。
-
模型的性能优化,尽可能减少模型不可见或者不必要的点线面,浏览器绘制模型点越多对机器的性能消耗越大。
-
模型的加载,考虑网络流量因素建议转换成GLTF或者fbx这类的二进制模型,使用promise.all 加上加载动画,提升用户体验。如果是局域网带宽足够,不是特大模型不建议压缩模型,因为解压缩本身就需要一定的性能消耗。
-
事件注册,setTimeout,setInterval,requestAnimationFrame,地图实例等在组件销毁时一定要注意解绑和销毁。
-
模型动画处理时,能用requestAnimationFrame坚决不使用setInterval,当浏览器达不到设定的调用周期时,requestAnimationFrame采用跳过某些帧的方式来表现动画,虽然会有卡滞的效果但是整体速度不会拖慢,而setInterval会因此使整个程序放慢运行,但是每一帧都会绘制出来。还有一点但你不在当前页面时requestAnimationFrame会自动休眠程序,setInterval则会一直执行,当你的电脑性能不够时就会出现页面崩溃的现象。下面是个小例子:
let s = 0;
let a = 0;
setInterval(() => {
s++;
console.log("setInterval", s);
}, 16);
function animation() {
a++;
requestAnimationFrame(animation);
console.log("requestAnimationFrame", a);
}
animation();
-
涉及到数据组装计算,多层循环处理时,合理使用webworker,为渲染主线程分担压力。
-
使用vue,react频繁更新数据,模型动画操作时,要做好数据对比,避免重复数据一直触发。因为这不涉及虚拟dom,框架不会为你做diff对比。
-
数据量大且请求频繁,建议使用websockt+protobuf代替http+json,减少单帧数据量大小,提升稳定度
还有很多等我想起来在补充吧。
总结
总的来说无论从易用性,拓展性,和效果MapTalks是一款非常出色的webgl三维地图框架,但是由于当前版本公测,包的引入还是有些繁杂,没有TS支持,有一些BUG,还不是足够稳定。但是官方团队一直在倾听大家的意见积极改进,没准你还会获取zhen神的专属版本。公测阶段可以理解,我们愿意给国人自主研发的优秀框架多一些时间。本篇文章我就不对API做介绍了,因为官方本身就非常详细用心,有各种各样的示例和API共大家查阅。
MapTalks官网:maptalks.com/
MapTalks核心库:maptalks.org/
MapTalks.three 插件:deyihu.github.io/maptalks.th…
QQ群:971657972