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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.