Skip to content
Permalink
Browse files

Fix "zoom to" actions fail to correctly set canvas extent

when canvas has a locked scale

In these particular actions, we should ignore the canvas scale
lock so that the canvas correctly zooms to the specified extent
and matches user expectations

In particular this fixes:
- zooming to bookmarks
- matching canvas extent to layout map extents
- zooming to layer and feature extents
- pushing layout map scales from layout maps to canvas

Also improve dox
  • Loading branch information
nyalldawson committed Mar 23, 2020
1 parent 6fb8477 commit ab04656092c331d672235279146909e153f0bc3e
@@ -184,7 +184,15 @@ Returns the combined extent for all layers on the map canvas

void setExtent( const QgsRectangle &r, bool magnified = false );
%Docstring
Sets the extent of the map canvas
Sets the extent of the map canvas to the specified rectangle.

The ``magnified`` argument dictates whether existing canvas constraints such
as a scale lock should be respected or not during the operation. If ``magnified`` is
``True`` then an existing scale lock constraint will be applied. This means that the final
visible canvas extent may not match the specified extent.

If ``magnified`` is ``False`` then scale lock settings will be ignored, and the specified
rectangle will ALWAYS be visible in the canvas.
%End

bool setReferencedExtent( const QgsReferencedRectangle &extent ) throw( QgsCsException );
@@ -483,16 +491,22 @@ returns current layer (set by legend widget)
Sets wheel zoom factor (should be greater than 1)
%End

void zoomScale( double scale );
void zoomScale( double scale, bool ignoreScaleLock = false );
%Docstring
Zooms the canvas to a specific ``scale``.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.

If ``ignoreScaleLock`` is set to ``True``, then any existing constraint on the map scale
of the canvas will be ignored during the zoom operation.
%End

void zoomByFactor( double scaleFactor, const QgsPointXY *center = 0 );
void zoomByFactor( double scaleFactor, const QgsPointXY *center = 0, bool ignoreScaleLock = false );
%Docstring
Zoom with the factor supplied. Factor > 1 zooms out, interval (0,1) zooms in
If point is given, re-center on it
If point is given, re-center on it.

If ``ignoreScaleLock`` is set to ``True``, then any existing constraint on the map scale
of the canvas will be ignored during the zoom operation.
%End

void zoomWithCenter( int x, int y, bool zoomIn );
@@ -943,7 +943,7 @@ void QgsGpsInformationWidget::displayGPSInformation( const QgsGpsInformation &in
if ( radRecenterMap->isChecked() ||
( radRecenterWhenNeeded->isChecked() && !myExtentLimit.contains( myPoint ) ) )
{
mMapCanvas->setExtent( myRect );
mMapCanvas->setExtent( myRect, true );
mMapCanvas->refresh();
}
}
@@ -1873,7 +1873,7 @@ void QgsIdentifyResultsDialog::zoomToFeature()
rect.scale( 0.5, &c );
}

mCanvas->setExtent( rect );
mCanvas->setExtent( rect, true );
mCanvas->refresh();
}

@@ -651,7 +651,7 @@ void QgsRelationReferenceWidget::highlightFeature( QgsFeature f, CanvasExtent ca
{
extent.combineExtentWith( featBBox );
extent.scale( 1.1 );
mCanvas->setExtent( extent );
mCanvas->setExtent( extent, true );
mCanvas->refresh();
}
}
@@ -374,7 +374,7 @@ void QgsLayerTreeViewDefaultActions::zoomToLayers( QgsMapCanvas *canvas, const Q
extent.scale( 1.05 );

//zoom to bounding box
canvas->setExtent( extent );
canvas->setExtent( extent, true );
canvas->refresh();
}

@@ -714,7 +714,7 @@ void QgsLayoutMapWidget::viewScaleInCanvas()
}

const double currentScale = mMapItem->scale();
mMapCanvas->zoomScale( currentScale );
mMapCanvas->zoomScale( currentScale, true );
}

void QgsLayoutMapWidget::mXMinLineEdit_editingFinished()
@@ -938,7 +938,7 @@ bool QgsMapCanvas::setReferencedExtent( const QgsReferencedRectangle &extent )
}
}

