Merge pull request #10537 from mike-000/patch-3

Correct resolution used for scale bar and add dpi option
This commit is contained in:
Andreas Hocevar
2020-04-04 09:53:54 +02:00
committed by GitHub
5 changed files with 218 additions and 6 deletions
+1
View File
@@ -5,6 +5,7 @@
"common": false,
"createMapboxStreetsV6Style": false,
"d3": false,
"domtoimage": false,
"geojsonvt": false,
"GyroNorm": false,
"jsPDF": false,
+6
View File
@@ -0,0 +1,6 @@
.wrapper {
max-width: 566px;
width: 100%;
height: 400px;
overflow: hidden;
}
+47
View File
@@ -0,0 +1,47 @@
---
layout: example.html
title: Print to scale example
shortdesc: Example of printing a map to a specified scale.
docs: >
Example of printing a map to a specified scale.
The print is exported as a PDF using the <a href="https://github.com/MrRio/jsPDF" target="_blank">jsPDF</a> library.
Unlike the <a href="export-pdf.html">Export PDF example</a> the on screen map is only used to set the center and rotation.
The extent printed depends on the scale and page size. To print the scale bar and attributions the example uses the
<a href="https://github.com/1904labs/dom-to-image-more" target="_blank">dom-to-image-more</a> library. Due to browser
limitations and restrictions <b>Internet Explorer and Safari are not supported</b>.
tags: "print, printing, scale, scaleline, export, pdf"
resources:
- https://unpkg.com/dom-to-image-more@2.8.0/dist/dom-to-image-more.min.js
- https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js
---
<div class="wrapper">
<div id="map" class="map"></div>
</div>
<form class="form">
<label>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>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>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>
+128
View File
@@ -0,0 +1,128 @@
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import {defaults as defaultControls, ScaleLine} from '../src/ol/control.js';
import WMTSCapabilities from '../src/ol/format/WMTSCapabilities.js';
import TileLayer from '../src/ol/layer/Tile.js';
import {get as getProjection, getPointResolution} from '../src/ol/proj.js';
import {register} from '../src/ol/proj/proj4.js';
import WMTS, {optionsFromCapabilities} from '../src/ol/source/WMTS.js';
import proj4 from 'proj4';
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 html-to-image.
// See: https://github.com/bubkoo/html-to-image#options
const exportOptions = {
filter: function(element) {
const className = element.className || '';
return (
className.indexOf('ol-control') === -1 ||
className.indexOf('ol-scale') > -1 ||
(className.indexOf('ol-attribution') > -1 &&
className.indexOf('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;
domtoimage.toJpeg(map.getViewport(), exportOptions).then(function(dataUrl) {
const pdf = new jsPDF('landscape', undefined, format);
pdf.addImage(dataUrl, '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);