Mapbox GL JS:将地图导出为 PNG 或 PDF?

Mapbox GL JS: Export map to PNG or PDF?

我正在使用 Mapbox GL JS 0.32 版。有没有办法将地图导出为高分辨率 PNG 或 PDF?

当然,我只能截图,但如果有更正式的方式就更好了。

我找到了 this repo,但它看起来很旧而且不清楚它是如何工作的。

我尝试使用 the preserveDrawingBuffer option:

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/light-v9',
    minZoom: 4,
    maxZoom: 14,
    center: [-2.0, 53.3],
    preserveDrawingBuffer: true
});
console.log(map.getCanvas().toDataURL());

这会在控制台中输出一个长数据 URL,但是将其复制并粘贴到 a base64 converter 中似乎只会生成一个空图像。

更新:这是我的新代码,完整的:

mapboxgl.accessToken = 'pk.eyXXX';
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/light-v9',
    minZoom: 4,
    maxZoom: 14,
    center: [-2.0, 53.3],
    preserveDrawingBuffer: true
});
var dpi = 300;
Object.defineProperty(window, 'devicePixelRatio', {
    get: function() {return dpi / 96}
});

map.on('load', function () {
    var content = map.getCanvas().toDataURL();
    console.log(content)
});

控制台的输出是这样的:http://pastebin.com/raw/KhyJkJWJ

主要有两个问题:

1.如何获取地图 canvas 作为图像?

事实上,你做的是对的,只是太早了。当 load 事件被触发时,给地图一些时间来加载和获取图像数据:

map.on('load', () => console.log(map.getCanvas().toDataURL()));

2。如何获得高分辨率图像?

通过根据目标 dpi 更改 window.devicePixelRatio,您可以诱使浏览器生成高分辨率输出。我在 Matthew Petroff 创建的实现中找到了该解决方案,请参阅他在 https://github.com/mpetroff/print-maps 上的代码。 这是他用于生成高分辨率输出的技巧:

Object.defineProperty(window, 'devicePixelRatio', {
    get: function() {return dpi / 96}
});

Source

我为遇到此问题的任何人创建了一个简单的工作示例:

(感谢@Vic 指出 Mapbox GL JS 中的 preserveDrawingBuffer-选项)

<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8' />
    <title>Display a map</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css' rel='stylesheet' />
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <style>
    #map {
        margin: auto;
        width: 400px;
        height: 400px;
    }
    </style>
</head>

<body>
    <div id='map'></div>
    <a id="downloadLink" href="" download="map.png">Download ↓</a>
    <div id="image"></div>
    <script>
    mapboxgl.accessToken = 'your-token-here';
    var map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/streets-v9',
        center: [-74.50, 40],
        zoom: 9,
        preserveDrawingBuffer: true
    });

    $('#downloadLink').click(function() {
        var img = map.getCanvas().toDataURL('image/png')
        this.href = img
    })
    </script>
</body>

</html>