Skip to content

Commit 8410ea7

Browse files
manisandronyalldawson
authored andcommittedJan 17, 2020
Add QgsMapCanvas::setZoomResolutions
1 parent c658159 commit 8410ea7

File tree

4 files changed

+111
-4
lines changed

4 files changed

+111
-4
lines changed
 

‎python/gui/auto_generated/qgsmapcanvas.sip.in

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,25 @@ Zoom out with fixed factor
841841
Zoom to the extent of the selected features of provided (vector) layer.
842842

843843
:param layer: optionally specify different than current layer
844+
%End
845+
846+
void setZoomResolutions( const QList<double> &resolutions );
847+
%Docstring
848+
Set a list of resolutions (map units per pixel) to which to "snap to" when zooming the map
849+
850+
:param resolutions: A list of resolutions
851+
852+
.. versionadded:: 3.12
853+
%End
854+
855+
const QList<double> &zoomResolutions() const;
856+
%Docstring
857+
858+
:return: List of resolutions to which to "snap to" when zooming the map
859+
860+
.. seealso:: :py:func:`setZoomResolutions`
861+
862+
.. versionadded:: 3.12
844863
%End
845864

846865
signals:

‎src/gui/qgsmapcanvas.cpp

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,7 +1639,7 @@ void QgsMapCanvas::wheelEvent( QWheelEvent *e )
16391639
return;
16401640
}
16411641

1642-
double zoomFactor = mWheelZoomFactor;
1642+
double zoomFactor = e->angleDelta().y() > 0 ? 1. / zoomInFactor() : zoomOutFactor();
16431643

16441644
// "Normal" mouse have an angle delta of 120, precision mouses provide data faster, in smaller steps
16451645
zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 120.0 * std::fabs( e->angleDelta().y() );
@@ -1670,13 +1670,13 @@ void QgsMapCanvas::setWheelFactor( double factor )
16701670
void QgsMapCanvas::zoomIn()
16711671
{
16721672
// magnification is alreday handled in zoomByFactor
1673-
zoomByFactor( 1 / mWheelZoomFactor );
1673+
zoomByFactor( zoomInFactor() );
16741674
}
16751675

16761676
void QgsMapCanvas::zoomOut()
16771677
{
16781678
// magnification is alreday handled in zoomByFactor
1679-
zoomByFactor( mWheelZoomFactor );
1679+
zoomByFactor( zoomOutFactor() );
16801680
}
16811681

16821682
void QgsMapCanvas::zoomScale( double newScale )
@@ -1686,7 +1686,7 @@ void QgsMapCanvas::zoomScale( double newScale )
16861686

