Esri北京研发中心原创
Esri(北京)软件研发中心成立于2011年,它是Esri在美国之外成立的第一个研发中心,也是目前Esri海外最大的研发中心。
作者:Mr Teng
一直以来,在Web前端领域我们主要使用JavaScript语言来编写运行在浏览器上的Web应用。而浏览器作为运行平台,虽然其内部的JavaScript引擎在不断被优化,但限于JavaScript语言本身的一些特性,根本无法满足日益增长的应用性能需求。
WebAssembly(简称Wasm)是一种新型的二进制代码格式,包含这种二进制代码格式的文件可以用类似加载模块的方式被浏览器快速, 高效地解析和执行。它可以被分发在互联网上,只要位于用户端的浏览器支持WASM格式,用户便可以正常使用其中的功能。
基本原理
Wasm文件如何生成
C/C++ 源代码,通过Emscripten工具链编译为ASM.js 代码,然后通过Binaryen工具链中的asm2wasm工具将这些ASM.js代码转译成一个标准的Wasm模块。
浏览器如何解析
以chrome浏览器V8引擎为例。
V8引擎在处理Wasm模块时省略了大量Pipeline中的环节,引擎并不需要对Wasm模块的二进制进行优化。只需要把这些模块里的二进制代码直接加载到内存中,然后经过位于V8链路末端编译器后端的处理,最后生成的机器码便可以被浏览器直接执行。
从Wasm模块被浏览器加载到最后执行的整个过程并不需要很多的处理环节和系统资源开销, 这也是Wasm应用为何保持如此高性能的众多原因之一。
Wasm的优势
Wasm的优势在于:
速度
Wasm的目标是速度。它的二进制文件比 JavaScript 文本文件小得多。因而下载速度更快,这在网速低的时候尤为重要。WebAssembly 的解析和执行速度也更快。
可移植性
设计WebAssembly的主要目标之一是可移植性。使用 WebAssembly ,只需要一次编译,您的应用程序将可以在每个现代浏览器中运行。
灵活性
JavaScript 仍然是大多数用例的最佳选择,但是现在有可以在你真正需要提升性能的时候的提供一个额外的选项,使用某个特定的语言。UI 和 app 逻辑等部分可以依旧使用JavaScript,其中核心功能可以使用 Wasm。
了解了Wasm的原理和优势后,回到GIS的应用场景。实际业务里,地理数据量不断增加,实时性要求变高,从而对端的可视化与计算性能提出了更高的要求。笔者基于一些GIS业务中的需求,讨论了下Wasm可以应用的场景,同时也欢迎大家一起讨论。
Wasm在GIS的应用
一. 海量空间数据实时动态可视化
在一些业务里,轨迹数据(如车辆,人等)的可视化是重要的一环。例如展示某个市区里浮动车的实时运行状态。在这个场景下,需求拆分如下:
1.浮动车位置的展示;
2.浮动车运动状态动画绘制;
3.浮动车数据实时更新;
目前常见的做法是不断刷新地图上要素点的位置来达到可视化的效果。但这样的体验上,地图要素动画不平滑,并且大数据量容易造成端的崩溃。
因此,我们可以把空间计算和要素渲染等复杂计算逻辑提取在wasm模块去实现。端只需要调用相应模块。从而最大提升端上要素渲染速度,使轨迹运动更加流畅实时。
二.地理要素客户端上空间计算
除了地理要素的可视化,空间要素基于空间关系的查找与计算这一需求也很常见。例如,查找和过滤出某个面要素下的点元素。详情
在这个场景下,通常的做法有两种:
a. 通过远程服务,利用空间数据库的空间计算,检索出结果,客户端再根据结果去更新;
b. 利用前端的矢量库去进行空间计算,前端去更新,但大数据量下效率不高;
因此,我们可以把空间计算的逻辑模块抽取出来,使用c/c++源码编写,编译为wasm模块去实现。这样实现的好处在于, 空间分析可以在端上离线完成,同时相比前端矢量库效率更高。
三. 空间坐标系端上转换
与空间关系的计算类似,空间要素的坐标实时转换同样也可基于wasm去实现。虽然原生js同样可以实现坐标的转换,但是在大数据量下的批量转换时,往往会造成端的卡顿和奔溃。
例如@ne_fe/gis这个模块,它是一个前端高性能的经纬度转换库,该模块主逻辑由c++编写,并被编译为wasm。它提供了大批量坐标的经纬度转换功能,在十几万坐标点转换的情况下,依然有优秀的性能表现。
同样,ArcGIS API 4.x也提供了client-side projection engine。也是基于wasm实现。详情
四. 图像预处理
利用wasm,除了进行空间计算和地图渲染外,我们也可以进行一些图像处理。Demo体验
wasm的目的在于解决一些复杂的计算问题,优化 JavaScript 的执行效率。所以我们可以使用 Wasm 来处理一些图像或者矩阵的计算问题。我们可以通过Wasm来处理一些图像的卷积问题。大体流程如下:
将原图像使用 canvas 绘制到屏幕上。
a.使用 getImageData 获取图像像素内容,并转化成类型数组。
b.将上述类型数组通过共享内存的方式传递给 Wasm 部分。
c.Wasm 部分接收到数据,进行计算,并且通过共享内存的方式返回。
d.将最终结果通过 canvas 画布更新。
总结
虽然wasm有很多优势,但在实际应用中,我们也应该根据场景进行恰当的技术选型,把合适的计算以及渲染逻辑抽取出来为wasm模块去使用,使用不当的话,也可能会造成性能的下降甚至不如原生的实现,最合适的才是最好的。
“Esri北研”公众号版权所有