星期一的早上,我在办公区鸟瞰窗外,目光所到之处,用顾城的那首“你看天时很近,看我时很远”倒是格外的应景。作为一名父亲,看着工位上3M的口罩,想想此刻还在熟睡的孩子,多少有些无奈——又是PM25指数200+的一天。这么大的中国,如何给孩子找一方净土,让孩子能够健康快乐的成长。正是带着这样的一个想法,我查询了几个我比较关注的城市的PM值,比如北京,成都,杭州,深圳,厦门等地方,都不理想,一种赶尽杀绝的节奏,难道在中国只能做君子,自强不吸?同时,我个人发现一个情况,我的手机是华为荣耀6plus,天气数据显示来自中国天气网,PM25指数相比AQI(Air Quality Index)上的要偏低。比如我所在的城市成都,此刻手机上显示PM25指数为162,而AQI上显示为212,对比如下:
这个过程中,体现了我对数据的三点需要:实时性,准确性和易对比。首先数据必须是准确的,及时的,这样最有价值,这两点不难理解。易对比的涵义则比较宽泛,并没有一个绝对的标准。首先数据量上要丰富,这样客观上才有有代表性,其次可视化上要便于理解,比如数据都有自己的大小和位置,如何形象高效的展现这些信息,怎样把数字更好的转化为易于人类感官理解的形式,最后就是一个抽象的过程,提炼有价值的数据,降低过多数据带来的噪音。当然,我在做这个小应用的时候并没有考虑这么多,只是做完后自己的总结知新,看似有用,实则完全为了提升逼格。
带着这些疑问,我个人认为,AQI的数据是全球各个监测站的数据,更原始一些,更具有代表性和权威性,在中国呆久了,如果不对政府提供的数据有怀疑,只能证明自己too young too naive了。所以很自然的觉得AQI的数据在准确性和实时性上是目前的最佳选择。而且我知道某网站上是有实时的全球的AQI数据,反编译代码获取里面请求数据的方法应该可行。所以,从技术上是可以搞定数据需求的。
有了数据,可视化上如何展示呢,如何找到一种直观,简单的形式来?作为一个GIS行业的码农Coder(以前我并不介意码农这个称呼,但工作时间越久,发现真的大部分程序员只配做码农,所以本着谦让的态度,还是把这个称号让给他们吧),当然要在地图上展示了。这是某网站上的一个展示效果,也是我的参照物,这里通过地图来解决对经纬度的理解,通过数字和颜色来解决对PM指数的感官体验:
但从细节处,我觉得还可以做到更好,第一,地图本身就是对地球的一次抽象,因此这个抽象过程中,在数据的形象和对比上是存在损失的,第二,该网站的技术较为传统,数据都是以HTML标签的形式来展现,在数据较大的情况下存在性能的瓶颈,第三,如下图,按照AQI的标准来做的颜色区分,但这个Level是区间分段的方式,而不是单值的一一映射的关系。比如PM值300和500是有差别的,但却对应同一个颜色,可以更好的体现这种差别。
当我看到这里就想到用球的形式来展现全球的PM数据,应该会有一个不错的视觉效果,而且也可以很好的体现WebGL在大数据渲染上的性能优势,这是吸引我的一个因素。同时我觉得雾霾目前是一个大众比较关注的问题,所以不应该只是我一个人的小众喜好,对很多人或地球人而言都是一个兴趣点,坦白说,我当时觉得想想就好,上班了,撞钟时间开始了。这时候是罗胖的一句话开导了我“如果一件事情可做可不做,而你又有时间做的话,那你最好去做,万一有什么意料之外的收获的,这就是机会”。开工。
首先就是反编译某网站的JS代码,把请求PM数据的url和参数规范找到,url里面竟然有key参数,所以就得看看在自己的环境下是否能走通。说明一下,据我了解,该网站是一个在中国北京?居住的外国人搞的,而且数据比较敏感,毕竟有损墙国形象,我从AirNow网站取到的中国数据才几十个监测点,就可以看到墙国对该数据的重视程度。所以我是出于尊重该网站,钦佩作者的这种精神而刻意不分享。而如果你有这个能力做到这个事情,也希望你能够保护它而不是谋私。有了数据,直接在WebGL Earth下展现的效果:
这样一个完整的流程算是走通了,下面就是渲染效果了。最开始,我是希望能做成热点图那种效果的,午饭时间也在思考这个问题,主要是原始数据结构,还有工作量两个要素,对这样一个实时的数据做全球的热点图,至少需要服务端能够对数据存储策略和传输方式上做优化,假设全球有10万个监测点(远远大于实际数),位置,监测站名称这类不会频繁变更的内容,都可以放在配置文件中,通过ID来索引,唯一变化的就是pm25这个数值,一个unsigned short就足够了,这样全球数据就是10万字节,约等于100K,这样数据量就小太多了,完全可以做到实时的全球范围的数据传输,而目前json格式,基于可视范围的呆滞型传输就不行了。服务端怎么来做这个优化呢,其实可以每小时做一次更新,生成一张纹理图片,纹理值就是pm的数值,以后还有其他数据,比如pm10,臭氧或硫化物,风向等都是一个思路,这样也是一个不错的数据优化策略。所以,不管你怎么绕,最后服务端不吊你,你也没辙。
WebGL的优势在于能够发挥显卡的性能,所以尽管在数据传输和解析上需要受限于服务端,但在渲染上还是有不错的自由度,退而求其次,根据PM25值做一个点的单值专题图,也是可接受的。通过批次,即使点数据量很大,渲染上并不会造成瓶颈。于是我决定选择点+颜色的展现效果,其实这就和某网站的展现方式很相似了。总得做出一个微创新吧,那好,你是分段专题图效果,只有6个颜色,我就给你搞一个渐变颜色(如上图),这个也难不倒我,先搞一个0~500的色带,其实就相当于一个哈希表,然后根据PM值对号入座,有了PM值->颜色这个映射表,只需要初始化时先创建色带的消耗而没有额外的计算,算是性能优化上的一个技巧。这是目前的效果,依次为中国&日韩,欧洲和美国,看完后整个人的心情都不好了:
如上,基本上要做的都已经结束了,但实际浏览的时候还是会有卡顿的现象。当然,我可以归咎到请求的数据是JSON格式,而Earth浏览的范围都比较大,且是实时的,所以这是性能瓶颈。我个人也觉得这是一个很充分的理由。计算需要消耗,请求需要等待,但通过Workers技术,可以把这部分放到线程中,避免卡顿的效果。这也是前端代码可以优化的一点。于是昨天晚上我又对代码进行了优化,把大量的请求,渐变色计算,json解析等工作都放到Workers线程来完成,主线程主要负责Earth球本身的内容。至此,我觉得对于这样一个应用,可以告一段落了。
总结这个过程,我觉得有三点收获,第一,无论简单还是复杂的事情,在理论上都要讲的通,模型是简单的,这个范例级别的应用,本质上就是AQI+颜色分段,所以AQI数值要具有准确实时易对比的特点,同时颜色的意义也是有依据的,不是自己凭空捏造的。第二,目前各类实时数据很多,数据固然有价值,但该应用的本质并不是获取数据,而是过滤数据,是对数据的一次加工,在广度和深度上抓住数据对人类有价值的部分。我觉得在大数据时代,获取数据的渠道会很多,数据固然重要,但关键还在于过滤数据的能力,这种应变能力可以有效的降低噪音,通过数据的加工而产生服务价值。
第三点可能有点牵强,但我最想借题发挥了,所以单独列出来。前几天听了吴军讲的众筹经济,吴军老师通过滴滴,Airbnb举例说明通过资源的有效整合扩大了市场的规模,分析了未来经济的发展趋势。个人认为,所谓的众筹,如何能够突破零和博弈,通过市场规模的扩大而达到共赢,要做到这点并不容易。正好在TED里听到的一个老外的演讲,也举了滴滴,Uber和Airbnb的例子,我觉得总结的更深刻。关键在于信任(Trust):首先,你要认可这个想法,愿意尝试,其次,你认可这个平台,愿意使用,最后,基于已有的这种认可,基于这个平台,你愿意相信你不认识的人。通过这三个层次的信任达到共赢,可以有效整合资源,别人能够更容易的得到有价值的资源,自然也愿意购买这种资源,这样的良性循环可以更好的扩大市场规模。套用这个想法,如果我继续做这个PM的应用,该怎样继续呢?首先,PM值是当下大众很关心的一个内容,如何高效,及时,准确,全面,形象的,有针对性的展现出来,这个想法是有价值的,从这个点子来看是经得起考验的。其次,要做一个有影响力的平台,除了数据的权威性,其次就是数据的统计分析可视化以及个性化,比如历史数据的推演,预报预警,多样的可视化效果,通过服务端了解用户的焦点,基于位置的个性化推送,内容深度和广度的综合性,提高大家对平台的认可。
好了,以上就是一个大概流程和本人事后的思考,虽然并不能改变什么现状,但我想,环保面前,人人无法逃避,人人都可以尽力而为。对我个人而言,如果不能用手改变,那就只好用脚改变了。