最近在折腾的 web 端的可视化项目,因为相关业务的须要,用到了 Mapbox 这一地图开发的神器。在此先奉上一个基于mapbox-gl实现的demo(来源:uber的deck.gl项目):前端
下面咱们从这个项目一步步来介绍 Mapbox 的前端 GIS 引擎 Mapbox GL JS.react
首先,Mapbox 在地图领域是一家很 Newbee 的公司。已为 Foursquare、Pinterest、Evernote、金融时报、天气频道、优步科技 等公司的网站提供了订制在线地图服务。git
自2010年起,该公司快速地拓展了订制地图的市场地位,以回应 Google地图 等地图供应商提供的有限选择。Mapbox 是一些开放源代码地图库及应用程序的建立者或最大的贡献者,其中包含了MBTiles 规范、TileMill 制图 IDE、Leaflet JavaScript 库,以及 CartoCSS 地图格式化语言与语法分析器等。github
该公司的数据同时从开放与专有的来源获取,开放的数据源如 开放街图(OSM, Open Street Map) 以及 NASA 等,而专有的数据源则包含了 DigitalGlobe。其技术奠定于 Node.js、CouchDB、Mapnik、GDAL 与 Leafletjs。web
Mapbox 针对不一样平台均开发了相应的 GIS 引擎以知足开发者或相关用户的须要,如:iOS SDK(用于iOS端开发)、Android SDK(用于Andriod端开发)、Navigation SDK(用于Navigation端开发)、Unity SDK(用于Unity端开发)、GL JS(用于web端开发)。不一样平台的SDK,除使用方式不一样外,功能特性上也多多少少存在不一样。此外,Uber还针对react开发了 react-map-gl。总的来讲,Mapbox的开源技术栈是很是全面的。docker
mapbox-gl 的 文档 由 API、Style Specification、Example、Plugins 四部份内容组成。json
顾名思义,API 是通常框架(类库)提供给用户的所有接口(方法)的说明书;Style Specification 是 Mapbox 地图的样式规范;Example 是一些经常使用功能或常见业务的代码示例,囊括了使用 Mapbox 所能实现的大部分功能效果;Plugins 则是官方推荐的可与 mapbox-gl 一同使用的一些增效插件和开源项目,如一些第三方的UI控件、显示类插件、框架集成工具、开发辅助工具、实用工具类库等等。api
对于初了解 Mapbox 的童鞋,建议先从官网的 Example 入手,可以较快掌握 mapbox-gl 的使用并投入开发实践。负载均衡
下面以文章开头展现的项目为主,介绍其实战步骤。框架
因为使用在线地图服务和 style
时须要验证用户 token
,因此在使用 mapboxgl
时须要先配置用户 token
(在Mapbox官网注册用户便可获取)。
import mapboxgl from 'mapbox-gl'; mapboxgl.accessToken = '<Your Token Here>';
接下来使用建立地图实例。主要配置项以下:
const myMap = new mapboxgl.Map({ container: '<Id of Container Element>', style: '<Your Style Here>', center: [112.508203125, 37.97980872872457], zoom: 4, pitch: 0, bearing: 0, });
其中,container
是地图容器的元素 id
,style
是地图样式的 url
,或者你本身定义的 style
(需遵循Mapbox样式规范),center
是地图加载后默认的中心点位置,用以定位地图加载时的位置。zoom
pitch
bearing
分别指缩放级别、地面法线偏移角、地轴偏移角等,用以肯定当前视窗所显示的地图区域和空间关系。配置项的意义都可查看官网文档。
这里主要介绍视频中的3D建筑、飞线动画等是如何实现的。这里以相关代码片断来介绍实践的方法。
在Mapbox中绘制图形时, layer
和 source
是最重要的一组概念,后者用于存储图形的数据内容,前者则是图形在3D场景中的表现(图层)。在Mapbox中,图层一旦被建立,与其同名(id
相同)的数据源源(即source
)也必然被建立。反之,也能够在建立source后再建立一个图层使用这个已建立的数据源,这时数据源与图层间并不要求同名。而咱们经过改变数据来驱动图形变化,即是才去的第二种方式:
// 建立id为buildings的数据源 myMap.addSource('buildings', { type: 'geojson', data: '<GeoJson Contents>', }); // 使用buildings的数据来绘制id为building_layer的图形 myMap.addLayer({ id: 'building_layer', type: 'fill-extrusion', source: 'buildings', ...<Other Options>, });
基于上面的方式,当数据改变时,咱们只须要重设数据源的数据,便可驱动图层重绘:
if (myMap.getLayer('building_layer')) { myMap.getSource('buildings').setData(<New GeoJson Contents>); }
至于3D效果及动画的具体实现,这里给出两个官网上的示例,相信你们能一目了然:
i. 用3D形式呈现建筑
ii. 给路径中的一个点添加动画效果
Mapbox提供的交互方法是比较灵活的,活学活用API文档便能实现各类炫酷、实用的交互效果。好比:使用myMap.on('zoom', callback)
能够将图形与地图的缩放相绑定,当缩放系数小于某个值时,能够隐藏掉一些图形元素:
myMap.on('zoom', () => { if (myMap.getZoom() <= 4) { myMap.setLayoutProperty('building_layer', 'visibility', 'none'); } else { myMap.setLayoutProperty('building_layer', 'visibility', 'visible'); } });
再好比,连续调用 myMap.flyTo()
的方法使视图在地图上按照必定的轨迹缓慢移动,能够给用户一种模拟飞行的体验。视频中的自动巡视的效果正是这样实现的。
诸如 click
mouseover
popup
等效果,官网文档中的示例已经具体呈现,这里就不详细展开了。
因为 Mapbox 地图服务使用 MBTiles 存储数据,目前不少地图服务都接受了这套标准(如:OSM,Open Street Map)。因此能够经过搭建本身的 tiles-server 以替代直接使用 Mapbox 的在线地图服务。
这样作的好处是显而易见的:一是能够经过负载均衡等手段提升数据接口的访问速度,有效提升数据的加载速度;一是保障应用能在零带宽的环境下仍能有效部署和使用。
这里墙裂安利一个docker开源镜像:openmaptiles-server ,在其 官网 和 dockerhub 上都可下载。我的认为其最大的亮点在于——即便不了解内部实现,也不影响其使用。
运行 tiles-server 服务的 docker 命令以下:
$ docker run --rm -it -v $(pwd):/data -p 8080:80
而后剩下来须要作的事情就是打开其导航页面 http://localhost:8080/(端口号取决于你的启动命令),而后跟着页面上的提示一步一步设置就行了(最后一步设置后会从OSM走动下载地图,因此一开始你不用担忧数据从哪来),彻底是傻瓜式的部署。
在 Mapbox GL 实践的过程当中,发现了一些影响应用总体性能的因素,故而在此陈述一番,为以后填坑的童鞋提供一些经验:
i. 在 http 请求先后对数据进行合理的压缩和解压,以尽量节省 http 请求传输的数据量;
ii. 条件容许的状况下,可将一组数据分片加载,以空间换时间。
mapboxgl.Marker
来添加标记,其性能不如使用 type
为 symbol
类型的图层来添加标记。缘由在于前者生成的标记是一个个 DOM 元素,若是你能够想象在一个 web 页面中同时操做成百上千个 DOM 节点会是什么结果,那么你或许能明白个人建议。最后,在此总结下我的对 Mapbox 的一些感观。
Mapbox 的产品定位是随时随地的 GIS(跨平台、应用),它为咱们提供了一系列的简单操做的 API,使得 GIS 开发变得灵活而有趣。尤为对于开发 GIS 类型的数据可视化应用,Mapbox 是绝佳的选择。
然而,若是你只是为了那些绚丽的 3D 效果的话,或许选择专门的框架更为合适。