MapBox GL 地图页面保存为图片的方法
MapBox GL没有自带的截图api,在github上有人写了一个控件 https://github.com/geolonia/mbgl-export-control。
但控件只能以固定的方式使用,本人做了一下改动:
核心代码如下:
1 import 'canvas-toBlob' 2 import FileSaver from 'file-saver' 3 import mapboxgl from 'mapbox-gl' 4 5 function setStyles (element, styles) { 6 for (const style in styles) { 7 element.style[style] = styles[style] 8 } 9 } 10 11 export default function (map, name) { 12 const actualPixelRatio = window.devicePixelRatio 13 Object.defineProperty(window, 'devicePixelRatio', { 14 get: () => 300 / 96 15 }) 16 17 const _container = document.createElement('div') 18 document.body.appendChild(_container) 19 20 const width = map.getContainer().offsetWidth 21 const height = map.getContainer().offsetHeight 22 // const bottomRight = map.unproject([width, height]).toArray() 23 24 setStyles(_container, { 25 visibility: 'hidden', 26 position: 'absolute', 27 top: 0, 28 bottom: 0, 29 width: `${width}px`, 30 height: `${height}px` 31 }) 32 33 let fontFamily = [] 34 if (map.style.glyphManager && map.style.glyphManager.localIdeographFontFamily) { 35 fontFamily = map.style.glyphManager.localIdeographFontFamily 36 } 37 38 let MBGL = mapboxgl.Map 39 const _map = new MBGL({ 40 container: _container, 41 center: map.getCenter(), 42 zoom: map.getZoom(), 43 bearing: map.getBearing(), 44 pitch: map.getPitch(), 45 style: map.getStyle(), 46 localIdeographFontFamily: fontFamily, 47 hash: false, 48 preserveDrawingBuffer: true, 49 interactive: false, 50 attributionControl: false 51 }) 52 53 _map.once('load', () => { 54 _map.getCanvas().toBlob((blob) => { 55 FileSaver.saveAs(blob, name + '.png') 56 _map.remove() 57 _container.parentNode.removeChild(_container) 58 _loading.parentNode.removeChild(_loading) 59 Object.defineProperty(window, 'devicePixelRatio', { 60 get: () => actualPixelRatio 61 }) 62 }) 63 }) 64 }
说明:
1. 需要安装canvas-toBlob和file-saver,前者用于转换地图的canvas,后者用于把blob存储为图片;
mapbox-gl 是使用的地图库,如果基于ol或minemap的地图应用,引入相应的库即可
2. 截图的主要原理:
a.通过参数获取当前的map对象,得到div大小,地图的图层信息,地图状态的center、zoom、pitch和bearing等
b.新建一个和map对象容器一样大的div,在该div中创建新的地图对象,添加和原map对象一样的图层,设置相同的地图状态
注意,该新的div需要设置为隐藏状态,即 visibility: 'hidden'
c.获取新的地图对象的canvas,另存为图片
提供一种思路,可以修改后用于保存其他地图库,代码请参考:
https://github.com/shiyuan598/Map-Visualization/tree/master/mapbox-template