Mapbox GL JS 设计浅析
这是WebGIS引擎设计浅析系列中的第一篇,之后还会发布Leaflet和OpenLayers 3的设计浅析。把自己的分析和思考共享出来供大家讨论,为我们自己F3Earth设计提供参考。
Mapbox太牛逼了,在此就不用介绍了,不了解的请google。它推出的前端GIS引擎Mapbox GL JS值得我们学习,下面就是自己的一些总结。错误和不详的地方请各位大神多多指正,谢谢。
能表达整个Map的Style文件
mapbox-gl-js目前是围绕着style文件来进行的,其内容定义如下:
{
"version": 8,
"name": "Mapbox
Streets",
"sprite": "mapbox://sprites/mapbox/streets-v8",
"glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
"sources": {...},
"layers": [...]
}
从这里可以看到, 除了基本的属性定义之外,就是sources和layers。基本属性目前还不是很多,毕竟处于开发状态,
对具体属性感兴趣的可以参见 https://www.mapbox.com/mapbox-gl-style-spec/。 因为这不是我们要讲解的重点。
重点是mapbox正在通过这样一个style的配置文件来描述整个地图。这是目前其他map都没有使用的方式。在讨论如何设计实现这个目的之前, 我们想一下这样做有什么好处?最大的好处莫过于为自定义地图提供了方便之门。使用者压根可以不写任何代码,用mapbox就能做出一个自己想要的地图。这一点很符合mapbox目前提供的服务。这点提醒我们,设计最终还是为需求和业务服务的。而不是凭空想象的。style如此之重要,以至于官网专门对style进行详细了说明, 涉及到各个参数及作用。
Map的组成
任何GIS引擎必然要处理两部分, 一个是数据来源, 一个这些数据在界面呈现的样子。在style里面包含的source和layer对应于这两部分。
Source的设计
目前source支持vector,raster, geojson, image,video。geojson的支持比较巧妙,有了这个就可以处理各种矢量类型,包括集合。而前面的vector主要解决的是矢量瓦片,raster解决的是目前常用的栅格化的瓦片。video的加入使得功能更加的现代化。 mapbox在style里面,为source定义了一个type属性,来说明这些类型。
除了这个属性之外,source其实都有一个id,被layer引用,从而让数据源和数据呈现关联在一起。 这个地方需要注意的是,source和layer之间的关系,可以是1->n, 设计如此,为什么?结合下面的Layer的设计来看就明白了。
Layer的设计
分类
再来看layer的设计,虽然也是分为几类的,但并不是直接根据source来分类的。这一点你或许没有想到吧。我只能说mapbox开启了新的一种layer样式方式。目前分为:background,fill, line, symbol, raster, circle。除了background类型的layer不需要绑定source之外。其他的都需要有source。fill类型的layer只负责填充;line类型的layer只负责线条;symbol类型的layer会处理sprite,文字等;raster类型的layer就只负责图片, circle类型的layer是更高一层的业务处理需要。
大致看一下分类方式,肯定会有点莫名其妙。为什么要这样来分类?
首先想想各种界面,不就是点线面组成的吗? layer其实代表的就是界面,只是大家通常会认为一个layer上会放置各种点,线,面。 mapbox把这种layer再细分层了更小的单元, 只包含点的layer,只负责呈现线的layer,只负责面的layer。如果把多个layer组合在一起,就和现在的通用想法的layer是一样的,source和layer的1->n关系在这个地方发挥作用了。Okay,虽然功能上是能实现,但是为什么要搞的这么细分?
原因在于这样实现上就简单了,关键是可以提高效率,能批量化的渲染。只能说mapbox团队真的很牛,能从最贴近用户的需求到实现的最底层整个过程的东西都考虑进去来进行设计。 在很多时候, 少量的规则会带来很大的收获,关键在于找到一个折中的实现。这样设计虽然可能给使用上带来一点不快,但还是能接受的。
Filter
Layer 除了上面这个牛逼的设计之外,mapbox也充分考虑了个别特殊元素的定制化显示需求:如果要对一批元素中的某些个别元素进行定制化呈现,可以在layer里面设置filter,满足条件的元素才会被呈现出来,并用layer设定的样式渲染。filter是一个很强大的功能,有效融合在设计中,可以解决很多问题。OpenLayers 3真的可以借鉴一下这个。
结束语
Mapbox GL JS设计的精彩部分基本就到此结束了。什么?就完了? API都还没有说呢? 不好意思,style文件才是核心,API只是围绕着这个核心服务的, 所以也就可想而知了, 想看看具体有哪些API, 可以参见 https://www.mapbox.com/mapbox-gl-js/api 。
除此之外,Mapbox GL JS还可以支持plugin,提供了对应的接口, 和leaflet类似,但这部分的精彩,还是放在Leaflet的部分来讲解吧。