Skip to content

Commit 1602c02

Browse files
committed
Merge pull request #3009 from pblottiere/magnifier
[FEATURE] add a map canvas magnifier
2 parents daa23b5 + f15197d commit 1602c02

19 files changed

+545
-15
lines changed

python/core/qgsmapsettings.sip

+8-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class QgsMapSettings
1717
//! The actual visible extent used for rendering could be slightly different
1818
//! since the given extent may be expanded in order to fit the aspect ratio
1919
//! of output size. Use visibleExtent() to get the resulting extent.
20-
void setExtent( const QgsRectangle& rect );
20+
void setExtent( const QgsRectangle& rect, bool magnified = true );
2121

2222
//! Return the size of the resulting map image
2323
QSize outputSize() const;
@@ -39,6 +39,13 @@ class QgsMapSettings
3939
//! Set DPI used for conversion between real world units (e.g. mm) and pixels
4040
void setOutputDpi( int dpi );
4141

42+
//! Set the magnification factor.
43+
//! @note added in 2.16
44+
void setMagnificationFactor( double factor );
45+
//! Return the magnification factor.
46+
//! @note added in 2.16
47+
double magnificationFactor() const;
48+
4249
//! Get list of layer IDs for map rendering
4350
//! The layers are stored in the reverse order of how they are rendered (layer with index 0 will be on top)
4451
QStringList layers() const;

python/gui/qgsmapcanvas.sip

+10
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ class QgsMapCanvas : QGraphicsView
5050
//! Destructor
5151
~QgsMapCanvas();
5252

53+
//! Sets the factor of magnification to apply to the map canvas. Indeed, we
54+
//! increase/decrease the DPI of the map settings according to this factor
55+
//! in order to render marker point, labels, ... bigger.
56+
//! @note added in 2.16
57+
void setMagnificationFactor( double level );
58+
59+
//! Returns the magnification factor
60+
//! @note added in 2.16
61+
double magnificationFactor() const;
62+
5363
void setLayerSet( QList<QgsMapCanvasLayer>& layers );
5464

5565
void setCurrentLayer( QgsMapLayer* layer );

