Skip to content
Permalink
Browse files
[FEATURE][composer] Add a 'predefined scales' mode to atlas maps, whi…
…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 084fa8992b088ad6289b8c674eb0e00dac718d47
@@ -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();
@@ -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
@@ -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;
@@ -929,6 +929,7 @@ void QgsComposer::on_mActionAtlasPreview_triggered( bool checked )

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

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

try
{
loadAtlasPredefinedScalesFromProject();
atlasMap->beginRender();
}
catch ( std::exception& e )
@@ -2015,6 +2019,7 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
{
try
{
loadAtlasPredefinedScalesFromProject();
atlasMap->beginRender();
}
catch ( std::exception& e )
@@ -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 );
}

@@ -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;

@@ -32,6 +32,7 @@
#include "qgscomposershape.h"
#include "qgspaperitem.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsproject.h"
#include <QColorDialog>
#include <QFontDialog>
#include <QMessageBox>
@@ -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() ) );
@@ -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 );
@@ -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 );
@@ -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 )
@@ -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 )
@@ -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 )
{
@@ -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 );
}
}

@@ -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;
}
@@ -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 );
@@ -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.