TransWikia.com

QGIS2web Export open layers map as PDF, PNG or JPEG

Geographic Information Systems Asked on May 18, 2021

I want to have an option to export my map as the PDF

I would like to use the example from here:

https://openlayers.org/en/latest/examples/export-pdf.html

but it doesn’t work unfortunately. All the issues have been described here:

https://github.com/tomchadwin/qgis2web/issues/934

it looks like I need to set the server for this.

Here is also the solution:

https://talk.observablehq.com/t/save-a-map-openlayers/2598

which I don’t really understand

I think everything is related to the issue here:

https://github.com/openlayers/openlayers/issues/10593

In all the cases I can’t use the stuff

 import 'ol/ol.css';
 import Map from 'ol/Map';

and so on, because I am getting an error:

because the console says:

Cannot use import statement outside a module

related to this query:

https://stackoverflow.com/questions/58211880/uncaught-syntaxerror-cannot-use-import-statement-outside-a-module-when-import

https://github.com/TypeStrong/ts-node/issues/922

https://github.com/vercel/next.js/discussions/15957

I found another hint here:

Export map with legend using OpenLayers 6

but seems to be not suitable for my case

In the other side, the code presented here:

https://stackoverflow.com/questions/64823306/save-openlayers-map-as-pdf

returns the blank PDF document.

enter image description here

The final question is – does anyone know how to export map from Openlayers to PDF, PNG or JPEG without any import operator and additional server requirements?

I could need something like this:

https://codepen.io/barbalex/pen/raagKq

One Answer

You do not need to use imports, you can use the full build syntax in your code instead, where https://openlayers.org/en/latest/doc/quickstart.html is equivalent to https://openlayers.org/en/latest/examples/simple.html

So the Export PDF example becomes:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css" type="text/css">
    <style>
      .map {
        width: 100%;
        height:400px;
      }
      .map {
        max-width: 566px;
      }
    </style>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
    <title>Export PDF example</title>
</head>
<body>
    <div class="row-fluid">
      <div class="span12">
        <div id="map" class="map"></div>
      </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="300">300 dpi (slow)</option>
      </select>
    </form>
    <button id="export-pdf">Export PDF</button>
<script>

var raster = new ol.layer.Tile({
  source: new ol.source.XYZ({
    url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
    crossOrigin: 'anonymous'
  }),
});

var format = new ol.format.WKT();
var feature = format.readFeature(
  'POLYGON((10.689697265625 -25.0927734375, 34.595947265625 ' +
    '-20.1708984375, 38.814697265625 -35.6396484375, 13.502197265625 ' +
    '-39.1552734375, 10.689697265625 -25.0927734375))'
);
feature.getGeometry().transform('EPSG:4326', 'EPSG:3857');

var vector = new ol.layer.Vector({
  source: new ol.source.Vector({
    features: [feature],
  }),
  opacity: 0.5,
});

var map = new ol.Map({
  layers: [raster, vector],
  target: 'map',
  view: new ol.View({
    center: [0, 0],
    zoom: 2,
  }),
});

var dims = {
  a0: [1189, 841],
  a1: [841, 594],
  a2: [594, 420],
  a3: [420, 297],
  a4: [297, 210],
  a5: [210, 148],
};

var exportButton = document.getElementById('export-pdf');

exportButton.addEventListener(
  'click',
  function () {
    exportButton.disabled = true;
    document.body.style.cursor = 'progress';

    var format = document.getElementById('format').value;
    var resolution = document.getElementById('resolution').value;
    var dim = dims[format];
    var width = Math.round((dim[0] * resolution) / 25.4);
    var height = Math.round((dim[1] * resolution) / 25.4);
    var size = map.getSize();
    var viewResolution = map.getView().getResolution();

    map.once('rendercomplete', function () {
      var mapCanvas = document.createElement('canvas');
      mapCanvas.width = width;
      mapCanvas.height = height;
      var mapContext = mapCanvas.getContext('2d');
      Array.prototype.forEach.call(
        document.querySelectorAll('.ol-layer canvas'),
        function (canvas) {
          if (canvas.width > 0) {
            var opacity = canvas.parentNode.style.opacity;
            mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
            var transform = canvas.style.transform;
            // Get the transform parameters from the style's transform matrix
            var matrix = transform
              .match(/^matrix(([^(]*))$/)[1]
              .split(',')
              .map(Number);
            // Apply the transform to the export map context
            CanvasRenderingContext2D.prototype.setTransform.apply(
              mapContext,
              matrix
            );
            mapContext.drawImage(canvas, 0, 0);
          }
        }
      );
      var pdf = new jsPDF('landscape', undefined, format);
      pdf.addImage(
        mapCanvas.toDataURL('image/jpeg'),
        'JPEG',
        0,
        0,
        dim[0],
        dim[1]
      );
      pdf.save('map.pdf');
      // Reset original map size
      map.setSize(size);
      map.getView().setResolution(viewResolution);
      exportButton.disabled = false;
      document.body.style.cursor = 'auto';
    });

    // Set print size
    var printSize = [width, height];
    map.setSize(printSize);
    var scaling = Math.min(width / size[0], height / size[1]);
    map.getView().setResolution(viewResolution / scaling);
  },
  false
);

   </script>
</body>
</html>

Note I have changed OSM to XYZ, if you are not using an OpenLayers source such as OSM which defaults to crossOrigin it is important to specify the crossOrigin option as tainted canvas cannot be exported.

Correct answer by Mike on May 18, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP