Skip to content

Commit

Permalink
[FEATURE][composer] Add a 'predefined scales' mode to atlas maps, whi…
Browse files Browse the repository at this point in the history
…ch sets an atlas maps' extent to the largest predefined scale which fits the atlas feature. Scales are taken from the project's predefined scales, or the global predefined scales.
  • Loading branch information
Hugo Mercier authored and nyalldawson committed May 23, 2014
1 parent 2476a52 commit 084fa89
Show file tree
Hide file tree
Showing 15 changed files with 379 additions and 93 deletions.
9 changes: 9 additions & 0 deletions python/core/composer/qgsatlascomposition.sip
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@ public:
int sortKeyAttributeIndex() const /Deprecated/;
void setSortKeyAttributeIndex( int idx ) /Deprecated/;

/** Returns the current list of predefined scales
@returns a vector of doubles representing predefined scales
*/
const QVector<double>& predefinedScales() const;
/** Sets the predefined scales
@param scales a vector of doubles representing predefined scales
*/
void setPredefinedScales( const QVector<double>& scales );

/** Begins the rendering. Returns true if successful, false if no matching atlas
features found.*/
bool beginRender();
Expand Down
35 changes: 31 additions & 4 deletions python/core/composer/qgscomposermap.sip
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ class QgsComposerMap : QgsComposerItem
Top
};

/** Scaling modes used for the serial rendering (atlas)
*/
enum AtlasScalingMode
{
Fixed, /*< The current scale of the map is used for each feature of the atlas */
Predefined, /*< A scale is chosen from the predefined scales
@see QgsAtlasComposition::setPredefinedScales.
The smallest scale from the list of scales where the atlas feature
is fully visible is chosen.
*/
Auto /*< The extent is adjusted so that each feature is fully visible.
A margin is applied around the center @see setAtlasMargin */
};

/** \brief Draw to paint device
@param painter painter
@param extent map extent
Expand Down Expand Up @@ -394,10 +408,23 @@ class QgsComposerMap : QgsComposerItem
/** Set to true if the map extents should be set by the current atlas feature */
void setAtlasDriven( bool enabled );

/** Returns true if the map uses a fixed scale when in atlas mode */
bool atlasFixedScale() const;
/** Set to true if the map should use a fixed scale when in atlas mode */
void setAtlasFixedScale( bool fixed );
/** Returns true if the map uses a fixed scale when in atlas mode
@deprecated since 2.4 Use atlasScalingMode() instead
*/
bool atlasFixedScale() const /Deprecated/;
/** Set to true if the map should use a fixed scale when in atlas mode
@deprecated since 2.4 Use setAtlasScalingMode() instead
*/
void setAtlasFixedScale( bool fixed ) /Deprecated/;

/** Returns the current atlas scaling mode
@returns the current scaling mode
*/
AtlasScalingMode atlasScalingMode();
/** Sets the current atlas scaling mode
@param mode atlas scaling mode to set
*/
void setAtlasScalingMode( AtlasScalingMode mode );

/** Returns the margin size (percentage) used when the map is in atlas mode */
double atlasMargin() const;
Expand Down
34 changes: 34 additions & 0 deletions src/app/composer/qgscomposer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@ void QgsComposer::on_mActionAtlasPreview_triggered( bool checked )

if ( checked )
{
loadAtlasPredefinedScalesFromProject();
atlasMap->firstFeature();
emit( atlasPreviewFeatureChanged() );
}
Expand Down Expand Up @@ -1333,6 +1334,7 @@ void QgsComposer::exportCompositionAsPDF( QgsComposer::OutputMode mode )

try
{
loadAtlasPredefinedScalesFromProject();
atlasMap->beginRender();
}
catch ( std::exception& e )
Expand Down Expand Up @@ -1487,6 +1489,7 @@ void QgsComposer::printComposition( QgsComposer::OutputMode mode )
QPainter painter( &mPrinter );
try
{
loadAtlasPredefinedScalesFromProject();
atlasMap->beginRender();
}
catch ( std::exception& e )
Expand Down Expand Up @@ -1748,6 +1751,7 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )

