0

How would I adapt @ghettovoice JSFiddle that saves a map to PDF to save the map to a JPEG or PNG? I have no idea how to attempt this problem so ideally if you know hoe to do it you can explain the logic behind it.

        exportMap: function () {
            var map = this.$refs.map

            map.once('rendercomplete', function () {
                var mapCanvas = document.createElement('canvas');
                var size = map.getSize();
                mapCanvas.width = size[0];
                mapCanvas.height = size[1];
                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);
                    }
                }
                );
                if (navigator.msSaveBlob) {
                // link download attribuute does not work on MS browsers
                navigator.msSaveBlob(mapCanvas.msToBlob(), 'map.png');
                } else {
                var link = document.getElementById('image-download');
                link.href = mapCanvas.toDataURL();
                link.click();
                }
            });
            map.renderSync();

        }

Curious
  • 383
  • 3
  • 13
  • 1
    The example you linked is based on https://openlayers.org/en/v5.3.0/examples/export-pdf.html There is an equivalent example https://openlayers.org/en/v5.3.0/examples/export-map.html for exporting a png. If you are using OpenLayers 6 you should check the latest examples as they have changed significantly. – Mike Jun 03 '21 at 17:24
  • Thank you so much for the lead however I am sort of new to Vue plugins and where I get stuck is to try and hook up the Vue.js `data`, `methods`, `computed` and `mounted` to the OpenLayers wrapper `vuelayers`. How do you import the functions listed in the example from `vuelayers`? – Curious Jun 03 '21 at 17:54
  • @Mike Sorrt to bother but how would you import specific OpenLayers Functions from Vuelayers? Even Ghettovoice imported OpenLayers in his example JSFiddle. – Curious Jun 04 '21 at 13:58
  • 1
    Updated JSFiddle https://jsfiddle.net/4dougeqy/1/ – Mike Jun 04 '21 at 14:32
  • @Mike I get `Uncaught DOMException: Failed to execute 'toBlob' on 'HTMLCanvasElement': Tainted canvases may not be exported.` using your solution sir. Even after installing fakerator and FileSaver. I also tried to `canvas.setAttribute('crossOrigin', 'anonymous');` – Curious Jun 04 '21 at 14:55
  • 1
    You would have had the same error when exporting a PDF. The crossOrigin option must be set on layer sources where it is not already the default (such as OSM and Bing) to avoid tainted canvas. – Mike Jun 04 '21 at 15:10
  • Thank yes you were right setting the crossorigin to null fixed it for me and I learned something new about WMSs today. – Curious Jun 04 '21 at 15:36

1 Answers1

0

The problem was a combination of missing dependencies (namely FileSaver.js and fakerator.js) and a cross origin server block (CORS block) (Browsers automatically prevent httpRequests to a different domain name unless the server allows it). The first one is fixed by installing the packages while the second one is resolved by setting the crossOrigin Attribute of the ImageWMSLayer to null in my case but possibly to 'Anonymous' for other sources. Hope this helped someone else :)

Curious
  • 383
  • 3
  • 13