Search code examples
eclipseopenlayers-3

how to export openlayer3 map to png with its scale bar using js


i am trying to export openlayer3 map to png using canvas in js. Actualy map div and scale bar div is different so while export map to png how to draw scale bar and its legends on same png.


Solution

  • We need to create control and get control from html, then add it to canvas like this

    InsertToCanvas = (function() {
     //get the canvas element
    var canvas = $('canvas').get(0); 
    //get the Scaleline div container the style-width property
    var olscale = $('.ol-scale-line-inner');  
    //Scaleline thicknes
    var line1 = 6;
    //Offset from the left
    var x_offset = 10;
    //offset from the bottom
    var y_offset = 30;
    var fontsize1 = 15;
    var font1 = fontsize1 + 'px Arial';
    // how big should the scale be (original css-width multiplied)
    var multiplier = 2;
    
     /* go for it */
    function WriteScaletoCanvas(e) {
    var ctx = e.context;
    var scalewidth = parseInt(olscale.css('width'),10)*multiplier;
    var scale = olscale.text();
    var scalenumber = parseInt(scale,10)*multiplier;
    var scaleunit = scale.match(/[Aa-zZ]{1,}/g);
    
    //Scale Text
    ctx.beginPath();
    ctx.textAlign = "left";
    ctx.strokeStyle = "#ffffff";
    ctx.fillStyle = "#000000";
    ctx.lineWidth = 5;
    ctx.font = font1;
    ctx.strokeText([scalenumber + ' ' + scaleunit], x_offset + fontsize1 / 2, canvas.height - y_offset - fontsize1 / 2);
    ctx.fillText([scalenumber + ' ' + scaleunit], x_offset + fontsize1 / 2,     canvas.height - y_offset - fontsize1 / 2);
    
    //Scale Dimensions
    var xzero = scalewidth + x_offset;
    var yzero = canvas.height - y_offset;
    var xfirst = x_offset + scalewidth * 1 / 4;
    var xsecond = xfirst + scalewidth * 1 / 4;
    var xthird = xsecond + scalewidth * 1 / 4;
    var xfourth = xthird + scalewidth * 1 / 4;
    
    // Stroke
    ctx.beginPath();
    ctx.lineWidth = line1 + 2;
    ctx.strokeStyle = "#000000";
    ctx.fillStyle = "#ffffff";
    ctx.moveTo(x_offset, yzero);
    ctx.lineTo(xzero + 1, yzero);
    ctx.stroke();
    
    //sections black/white
    ctx.beginPath();
    ctx.lineWidth = line1;
    ctx.strokeStyle = "#000000";
    ctx.moveTo(x_offset, yzero);
    ctx.lineTo(xfirst, yzero);
    ctx.stroke();
    
    ctx.beginPath();
    ctx.lineWidth = line1;
    ctx.strokeStyle = "#FFFFFF";
    ctx.moveTo(xfirst, yzero);
    ctx.lineTo(xsecond, yzero);
    ctx.stroke();
    
    ctx.beginPath();
    ctx.lineWidth = line1;
    ctx.strokeStyle = "#000000";
    ctx.moveTo(xsecond, yzero);
    ctx.lineTo(xthird, yzero);
    ctx.stroke();
    
    ctx.beginPath();
    ctx.lineWidth = line1;
    ctx.strokeStyle = "#FFFFFF";
    ctx.moveTo(xthird, yzero);
    ctx.lineTo(xfourth, yzero);
    ctx.stroke();
    }
    function postcompose() {
    map.on('postcompose', function (evt) {
        WriteScaletoCanvas(evt);
    });
    }
    
    return {
    postcompose : postcompose
    };
    })();
    
    InsertToCanvas.postcompose();
    
    //Now export map as png
    
       var exportMap = function () {
    
    
              canvas = document.getElementsByTagName('canvas')[0];
              canvas.toBlob(function (blob) {
                  alert("jsp page export map function"); 
                saveAs(blob, 'map.png');
              })
            }
    

    This way scale bar will be added to png.

    Step 2 For legend

      function WriteLegendtoCanvas(e) {  
        var ctx = e.context;
    
    
        var x=50,y=50;
        var arr = $('div#legendId img');
    
        for(i=0;i<arr.length;i++)
        {
    
          var img = new Image();
        img.src = $(arr[i]).attr('src');
        img.onload = function() { ctx.drawImage(img, x, y); }
        ctx.drawImage(img, x, y); 
        ctx.beginPath();
        ctx.lineWidth = line1;
        ctx.strokeStyle = "#FFFFFF";
        ctx.moveTo(x, y);
        y+=20;
        ctx.lineTo(x, y);
        ctx.stroke();
    
        }
    
            }
    

    And call this function with postcompose

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