try
{
loadAtlasPredefinedScalesFromProject();
atlasMap->beginRender();
}
catch ( std::exception& e )
Expand Down Expand Up @@ -2015,6 +2019,7 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
{
try
{
loadAtlasPredefinedScalesFromProject();
atlasMap->beginRender();
}
catch ( std::exception& e )
Expand Down Expand Up @@ -3470,3 +3475,32 @@ void QgsComposer::updateAtlasMapLayerAction( bool atlasEnabled )
}
}

void QgsComposer::loadAtlasPredefinedScalesFromProject()
{
if ( !mComposition ) {
return;
}
QgsAtlasComposition& atlasMap = mComposition->atlasComposition();
QVector<double> pScales;
// first look at project's scales
QStringList scales( QgsProject::instance()->readListEntry( "Scales", "/ScalesList" ) );
bool hasProjectScales( QgsProject::instance()->readBoolEntry( "Scales", "/useProjectScales" ) );
if ( !hasProjectScales || scales.isEmpty() )
{
// default to global map tool scales
QSettings settings;
QString scalesStr( settings.value( "Map/scales", PROJECT_SCALES ).toString() );
scales = scalesStr.split( "," );
}

for ( QStringList::const_iterator scaleIt = scales.constBegin(); scaleIt != scales.constEnd(); ++scaleIt )
{
QStringList parts(scaleIt->split(':'));
if (parts.size() == 2)
{
pScales.push_back( parts[1].toDouble() );
}
}
atlasMap.setPredefinedScales( pScales );
}

3 changes: 3 additions & 0 deletions src/app/composer/qgscomposer.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
//! Set default settings for printer page settings based on composition paper size
void setPrinterPageDefaults();

//! Load predefined scales from the project's properties
void loadAtlasPredefinedScalesFromProject();

/**Composer title*/
QString mTitle;

Expand Down
134 changes: 90 additions & 44 deletions src/app/composer/qgscomposermapwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "qgscomposershape.h"
#include "qgspaperitem.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsproject.h"
#include <QColorDialog>
#include <QFontDialog>
#include <QMessageBox>
Expand Down Expand Up @@ -92,8 +93,6 @@ QgsComposerMapWidget::QgsComposerMapWidget( QgsComposerMap* composerMap ): QWidg
connect( mGridCheckBox, SIGNAL( toggled( bool ) ),
mDrawAnnotationCheckableGroupBox, SLOT( setEnabled( bool ) ) );

connect( mAtlasCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( atlasToggled( bool ) ) );

if ( composerMap )
{
connect( composerMap, SIGNAL( itemChanged() ), this, SLOT( setGuiElementValues() ) );
Expand Down Expand Up @@ -133,27 +132,16 @@ void QgsComposerMapWidget::compositionAtlasToggled( bool atlasEnabled )
}
}

