本示例演示按给定比例导出地图.
本示例演示按给定比例导出地图。 本示例使用 jsPDF 库将地图导出为 PDF。 跟 Export PDF example 不一样的是,此屏幕上的地图只用来设置中心点和旋转。 地图打印依赖于设置的比例和页面尺寸。 为了打印比例尺和属性,本示例使用了 html2canvas 库。
import Map from 'ol/Map.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
import WMTS, {optionsFromCapabilities} from 'ol/source/WMTS.js';
import WMTSCapabilities from 'ol/format/WMTSCapabilities.js';
import proj4 from 'proj4';
import {ScaleLine, defaults as defaultControls} from 'ol/control.js';
import {getPointResolution, get as getProjection} from 'ol/proj.js';
import {register} from 'ol/proj/proj4.js';
proj4.defs(
'EPSG:27700',
'+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 ' +
'+x_0=400000 +y_0=-100000 +ellps=airy ' +
'+towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 ' +
'+units=m +no_defs'
);
register(proj4);
const proj27700 = getProjection('EPSG:27700');
proj27700.setExtent([0, 0, 700000, 1300000]);
const raster = new TileLayer();
const url =
'https://tiles.arcgis.com/tiles/qHLhLQrcvEnxjtPr/arcgis/rest/services/OS_Open_Raster/MapServer/WMTS';
fetch(url)
.then(function (response) {
return response.text();
})
.then(function (text) {
const result = new WMTSCapabilities().read(text);
const options = optionsFromCapabilities(result, {
layer: 'OS_Open_Raster',
});
options.attributions =
'Contains OS data © Crown Copyright and database right ' +
new Date().getFullYear();
options.crossOrigin = '';
options.projection = proj27700;
options.wrapX = false;
raster.setSource(new WMTS(options));
});
const map = new Map({
layers: [raster],
controls: defaultControls({
attributionOptions: {collapsible: false},
}),
target: 'map',
view: new View({
center: [373500, 436500],
projection: proj27700,
zoom: 7,
}),
});
const scaleLine = new ScaleLine({bar: true, text: true, minWidth: 125});
map.addControl(scaleLine);
const dims = {
a0: [1189, 841],
a1: [841, 594],
a2: [594, 420],
a3: [420, 297],
a4: [297, 210],
a5: [210, 148],
};
// export options for html2canvase.
// See: https://html2canvas.hertzen.com/configuration
const exportOptions = {
useCORS: true,
ignoreElements: function (element) {
const className = element.className || '';
return (
className.includes('ol-control') &&
!className.includes('ol-scale') &&
(!className.includes('ol-attribution') ||
!className.includes('ol-uncollapsible'))
);
},
};
const exportButton = document.getElementById('export-pdf');
exportButton.addEventListener(
'click',
function () {
exportButton.disabled = true;
document.body.style.cursor = 'progress';
const format = document.getElementById('format').value;
const resolution = document.getElementById('resolution').value;
const scale = document.getElementById('scale').value;
const dim = dims[format];
const width = Math.round((dim[0] * resolution) / 25.4);
const height = Math.round((dim[1] * resolution) / 25.4);
const viewResolution = map.getView().getResolution();
const scaleResolution =
scale /
getPointResolution(
map.getView().getProjection(),
resolution / 25.4,
map.getView().getCenter()
);
map.once('rendercomplete', function () {
exportOptions.width = width;
exportOptions.height = height;
html2canvas(map.getViewport(), exportOptions).then(function (canvas) {
const pdf = new jspdf.jsPDF('landscape', undefined, format);
pdf.addImage(
canvas.toDataURL('image/jpeg'),
'JPEG',
0,
0,
dim[0],
dim[1]
);
pdf.save('map.pdf');
// Reset original map size
scaleLine.setDpi();
map.getTargetElement().style.width = '';
map.getTargetElement().style.height = '';
map.updateSize();
map.getView().setResolution(viewResolution);
exportButton.disabled = false;
document.body.style.cursor = 'auto';
});
});
// Set print size
scaleLine.setDpi(resolution);
map.getTargetElement().style.width = width + 'px';
map.getTargetElement().style.height = height + 'px';
map.updateSize();
map.getView().setResolution(scaleResolution);
},
false
);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Print to scale example</title>
<link rel="stylesheet" href="node_modules/ol/ol.css">
<style>
.map {
width: 100%;
height: 400px;
}
.wrapper {
max-width: 566px;
width: 100%;
height: 400px;
overflow: hidden;
}
</style>
</head>
<body>
<div class="wrapper">
<div id="map" class="map"></div>
</div>
<form class="form">
<label for="format">Page size </label>
<select id="format">
<option value="a0">A0 (slow)</option>
<option value="a1">A1</option>
<option value="a2">A2</option>
<option value="a3">A3</option>
<option value="a4" selected>A4</option>
<option value="a5">A5 (fast)</option>
</select>
<label for="resolution">Resolution </label>
<select id="resolution">
<option value="72">72 dpi (fast)</option>
<option value="150">150 dpi</option>
<option value="200" selected>200 dpi</option>
<option value="300">300 dpi (slow)</option>
</select>
<label for="scale">Scale </label>
<select id="scale">
<option value="500">1:500000</option>
<option value="250" selected>1:250000</option>
<option value="100">1:100000</option>
<option value="50">1:50000</option>
<option value="25">1:25000</option>
<option value="10">1:10000</option>
</select>
</form>
<button id="export-pdf">Export PDF</button>
<!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
<script src="./resources/elm-pep.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.3.1/jspdf.umd.min.js"></script>
<script type="module" src="main.js"></script>
</body>
</html>
{
"name": "print-to-scale",
"dependencies": {
"ol": "7.3.0",
"proj4": "2.8.1"
},
"devDependencies": {
"vite": "^3.2.3"
},
"scripts": {
"start": "vite",
"build": "vite build"
}
}