Mapbox GL JS 设计浅析

作者: 猿基地 | 来源:发表于2016-06-19 13:31 被阅读3659次

这是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的部分来讲解吧。

相关文章

网友评论

  • 8e253418ddd8:请问MapBox GL 中.pbf格式的矢量切片行列号的算法是什么,或者在哪个文件中?
    8e253418ddd8:淡叔,如何将openlayers计算出来的矢量切片坐标编号(tileX, tileY)转成相应的WGS84坐标,或者将openlayers计算出来的矢量切片坐标编号(tileX, tileY)转成相应的mapbox矢量切片坐标编号(tileX, tileY)?
    8e253418ddd8:@猿基地 淡叔openlayers计算行列号的方式与mapbox不同,导致我在向后台请求数据时,将行列号传到后台时,计算出的地理范围有偏差,该如何解决?
    猿基地:@无量子_2167 谈不上什么算法,源码没有看到,但这就是一个分段索引,目的是为了减少一次传输的字体文件大小,如果觉得现在的分段后传输的字体文件还大了,可以自己找到源码调整,或者用其他加速方案,比如字体放本地,CDN,压缩等等
  • 四爷在此:突然又看到淡叔的这篇,看到 mapbox 为啥要给图层按照 fill, line, symbol 分类,应该是针对webgl 的批量渲染吧。。一个图层用一套shader,是这个意思吗?
    猿基地:@四爷在此 是的
  • 7dc0d83b2aa1:大神能不能修改mapbox源码,让他支持其他坐标系。 目前好像只有web墨卡托和wgs84.
    猿基地:@杨德龙_4092 想修改来着,但现在确实没时间
  • 技术笔记叔:Mapbox里面阿克赛钦、藏南和台湾都不属于中国怎么样解决这个问题?
    猿基地:建议看看本地化那篇文章,可以修改source的url成其他的底图
    猿基地:@流亡的重耳 不要用mapbox 的底图就行了
  • WHU_GIS_LJ:symbol类型的layer处理sprite,请问sprite是指的什么?
  • 2f81f7eed344:能不能解释一下 mapbox 和openlayers的关系啊都是webgis api吗
    猿基地: @我就是小春 都是webgis引擎,不同的团队开发的。都开源。

本文标题:Mapbox GL JS 设计浅析

本文链接:https://www.haomeiwen.com/subject/ldubdttx.html