Discussion:
[Qgis-developer] setting QgsMapCanvas size, for testing map tools
Sandro Santilli
2016-06-29 14:37:57 UTC
Permalink
I'm writing a testcase for bug 13952 [1] and would need a
way to set the map canvas size so to be able to syntetize
clicks on pixels with predictable contents. How can it be
done ?

Beside, I've found an QgsMapCanvas::updateMapSize() method
which is declared in the header but never defined (git blame
says it's yours, Nathan).

I'm thinking there could be enough similar testcases to
justify a service class to simplify writing them. What
do you think ?

[1] http://hub.qgis.org/issues/13952

--strk;

() Free GIS & Flash consultant/developer
/\ https://strk.kbt.io/services.html
Richard Duivenvoorde
2016-06-29 14:44:29 UTC
Permalink
Post by Sandro Santilli
I'm writing a testcase for bug 13952 [1] and would need a
way to set the map canvas size so to be able to syntetize
clicks on pixels with predictable contents. How can it be
done ?
Beside, I've found an QgsMapCanvas::updateMapSize() method
which is declared in the header but never defined (git blame
says it's yours, Nathan).
I'm thinking there could be enough similar testcases to
justify a service class to simplify writing them. What
do you think ?
Hi Sandro,

I once was asked to define a mapcanvas with a certain size, and tried it
in python, see:

https://github.com/rduivenvoorde/simplesvg/blob/master/src/simplesvg/mapsizer/MapSizerDialog.py#L93

the hard part (I think) is that the exact size of the mapcanvas was
defined relative to other (parent) widgets, and for example depending on
the OS....

would be cool though to be able to just SET it, given that is the most
important widget in QGIS...

Regards,

Richard
Sandro Santilli
2016-06-29 15:16:07 UTC
Permalink
Post by Richard Duivenvoorde
https://github.com/rduivenvoorde/simplesvg/blob/master/src/simplesvg/mapsizer/MapSizerDialog.py#L93
the hard part (I think) is that the exact size of the mapcanvas was
defined relative to other (parent) widgets, and for example depending on
the OS....
I just figured my test canvas has no parent, but still ->resize()
doesn't make ->scale() return what I would expect...

I'm not sure if this is done in any other testcase, but I'm trying
to emulate user interaction, like:

1. Select a layer in the registry
2. Put layer in edit mode
3. Activate node tool
4. Click on a pixel coordinate

Do you know of an example test I should look at, if any ?

--strk;
Tom Chadwin
2016-06-30 10:24:12 UTC
Permalink
I asked about this a while back, as I could not get a defined canvas size in
my tests. I never found an answer, but never understood why it didn't work:

https://lists.osgeo.org/pipermail/qgis-developer/2015-November/040392.html

Tom



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/setting-QgsMapCanvas-size-for-testing-map-tools-tp5273987p5274142.html
Sent from the Quantum GIS - Developer mailing list archive at Nabble.com.
Sandro Santilli
2016-06-30 19:49:26 UTC
Permalink
Post by Tom Chadwin
I asked about this a while back, as I could not get a defined canvas size in
https://lists.osgeo.org/pipermail/qgis-developer/2015-November/040392.html
Yeah, I feel your pain. It's a frustrating situation indeed.
We'd need an helper class for testcases, to make things like
setting the canvas size easy, and to simulate user events
like mouse moves and clicks, tools selection and the like.


--strk;
Barry Rowlingson
2016-06-30 21:14:34 UTC
Permalink
Maybe I've missed something here, but doesn't the canvas resize method
set the canvas pixel size? This behaves as expected when run
standalone from a python prompt.

from qgis.core import *
from qgis.gui import *
app = QgsApplication([],True)
canvas = QgsMapCanvas()
canvas.show()
canvas.resize(1000,200)
canvas.resize(1000,1000)

Note the map canvas has no parent, so just appears on its own at the
specified size.

Or maybe I've missed a point....
Post by Sandro Santilli
Post by Tom Chadwin
I asked about this a while back, as I could not get a defined canvas size in
https://lists.osgeo.org/pipermail/qgis-developer/2015-November/040392.html
Yeah, I feel your pain. It's a frustrating situation indeed.
We'd need an helper class for testcases, to make things like
setting the canvas size easy, and to simulate user events
like mouse moves and clicks, tools selection and the like.
--strk;
_______________________________________________
Qgis-developer mailing list
List info: http://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: http://lists.osgeo.org/mailman/listinfo/qgis-developer
Tom Chadwin
2016-07-01 11:08:32 UTC
Permalink
Post by Barry Rowlingson
Maybe I've missed something here, but doesn't the canvas resize method
set the canvas pixel size? This behaves as expected when run
standalone from a python prompt.
from qgis.core import *
from qgis.gui import *
app = QgsApplication([],True)
canvas = QgsMapCanvas()
canvas.show()
canvas.resize(1000,200)
canvas.resize(1000,1000)
Note the map canvas has no parent, so just appears on its own at the
specified size.
Or maybe I've missed a point....
I don't want to misrepresent what Sandro is asking, but I think it's the
same as me. I think (and this is from memory), that we need to do this to
the QGIS app canvas instance, rather than a newly created one.

When I run canvas.resize() locally, it behaves as I expect. I can then run
qgis2web (this is my reason for wanting to solve this), to export a web map
of the same size as the canvas.

What I don't understand is that when testing under Travis, with the same
canvas.resize() in the test script, I get different bounds in the webmap to
what I get when resizing my client canvas and exporting.

This experience was a while ago, of course. Perhaps the qgis2web code has
evolved so that this now works - I'll look into it when I can. However, last
time around, it didn't work for me, hence my earlier message to this list.



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/setting-QgsMapCanvas-size-for-testing-map-tools-tp5273987p5274351.html
Sent from the Quantum GIS - Developer mailing list archive at Nabble.com.
Martin Dobias
2016-07-01 14:15:44 UTC
Permalink
Hi Tom!
Post by Tom Chadwin
Post by Barry Rowlingson
Maybe I've missed something here, but doesn't the canvas resize method
set the canvas pixel size? This behaves as expected when run
standalone from a python prompt.
from qgis.core import *
from qgis.gui import *
app = QgsApplication([],True)
canvas = QgsMapCanvas()
canvas.show()
canvas.resize(1000,200)
canvas.resize(1000,1000)
Note the map canvas has no parent, so just appears on its own at the
specified size.
Or maybe I've missed a point....
I don't want to misrepresent what Sandro is asking, but I think it's the
same as me. I think (and this is from memory), that we need to do this to
the QGIS app canvas instance, rather than a newly created one.
When I run canvas.resize() locally, it behaves as I expect. I can then run
qgis2web (this is my reason for wanting to solve this), to export a web map
of the same size as the canvas.
What I don't understand is that when testing under Travis, with the same
canvas.resize() in the test script, I get different bounds in the webmap to
what I get when resizing my client canvas and exporting.
I guess the problem lies in the fact that canvas widget has a frame at
its edge (it is drawn within the area of canvas widget). There may be
differences between the "internal" area of canvas due to different Qt
Post by Tom Chadwin
Post by Barry Rowlingson
iface.mapCanvas().geometry()
PyQt4.QtCore.QRect(0, 0, 879, 390)
Post by Tom Chadwin
Post by Barry Rowlingson
iface.mapCanvas().viewport().geometry()
PyQt4.QtCore.QRect(3, 3, 873, 384)
Post by Tom Chadwin
Post by Barry Rowlingson
iface.mapCanvas().setFrameStyle(0)
iface.mapCanvas().geometry()
PyQt4.QtCore.QRect(0, 0, 879, 390)
Post by Tom Chadwin
Post by Barry Rowlingson
iface.mapCanvas().viewport().geometry()
PyQt4.QtCore.QRect(0, 0, 879, 390)

Hope that helps!

Cheers
Martin
Tom Chadwin
2016-07-01 15:25:07 UTC
Permalink
Hi Martin
Post by Martin Dobias
iface.mapCanvas().geometry()
PyQt4.QtCore.QRect(0, 0, 879, 390)
iface.mapCanvas().viewport().geometry()
PyQt4.QtCore.QRect(3, 3, 873, 384)
Ah, OK! I didn't know anything about a canvas frame. So, without doing
setFrameStyle(), does canvas.extent() give canvas.geometry() or
canvas.viewport().geometry()?

Thanks

Tom



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/setting-QgsMapCanvas-size-for-testing-map-tools-tp5273987p5274394.html
Sent from the Quantum GIS - Developer mailing list archive at Nabble.com.
Martin Dobias
2016-07-01 16:52:18 UTC
Permalink
Hi Tom
Post by Tom Chadwin
Hi Martin
Post by Martin Dobias
iface.mapCanvas().geometry()
PyQt4.QtCore.QRect(0, 0, 879, 390)
iface.mapCanvas().viewport().geometry()
PyQt4.QtCore.QRect(3, 3, 873, 384)
Ah, OK! I didn't know anything about a canvas frame. So, without doing
setFrameStyle(), does canvas.extent() give canvas.geometry() or
canvas.viewport().geometry()?
With the frame, canvas.extent() is linked to size reported by
cavas.viewport().geometry().

Even better is to use canvas.mapSettings().outputSize() that gives you
the actual image size used for rendering (although it should be the
same as the size from canvas.viewport().geometry()).

Cheers
Martin
Sandro Santilli
2016-07-01 15:58:57 UTC
Permalink
Post by Barry Rowlingson
Maybe I've missed something here, but doesn't the canvas resize method
set the canvas pixel size? This behaves as expected when run
standalone from a python prompt.
It does ! Thanks for the pointer.

--strk;
Sandro Santilli
2016-07-01 16:07:54 UTC
Permalink
Post by Sandro Santilli
Post by Barry Rowlingson
Maybe I've missed something here, but doesn't the canvas resize method
set the canvas pixel size? This behaves as expected when run
standalone from a python prompt.
It does ! Thanks for the pointer.
Still, my problem is the following:

QgsMapCanvas *mCanvas = new QgsMapCanvas();
mCanvas->resize( QSize(50, 50) );
mCanvas->setExtent( QgsRectangle( 0, 0, 50, 50 ) );
QCOMPARE( mCanvas->scale(), 1.0 ); //<-- fails, returning 3.1631e+07

--strk;
Martin Dobias
2016-07-01 16:47:16 UTC
Permalink
Hi Sandro
Post by Sandro Santilli
Post by Sandro Santilli
Post by Barry Rowlingson
Maybe I've missed something here, but doesn't the canvas resize method
set the canvas pixel size? This behaves as expected when run
standalone from a python prompt.
It does ! Thanks for the pointer.
QgsMapCanvas *mCanvas = new QgsMapCanvas();
mCanvas->resize( QSize(50, 50) );
mCanvas->setExtent( QgsRectangle( 0, 0, 50, 50 ) );
QCOMPARE( mCanvas->scale(), 1.0 ); //<-- fails, returning 3.1631e+07
I think what you are up to is not to find out scale(), but actually
mapUnitsPerPixel(). Scale in QGIS is calculated as ( extent_width / (
canvas_width * dpi) ) with some extra conversions involved, see
QgsScaleCalculator class.
Post by Sandro Santilli
Post by Sandro Santilli
Post by Barry Rowlingson
cx = QgsMapCanvas()
cx.setFrameStyle(0)
cx.resize(QSize(100,100))
cx.setExtent(QgsRectangle(0,0,100,100))
cx.show()
cx.mapSettings().outputSize()
PyQt4.QtCore.QSize(100, 100)
Post by Sandro Santilli
Post by Sandro Santilli
Post by Barry Rowlingson
cx.mapSettings().mapUnitsPerPixel()
1.0

One caveat here is the fact you need to call show() method of canvas,
otherwise the resize event (that sets image output size) will not be
fired and thus the image output size not updated.

Cheers
Martin
Sandro Santilli
2016-07-01 17:17:35 UTC
Permalink
Post by Martin Dobias
I think what you are up to is not to find out scale(), but actually
mapUnitsPerPixel(). Scale in QGIS is calculated as ( extent_width / (
canvas_width * dpi) ) with some extra conversions involved, see
QgsScaleCalculator class.
Thanks, with the show() trick, mapUnitsPerPixel() works as expected
(while scale() still gives wild returns, maybe due to wild dpis..)

--strk;
Tom Chadwin
2016-07-04 07:53:47 UTC
Permalink
I don't think I knew about show() either, so I have a couple of things to
try. Many thanks!

Tom



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/setting-QgsMapCanvas-size-for-testing-map-tools-tp5273987p5274573.html
Sent from the Quantum GIS - Developer mailing list archive at Nabble.com.
Loading...