src/app/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ SET(QGIS_APP_SRCS
5151
qgsrulebasedlabelingwidget.cpp
5252
qgssavestyletodbdialog.cpp
5353
qgsstatusbarcoordinateswidget.cpp
54+
qgsstatusbarmagnifierwidget.cpp
5455
qgsversioninfo.cpp
5556
qgswelcomepageitemsmodel.cpp
5657
qgswelcomepage.cpp
@@ -229,6 +230,7 @@ SET (QGIS_APP_MOC_HDRS
229230
qgssavestyletodbdialog.h
230231
qgsshortcutsmanager.h
231232
qgsstatusbarcoordinateswidget.h
233+
qgsstatusbarmagnifierwidget.h
232234
qgsversioninfo.h
233235
qgswelcomepageitemsmodel.h
234236
qgswelcomepage.h

src/app/qgisapp.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
#include "qgscomposermanager.h"
124124
#include "qgscomposerview.h"
125125
#include "qgsstatusbarcoordinateswidget.h"
126+
#include "qgsstatusbarmagnifierwidget.h"
126127
#include "qgsconfigureshortcutsdialog.h"
127128
#include "qgscoordinatetransform.h"
128129
#include "qgscoordinateutils.h"
@@ -545,6 +546,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
545546
, mScaleLabel( nullptr )
546547
, mScaleEdit( nullptr )
547548
, mScaleEditValidator( nullptr )
549+
, mMagnifierWidget( nullptr )
548550
, mCoordsEdit( nullptr )
549551
, mRotationLabel( nullptr )
550552
, mRotationEdit( nullptr )
@@ -1001,6 +1003,7 @@ QgisApp::QgisApp()
10011003
, mScaleLabel( nullptr )
10021004
, mScaleEdit( nullptr )
10031005
, mScaleEditValidator( nullptr )
1006+
, mMagnifierWidget( nullptr )
10041007
, mCoordsEdit( nullptr )
10051008
, mRotationLabel( nullptr )
10061009
, mRotationEdit( nullptr )
@@ -2161,6 +2164,13 @@ void QgisApp::createStatusBar()
21612164
statusBar()->addPermanentWidget( mScaleEdit, 0 );
21622165
connect( mScaleEdit, SIGNAL( scaleChanged( double ) ), this, SLOT( userScale() ) );
21632166

2167+
// zoom widget
2168+
QSettings mySettings;
2169+
mMagnifierWidget = new QgsStatusBarMagnifierWidget( statusBar(), mMapCanvas );
2170+
mMagnifierWidget->setFont( myFont );
2171+
mMagnifierWidget->setMagnificationLevel( mySettings.value( "/qgis/magnifier_level", 100 ).toInt() );
2172+
statusBar()->addPermanentWidget( mMagnifierWidget, 0 );
2173+
21642174
if ( QgsMapCanvas::rotationEnabled() )
21652175
{
21662176
// add a widget to show/set current rotation
@@ -8602,6 +8612,8 @@ void QgisApp::showOptionsDialog( QWidget *parent, const QString& currentPage )
86028612
layer->setLayerName( layer->originalName() );
86038613
}
86048614

8615+
mMagnifierWidget->setMagnificationLevel( mySettings.value( "/qgis/magnifier_level" ).toInt() );
8616+
86058617
//update any open compositions so they reflect new composer settings
86068618
//we have to push the changes to the compositions here, because compositions
86078619
//have no access to qgisapp and accordingly can't listen in to changes

src/app/qgisapp.h

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class QgsComposer;
4545
class QgsComposerManager;
4646
class QgsComposerView;
4747
class QgsStatusBarCoordinatesWidget;
48+
class QgsStatusBarMagnifierWidget;
4849
class QgsContrastEnhancement;
4950
class QgsCustomLayerOrderWidget;
5051
class QgsDoubleSpinBox;
@@ -1595,6 +1596,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
15951596
//! The validator for the mScaleEdit
15961597
QValidator * mScaleEditValidator;
15971598

1599+
//! zoom widget
1600+
QgsStatusBarMagnifierWidget *mMagnifierWidget;
1601+
15981602
//! Widget that will live in the statusbar to display and edit coords
15991603
QgsStatusBarCoordinatesWidget *mCoordsEdit;
16001604

src/app/qgsoptions.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,13 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl )
589589
mSimplifyMaximumScaleComboBox->updateScales( myScalesList );
590590
mSimplifyMaximumScaleComboBox->setScale( 1.0 / mSettings->value( "/qgis/simplifyMaxScale", 1 ).toFloat() );
591591

592+
// Magnifier
593+
doubleSpinBoxMagnifierDefault->setRange( 100, 1000 );
594+
doubleSpinBoxMagnifierDefault->setSingleStep( 50 );
595+
doubleSpinBoxMagnifierDefault->setDecimals( 0 );
596+
doubleSpinBoxMagnifierDefault->setSuffix( "%" );
597+
doubleSpinBoxMagnifierDefault->setValue( mSettings->value( "/qgis/magnifier_level", 100 ).toInt() );
598+
592599
// Slightly awkard here at the settings value is true to use QImage,
593600
// but the checkbox is true to use QPixmap
594601
chkAddedVisibility->setChecked( mSettings->value( "/qgis/new_layers_visible", true ).toBool() );
@@ -1192,6 +1199,9 @@ void QgsOptions::saveOptions()
11921199
mSettings->setValue( "/qgis/simplifyLocal", !mSimplifyDrawingAtProvider->isChecked() );
11931200
mSettings->setValue( "/qgis/simplifyMaxScale", 1.0 / mSimplifyMaximumScaleComboBox->scale() );
11941201

1202+
// magnification
1203+
mSettings->setValue( "/qgis/magnifier_level", doubleSpinBoxMagnifierDefault->value() );
1204+
11951205
// project
11961206
mSettings->setValue( "/qgis/projOpenAtLaunch", mProjectOnLaunchCmbBx->currentIndex() );
11971207
mSettings->setValue( "/qgis/projOpenAtLaunchPath", mProjectOnLaunchLineEdit->text() );
+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/***************************************************************************
2+
qgsstatusbarmagnifierwidget.cpp
3+
begin : April 2016
4+
copyright : (C) 2016 Paul Blottiere, Oslandia
5+
email : paul dot blottiere at oslandia dot com
6+
***************************************************************************/
7+
8+
/***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
17+
#include <QFont>
18+
#include <QHBoxLayout>
19+
#include <QLabel>
20+
21+
#include <qgsapplication.h>
22+
#include "qgsstatusbarmagnifierwidget.h"
23+
#include "qgsmapcanvas.h"
24+
#include "qgsdoublespinbox.h"
25+
26+
QgsStatusBarMagnifierWidget::QgsStatusBarMagnifierWidget( QWidget* parent,
27+
QgsMapCanvas *canvas ) :
28+
QWidget( parent ),
29+
mCanvas( canvas ),
30+
mMagnifier( 100 ),
31+
mMagnifierMin( 100 ),
32+
mMagnifierMax( 1000 )
33+
{
34+
// label
35+
mLabel = new QLabel( this );
36+
mLabel->setMinimumWidth( 10 );
37+
mLabel->setMargin( 3 );
38+
mLabel->setAlignment( Qt::AlignCenter );
39+
mLabel->setFrameStyle( QFrame::NoFrame );
40+
mLabel->setText( tr( "Magnifier" ) );
41+
mLabel->setToolTip( tr( "Magnifier" ) );
42+
43+
mSpinBox = new QgsDoubleSpinBox( this );
44+
mSpinBox->setSuffix( "%" );
45+
mSpinBox->setClearValue( mMagnifierMin );
46+
mSpinBox->setKeyboardTracking( false );
47+
mSpinBox->setMaximumWidth( 120 );
48+
mSpinBox->setDecimals( 0 );
49+
mSpinBox->setRange( mMagnifierMin, mMagnifierMax );
50+
mSpinBox->setWrapping( false );
51+
mSpinBox->setSingleStep( 50 );
52+
mSpinBox->setToolTip( tr( "Magnifier level" ) );
53+
54+
connect( mSpinBox, SIGNAL( valueChanged( double ) ), this,
55+
SLOT( updateMagnifier() ) );
56+
57+
// layout
58+
mLayout = new QHBoxLayout( this );
59+
mLayout->addWidget( mLabel );
60+
mLayout->addWidget( mSpinBox );
61+
mLayout->setContentsMargins( 0, 0, 0, 0 );
62+
mLayout->setAlignment( Qt::AlignRight );
63+
mLayout->setSpacing( 0 );
64+
65+
setLayout( mLayout );
66+
67+
updateMagnifier();
68+
}
69+
70+
QgsStatusBarMagnifierWidget::~QgsStatusBarMagnifierWidget()
71+
{
72+
}
73+
74+
double QgsStatusBarMagnifierWidget::magnificationLevel()
75+
{
76+
return mMagnifier;
77+
}
78+
79+
void QgsStatusBarMagnifierWidget::setFont( const QFont& myFont )
80+
{
81+
mLabel->setFont( myFont );
82+
mSpinBox->setFont( myFont );
83+
}
84+
85+
bool QgsStatusBarMagnifierWidget::setMagnificationLevel( int level )
86+
{
87+
bool rc = false;
88+
89+
if ( level >= mMagnifierMin && level <= mMagnifierMax )
90+
{
91+
mSpinBox->setValue( level );
92+
rc = true;
93+
}
94+
95+
return rc;
96+
}
97+
98+
void QgsStatusBarMagnifierWidget::updateMagnifier()
99+
{
100+
// get current data
101+
mMagnifier = mSpinBox->value();
102+
103+
// update map canvas
104+
mCanvas->setMagnificationFactor( mMagnifier / double( mMagnifierMin ) );
105+
}

src/app/qgsstatusbarmagnifierwidget.h

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/***************************************************************************
2+
qgsstatusbarmagnifierwidget.h
3+
begin : April 2016
4+
copyright : (C) 2016 Paul Blottiere, Oslandia
5+
email : paul dot blottiere at oslandia dot com
6+
***************************************************************************/
7+
8+
/***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
17+
#ifndef QGSSTATUSBARMAGNIFIERWIDGET_H
18+
#define QGSSTATUSBARMAGNIFIERWIDGET_H
19+
20+
class QLabel;
21+
class QFont;
22+
class QHBoxLayout;
23+
class QgsMapCanvas;
24+
class QgsDoubleSpinBox;
25+
26+
#include <QWidget>
27+
28+
/**
29+
* A widget which lets the user select the current level of magnification to
30+
* apply to the canvas.
31+
* @note added in 2.16
32+
*/
33+
class APP_EXPORT QgsStatusBarMagnifierWidget : public QWidget
34+
{
35+
Q_OBJECT
36+
37+
public:
38+
39+
/** Constructor
40+
* @param parent is the parent widget
41+
* @param canvas the map canvas
42+
*/
43+
QgsStatusBarMagnifierWidget( QWidget* parent, QgsMapCanvas *canvas );
44+
45+
/** Destructor */
46+
virtual ~QgsStatusBarMagnifierWidget();
47+
48+
/** Set the font of the text
49+
* @param font the font to use
50+
*/
51+
void setFont( const QFont& font );
52+
53+
/** Returns the current magnification level
54+
* @return magnification level
55+
*/
56+
double magnificationLevel();
57+
58+
/** Set the magnification level
59+
* @param level the magnification level
60+
* @return true if the level is valid, false otherwise
61+
*/
62+
bool setMagnificationLevel( int level );
63+
64+
private slots:
65+
66+
void updateMagnifier();
67+
68+
private:
69+
QgsMapCanvas *mCanvas;
70+
QHBoxLayout *mLayout;
71+
QLabel *mLabel;
72+
QgsDoubleSpinBox *mSpinBox;
73+
int mMagnifier;
74+
int mMagnifierMin;
75+
int mMagnifierMax;
76+
};
77+
78+
#endif

src/core/qgsmapsettings.cpp

+30-2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ QgsMapSettings::QgsMapSettings()
3535
, mSize( QSize( 0, 0 ) )
3636
, mExtent()
3737
, mRotation( 0.0 )
38+
, mMagnificationFactor( 1.0 )
3839
, mProjectionsEnabled( false )
3940
, mDestCRS( GEOCRS_ID, QgsCoordinateReferenceSystem::InternalCrsId ) // WGS 84
4041
, mDatumTransformStore( mDestCRS )
@@ -53,15 +54,42 @@ QgsMapSettings::QgsMapSettings()
5354
setMapUnits( QGis::Degrees );
5455
}
5556

