Mapbox GL JS: экспортировать карту в PNG или PDF?
Я использую Mapbox GL JS версии 0.32. Есть ли способ экспортировать карту в PNG с высоким разрешением или PDF?
Очевидно, я могу просто скриншот, но было бы неплохо, если бы был более формальный способ.
Я нашел это репо, но он выглядит старым и непонятно, как это работает.
Я попытался использовать параметр preserveDrawingBuffer
:
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-адрес данных в консоли, но копирование и вставка его в конвертер base64, похоже, создает пустой образ.
UPDATE: Это мой новый код, в полном объеме:
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
Есть два основных вопроса:
1. Как я могу получить холст карты как изображение?
На самом деле, вы делаете правильные вещи, но слишком рано. Дайте этой карте некоторое время для загрузки и извлечения данных изображения при load
события load
:
map.on('load', () => console.log(map.getCanvas().toDataURL()));
2. Как я могу получить это изображение в высоком разрешении?
Изменяя window.devicePixelRatio
соответствии с вашим целевым dpi, вы можете обмануть свой браузер, создавая вывод с высоким разрешением. Я нашел это решение в реализации, созданной Мэтью Петроффом, см. Его код на https://github.com/mpetroff/print-maps. Это трюк, который он использует для генерации высокого разрешения:
Object.defineProperty(window, 'devicePixelRatio', {
get: function() {return dpi / 96}
});
Источник
Ответ 2
Я создал простой рабочий пример для любого, кто наткнулся на этот поток:
(Спасибо @Vic за указание preserveDrawingBuffer
-option в MapBox GL JS)
<!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>