void QgsComposerMapWidget::atlasToggled( bool checked )
void QgsComposerMapWidget::on_mAtlasCheckBox_toggled( bool checked )
{
if ( checked && mComposerMap )
{
//check atlas coverage layer type
QgsComposition* composition = mComposerMap->composition();
if ( composition )
{
toggleAtlasMarginByLayerType();
}
else
{
mAtlasMarginRadio->setEnabled( false );
}
}
else
if ( !mComposerMap )
{
mAtlasMarginRadio->setEnabled( false );
return;
}

mAtlasFixedScaleRadio->setEnabled( checked );
mAtlasMarginRadio->setEnabled( checked );

if ( mAtlasMarginRadio->isEnabled() && mAtlasMarginRadio->isChecked() )
{
mAtlasMarginSpinBox->setEnabled( true );
Expand All @@ -162,14 +150,23 @@ void QgsComposerMapWidget::atlasToggled( bool checked )
{
mAtlasMarginSpinBox->setEnabled( false );
}
}

mAtlasPredefinedScaleRadio->setEnabled( checked );

void QgsComposerMapWidget::on_mAtlasCheckBox_toggled( bool checked )
{
if ( !mComposerMap )
if ( checked )
{
return;
//check atlas coverage layer type
QgsComposition* composition = mComposerMap->composition();
if ( composition )
{
toggleAtlasScalingOptionsByLayerType();
}
}

// disable predefined scales if none are defined
if ( !hasPredefinedScales() )
{
mAtlasPredefinedScaleRadio->setEnabled( false );
}

mComposerMap->setAtlasDriven( checked );
Expand Down Expand Up @@ -201,6 +198,12 @@ void QgsComposerMapWidget::updateMapForAtlas()
void QgsComposerMapWidget::on_mAtlasMarginRadio_toggled( bool checked )
{
mAtlasMarginSpinBox->setEnabled( checked );

if (checked && mComposerMap)
{
mComposerMap->setAtlasScalingMode( QgsComposerMap::Auto );
updateMapForAtlas();
}
}

void QgsComposerMapWidget::on_mAtlasMarginSpinBox_valueChanged( int value )
Expand All @@ -221,8 +224,36 @@ void QgsComposerMapWidget::on_mAtlasFixedScaleRadio_toggled( bool checked )
return;
}

mComposerMap->setAtlasFixedScale( checked );
updateMapForAtlas();
if (checked)
{
mComposerMap->setAtlasScalingMode( QgsComposerMap::Fixed );
updateMapForAtlas();
}
}

void QgsComposerMapWidget::on_mAtlasPredefinedScaleRadio_toggled( bool checked )
{
if ( !mComposerMap )
{
return;
}

if ( hasPredefinedScales() )
{
if ( checked )
{
mComposerMap->setAtlasScalingMode( QgsComposerMap::Predefined );
updateMapForAtlas();
}
}
else
{
// restore to fixed scale if no predefined scales exist
mAtlasFixedScaleRadio->blockSignals( true );
mAtlasFixedScaleRadio->setChecked( Qt::Checked );
mAtlasFixedScaleRadio->blockSignals( false );
mComposerMap->setAtlasScalingMode( QgsComposerMap::Fixed );
}
}

void QgsComposerMapWidget::on_mPreviewModeComboBox_activated( int i )
Expand Down Expand Up @@ -536,33 +567,30 @@ void QgsComposerMapWidget::updateGuiElements()
//atlas controls
mAtlasCheckBox->setChecked( mComposerMap->atlasDriven() );
mAtlasMarginSpinBox->setValue( static_cast<int>( mComposerMap->atlasMargin() * 100 ) );
if ( mComposerMap->atlasFixedScale() )
{
mAtlasFixedScaleRadio->setChecked( true );
mAtlasMarginSpinBox->setEnabled( false );
}
else
{
mAtlasMarginRadio->setChecked( true );
mAtlasMarginSpinBox->setEnabled( true );
}
if ( !mComposerMap->atlasDriven() )

mAtlasFixedScaleRadio->setEnabled( mComposerMap->atlasDriven() );
mAtlasFixedScaleRadio->setChecked( mComposerMap->atlasScalingMode() == QgsComposerMap::Fixed );
mAtlasMarginSpinBox->setEnabled( mComposerMap->atlasScalingMode() == QgsComposerMap::Auto );
mAtlasMarginRadio->setEnabled( mComposerMap->atlasDriven() );
mAtlasMarginRadio->setChecked( mComposerMap->atlasScalingMode() == QgsComposerMap::Auto );
mAtlasPredefinedScaleRadio->setEnabled( mComposerMap->atlasDriven() );
mAtlasPredefinedScaleRadio->setChecked( mComposerMap->atlasScalingMode() == QgsComposerMap::Predefined );

