I need to print a map with a fixed scale (1:500 and 1:1000) on A4. The online map is done with Openlayers, the print request is sent to QGIS Server using WMS getPrint function.
I mange to get an approximate scale of around 1:500 (1:594 horizontally and 1:554 vertically), but I can't figure out how to fix my formulas to get an exact solution. The formula I use to calculate the extent in meters is:
extent_width = width*printResolution/screenScale
extent_height = height*printResolution/screenScale
To calculate printResolution in m/px I use an approach described in this post:
function printResolution(scale) {
var unit = map.getView().getProjection().getUnits();
var inchesPerMetre = 39.3700787;
var dpi = 120;
return scale / (ol.proj.Units.METERS_PER_UNIT[unit] * inchesPerMetre * dpi);
}
To calculate the actual screenScale I use the approach described in this post:
function screenScale() {
var unit = map.getView().getProjection().getUnits();
var resolution = map.getView().getResolution();
var inchesPerMetre = 39.3700787;
var dpi = 96;
return resolution * ol.proj.Units.METERS_PER_UNIT[unit] * inchesPerMetre * dpi;
}
And finally I put it together calculation the size of the print box on screen using:
var w = Number(size[0])*printResolution(scale)/screenScale()*18000;
var h = Number(size[1])*printResolution(scale)/screenScale()*18000;
var bounds = map.getView().calculateExtent([w,h]);
var printBox = [
[bounds[0], bounds[1]],
[bounds[0], bounds[3]],
[bounds[2], bounds[3]],
[bounds[2], bounds[1]],
[bounds[0], bounds[1]]
];
So I'm aware of errors in the calculation (as I have to multiply by 18000 to get an approximate scaling), but I can't figure out what is wrong.
Here is the complete code in a jsfiddle showing the described behavior.
PS: This is a follow up to this question posted some time ago.