Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map canvas scale wrong due to logical vs physical DPI #41248

Closed
Houska1 opened this issue Jan 28, 2021 · 5 comments
Closed

Map canvas scale wrong due to logical vs physical DPI #41248

Houska1 opened this issue Jan 28, 2021 · 5 comments
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter! Map and Legend Related to map or legend rendering

Comments

@Houska1
Copy link
Contributor

Houska1 commented Jan 28, 2021

I'm calling this a bug since QGIS generates on-screen maps that are technically wrong (at the wrong scale), and since Qt provides the facility to do it right by using physical screen DPI. However, for backwards compatibility and to match some user expectations, I think this should be addressed via a QGIS setting rather than a forced change. Sorry for the length.

Problem

On my laptop, the physical dpi is 158. The logical dpi is 120 (the Windows standard 96 multiplied by a scaling factor of 125% set under Windows OS settings, for all applications). Lots of users will have these 2 dpi's different, since Windows only allows changing the scaling factor in 25% increments, and most people set it by what their eyes prefer for UI elements, not for accuracy.

In QGIS, iface.mapCanvas().mapSettings().outputDpi() seems to equal iface.mainWindow().logicalDpiX(). For the on-screen map to be at the right scale, it should instead equal iface.mainWindow().physicalDpiX(). As a result, to actually get the canvas scale to be accurate, I need to set magnification to 132%(=158/120). For other users, this factor will vary.

QGIS does correctly use the logical DPI for UI elements such as panels, toolbars, and dialogs, in line with other applications. However, switching to physical DPI for the canvas would be consistent with the guidance at the Qt docs:

"physical DPI [...] is useful for print preview and other cases where it's desirable to know the exact physical dimensions of screen displayed contents [...] Logical dots per inch are used to convert font and user interface elements"

Solutions

It is possible to work around this by adjusting magnification, e.g. iface.mapCanvas().setMagnificationFactor(iface.mainWindow().physicalDpiX()/iface.mainWindow().logicalDpiX()) at the Python console. But this is not user friendly, and then the displayed magnification factor is actually incorrect.

While more "correct", QGIS silently switching to physical DPI for the canvas would change the experience for users grown accustomed to how certain map scales appear on their screen, and to the apparent size on screen of map labels with a specified point size. We are accustomed to, say, 10 pt type displaying in a certain way (across all applications, based on system-wide logical DPI settings), even if a sheet of paper with the same 10 pt font on it would have it a different size. Actually, for users with logical and physical dpi different, fonts would now be rendered a different size on the canvas versus in the UI. While annoying, however, font size inconsistencies now come up anyway, if you visually optimize a map on screen and then print it, at "correct" font size and scale.

I think the right solution would be a setting, under Settings / Options / Canvas & Legend, called something like "Render canvas at" and a choice of "System DPI" (=logical DPI), "Physical screen DPI", or a user-defined DPI (since I'm sure some external monitors will have physical DPI wrong).

Merely telling users to change their systemwide logical DPI is not a good solution, since it affects the display of all open applications, and can't quite be accurate anyway due to the discrete scaling factor allowed. As a GIS application, we should allow users to have an on-screen map which is accurate, including stated scale.

Reactions? I suspect this will be a bit controversial...

@Houska1 Houska1 added the Bug Either a bug report, or a bug fix. Let's hope for the latter! label Jan 28, 2021
@Houska1
Copy link
Contributor Author

Houska1 commented Jan 28, 2021

@gioman
Copy link
Contributor

gioman commented Jan 28, 2021

@Houska1 you should raise this matter in the developers mailing list too.

@Houska1
Copy link
Contributor Author

Houska1 commented Jul 13, 2021

At @m-kuhn 's request, I tested https://github.com/qgis/QGIS/suites/3219192054/artifacts/74539265 to see if #44132 fixes this issue (Windows). Unfortunately it does not.

On my system, my laptop screen has actual DPI of 158. I use it with Windows system scaling 125% which means 120 DPI (nominal 96 * 1.25).

On all of 3.20RC, earlier QGIS, and the post-44132 patch, Qt/QGIS correctly sets iface.mainWindow().logicalDpiX() as 120 and ...physicalDpiX() as 158.

However, on 3.20RC and earlier QGIS iface.mapCanvas().mapSettings().outputDpi() is 120, so canvas symbols and text is too small and so is the reported scale in the status bar.

On the post-44132 patch version with respect screen DPI off (the out-of-box default), .outputDpi() is now 96, i.e. symbols and scale even more wrong. With respect screen DPI turn on, .outputDpi() goes back to 120, as before, but is still not 158.

I think you need a 3 way option called something like Map canvas DPI:

  1. Respect system UI scaling (default; uses .logicalDpiX; matches previous behaviour and font sizes match UI panels etc)
  2. Use physical screen DPI (uses .physicalDpiX)
  3. Scaling off = 96 DPI.

@Houska1
Copy link
Contributor Author

Houska1 commented Feb 3, 2022

The final committed #44132 sufficiently addresses this to close this issue.

@Houska1 Houska1 closed this as completed Feb 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter! Map and Legend Related to map or legend rendering
Projects
None yet
Development

No branches or pull requests

2 participants