使用 MapBox GL 的数据驱动地图(带有底图和快速的等值线图)

Data Driven Maps using MapBox GL (choropleth with base map and fast)

tl;dr 版本:我们如何使用 MapBox GL 构建快速等值线图?

@RyanBaumann 发布了一个示例: 参见 https://ryanbaumann.squarespace.com/blog/2016/1/23/mapbox-gl-create-data-driven-styles

但是这个例子显示直接在 javascript 中加载 GeoJSON 文件。一个关于如何处理大型 GeoJSON 文件的问题。假设您有一个 18M 的 GeoJSON 文件。并且您想查看地图和 Data-Driven 样式并高效地完成这一切。

例如,我加载了一个大的 GeoJSON 文件:

https://cityregister.firebaseapp.com/recentsaleslocal.geojson

在此 mapbox 样式中:

https://api.mapbox.com/styles/v1/fedex1/cijrx09ej007o90lx1g1m5b0j.html?title=true&access_token=pk.eyJ1IjoiZmVkZXgxIiwiYSI6ImNpam5jZXZvczAwZnd0b201ajhybXE0OW8ifQ.IumX7VWjU71UjEsKTN4bdw#11/40.7060/-73.9754

它会立即加载,并且不会在加载时通​​过网络传输整个 18M。

但是当我使用 Ryan 展示的方法时,似乎我必须在加载时通​​过网络加载整个 18M 文件。这要慢得多,尤其是在慢速网络上。

我想知道有没有办法让 data-driven 样式和来自 mapbox 的底图都在同一张地图上?

这里有几个例子:

https://cityregister.firebaseapp.com/map.html(立即加载,有底图,全部驻留在 mapbox studio 服务器上。无 data-driven 样式

https://cityregister.firebaseapp.com/testmapboxlayerchoropleth.html(加载速度很慢,有底图,mapbox上的底图,另一台服务器上的geojson。使用data-driven样式 https://cityregister.firebaseapp.com/testmapboxlayerchoropleth.html(立即加载,没有底图,似乎都是 mapbox-gl 生成的,使用 data-driven 样式。

我的问题是如何获得 mapbox 的速度和 data-driven 样式以及带有街道的底图等

谢谢。

上面的地图图片。

快速纽约地图但不是 data-driven


fast nyc choropleth 但没有底图


缓慢的 choropleth 通过网络加载 18M


您可以在服务器端对 GeoJSON 文件进行编码,然后在客户端使用 TopoJSON 再次对其进行解码。这应该会减少您的带宽,从而提供不错的速度提升。

TopoJSON is an extension of GeoJSON that encodes topology. Rather than representing geometries discretely, geometries in TopoJSON files are stitched together from shared line segments called arcs. TopoJSON eliminates redundancy, offering much more compact representations of geometry than with GeoJSON; typical TopoJSON files are 80% smaller than their GeoJSON equivalents. In addition, TopoJSON facilitates applications that use topology, such as topology-preserving shape simplification, automatic map coloring, and cartograms.

这并不涵盖所有的绘画和布局属性(这里正在积极开发完整的数据驱动样式:https://github.com/mapbox/mapbox-gl-js/pull/1932)但是...

如果您将 GeoJSON 文档上传到您的 Mapbox 帐户,它将被转换为矢量切片。然后,您可以在 style.load 事件之后将其单独添加为一个图层:

map.on('style.load', function() {
  map.addSource('SOURCENAME', {
    "type": "vector",
    "url": "mapbox://mapbox.660ui7x6"
  });
});

在这个阶段,您有一个无样式层,您可以以数据驱动的方式向其添加绘画属性:

var layers = [
  ['#723122', 25000000],
  ['#B86B25', 5000000],
  ['#F2F12D', 0]
];

layers.forEach(function(layer, i) {
  map.addLayer({
    "id": "layer-" + i,
    "type": "fill",
    "source": "SOURCENAME",
    "source-layer": "original",
    "paint": {
      "fill-color": layer[0]
    },
    filter: i == 0 ?
      ['>=', 'population', layer[0]] :
      ['all',
        ['>=', "population", layer[0]],
        ['<', "population", layers[i - 1][0]]
    ]
  });
});

您要定位的 source-layer 可以从 mapbox 上的上传数据页面找到。com/data 或者从它的 tilejson 文档中找到:

https://a.tiles.mapbox.com/v4/mapbox.660ui7x6.json?access_token=<YOURACCESSTOKEN>

这里有一个例子可以说明这一点 https://www.mapbox.com/mapbox-gl-js/example/updating-choropleth/