setExtent( canvasExtent );
setExtent( canvasExtent, true );
return true;
}

@@ -1722,9 +1722,9 @@ void QgsMapCanvas::zoomOut()
zoomByFactor( zoomOutFactor() );
}

void QgsMapCanvas::zoomScale( double newScale )
void QgsMapCanvas::zoomScale( double newScale, bool ignoreScaleLock )
{
zoomByFactor( newScale / scale() );
zoomByFactor( newScale / scale(), nullptr, ignoreScaleLock );
}

void QgsMapCanvas::zoomWithCenter( int x, int y, bool zoomIn )
@@ -2303,9 +2303,9 @@ void QgsMapCanvas::writeProject( QDomDocument &doc )
// TODO: store only units, extent, projections, dest CRS
}

void QgsMapCanvas::zoomByFactor( double scaleFactor, const QgsPointXY *center )
void QgsMapCanvas::zoomByFactor( double scaleFactor, const QgsPointXY *center, bool ignoreScaleLock )
{
if ( mScaleLocked )
if ( mScaleLocked && !ignoreScaleLock )
{
// zoom map to mouse cursor by magnifying
setMagnificationFactor( mapSettings().magnificationFactor() / scaleFactor );
@@ -218,7 +218,17 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
//! Returns the combined extent for all layers on the map canvas
QgsRectangle fullExtent() const;

//! Sets the extent of the map canvas
/**
* Sets the extent of the map canvas to the specified rectangle.
*
* The \a magnified argument dictates whether existing canvas constraints such
* as a scale lock should be respected or not during the operation. If \a magnified is
* TRUE then an existing scale lock constraint will be applied. This means that the final
* visible canvas extent may not match the specified extent.
*
* If \a magnified is FALSE then scale lock settings will be ignored, and the specified
* rectangle will ALWAYS be visible in the canvas.
*/
void setExtent( const QgsRectangle &r, bool magnified = false );

/**
@@ -462,14 +472,20 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
/**
* Zooms the canvas to a specific \a scale.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* If \a ignoreScaleLock is set to TRUE, then any existing constraint on the map scale
* of the canvas will be ignored during the zoom operation.
*/
void zoomScale( double scale );
void zoomScale( double scale, bool ignoreScaleLock = false );

/**
* Zoom with the factor supplied. Factor > 1 zooms out, interval (0,1) zooms in
* If point is given, re-center on it
* If point is given, re-center on it.
*
* If \a ignoreScaleLock is set to TRUE, then any existing constraint on the map scale
* of the canvas will be ignored during the zoom operation.
*/
void zoomByFactor( double scaleFactor, const QgsPointXY *center = nullptr );
void zoomByFactor( double scaleFactor, const QgsPointXY *center = nullptr, bool ignoreScaleLock = false );

//! Zooms in/out with a given center
void zoomWithCenter( int x, int y, bool zoomIn );
@@ -571,7 +571,7 @@ void eVisGenericEventBrowserGui::displayImage()
// only change the extents if the point is beyond the current extents to minimize repaints
if ( !mCanvas->extent().contains( myPoint ) )
{
mCanvas->setExtent( myRect );
mCanvas->setExtent( myRect, true );
}
mCanvas->refresh();
}
@@ -408,7 +408,7 @@ void QgsGeometryCheckerResultTab::highlightErrors( bool current )

if ( !totextent.isEmpty() )
{
mIface->mapCanvas()->setExtent( totextent );
mIface->mapCanvas()->setExtent( totextent, true );
}
mIface->mapCanvas()->refresh();
}
@@ -205,7 +205,7 @@ void checkDock::errorListClicked( const QModelIndex &index )
QgsRectangle r = mErrorList.at( row )->boundingBox();
r.scale( 1.5 );
QgsMapCanvas *canvas = qgsInterface->mapCanvas();
canvas->setExtent( r );
canvas->setExtent( r, true );
canvas->refresh();

mFixBox->clear();

0 comments on commit ab04656

Please sign in to comment.
You can’t perform that action at this time.