1

I am using OpenLayer to show the map on website. On map I put a tile info with some information.

        <div class="row">
            <div id="map" class="map">
                <pre id="info" />
            </div>
        </div>

I have an option to download the view of the map

$("#DownloadMapBtn").on('click', function () {
    canvas = document.getElementsByTagName('canvas')[0];
    canvas.toBlob((blob) => {
        saveAs(blob, "map.png");
    });
});

As you can see, I am downloading only canvas, and canvas doesnt have a tile info inside. How can I download both on one image? Source code with map looks like this:

<div id="map" class= "map">
    <pre id="info" > ... </pre>
    <div class="ol-viewport">
        <canvas>
        ...
    </div>
</div>

the idea of tile is taken from example on OpenLyer website

Thank You for help in advance.

EDIT: Thanks to @Mike (thanks!) I almost got what I need. The only thig is that I do not now what to set a grey background around the place where I set data. Checkout photos.

This is what I have what I have

This is what I need

what I need

EDIT2: I did! The code below.

InsertToCanvas = (function() {
    var canvas = $('canvas').get(0); 
    var font = 13 + 'px Courier New';

    function WriteScaletoCanvas(e) {
        var ctx = e.context;
        ctx.beginPath();
        ctx.textAlign = "left";

        ctx.lineWidth = 3;
        ctx.font = font;
        var infosplitted =[];
        infoAreasCanvas.forEach((elem, ind, arr) => { 
            if(elem.length > 45){                
                var splitText = splitter(elem, 45);
                splitText.forEach((elem, ind, arr) => {
                    infosplitted.push(elem)
                })
            }else
                infosplitted.push(elem)
        });
        var leninfosplitted = infosplitted.length;
        if(infoAreasCanvas.length > 0){
            ctx.fillStyle = '#ccd3d3d3';
            ctx.fillRect(0,canvas.height - (leninfosplitted * 14) - 5 , 45 * 8, leninfosplitted * 25 + 10 );
        }
        ctx.fillStyle = "#000";
        infosplitted.forEach((elem,ind,arr) => {
            ctx.fillText([elem], 5 , canvas.height - (leninfosplitted - ind) * 13 + 5);
        });

    }
    function postcompose() {
        map.on('postcompose', function (evt) {
            WriteScaletoCanvas(evt);
        });
    }
    return {
        postcompose : postcompose
    };
})();

InsertToCanvas.postcompose();
user0810
  • 886
  • 5
  • 19
  • 33
  • 2
    You would need to mirror your info panel on the canvas. Similar to how the scale line is done here https://www.kreidefossilien.de/webgis/dokumentation/beispiele/export-map-to-png-with-scale and scaleline and attributions here https://viglino.github.io/ol-ext/examples/canvas/map.canvas.control.html To see how to format text on canvas take a look at the ol-ext source for CanvasAttribution and CanvasTitle https://viglino.github.io/ol-ext/dist/ol-ext.js – Mike Feb 25 '19 at 20:02
  • Thanks @Mike your suggestion helped a lot. I have only one more issue (explaned above). Do you know where I could find solution? – user0810 Feb 26 '19 at 14:00
  • 1
    For word wrapping you would need to break the text into words and check the length. Some examples https://stackoverflow.com/questions/49614129/wrap-text-within-rect-without-overflowing-it-fiddle-canvas-html5 https://codepen.io/vostok/pen/zwQMzL – Mike Mar 08 '19 at 17:55
  • You helped again, thank You. The last question - do you know how to delete this from canvas? I mean leave the map, only clear the text and this grey backgroud I wrote on the map – user0810 Mar 11 '19 at 18:23

1 Answers1

1

To stop you would need to cancel the postcompose listener, then either force a render or simply wait until the map next re-renders itself. If you wanted to keep everything in your InsertToCanvas namespace this might work:

var evtkey;
function postcompose() {
    evtkey = map.on('postcompose', function (evt) {
        WriteScaletoCanvas(evt);
    });
}
function unpostcompose() {
    ol.Observable.unByKey(evtkey);
    map.render();
}
return {
    postcompose : postcompose,
    unpostcompose : unpostcompose
};
Mike
  • 16,042
  • 2
  • 14
  • 30