potree--加载二进制格式文件
针对二进制文件的处理,potree里面用到了第三方库plasio和Laszip,palsio是一个针对las、laz格式点云数据处理的js库,Potree里面的plasio主要包括以下几个部分:
其中laslaz.js主要负责数据的解析,bluebird主要是负责数据的异步加载,laz-loader-worker是一个数据加载的多线程解决方案;
首先介绍一下bluebird.js,bluebird是一个较好的Promises第三方库,bluebird几乎可以在所有的平台上运行,而且不会增加额外的开销;
什么是Promises?ES6中新增的一块内容,下面借用其他人的一些说法解释一下Promise:
MDN:The Promise
object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.
Promises象征着一个异步操作的最终结果。
到底什么是Promise?
Promise是抽象异步处理对象以及对其进行各种操作的组件。 其详细内容在接下来我们还会进行介绍,Promise并不是从JavaScript中发祥的概念。
Promise最初被提出是在 E语言中, 它是基于并列/并行处理设计的一种编程语言。
Promises交互主要通过它的then方法,then方法接受一个回调函数,这个回调函数接受执行成功的返回值或执行失败的错误原因,错误原因一般是Error对象。需要注意的是,then方法执行的返回值是一个Promise对象,而then方法接受的回调函数的返回值则可以是任意的JavaScript对象,包括Promises。基于这种机制,Promise对象的链式调用就起作用了。
Promises的状态
Promise对象有三种状态:pending(初始状态)、fulfilled(成功执行)、rejected(执行出错)。pending状态的Promise对象可以转换到其它两种状态。
附上一本电子书网址,比较详细的介绍了Promises,http://liubin.org/promises-book/
Web Workers 简介
至 2008 年 W3C 制定出第一个 HTML5 草案开始,HTML5 承载了越来越多崭新的特性和功能。它不但强化了 Web 系统或网页的表现性能,而且还增加了对本地数据库等 Web 应用功能的支持。其中,最重要的一个便是对多线程的支持。在 HTML5 中提出了工作线程(Web Workers)的概念,并且规范出 Web Workers 的三大主要特征:能够长时间运行(响应),理想的启动性能以及理想的内存消耗。Web Workers 允许开发人员编写能够长时间运行而不被用户所中断的后台程序,去执行事务或者逻辑,并同时保证页面对用户的及时响应。
Web Workers 为 Web 前端网页上的脚本提供了一种能在后台进程中运行的方法。一旦它被创建,Web Workers 就可以通过 postMessage 向任务池发送任务请求,执行完之后再通过 postMessage 返回消息给创建者指定的事件处理程序 ( 通过 onmessage 进行捕获 )。Web Workers 进程能够在不影响用户界面的情况下处理任务,并且,它还可以使用 XMLHttpRequest 来处理 I/O,但通常,后台进程(包括 Web Workers 进程)不能对 DOM 进行操作。如果希望后台程序处理的结果能够改变 DOM,只能通过返回消息给创建者的回调函数进行处理。
二进制文件加载
HTML5里面引进了ArrayBuffer以便可以直接操作二进制文件,JS原生代码操作二进制文件的效率要比Array数组高得多,MDN里面这样解释:The ArrayBuffer
object is used to represent a generic, fixed-length raw binary data buffer. You cannot directly manipulate the contents of an ArrayBuffer
; instead, you create one of the typed array objectsor a DataView
object which represents the buffer in a specific format, and use that to read and write the contents of the buffer.(ArrayBuffer对象是一个固定长度的初始化二进制数据缓冲区,不能直接对ArrayBuffer里面的内容进行操作,但是,可以通过类型化数组和视图对象去读和写缓冲区里面的内容);
Potree里面对bin格式的二进制文件处理方法如下图:
通过XMLHttpRequest的获取得到buffer,然后对buffer进行相关的处理,如下图:
首先创建了Worker对象,并给它指定了Javascript脚本文件——/workers/BinaryDecoderWorker.js,并且给Worker对象绑定了一个“onmessage”事件。该事件会在后台代码(BinaryDecoderWorker.js)向页面返回数据时触发。
“onmessage”事件可以通过event.data来获取后台代码传回的数据。最后,postMessage方法正式执行BinaryDecoderWorker.js,该方法还可以向后台代码传递参数(message, [message.buffer]), 后台代码同样通过onmessage事件获取该参数。
同样的,对于las、laz格式二进制文件处理大同小异,总结起来就是:ArrayBuffer + bluebird + worker + plasio,首先通过xhr把二进制文件进行读取。而读取的过程是放在worker里面的,同时Promise来控制多个load之间的异步关系,再加上Potree.LasLazBatcher()、Potree.LasLazLoader()等函数,整个二进制文件的加载以及转换成pointAttribute就完成了;