Skip to content
Permalink
Browse files

Merge pull request #3009 from pblottiere/magnifier

[FEATURE] add a map canvas magnifier
  • Loading branch information
3nids committed May 19, 2016
2 parents daa23b5 + f15197d commit 1602c02df78a19688e2cf0df9aa5c6788581bbcd
@@ -17,7 +17,7 @@ class QgsMapSettings
//! The actual visible extent used for rendering could be slightly different
//! since the given extent may be expanded in order to fit the aspect ratio
//! of output size. Use visibleExtent() to get the resulting extent.
void setExtent( const QgsRectangle& rect );
void setExtent( const QgsRectangle& rect, bool magnified = true );

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

//! Set the magnification factor.
//! @note added in 2.16
void setMagnificationFactor( double factor );
//! Return the magnification factor.
//! @note added in 2.16
double magnificationFactor() const;

//! Get list of layer IDs for map rendering
//! The layers are stored in the reverse order of how they are rendered (layer with index 0 will be on top)
QStringList layers() const;
@@ -50,6 +50,16 @@ class QgsMapCanvas : QGraphicsView
//! Destructor
~QgsMapCanvas();

//! Sets the factor of magnification to apply to the map canvas. Indeed, we
//! increase/decrease the DPI of the map settings according to this factor
//! in order to render marker point, labels, ... bigger.
//! @note added in 2.16
void setMagnificationFactor( double level );

//! Returns the magnification factor
//! @note added in 2.16
double magnificationFactor() const;

void setLayerSet( QList<QgsMapCanvasLayer>& layers );