57+
void QgsMapSettings::setMagnificationFactor( double factor )
58+
{
59+
double ratio = mMagnificationFactor / factor;
60+
mMagnificationFactor = factor;
61+
62+
double rot = rotation();
63+
setRotation( 0.0 );
64+
65+
QgsRectangle ext = visibleExtent();
66+
ext.scale( ratio );
67+
68+
mRotation = rot;
69+
mExtent = ext;
70+
mDpi = outputDpi() / ratio;
71+
72+
updateDerived();
73+
}
74+
75+
double QgsMapSettings::magnificationFactor() const
76+
{
77+
return mMagnificationFactor;
78+
}
5679

5780
QgsRectangle QgsMapSettings::extent() const
5881
{
5982
return mExtent;
6083
}
6184

62-
void QgsMapSettings::setExtent( const QgsRectangle& extent )
85+
void QgsMapSettings::setExtent( const QgsRectangle& extent, bool magnified )
6386
{
64-
mExtent = extent;
87+
QgsRectangle magnifiedExtent = extent;
88+
89+
if ( !magnified )
90+
magnifiedExtent.scale( 1 / mMagnificationFactor );
91+
92+
mExtent = magnifiedExtent;
6593

6694
updateDerived();
6795
}

0 commit comments

Comments
 (0)