[Qgis-developer] Force canvas to predefined scales : help needed to improve a script

Hugo Mercier hugo.mercier at oslandia.com
Fri Apr 17 02:26:25 PDT 2015


Hi,

Le 17/04/2015 10:46, kimaidou a écrit :
> Hi QGIS !
> 
> I would like to be able in QGIS to force the canvas scales to some
> predefined ones. Since we now have project scales (and QGIS pre-defined
> scales) in the scale selector, we could use them, and add a simple
> checkbox near the combobox "Stick to predefined scales".
> 
> The aim is to force the canvas to render only at these scales. For
> example, if I use the rectangle zoom tool, and I should go toe 1/56003,
> I would instead land on 1/50000 , the closest pre-defined scale.

That would be nice to have it in the core. I already had to do something
similar with a plugin.

> 
> I made a little python script as a proof of concept to illustrate it :
> http://paste.debian.net/167247/
> 
> In this script, I hard coded the scales, but oviously we should get them
> from the project properties.
> 
> I have a question regarding my script. Since I use the
> QgsMapCanvas::scaleChanged signal, I assume the rendering is done twice
> ? Once the "normal" way, and once again after I use the
> QgsMapCanvas::zoomScale method after calculating the new target scale.
> 
> Any idea for improving it ? I assume I would have to disconnect one (not
> found yet) signal/slot, then set the scale and reconnect this
> signal/slot afterwards ?

QObject::blockSignals might be of help here. But in this case, you don't
want to block all signals, only yours.

I guess your solution would work.
You can also use a flag in your callback, something like :

    def setScale( self, scale ):
	if self.reentrant:
		return

        targetScale = min(
            self.predefinedScales,
            key=lambda x:abs(x-scale)
        )
	self.reentrant = True
        self.mc.zoomScale( targetScale )
	self.reentrant = False



More information about the Qgis-developer mailing list