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