最近在折腾的 web 端的可视化项目,由于相关业务的需要,用到了 Mapbox 这一地图开发的神器.在此先奉上一个基于 mapbox-gl 实现的 demo 短片(来源: uber 的 deck.gl 项目 ):
下面我们从这个项目一步步来介绍 Mapbox 的前端 GIS 引擎 Mapbox GL JS .
一,简单了解
首先,Mapbox 在地图领域是一家很 Newbee 的公司.已为 Foursquare,Pinterest,Evernote,金融时报,天气频道,优步科技 等公司的网站提供了订制在线地图服务.
自 2010 年起,该公司快速地拓展了订制地图的市场地位,以回应 Google 地图 等地图供应商提供的有限选择.Mapbox 是一些开放源代码地图库及应用程序的创建者或最大的贡献者,其中包含了 MBTiles 规范,TileMill 制图 IDE,Leaflet JavaScript 库,以及 CartoCSS 地图格式化语言与语法分析器等.
该公司的数据同时从开放与专有的来源获取,开放的数据源如 开放街图(OSM, Open Street Map) 以及 NASA 等,而专有的数据源则包含了 DigitalGlobe.其技术奠基于 Node.js,CouchDB,Mapnik,GDAL 与 Leafletjs.
Mapbox 针对不同平台均开发了相应的 GIS 引擎以满足开发者或相关用户的需要,如:iOS SDK(用于 iOS 端开发),Android SDK(用于 Andriod 端开发),Navigation SDK(用于 Navigation 端开发),Unity SDK(用于 Unity 端开发),GL JS(用于 web 端开发).不同平台的 SDK,除使用方式不同外,功能特性上也多多少少存在不同.此外,Uber 还针对 react 开发了 react-map-gl .总的来说,Mapbox 的开源技术栈是非常全面的.
二,轻松上手
mapbox-gl 的 文档 由 API,Style Specification,Example,Plugins 四部分内容组成.
顾名思义,API 是一般框架 (类库) 提供给用户的全部接口(方法)的说明书;Style Specification 是 Mapbox 地图的样式规范;Example 是一些常用功能或常见业务的代码示例,囊括了使用 Mapbox 所能实现的大部分功能效果;Plugins 则是官方推荐的可与 mapbox-gl 一同使用的一些增效插件和开源项目,如一些第三方的 UI 控件,显示类插件,框架集成工具,开发辅助工具,实用工具类库等等.
对于初了解 Mapbox 的童鞋,建议先从官网的 Example 入手,能够较快掌握 mapbox-gl 的使用并投入开发实践.
三,快速实践
下面以文章开头展示的项目为主,介绍其实战步骤.
1. 加载地图:
由于使用在线地图服务和 style 时需要验证用户 token,所以在使用 mapboxgl 时需要先配置用户 token(在 Mapbox 官网注册用户即可获取).
接下来使用创建地图实例.主要配置项如下:
import mapboxgl from 'mapbox-gl';
mapboxgl.accessToken = '<Your Token Here>';
其中,container 是地图容器的元素 id,style 是地图样式的 url,或者你自己定义的 style(需遵循 Mapbox 样式规范),center 是地图加载后默认的中心点位置,用以定位地图加载时的位置.zoom pitch bearing 分别指缩放级别,地面法线偏移角,地轴偏移角等,用以确定当前视窗所显示的地图区域和空间关系.配置项的意义均可查看官网文档.
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,
});
2. 绘制图形
这里主要介绍视频中的 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 > ,
});
至于 3D 效果及动画的具体实现,这里给出两个官网上的示例,相信大家能一目了然:
if (myMap.getLayer('building_layer')) {
myMap.getSource('buildings').setData( < New GeoJson Contents > );
}
* i. 用 3D 形式呈现建筑
* ii. 给路径中的一个点添加动画效果
3. 图形交互
Mapbox 提供的交互方法是比较灵活的,活学活用 API 文档便能实现各种炫酷,实用的交互效果.比如:使用
myMap.on('zoom', callback)
可以将图形与地图的缩放相绑定,当缩放系数小于某个值时,可以隐藏掉一些图形元素:
再比如,连续调用 myMap.flyTo() 的方法使视图在地图上按照一定的轨迹缓慢移动,可以给用户一种模拟飞行的体验.视频中的自动巡视的效果正是这样实现的.
myMap.on('zoom', () = >{
if (myMap.getZoom() <= 4) {
myMap.setLayoutProperty('building_layer', 'visibility', 'none');
} else {
myMap.setLayoutProperty('building_layer', 'visibility', 'visible');
}
});
诸如 click mouseover popup 等效果,官网文档中的示例已经具体呈现,这里就不详细展开了.
4. tiles-server 的本地化
由于 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 实践的过程中,发现了一些影响应用整体性能的因素,故而在此陈述一番,为之后填坑的童鞋提供一些经验:
使用 geo 数据(如 GeoJson 格式数据)来定义图形的时候,若数据量过大,则会拖慢数据加载的速度,此时可考虑:
i. 在 http 请求前后对数据进行合理的压缩和解压,以尽可能节省 http 请求传输的数据量
ii. 条件允许的情况下,可将一组数据分片加载,以空间换时间
在 Mapboox 中绘制的图层不宜过多,一是不方便管理(当然,github 上有很多管理 Mapbox 图层的第三方工具),一是图层过多会明显降低 GL 的渲染和响应性能.所以在绘制图形前,可以先考虑一下图层的划分,以最少的图层实现尽可能多的效果.
数据量相同的情况下,使用 mapboxgl.Marker 来添加标记,其性能不如使用 type 为 symbol 类型的图层来添加标记.原因在于前者生成的标记是一个个 DOM 元素,如果你可以想象在一个 web 页面中同时操作成百上千个 DOM 节点会是什么结果,那么你或许能明白我的建议.
五,一点总结
最后,在此总结下个人对 Mapbox 的一些感观.
Mapbox 的产品定位是随时随地的 GIS(跨平台,应用),它为我们提供了一系列的简单操作的 API,使得 GIS 开发变得灵活而有趣.尤其对于开发 GIS 类型的数据可视化应用,Mapbox 是绝佳的选择.
然而,如果你只是为了那些绚丽的 3D 效果的话,或许选择专门的框架更为合适.
——————————————————————————————————————
来源: https://juejin.im/post/5a56d42c51882573432d1259