if ( mComposerMap->atlasDriven() )
{
mAtlasMarginSpinBox->setEnabled( false );
mAtlasMarginRadio->setEnabled( false );
mAtlasFixedScaleRadio->setEnabled( false );
toggleAtlasScalingOptionsByLayerType();
}
else
// disable predefined scales if none are defined
if ( !hasPredefinedScales() )
{
mAtlasFixedScaleRadio->setEnabled( true );
toggleAtlasMarginByLayerType();
mAtlasPredefinedScaleRadio->setEnabled( false );
}

blockAllSignals( false );
}
}

void QgsComposerMapWidget::toggleAtlasMarginByLayerType()
void QgsComposerMapWidget::toggleAtlasScalingOptionsByLayerType()
{
if ( !mComposerMap )
{
Expand Down Expand Up @@ -593,10 +621,12 @@ void QgsComposerMapWidget::toggleAtlasMarginByLayerType()
//For point layers buffer setting makes no sense, so set "fixed scale" on and disable margin control
mAtlasFixedScaleRadio->setChecked( true );
mAtlasMarginRadio->setEnabled( false );
mAtlasPredefinedScaleRadio->setEnabled( false );
break;
default:
//Not a point layer, so enable changes to fixed scale control
mAtlasMarginRadio->setEnabled( true );
mAtlasPredefinedScaleRadio->setEnabled( true );
}
}

Expand Down Expand Up @@ -1396,5 +1426,21 @@ void QgsComposerMapWidget::atlasLayerChanged( QgsVectorLayer* layer )
return;
}

toggleAtlasMarginByLayerType();
toggleAtlasScalingOptionsByLayerType();
}

bool QgsComposerMapWidget::hasPredefinedScales() const
{
// first look at project's scales
QStringList scales( QgsProject::instance()->readListEntry( "Scales", "/ScalesList" ) );
bool hasProjectScales( QgsProject::instance()->readBoolEntry( "Scales", "/useProjectScales" ) );
if ( !hasProjectScales || scales.isEmpty() )
{
// default to global map tool scales
QSettings settings;
QString scalesStr( settings.value( "Map/scales", PROJECT_SCALES ).toString() );
QStringList myScalesList = scalesStr.split( "," );
return myScalesList.size() > 0 && myScalesList[0] != "";
}
return true;
}
9 changes: 6 additions & 3 deletions src/app/composer/qgscomposermapwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ class QgsComposerMapWidget: public QWidget, private Ui::QgsComposerMapWidgetBase
void on_mGridFrameFill1ColorButton_colorChanged( const QColor& newColor );
void on_mGridFrameFill2ColorButton_colorChanged( const QColor& newColor );

void atlasToggled( bool checked );
void on_mAtlasMarginRadio_toggled( bool checked );

void on_mAtlasCheckBox_toggled( bool checked );
void on_mAtlasMarginSpinBox_valueChanged( int value );
void on_mAtlasFixedScaleRadio_toggled( bool checked );
void on_mAtlasPredefinedScaleRadio_toggled( bool checked );

protected:
void showEvent( QShowEvent * event );
Expand Down Expand Up @@ -144,12 +144,15 @@ class QgsComposerMapWidget: public QWidget, private Ui::QgsComposerMapWidgetBase
/**Enables/disables grid frame related controls*/
void toggleFrameControls( bool frameEnabled );

/**Enables or disables the atlas margin radio depending on the atlas coverage layer type*/
void toggleAtlasMarginByLayerType();
/**Enables or disables the atlas margin and predefined scales radio depending on the atlas coverage layer type*/
void toggleAtlasScalingOptionsByLayerType();

/**Recalculates the bounds for an atlas map when atlas properties change*/
void updateMapForAtlas();

/**Is there some predefined scales, globally or as project's options ?*/
bool hasPredefinedScales() const;

};

#endif

0 comments on commit 084fa89

Please sign in to comment.