16871687
void QgsMapCanvas::zoomWithCenter( int x, int y, bool zoomIn )
16881688
{
1689-
double scaleFactor = ( zoomIn ? 1 / mWheelZoomFactor : mWheelZoomFactor );
1689+
double scaleFactor = ( zoomIn ? zoomInFactor() : zoomOutFactor() );
16901690

16911691
if ( mScaleLocked )
16921692
{
@@ -2522,3 +2522,50 @@ bool QgsMapCanvas::panOperationInProgress()
25222522

25232523
return false;
25242524
}
2525+
2526+
int QgsMapCanvas::nextZoomLevel( const QList<double> &resolutions, bool zoomIn ) const
2527+
{
2528+
int resolutionLevel = -1;
2529+
double currentResolution = mapUnitsPerPixel();
2530+
2531+
for ( int i = 0, n = resolutions.size(); i < n; ++i )
2532+
{
2533+
if ( qgsDoubleNear( resolutions[i], currentResolution, 0.0001 ) )
2534+
{
2535+
resolutionLevel = zoomIn ? ( i - 1 ) : ( i + 1 );
2536+
break;
2537+
}
2538+
else if ( currentResolution <= resolutions[i] )
2539+
{
2540+
resolutionLevel = zoomIn ? ( i - 1 ) : i;
2541+
break;
2542+
}
2543+
}
2544+
return ( resolutionLevel < 0 || resolutionLevel >= resolutions.size() ) ? -1 : resolutionLevel;
2545+
}
2546+
2547+
double QgsMapCanvas::zoomInFactor() const
2548+
{
2549+
if ( !mZoomResolutions.isEmpty() )
2550+
{
2551+
int zoomLevel = nextZoomLevel( mZoomResolutions, true );
2552+
if ( zoomLevel != -1 )
2553+
{
2554+
return mZoomResolutions.at( zoomLevel ) / mapUnitsPerPixel();
2555+
}
2556+
}
2557+
return 1 / mWheelZoomFactor;
2558+
}
2559+
2560+
double QgsMapCanvas::zoomOutFactor() const
2561+
{
2562+
if ( !mZoomResolutions.isEmpty() )
2563+
{
2564+
int zoomLevel = nextZoomLevel( mZoomResolutions, false );
2565+
if ( zoomLevel != -1 )
2566+
{
2567+
return mZoomResolutions.at( zoomLevel ) / mapUnitsPerPixel();
2568+
}
2569+
}
2570+
return mWheelZoomFactor;
2571+
}

‎src/gui/qgsmapcanvas.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,20 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
751751
*/
752752
void zoomToSelected( QgsVectorLayer *layer = nullptr );
753753

754+
/**
755+
* Set a list of resolutions (map units per pixel) to which to "snap to" when zooming the map
756+
* \param resolutions A list of resolutions
757+
* \since QGIS 3.12
758+
*/
759+
void setZoomResolutions( const QList<double> &resolutions ) { mZoomResolutions = resolutions; }
760+
761+
/**
762+
* \returns List of resolutions to which to "snap to" when zooming the map
763+
* \see setZoomResolutions()
764+
* \since QGIS 3.12
765+
*/
766+
const QList<double> &zoomResolutions() const { return mZoomResolutions; }
767+
754768
private slots:
755769
//! called when current maptool is destroyed
756770
void mapToolDestroyed();
@@ -1055,6 +1069,7 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
10551069
QVector<QPointer<QgsCustomDropHandler >> mDropHandlers;
10561070

10571071
QgsDistanceArea mDa;
1072+
QList<double> mZoomResolutions;
10581073

10591074
/**
10601075
* Returns the last cursor position on the canvas in geographical coordinates
@@ -1102,6 +1117,10 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
11021117
*/
11031118
bool panOperationInProgress();
11041119

1120+
int nextZoomLevel( const QList<double> &resolutions, bool zoomIn = true ) const;
1121+
double zoomInFactor() const;
1122+
double zoomOutFactor() const;
1123+
11051124
friend class TestQgsMapCanvas;
11061125

11071126
}; // class QgsMapCanvas

‎tests/src/gui/testqgsmapcanvas.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class TestQgsMapCanvas : public QObject
6161
void testZoomByWheel();
6262
void testShiftZoom();
6363
void testDragDrop();
64+
void testZoomResolutions();
6465

6566
private:
6667
QgsMapCanvas *mCanvas = nullptr;
@@ -514,5 +515,26 @@ void TestQgsMapCanvas::testDragDrop()
514515
QVERIFY( dropEvent->isAccepted() );
515516
}
516517

518+
void TestQgsMapCanvas::testZoomResolutions()
519+
{
520+
mCanvas->setExtent( QgsRectangle( 0, 0, 10, 10 ) );
521+
double resolution = mCanvas->mapSettings().mapUnitsPerPixel();
522+
523+
double nextResolution = qCeil( resolution ) + 1;
524+
QList<double> resolutions = QList<double>() << nextResolution << ( 2.5 * nextResolution ) << ( 3.6 * nextResolution ) << ( 4.7 * nextResolution );
525+
mCanvas->setZoomResolutions( resolutions );
526+
527+
mCanvas->zoomOut();
528+
QGSCOMPARENEAR( mCanvas->mapSettings().mapUnitsPerPixel(), resolutions[0], 0.0001 );
529+
530+
mCanvas->zoomOut();
531+
QGSCOMPARENEAR( mCanvas->mapSettings().mapUnitsPerPixel(), resolutions[1], 0.0001 );
532+
533+
mCanvas->zoomIn();
534+
QGSCOMPARENEAR( mCanvas->mapSettings().mapUnitsPerPixel(), resolutions[0], 0.0001 );
535+
536+
QCOMPARE( mCanvas->zoomResolutions(), resolutions );
537+
}
538+
517539
QGSTEST_MAIN( TestQgsMapCanvas )
518540
#include "testqgsmapcanvas.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.