void setCurrentLayer( QgsMapLayer* layer );
@@ -51,6 +51,7 @@ SET(QGIS_APP_SRCS
qgsrulebasedlabelingwidget.cpp
qgssavestyletodbdialog.cpp
qgsstatusbarcoordinateswidget.cpp
qgsstatusbarmagnifierwidget.cpp
qgsversioninfo.cpp
qgswelcomepageitemsmodel.cpp
qgswelcomepage.cpp
@@ -229,6 +230,7 @@ SET (QGIS_APP_MOC_HDRS
qgssavestyletodbdialog.h
qgsshortcutsmanager.h
qgsstatusbarcoordinateswidget.h
qgsstatusbarmagnifierwidget.h
qgsversioninfo.h
qgswelcomepageitemsmodel.h
qgswelcomepage.h
@@ -123,6 +123,7 @@
#include "qgscomposermanager.h"
#include "qgscomposerview.h"
#include "qgsstatusbarcoordinateswidget.h"
#include "qgsstatusbarmagnifierwidget.h"
#include "qgsconfigureshortcutsdialog.h"
#include "qgscoordinatetransform.h"
#include "qgscoordinateutils.h"
@@ -545,6 +546,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
, mScaleLabel( nullptr )
, mScaleEdit( nullptr )
, mScaleEditValidator( nullptr )
, mMagnifierWidget( nullptr )
, mCoordsEdit( nullptr )
, mRotationLabel( nullptr )
, mRotationEdit( nullptr )
@@ -1001,6 +1003,7 @@ QgisApp::QgisApp()
, mScaleLabel( nullptr )
, mScaleEdit( nullptr )
, mScaleEditValidator( nullptr )
, mMagnifierWidget( nullptr )
, mCoordsEdit( nullptr )
, mRotationLabel( nullptr )
, mRotationEdit( nullptr )
@@ -2161,6 +2164,13 @@ void QgisApp::createStatusBar()
statusBar()->addPermanentWidget( mScaleEdit, 0 );
connect( mScaleEdit, SIGNAL( scaleChanged( double ) ), this, SLOT( userScale() ) );

// zoom widget
QSettings mySettings;
mMagnifierWidget = new QgsStatusBarMagnifierWidget( statusBar(), mMapCanvas );
mMagnifierWidget->setFont( myFont );
mMagnifierWidget->setMagnificationLevel( mySettings.value( "/qgis/magnifier_level", 100 ).toInt() );
statusBar()->addPermanentWidget( mMagnifierWidget, 0 );

if ( QgsMapCanvas::rotationEnabled() )
{
// add a widget to show/set current rotation
@@ -8602,6 +8612,8 @@ void QgisApp::showOptionsDialog( QWidget *parent, const QString& currentPage )
layer->setLayerName( layer->originalName() );
}

mMagnifierWidget->setMagnificationLevel( mySettings.value( "/qgis/magnifier_level" ).toInt() );

//update any open compositions so they reflect new composer settings
//we have to push the changes to the compositions here, because compositions
//have no access to qgisapp and accordingly can't listen in to changes
@@ -45,6 +45,7 @@ class QgsComposer;
class QgsComposerManager;
class QgsComposerView;
class QgsStatusBarCoordinatesWidget;
class QgsStatusBarMagnifierWidget;
class QgsContrastEnhancement;
class QgsCustomLayerOrderWidget;
class QgsDoubleSpinBox;
@@ -1595,6 +1596,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! The validator for the mScaleEdit
QValidator * mScaleEditValidator;

//! zoom widget
QgsStatusBarMagnifierWidget *mMagnifierWidget;

//! Widget that will live in the statusbar to display and edit coords
QgsStatusBarCoordinatesWidget *mCoordsEdit;

@@ -589,6 +589,13 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl )
mSimplifyMaximumScaleComboBox->updateScales( myScalesList );
mSimplifyMaximumScaleComboBox->setScale( 1.0 / mSettings->value( "/qgis/simplifyMaxScale", 1 ).toFloat() );

// Magnifier
doubleSpinBoxMagnifierDefault->setRange( 100, 1000 );
doubleSpinBoxMagnifierDefault->setSingleStep( 50 );
doubleSpinBoxMagnifierDefault->setDecimals( 0 );
doubleSpinBoxMagnifierDefault->setSuffix( "%" );
doubleSpinBoxMagnifierDefault->setValue( mSettings->value( "/qgis/magnifier_level", 100 ).toInt() );

// Slightly awkard here at the settings value is true to use QImage,
// but the checkbox is true to use QPixmap
chkAddedVisibility->setChecked( mSettings->value( "/qgis/new_layers_visible", true ).toBool() );
@@ -1192,6 +1199,9 @@ void QgsOptions::saveOptions()
mSettings->setValue( "/qgis/simplifyLocal", !mSimplifyDrawingAtProvider->isChecked() );
mSettings->setValue( "/qgis/simplifyMaxScale", 1.0 / mSimplifyMaximumScaleComboBox->scale() );

// magnification
mSettings->setValue( "/qgis/magnifier_level", doubleSpinBoxMagnifierDefault->value() );

// project
mSettings->setValue( "/qgis/projOpenAtLaunch", mProjectOnLaunchCmbBx->currentIndex() );
mSettings->setValue( "/qgis/projOpenAtLaunchPath", mProjectOnLaunchLineEdit->text() );
@@ -0,0 +1,105 @@
/***************************************************************************
qgsstatusbarmagnifierwidget.cpp
begin : April 2016
copyright : (C) 2016 Paul Blottiere, Oslandia
email : paul dot blottiere at oslandia dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include <QFont>
#include <QHBoxLayout>
#include <QLabel>

#include <qgsapplication.h>
#include "qgsstatusbarmagnifierwidget.h"
#include "qgsmapcanvas.h"
#include "qgsdoublespinbox.h"

QgsStatusBarMagnifierWidget::QgsStatusBarMagnifierWidget( QWidget* parent,
QgsMapCanvas *canvas ) :
QWidget( parent ),
mCanvas( canvas ),
mMagnifier( 100 ),
mMagnifierMin( 100 ),
mMagnifierMax( 1000 )
{
// label
mLabel = new QLabel( this );
mLabel->setMinimumWidth( 10 );
mLabel->setMargin( 3 );
mLabel->setAlignment( Qt::AlignCenter );
mLabel->setFrameStyle( QFrame::NoFrame );
mLabel->setText( tr( "Magnifier" ) );
mLabel->setToolTip( tr( "Magnifier" ) );

mSpinBox = new QgsDoubleSpinBox( this );
mSpinBox->setSuffix( "%" );
mSpinBox->setClearValue( mMagnifierMin );
mSpinBox->setKeyboardTracking( false );
mSpinBox->setMaximumWidth( 120 );
mSpinBox->setDecimals( 0 );
mSpinBox->setRange( mMagnifierMin, mMagnifierMax );
mSpinBox->setWrapping( false );
mSpinBox->setSingleStep( 50 );
mSpinBox->setToolTip( tr( "Magnifier level" ) );

connect( mSpinBox, SIGNAL( valueChanged( double ) ), this,
SLOT( updateMagnifier() ) );

// layout
mLayout = new QHBoxLayout( this );
mLayout->addWidget( mLabel );
mLayout->addWidget( mSpinBox );
mLayout->setContentsMargins( 0, 0, 0, 0 );
mLayout->setAlignment( Qt::AlignRight );
mLayout->setSpacing( 0 );

setLayout( mLayout );

updateMagnifier();
}

QgsStatusBarMagnifierWidget::~QgsStatusBarMagnifierWidget()
{
}

double QgsStatusBarMagnifierWidget::magnificationLevel()
{
return mMagnifier;
}

void QgsStatusBarMagnifierWidget::setFont( const QFont& myFont )
{
mLabel->setFont( myFont );
mSpinBox->setFont( myFont );
}

bool QgsStatusBarMagnifierWidget::setMagnificationLevel( int level )
{
bool rc = false;

if ( level >= mMagnifierMin && level <= mMagnifierMax )
{
mSpinBox->setValue( level );
rc = true;
}

return rc;
}

void QgsStatusBarMagnifierWidget::updateMagnifier()
{
// get current data
mMagnifier = mSpinBox->value();

// update map canvas
mCanvas->setMagnificationFactor( mMagnifier / double( mMagnifierMin ) );
}
@@ -0,0 +1,78 @@
/***************************************************************************
qgsstatusbarmagnifierwidget.h
begin : April 2016
copyright : (C) 2016 Paul Blottiere, Oslandia
email : paul dot blottiere at oslandia dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSSTATUSBARMAGNIFIERWIDGET_H
#define QGSSTATUSBARMAGNIFIERWIDGET_H

class QLabel;
class QFont;
class QHBoxLayout;
class QgsMapCanvas;
class QgsDoubleSpinBox;

#include <QWidget>

/**
* A widget which lets the user select the current level of magnification to
* apply to the canvas.
* @note added in 2.16
*/
class APP_EXPORT QgsStatusBarMagnifierWidget : public QWidget
{
Q_OBJECT

public:

/** Constructor
* @param parent is the parent widget
* @param canvas the map canvas
*/
QgsStatusBarMagnifierWidget( QWidget* parent, QgsMapCanvas *canvas );

/** Destructor */
virtual ~QgsStatusBarMagnifierWidget();

/** Set the font of the text
* @param font the font to use
*/
void setFont( const QFont& font );

/** Returns the current magnification level
* @return magnification level
*/
double magnificationLevel();

/** Set the magnification level
* @param level the magnification level
* @return true if the level is valid, false otherwise
*/
bool setMagnificationLevel( int level );

private slots:

void updateMagnifier();

private:
QgsMapCanvas *mCanvas;
QHBoxLayout *mLayout;
QLabel *mLabel;
QgsDoubleSpinBox *mSpinBox;
int mMagnifier;
int mMagnifierMin;
int mMagnifierMax;
};

#endif
@@ -35,6 +35,7 @@ QgsMapSettings::QgsMapSettings()
, mSize( QSize( 0, 0 ) )
, mExtent()
, mRotation( 0.0 )
, mMagnificationFactor( 1.0 )
, mProjectionsEnabled( false )
, mDestCRS( GEOCRS_ID, QgsCoordinateReferenceSystem::InternalCrsId ) // WGS 84
, mDatumTransformStore( mDestCRS )
@@ -53,15 +54,42 @@ QgsMapSettings::QgsMapSettings()
setMapUnits( QGis::Degrees );
}

void QgsMapSettings::setMagnificationFactor( double factor )
{
double ratio = mMagnificationFactor / factor;
mMagnificationFactor = factor;

double rot = rotation();
setRotation( 0.0 );

QgsRectangle ext = visibleExtent();
ext.scale( ratio );

mRotation = rot;
mExtent = ext;
mDpi = outputDpi() / ratio;

updateDerived();
}

double QgsMapSettings::magnificationFactor() const
{
return mMagnificationFactor;
}

QgsRectangle QgsMapSettings::extent() const
{
return mExtent;
}

void QgsMapSettings::setExtent( const QgsRectangle& extent )
void QgsMapSettings::setExtent( const QgsRectangle& extent, bool magnified )
{
mExtent = extent;
QgsRectangle magnifiedExtent = extent;

if ( !magnified )
magnifiedExtent.scale( 1 / mMagnificationFactor );

mExtent = magnifiedExtent;

updateDerived();
}

1 comment on commit 1602c02

@nirvn

This comment has been minimized.

Copy link
Contributor

@nirvn nirvn commented on 1602c02 May 19, 2016

Nice. Here's how it looks on my machine ATM:
untitled

Any chance we could reduce the width of the magnification spin box? We could also reduce the rotation spin box too.

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