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

时间:2017-02-27 10:33:01

标签: mapbox mapbox-gl-js

我使用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

2 个答案:

答案 0 :(得分:13)

有两个主要问题:

<强> 1。如何将地图画布作为图像?

实际上,你做的是正确的,但是太早了。在触发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

答案 1 :(得分:2)

我为任何绊倒这个帖子的人创建了一个简单的工作示例:

(感谢@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>