Keeping the Scale after exporting the Map to PNG

OpenLayers 3.6.0, scale, canvas
Export PNG with Scale

The Scaleline is a CSS-Element with a fixed pixel width depending on the actual resolution/zoom. Since I didn't managed to "retrace" the math on all the DPI/PointResolution/Scale thing i just extract the width from the .ol-scale-line-inner CSS-Container with jQuery.

The Drawing will be included in the postcompose event. I'm not a Pro-Programmer - so feel free to enhance this basic example.

www.kreidefossilien.de

More custom examples


  <!DOCTYPE html>
<html>
<head>
<title>Export map example</title>
</head>
<body>
<script>
//[...] see export-map example


/**  Add a Scale/Scaleline to the CANVAS itself **/

// we need the width of the scaleline-container (style="width:100px")
map.addControl(new ol.control.ScaleLine());

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();

//this is it 

// rest of export-map example [...]
</script>
</body>
</html>