查看原文
其他

故事 | Uber 如何做地理信息数据可视化?附案例源码

Mapbox 2019-06-01

你知道吗?Uber的开源工具 Deck.gl 和 Mapbox GL JS 经常被组合使用,可以创建炫酷的地理信息可视化效果。

deck.gl + Mapbox 的效果

Deck.gl 的 MapView 可以与 Mapbox 协同工作, 两个库中相同的相机设置(中心,缩放,间距和方位)可以进行无缝匹配, 在几乎所有的地理空间数据应用程序中,Mapbox都被用作 deck.gl 可视化层的背景。

这为更紧密集成的地理空间可视化开辟了许多新的可能性。

例如,可以在Mapbox的基础地理和标签图层之间插入 deck.gl GeoJSON 图层,这样填充的多边形不再妨碍地图的可读性; Deck.gl 的弧形图层和Mapbox的建筑物图层可以同时出现在城市的空域,3D 元素也可以正确地相互遮挡。

deck.gl 和 Mapbox gl js单独使用原理


deck.gl 和 Mapbox gl js结合使用原理

具体来说,Uber在deck.gl的V6.2版本中推出了新的模块@deck.gl/mapbox, 您可以到Github上研究开源代码,也可以继续看下面的快速上手教程。

🔥
快速上手教程

全新的实验类MapboxLayer是Mapbox GL JS的自定义图层界面的实现,我们可以使用nmp导入。


npm install @deck.gl/mapbox
import {MapboxLayer} from ‘@deck.gl/mapbox’;

或者使用 deck.gl standalone bundle

<script src=”https://unpkg.com/deck.gl@^6.2.0/deckgl.min.js"></script>
<script src=’https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js'></script>
<script type=”text/javascript”>
const {MapboxLayer} = deck;
</script>

MapboxLayer的实例可以通过map.addLayer()加载到Mapbox图层中。这一步,官网有详细的教程。


使用deck.gl图层作为Mapbox附加组件

您可以使用deck.gl的图层目录中的任何图层类型及其相应的道具制作MapboxLayer:

import {ScatterplotLayer} from '@deck.gl/layers';
import {MapboxLayer} from '@deck.gl/mapbox';
import mapboxgl from 'mapbox-gl';

// Get a mapbox API access token
mapboxgl.accessToken = '<your access token here>';

// Initialize mapbox map
const map = new mapboxgl.Map({
 container: 'map',
 style: 'mapbox://styles/mapbox/streets-v9',
 center: [-74.50, 40],
 zoom: 9
});

// Create a mapbox-compatible deck.gl layer
const myDeckLayer = new MapboxLayer({
 id: 'my-scatterplot',
 type: ScatterplotLayer,
 data: [
   {position: [-74.5, 40], size: 10000}
 ],
 getPosition: d => d.position,
 getRadius: d => d.size,
 getColor: [255, 0, 0]
});

// Insert the layer before mapbox labels
map.on('load', () => {
 map.addLayer(myDeckLayer, 'waterway-label');
});

一个可以学习的Demo

请注意:以这种方式使用时,不支持基于WebGL2的deck.gl功能,例如属性转换和GPU加速聚合。

将Mapbox添加到deck.gl React应用程序

修改正在工作的deck.gl React应用,并集成Mapbox并不难,下面是简单的步骤:

  1. 将应用程序的react-map-gl依赖项升级到版本4.0.0-beta。 这个版本允许我们提供为Mapbox创建的deck.gl的WebGL环境。

  2. 像往常一样将图层传递到<DeckGL />组件中。

  3. 加载Mapbox地图时,我们通过引用deck.gl堆栈中现有图层的ID来创建MapboxLayers并将其添加到Mapbox中。


import React from 'react';
import DeckGL, {ScatterplotLayer} from 'deck.gl';
import {StaticMap} from 'react-map-gl';

import {MapboxLayer} from '@deck.gl/mapbox';

const INITIAL_VIEW_STATE = {
 longitude: -74.50,
 latitude: 40,
 zoom: 9
};

export class App extends React.Component {
 state = {};

 // DeckGL and mapbox will both draw into this WebGL context
 _onWebGLInitialized = (gl) => {
   this.setState({gl});
 }

 // Add deck layer to mapbox
 _onMapLoad = () => {
   const map = this._map;
   const deck = this._deck;
   map.addLayer(new MapboxLayer({id: 'my-scatterplot', deck}), 'waterway-label');
 }

 render() {
   const {gl} = this.state;
   const layers = [
     new ScatterplotLayer({
       id: 'my-scatterplot',
       data: [
         {position: [-74.5, 40], size: 10000}
       ],
       getPosition: d => d.position,
       getRadius: d => d.size,
       getColor: [255, 0, 0]
     })
   ];

   return (
     <DeckGL
       ref={ref => {
         // save a reference to the Deck instance
         this._deck = ref && ref.deck;
       }}
       layers={layers}
       initialViewState={INITIAL_VIEW_STATE}
       controller={true}
       onWebGLInitialized={this._onWebGLInitialized}
     >
       {gl && (
         <StaticMap
           ref={ref => {
             // save a reference to the mapboxgl.Map instance
             this._map = ref && ref.getMap();
           }}
           gl={gl}
           mapStyle="mapbox://styles/mapbox/light-v9"
           mapboxApiAccessToken="<your access token here>"
           onLoad={this._onMapLoad}
         />
       )}
     </DeckGL>
   );
 }
}

📖

几个案例

就像在文章《Custom Layers | 一行代码生成炫酷的可视化地图,别错过这款 Uber 开源工具》中提到的那样,这样的可视化方案已经集成到了实际案例中,例如:

可视化英国的道路交通事故情况

该可视化案例描绘了1979年至2016年英国的人身伤害交通事故。它使用deck.gl的HexagonLayer来汇总每个六边形单元边界内的数据。 HexagonLayer插入Mapbox的标签图层下方。

这个案例比较突出的地方是3D拉伸,为可视化显示新增了维度。

案例源码

可视化美国的县城迁徙情况

该可视化案例显示了2009 - 2013年间美国的县到县迁移。 将鼠标悬停在地图上可查看进出特定区域的人员。 它使用自定义的deck.gl图层,根据鼠标位置过滤弧线。这个案例比较突出的地方是弧线轨迹绘制,之前并没有很好的工具支持这一点。

案例源码9a46f

不妨跟着上面的案例,一起学习一下Uber的可视化效果吧,感受如何将地理空间数据可视化扩展新的维度:更灵活、更轻量、更美观。

如果你还是觉得比较晕,不妨尝试一下这个Uber官方的Demo

👀相关阅读

数据可视化5个例子,Atlas 帮你的数据在私有云上「自由可视化」

教程 | 选情数据可视化,一张地图展示中期选举动态(上)

刚刚!亚马逊 Alexa Auto 集成了 Mapbox 地图和导航服务


您还可以在下面的渠道持续关注我们哦。



微博

@Mapbox地图数据平台,或者tag #mapbox# 



知乎

@Mapbox中国


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存