[FEATURE][composer] Allow for more than one atlas controlled map in compositions (or none), by moving some atlas properties to map items (fix #9248) (fix #6484)

This commit is contained in:
Nyall Dawson 2014-01-14 22:20:40 +11:00
parent 2cdc89654b
commit 6bb9dfec00
31 changed files with 818 additions and 342 deletions

View File

@ -17,16 +17,34 @@ public:
bool enabled() const; bool enabled() const;
void setEnabled( bool e ); void setEnabled( bool e );
/**Returns the map used by the atlas
* @deprecated Use QgsComposerMap::atlasDriven() instead
*/
QgsComposerMap* composerMap() const; QgsComposerMap* composerMap() const;
/**Sets the map used by the atlas
* @deprecated Use QgsComposerMap::setAtlasDriven( true ) instead
*/
void setComposerMap( QgsComposerMap* map ); void setComposerMap( QgsComposerMap* map );
bool hideCoverage() const; bool hideCoverage() const;
void setHideCoverage( bool hide ); void setHideCoverage( bool hide );
/**Returns whether the atlas map uses a fixed scale
* @deprecated Use QgsComposerMap::atlasFixedScale() instead
*/
bool fixedScale() const; bool fixedScale() const;
/**Sets whether the atlas map should use a fixed scale
* @deprecated Use QgsComposerMap::setAtlasFixedScale( bool ) instead
*/
void setFixedScale( bool fixed ); void setFixedScale( bool fixed );
/**Returns the margin for the atlas map
* @deprecated Use QgsComposerMap::atlasMargin() instead
*/
float margin() const; float margin() const;
/**Sets the margin for the atlas map
* @deprecated Use QgsComposerMap::setAtlasMargin( double ) instead
*/
void setMargin( float margin ); void setMargin( float margin );
QString filenamePattern() const; QString filenamePattern() const;
@ -66,6 +84,21 @@ public:
/** Returns the current filename. Must be called after prepareForFeature( i ) */ /** Returns the current filename. Must be called after prepareForFeature( i ) */
const QString& currentFilename() const; const QString& currentFilename() const;
/** Requeries the current atlas coverage layer and applies filtering and sorting. Returns
number of matching features. Must be called after prepareForFeature( i ) */
int updateFeatures();
void nextFeature();
void prevFeature();
void lastFeature();
void firstFeature();
/** Returns the current atlas feature. Must be called after prepareForFeature( i ). */
QgsFeature* currentFeature();
/** Recalculates the bounds of an atlas driven map */
void prepareMap( QgsComposerMap* map );
void writeXML( QDomElement& elem, QDomDocument& doc ) const; void writeXML( QDomElement& elem, QDomDocument& doc ) const;
void readXML( const QDomElement& elem, const QDomDocument& doc ); void readXML( const QDomElement& elem, const QDomDocument& doc );

View File

@ -366,7 +366,22 @@ class QgsComposerMap : QgsComposerItem
* @deprecated Use QgsComposerItem::sizeChangedByRotation( double& width, double& height, double rotation ) * @deprecated Use QgsComposerItem::sizeChangedByRotation( double& width, double& height, double rotation )
* instead * instead
*/ */
void sizeChangedByRotation( double& width, double& height ); void sizeChangedByRotation( double& width, double& height );
/** Returns true if the map extent is set to follow the current atlas feature */
bool atlasDriven() const;
/** 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 the margin size (percentage) used when the map is in atlas mode */
double atlasMargin() const;
/** Sets the margin size (percentage) used when the map is in atlas mode */
void setAtlasMargin( double margin );
signals: signals:
void extentChanged(); void extentChanged();

View File

@ -49,27 +49,10 @@ QgsAtlasCompositionWidget::QgsAtlasCompositionWidget( QWidget* parent, QgsCompos
connect( layerRegistry, SIGNAL( layerWasAdded( QgsMapLayer* ) ), this, SLOT( onLayerAdded( QgsMapLayer* ) ) ); connect( layerRegistry, SIGNAL( layerWasAdded( QgsMapLayer* ) ), this, SLOT( onLayerAdded( QgsMapLayer* ) ) );
} }
// update the composer map combo box
// populate the map list
mComposerMapComboBox->clear();
QList<const QgsComposerMap*> availableMaps = mComposition->composerMapItems();
QList<const QgsComposerMap*>::const_iterator mapItemIt = availableMaps.constBegin();
for ( ; mapItemIt != availableMaps.constEnd(); ++mapItemIt )
{
mComposerMapComboBox->addItem( tr( "Map %1" ).arg(( *mapItemIt )->id() ), qVariantFromValue(( void* )*mapItemIt ) );
}
// Sort direction // Sort direction
mAtlasSortFeatureDirectionButton->setEnabled( false ); mAtlasSortFeatureDirectionButton->setEnabled( false );
mAtlasSortFeatureKeyComboBox->setEnabled( false ); mAtlasSortFeatureKeyComboBox->setEnabled( false );
// Connect to addition / removal of maps
connect( mComposition, SIGNAL( composerMapAdded( QgsComposerMap* ) ), this, SLOT( onComposerMapAdded( QgsComposerMap* ) ) );
connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( onItemRemoved( QgsComposerItem* ) ) );
connect( mAtlasMarginRadio, SIGNAL( toggled( bool ) ), mAtlasMarginSpinBox, SLOT( setEnabled( bool ) ) );
// connect to updates // connect to updates
connect( &mComposition->atlasComposition(), SIGNAL( parameterChanged() ), this, SLOT( updateGuiElements() ) ); connect( &mComposition->atlasComposition(), SIGNAL( parameterChanged() ), this, SLOT( updateGuiElements() ) );
@ -90,7 +73,6 @@ void QgsAtlasCompositionWidget::on_mUseAtlasCheckBox_stateChanged( int state )
mVisibilityGroup->setEnabled( true ); mVisibilityGroup->setEnabled( true );
mSortingGroup->setEnabled( true ); mSortingGroup->setEnabled( true );
mFilteringGroup->setEnabled( true ); mFilteringGroup->setEnabled( true );
mScalingGroup->setEnabled( true );
mOutputGroup->setEnabled( true ); mOutputGroup->setEnabled( true );
} }
else else
@ -100,7 +82,6 @@ void QgsAtlasCompositionWidget::on_mUseAtlasCheckBox_stateChanged( int state )
mVisibilityGroup->setEnabled( false ); mVisibilityGroup->setEnabled( false );
mSortingGroup->setEnabled( false ); mSortingGroup->setEnabled( false );
mFilteringGroup->setEnabled( false ); mFilteringGroup->setEnabled( false );
mScalingGroup->setEnabled( false );
mOutputGroup->setEnabled( false ); mOutputGroup->setEnabled( false );
} }
} }
@ -137,39 +118,10 @@ void QgsAtlasCompositionWidget::onLayerAdded( QgsMapLayer* map )
{ {
atlasMap->setCoverageLayer( vectorLayer ); atlasMap->setCoverageLayer( vectorLayer );
updateAtlasFeatures(); updateAtlasFeatures();
checkLayerType( vectorLayer );
} }
} }
} }
void QgsAtlasCompositionWidget::onComposerMapAdded( QgsComposerMap* map )
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
mComposerMapComboBox->addItem( tr( "Map %1" ).arg( map->id() ), qVariantFromValue(( void* )map ) );
if ( mComposerMapComboBox->count() == 1 )
{
atlasMap->setComposerMap( map );
}
}
void QgsAtlasCompositionWidget::onItemRemoved( QgsComposerItem* item )
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
QgsComposerMap* map = dynamic_cast<QgsComposerMap*>( item );
if ( map )
{
int idx = mComposerMapComboBox->findData( qVariantFromValue(( void* )map ) );
if ( idx != -1 )
{
mComposerMapComboBox->removeItem( idx );
}
}
if ( mComposerMapComboBox->count() == 0 )
{
atlasMap->setComposerMap( 0 );
}
}
void QgsAtlasCompositionWidget::on_mAtlasCoverageLayerComboBox_currentIndexChanged( int index ) void QgsAtlasCompositionWidget::on_mAtlasCoverageLayerComboBox_currentIndexChanged( int index )
{ {
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition(); QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
@ -190,7 +142,6 @@ void QgsAtlasCompositionWidget::on_mAtlasCoverageLayerComboBox_currentIndexChang
if ( layer ) if ( layer )
{ {
checkLayerType( layer );
atlasMap->setCoverageLayer( layer ); atlasMap->setCoverageLayer( layer );
updateAtlasFeatures(); updateAtlasFeatures();
} }
@ -200,44 +151,6 @@ void QgsAtlasCompositionWidget::on_mAtlasCoverageLayerComboBox_currentIndexChang
} }
} }
void QgsAtlasCompositionWidget::checkLayerType( QgsVectorLayer *layer )
{
// enable or disable fixed scale control based on layer type
if ( !layer ) return;
switch ( layer->wkbType() )
{
case QGis::WKBPoint:
case QGis::WKBPoint25D:
case QGis::WKBMultiPoint:
case QGis::WKBMultiPoint25D:
//For point layers buffer setting makes no sense, so set "fixed scale" on and disable margin control
mAtlasFixedScaleRadio->setChecked( true );
mAtlasMarginRadio->setEnabled( false );
break;
default:
//Not a point layer, so enable changes to fixed scale control
mAtlasMarginRadio->setEnabled( true );
}
}
void QgsAtlasCompositionWidget::on_mComposerMapComboBox_currentIndexChanged( int index )
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
if ( !atlasMap )
{
return;
}
if ( index == -1 )
{
atlasMap->setComposerMap( 0 );
}
else
{
QgsComposerMap* map = reinterpret_cast<QgsComposerMap*>( mComposerMapComboBox->itemData( index ).value<void*>() );
atlasMap->setComposerMap( map );
}
}
void QgsAtlasCompositionWidget::on_mAtlasFilenamePatternEdit_textChanged( const QString& text ) void QgsAtlasCompositionWidget::on_mAtlasFilenamePatternEdit_textChanged( const QString& text )
{ {
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition(); QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
@ -280,22 +193,6 @@ void QgsAtlasCompositionWidget::on_mAtlasHideCoverageCheckBox_stateChanged( int
atlasMap->setHideCoverage( state == Qt::Checked ); atlasMap->setHideCoverage( state == Qt::Checked );
} }
void QgsAtlasCompositionWidget::on_mAtlasFixedScaleRadio_toggled( bool checked )
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
if ( !atlasMap )
{
return;
}
atlasMap->setFixedScale( checked );
}
void QgsAtlasCompositionWidget::on_mAtlasMarginSpinBox_valueChanged( int value )
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
atlasMap->setMargin( value / 100. );
}
void QgsAtlasCompositionWidget::on_mAtlasSingleFileCheckBox_stateChanged( int state ) void QgsAtlasCompositionWidget::on_mAtlasSingleFileCheckBox_stateChanged( int state )
{ {
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition(); QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
@ -487,26 +384,9 @@ void QgsAtlasCompositionWidget::updateGuiElements()
if ( idx != -1 ) if ( idx != -1 )
{ {
mAtlasCoverageLayerComboBox->setCurrentIndex( idx ); mAtlasCoverageLayerComboBox->setCurrentIndex( idx );
checkLayerType( atlasMap->coverageLayer() );
}
idx = mComposerMapComboBox->findData( qVariantFromValue(( void* )atlasMap->composerMap() ) );
if ( idx != -1 )
{
mComposerMapComboBox->setCurrentIndex( idx );
} }
mAtlasMarginSpinBox->setValue( static_cast<int>( atlasMap->margin() * 100 ) );
mAtlasFilenamePatternEdit->setText( atlasMap->filenamePattern() ); mAtlasFilenamePatternEdit->setText( atlasMap->filenamePattern() );
if ( atlasMap->fixedScale() )
{
mAtlasFixedScaleRadio->setChecked( true );
mAtlasMarginSpinBox->setEnabled( false );
}
else
{
mAtlasMarginRadio->setChecked( true );
mAtlasMarginSpinBox->setEnabled( true );
}
mAtlasHideCoverageCheckBox->setCheckState( atlasMap->hideCoverage() ? Qt::Checked : Qt::Unchecked ); mAtlasHideCoverageCheckBox->setCheckState( atlasMap->hideCoverage() ? Qt::Checked : Qt::Unchecked );
mAtlasSingleFileCheckBox->setCheckState( atlasMap->singleFile() ? Qt::Checked : Qt::Unchecked ); mAtlasSingleFileCheckBox->setCheckState( atlasMap->singleFile() ? Qt::Checked : Qt::Unchecked );
mAtlasSortFeatureCheckBox->setCheckState( atlasMap->sortFeatures() ? Qt::Checked : Qt::Unchecked ); mAtlasSortFeatureCheckBox->setCheckState( atlasMap->sortFeatures() ? Qt::Checked : Qt::Unchecked );
@ -523,6 +403,5 @@ void QgsAtlasCompositionWidget::blockAllSignals( bool b )
mVisibilityGroup->blockSignals( b ); mVisibilityGroup->blockSignals( b );
mSortingGroup->blockSignals( b ); mSortingGroup->blockSignals( b );
mFilteringGroup->blockSignals( b ); mFilteringGroup->blockSignals( b );
mScalingGroup->blockSignals( b );
mOutputGroup->blockSignals( b ); mOutputGroup->blockSignals( b );
} }

View File

@ -36,12 +36,10 @@ class QgsAtlasCompositionWidget:
public slots: public slots:
void on_mUseAtlasCheckBox_stateChanged( int state ); void on_mUseAtlasCheckBox_stateChanged( int state );
void on_mComposerMapComboBox_currentIndexChanged( int index );
void on_mAtlasCoverageLayerComboBox_currentIndexChanged( int index ); void on_mAtlasCoverageLayerComboBox_currentIndexChanged( int index );
void on_mAtlasFilenamePatternEdit_textChanged( const QString& text ); void on_mAtlasFilenamePatternEdit_textChanged( const QString& text );
void on_mAtlasFilenameExpressionButton_clicked(); void on_mAtlasFilenameExpressionButton_clicked();
void on_mAtlasHideCoverageCheckBox_stateChanged( int state ); void on_mAtlasHideCoverageCheckBox_stateChanged( int state );
void on_mAtlasFixedScaleRadio_toggled( bool checked );
void on_mAtlasSingleFileCheckBox_stateChanged( int state ); void on_mAtlasSingleFileCheckBox_stateChanged( int state );
void on_mAtlasSortFeatureCheckBox_stateChanged( int state ); void on_mAtlasSortFeatureCheckBox_stateChanged( int state );
@ -50,15 +48,12 @@ class QgsAtlasCompositionWidget:
void on_mAtlasFeatureFilterEdit_editingFinished(); void on_mAtlasFeatureFilterEdit_editingFinished();
void on_mAtlasFeatureFilterButton_clicked(); void on_mAtlasFeatureFilterButton_clicked();
void on_mAtlasFeatureFilterCheckBox_stateChanged( int state ); void on_mAtlasFeatureFilterCheckBox_stateChanged( int state );
void on_mAtlasMarginSpinBox_valueChanged( int value );
// extract fields from the current coverage layer and populate the corresponding combo box // extract fields from the current coverage layer and populate the corresponding combo box
void fillSortColumns(); void fillSortColumns();
private slots: private slots:
void onLayerRemoved( QString ); void onLayerRemoved( QString );
void onLayerAdded( QgsMapLayer* ); void onLayerAdded( QgsMapLayer* );
void onComposerMapAdded( QgsComposerMap* );
void onItemRemoved( QgsComposerItem* );
void updateGuiElements(); void updateGuiElements();

View File

@ -90,9 +90,21 @@ QgsComposerMapWidget::QgsComposerMapWidget( QgsComposerMap* composerMap ): QWidg
connect( mGridCheckBox, SIGNAL( toggled( bool ) ), connect( mGridCheckBox, SIGNAL( toggled( bool ) ),
mDrawAnnotationCheckableGroupBox, SLOT( setEnabled( bool ) ) ); mDrawAnnotationCheckableGroupBox, SLOT( setEnabled( bool ) ) );
connect( mAtlasCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( atlasToggled( bool ) ) );
if ( composerMap ) if ( composerMap )
{ {
connect( composerMap, SIGNAL( itemChanged() ), this, SLOT( setGuiElementValues() ) ); connect( composerMap, SIGNAL( itemChanged() ), this, SLOT( setGuiElementValues() ) );
//get composition
QgsComposition* composition = mComposerMap->composition();
if ( composition )
{
QgsAtlasComposition* atlas = &composition->atlasComposition();
connect( atlas, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ),
this, SLOT( atlasLayerChanged( QgsVectorLayer* ) ) );
connect( atlas, SIGNAL( toggled( bool ) ), this, SLOT( compositionAtlasToggled( bool ) ) );
}
} }
updateOverviewSymbolMarker(); updateOverviewSymbolMarker();
@ -106,6 +118,111 @@ QgsComposerMapWidget::~QgsComposerMapWidget()
{ {
} }
void QgsComposerMapWidget::compositionAtlasToggled( bool atlasEnabled )
{
if ( atlasEnabled )
{
mAtlasCheckBox->setEnabled( true );
}
else
{
mAtlasCheckBox->setEnabled( false );
mAtlasCheckBox->setChecked( false );
}
}
void QgsComposerMapWidget::atlasToggled( bool checked )
{
if ( checked && mComposerMap )
{
//check atlas coverage layer type
QgsComposition* composition = mComposerMap->composition();
if ( composition )
{
toggleAtlasMarginByLayerType();
}
else
{
mAtlasMarginRadio->setEnabled( false );
}
}
else
{
mAtlasMarginRadio->setEnabled( false );
}
mAtlasFixedScaleRadio->setEnabled( checked );
if ( mAtlasMarginRadio->isEnabled() && mAtlasMarginRadio->isChecked() )
{
mAtlasMarginSpinBox->setEnabled( true );
}
else
{
mAtlasMarginSpinBox->setEnabled( false );
}
}
void QgsComposerMapWidget::on_mAtlasCheckBox_toggled( bool checked )
{
if ( !mComposerMap )
{
return;
}
mComposerMap->setAtlasDriven( checked );
updateMapForAtlas();
}
void QgsComposerMapWidget::updateMapForAtlas()
{
//update map if in atlas preview mode
QgsComposition* composition = mComposerMap->composition();
if ( !composition )
{
return;
}
if ( composition->atlasMode() == QgsComposition::AtlasOff )
{
return;
}
//update atlas based extent for map
QgsAtlasComposition* atlas = &composition->atlasComposition();
atlas->prepareMap( mComposerMap );
//redraw map
mComposerMap->cache();
mComposerMap->update();
}
void QgsComposerMapWidget::on_mAtlasMarginRadio_toggled( bool checked )
{
mAtlasMarginSpinBox->setEnabled( checked );
}
void QgsComposerMapWidget::on_mAtlasMarginSpinBox_valueChanged( int value )
{
if ( !mComposerMap )
{
return;
}
mComposerMap->setAtlasMargin( value / 100. );
updateMapForAtlas();
}
void QgsComposerMapWidget::on_mAtlasFixedScaleRadio_toggled( bool checked )
{
if ( !mComposerMap )
{
return;
}
mComposerMap->setAtlasFixedScale( checked );
updateMapForAtlas();
}
void QgsComposerMapWidget::on_mPreviewModeComboBox_activated( int i ) void QgsComposerMapWidget::on_mPreviewModeComboBox_activated( int i )
{ {
Q_UNUSED( i ); Q_UNUSED( i );
@ -402,10 +519,73 @@ void QgsComposerMapWidget::updateGuiElements()
mCoordinatePrecisionSpinBox->setValue( mComposerMap->gridAnnotationPrecision() ); mCoordinatePrecisionSpinBox->setValue( mComposerMap->gridAnnotationPrecision() );
//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() )
{
mAtlasMarginSpinBox->setEnabled( false );
mAtlasMarginRadio->setEnabled( false );
mAtlasFixedScaleRadio->setEnabled( false );
}
else
{
mAtlasFixedScaleRadio->setEnabled( true );
toggleAtlasMarginByLayerType();
}
blockAllSignals( false ); blockAllSignals( false );
} }
} }
void QgsComposerMapWidget::toggleAtlasMarginByLayerType()
{
if ( !mComposerMap )
{
return;
}
//get composition
QgsComposition* composition = mComposerMap->composition();
if ( !composition )
{
return;
}
QgsAtlasComposition* atlas = &composition->atlasComposition();
QgsVectorLayer* coverageLayer = atlas->coverageLayer();
if ( !coverageLayer )
{
return;
}
switch ( atlas->coverageLayer()->wkbType() )
{
case QGis::WKBPoint:
case QGis::WKBPoint25D:
case QGis::WKBMultiPoint:
case QGis::WKBMultiPoint25D:
//For point layers buffer setting makes no sense, so set "fixed scale" on and disable margin control
mAtlasFixedScaleRadio->setChecked( true );
mAtlasMarginRadio->setEnabled( false );
break;
default:
//Not a point layer, so enable changes to fixed scale control
mAtlasMarginRadio->setEnabled( true );
}
}
void QgsComposerMapWidget::updateComposerExtentFromGui() void QgsComposerMapWidget::updateComposerExtentFromGui()
{ {
if ( !mComposerMap ) if ( !mComposerMap )
@ -480,6 +660,10 @@ void QgsComposerMapWidget::blockAllSignals( bool b )
mOverviewBlendModeComboBox->blockSignals( b ); mOverviewBlendModeComboBox->blockSignals( b );
mOverviewInvertCheckbox->blockSignals( b ); mOverviewInvertCheckbox->blockSignals( b );
mOverviewCenterCheckbox->blockSignals( b ); mOverviewCenterCheckbox->blockSignals( b );
mAtlasCheckBox->blockSignals( b );
mAtlasMarginSpinBox->blockSignals( b );
mAtlasFixedScaleRadio->blockSignals( b );
mAtlasMarginRadio->blockSignals( b );
} }
void QgsComposerMapWidget::on_mUpdatePreviewButton_clicked() void QgsComposerMapWidget::on_mUpdatePreviewButton_clicked()
@ -1173,3 +1357,14 @@ void QgsComposerMapWidget::refreshMapComboBox()
mOverviewFrameMapComboBox->blockSignals( false ); mOverviewFrameMapComboBox->blockSignals( false );
} }
void QgsComposerMapWidget::atlasLayerChanged( QgsVectorLayer* layer )
{
// enable or disable fixed scale control based on layer type
if ( !layer || !mAtlasCheckBox->isChecked() )
{
return;
}
toggleAtlasMarginByLayerType();
}

View File

@ -90,6 +90,13 @@ class QgsComposerMapWidget: public QWidget, private Ui::QgsComposerMapWidgetBase
void on_mGridFrameFill1ColorButton_colorChanged( const QColor& newColor ); void on_mGridFrameFill1ColorButton_colorChanged( const QColor& newColor );
void on_mGridFrameFill2ColorButton_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 );
protected: protected:
void showEvent( QShowEvent * event ); void showEvent( QShowEvent * event );
@ -103,6 +110,12 @@ class QgsComposerMapWidget: public QWidget, private Ui::QgsComposerMapWidgetBase
/**Sets the GUI elements to the values of mPicture*/ /**Sets the GUI elements to the values of mPicture*/
void setGuiElementValues(); void setGuiElementValues();
/**Enables or disables the atlas margin around feature option depending on coverage layer type*/
void atlasLayerChanged( QgsVectorLayer* layer );
/**Enables or disables the atlas controls when composer atlas is toggled on/off*/
void compositionAtlasToggled( bool atlasEnabled );
private: private:
QgsComposerMap* mComposerMap; QgsComposerMap* mComposerMap;
@ -129,6 +142,13 @@ class QgsComposerMapWidget: public QWidget, private Ui::QgsComposerMapWidgetBase
/**Enables/disables grid frame related controls*/ /**Enables/disables grid frame related controls*/
void toggleFrameControls( bool frameEnabled ); void toggleFrameControls( bool frameEnabled );
/**Enables or disables the atlas margin radio depending on the atlas coverage layer type*/
void toggleAtlasMarginByLayerType();
/**Recalculates the bounds for an atlas map when atlas properties change*/
void updateMapForAtlas();
}; };
#endif #endif

View File

@ -31,8 +31,7 @@
QgsAtlasComposition::QgsAtlasComposition( QgsComposition* composition ) : QgsAtlasComposition::QgsAtlasComposition( QgsComposition* composition ) :
mComposition( composition ), mComposition( composition ),
mEnabled( false ), mEnabled( false ),
mComposerMap( 0 ), mHideCoverage( false ), mFilenamePattern( "'output_'||$feature" ),
mHideCoverage( false ), mFixedScale( false ), mMargin( 0.10 ), mFilenamePattern( "'output_'||$feature" ),
mCoverageLayer( 0 ), mSingleFile( false ), mCoverageLayer( 0 ), mSingleFile( false ),
mSortFeatures( false ), mSortAscending( true ), mCurrentFeatureNo( 0 ), mSortFeatures( false ), mSortAscending( true ), mCurrentFeatureNo( 0 ),
mFilterFeatures( false ), mFeatureFilter( "" ) mFilterFeatures( false ), mFeatureFilter( "" )
@ -70,6 +69,87 @@ void QgsAtlasComposition::setCoverageLayer( QgsVectorLayer* layer )
layer->getFeatures().nextFeature( fet ); layer->getFeatures().nextFeature( fet );
QgsExpression::setSpecialColumn( "$atlasfeatureid", fet.id() ); QgsExpression::setSpecialColumn( "$atlasfeatureid", fet.id() );
QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *fet.geometry() ) ); QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *fet.geometry() ) );
emit coverageLayerChanged( layer );
}
QgsComposerMap* QgsAtlasComposition::composerMap() const
{
//deprecated method. Until removed just return the first atlas-enabled composer map
//build a list of composer maps
QList<QgsComposerMap*> maps;
mComposition->composerItems( maps );
for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
{
QgsComposerMap* currentMap = ( *mit );
if ( currentMap->atlasDriven() )
{
return currentMap;
}
}
return 0;
}
void QgsAtlasComposition::setComposerMap( QgsComposerMap* map )
{
//deprecated
if ( !map )
{
return;
}
map->setAtlasDriven( true );
}
bool QgsAtlasComposition::fixedScale() const
{
//deprecated method. Until removed just return the property for the first atlas-enabled composer map
QgsComposerMap * map = composerMap();
if ( !map )
{
return false;
}
return map->atlasFixedScale();
}
void QgsAtlasComposition::setFixedScale( bool fixed )
{
//deprecated method. Until removed just set the property for the first atlas-enabled composer map
QgsComposerMap * map = composerMap();
if ( !map )
{
return;
}
map->setAtlasFixedScale( fixed );
}
float QgsAtlasComposition::margin() const
{
//deprecated method. Until removed just return the property for the first atlas-enabled composer map
QgsComposerMap * map = composerMap();
if ( !map )
{
return 0;
}
return map->atlasMargin();
}
void QgsAtlasComposition::setMargin( float margin )
{
//deprecated method. Until removed just set the property for the first atlas-enabled composer map
QgsComposerMap * map = composerMap();
if ( !map )
{
return;
}
map->setAtlasMargin(( double ) margin );
} }
// //
@ -107,17 +187,11 @@ int QgsAtlasComposition::updateFeatures()
{ {
//needs to be called when layer, filter, sort changes //needs to be called when layer, filter, sort changes
if ( !mComposerMap || !mCoverageLayer ) if ( !mCoverageLayer )
{ {
return 0; return 0;
} }
const QgsCoordinateReferenceSystem& coverage_crs = mCoverageLayer->crs();
const QgsCoordinateReferenceSystem& destination_crs = mComposerMap->mapRenderer()->destinationCrs();
// transformation needed for feature geometries
mTransform.setSourceCrs( coverage_crs );
mTransform.setDestCRS( destination_crs );
updateFilenameExpression(); updateFilenameExpression();
// select all features with all attributes // select all features with all attributes
@ -184,7 +258,7 @@ int QgsAtlasComposition::updateFeatures()
bool QgsAtlasComposition::beginRender() bool QgsAtlasComposition::beginRender()
{ {
if ( !mComposerMap || !mCoverageLayer ) if ( !mCoverageLayer )
{ {
return false; return false;
} }
@ -218,7 +292,7 @@ bool QgsAtlasComposition::beginRender()
void QgsAtlasComposition::endRender() void QgsAtlasComposition::endRender()
{ {
if ( !mComposerMap || !mCoverageLayer ) if ( !mCoverageLayer )
{ {
return; return;
} }
@ -239,7 +313,24 @@ void QgsAtlasComposition::endRender()
layerSet.push_back( mCoverageLayer->id() ); layerSet.push_back( mCoverageLayer->id() );
} }
mComposerMap->cache(); updateAtlasMaps();
}
void QgsAtlasComposition::updateAtlasMaps()
{
//update atlas-enabled composer maps
QList<QgsComposerMap*> maps;
mComposition->composerItems( maps );
for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
{
QgsComposerMap* currentMap = ( *mit );
if ( !currentMap->atlasDriven() )
{
continue;
}
currentMap->cache();
}
} }
int QgsAtlasComposition::numFeatures() const int QgsAtlasComposition::numFeatures() const
@ -283,7 +374,7 @@ void QgsAtlasComposition::lastFeature()
void QgsAtlasComposition::prepareForFeature( int featureI ) void QgsAtlasComposition::prepareForFeature( int featureI )
{ {
if ( !mComposerMap || !mCoverageLayer ) if ( !mCoverageLayer )
{ {
return; return;
} }
@ -304,70 +395,6 @@ void QgsAtlasComposition::prepareForFeature( int featureI )
// generate filename for current feature // generate filename for current feature
evalFeatureFilename(); evalFeatureFilename();
//
// compute the new extent
// keep the original aspect ratio
// and apply a margin
// QgsGeometry::boundingBox is expressed in the geometry"s native CRS
// We have to transform the grometry to the destination CRS and ask for the bounding box
// Note: we cannot directly take the transformation of the bounding box, since transformations are not linear
QgsGeometry tgeom( *mCurrentFeature.geometry() );
tgeom.transform( mTransform );
QgsRectangle geom_rect = tgeom.boundingBox();
double xa1 = geom_rect.xMinimum();
double xa2 = geom_rect.xMaximum();
double ya1 = geom_rect.yMinimum();
double ya2 = geom_rect.yMaximum();
QgsRectangle new_extent = geom_rect;
QgsRectangle mOrigExtent = mComposerMap->extent();
if ( mFixedScale )
{
// only translate, keep the original scale (i.e. width x height)
double geom_center_x = ( xa1 + xa2 ) / 2.0;
double geom_center_y = ( ya1 + ya2 ) / 2.0;
double xx = geom_center_x - mOrigExtent.width() / 2.0;
double yy = geom_center_y - mOrigExtent.height() / 2.0;
new_extent = QgsRectangle( xx,
yy,
xx + mOrigExtent.width(),
yy + mOrigExtent.height() );
}
else
{
// auto scale
double geom_ratio = geom_rect.width() / geom_rect.height();
double map_ratio = mOrigExtent.width() / mOrigExtent.height();
// geometry height is too big
if ( geom_ratio < map_ratio )
{
// extent the bbox's width
double adj_width = ( map_ratio * geom_rect.height() - geom_rect.width() ) / 2.0;
xa1 -= adj_width;
xa2 += adj_width;
}
// geometry width is too big
else if ( geom_ratio > map_ratio )
{
// extent the bbox's height
double adj_height = ( geom_rect.width() / map_ratio - geom_rect.height() ) / 2.0;
ya1 -= adj_height;
ya2 += adj_height;
}
new_extent = QgsRectangle( xa1, ya1, xa2, ya2 );
if ( mMargin > 0.0 )
{
new_extent.scale( 1 + mMargin );
}
}
// evaluate label expressions // evaluate label expressions
QList<QgsComposerLabel*> labels; QList<QgsComposerLabel*> labels;
mComposition->composerItems( labels ); mComposition->composerItems( labels );
@ -392,10 +419,118 @@ void QgsAtlasComposition::prepareForFeature( int featureI )
( *pageIt )->update(); ( *pageIt )->update();
} }
// set the new extent (and render)
mComposerMap->setNewAtlasFeatureExtent( new_extent );
emit statusMsgChanged( QString( tr( "Atlas feature %1 of %2" ) ).arg( featureI + 1 ).arg( mFeatureIds.size() ) ); emit statusMsgChanged( QString( tr( "Atlas feature %1 of %2" ) ).arg( featureI + 1 ).arg( mFeatureIds.size() ) );
//update composer maps
//build a list of atlas-enabled composer maps
QList<QgsComposerMap*> maps;
QList<QgsComposerMap*> atlasMaps;
mComposition->composerItems( maps );
for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
{
QgsComposerMap* currentMap = ( *mit );
if ( !currentMap->atlasDriven() )
{
continue;
}
atlasMaps << currentMap;
}
if ( atlasMaps.isEmpty() )
{
//no atlas enabled maps
return;
}
//
// compute the new extent
// keep the original aspect ratio
// and apply a margin
const QgsCoordinateReferenceSystem& coverage_crs = mCoverageLayer->crs();
// transformation needed for feature geometries. This should be set on a per-atlas map basis,
// but given that it's not currently possible to have maps with different CRSes we can just
// calculate it once based on the first atlas maps' CRS.
const QgsCoordinateReferenceSystem& destination_crs = atlasMaps[0]->mapRenderer()->destinationCrs();
mTransform.setSourceCrs( coverage_crs );
mTransform.setDestCRS( destination_crs );
// QgsGeometry::boundingBox is expressed in the geometry"s native CRS
// We have to transform the grometry to the destination CRS and ask for the bounding box
// Note: we cannot directly take the transformation of the bounding box, since transformations are not linear
QgsGeometry tgeom( *mCurrentFeature.geometry() );
tgeom.transform( mTransform );
mTransformedFeatureBounds = tgeom.boundingBox();
//update atlas bounds of every atlas enabled composer map
for ( QList<QgsComposerMap*>::iterator mit = atlasMaps.begin(); mit != atlasMaps.end(); ++mit )
{
prepareMap( *mit );
}
}
void QgsAtlasComposition::prepareMap( QgsComposerMap* map )
{
if ( !map->atlasDriven() )
{
return;
}
double xa1 = mTransformedFeatureBounds.xMinimum();
double xa2 = mTransformedFeatureBounds.xMaximum();
double ya1 = mTransformedFeatureBounds.yMinimum();
double ya2 = mTransformedFeatureBounds.yMaximum();
QgsRectangle new_extent = mTransformedFeatureBounds;
QgsRectangle mOrigExtent = map->extent();
if ( map->atlasFixedScale() )
{
// only translate, keep the original scale (i.e. width x height)
double geom_center_x = ( xa1 + xa2 ) / 2.0;
double geom_center_y = ( ya1 + ya2 ) / 2.0;
double xx = geom_center_x - mOrigExtent.width() / 2.0;
double yy = geom_center_y - mOrigExtent.height() / 2.0;
new_extent = QgsRectangle( xx,
yy,
xx + mOrigExtent.width(),
yy + mOrigExtent.height() );
}
else
{
// auto scale
double geom_ratio = mTransformedFeatureBounds.width() / mTransformedFeatureBounds.height();
double map_ratio = mOrigExtent.width() / mOrigExtent.height();
// geometry height is too big
if ( geom_ratio < map_ratio )
{
// extent the bbox's width
double adj_width = ( map_ratio * mTransformedFeatureBounds.height() - mTransformedFeatureBounds.width() ) / 2.0;
xa1 -= adj_width;
xa2 += adj_width;
}
// geometry width is too big
else if ( geom_ratio > map_ratio )
{
// extent the bbox's height
double adj_height = ( mTransformedFeatureBounds.width() / map_ratio - mTransformedFeatureBounds.height() ) / 2.0;
ya1 -= adj_height;
ya2 += adj_height;
}
new_extent = QgsRectangle( xa1, ya1, xa2, ya2 );
if ( map->atlasMargin() > 0.0 )
{
new_extent.scale( 1 + map->atlasMargin() );
}
}
// set the new extent (and render)
map->setNewAtlasFeatureExtent( new_extent );
} }
const QString& QgsAtlasComposition::currentFilename() const const QString& QgsAtlasComposition::currentFilename() const
@ -420,18 +555,9 @@ void QgsAtlasComposition::writeXML( QDomElement& elem, QDomDocument& doc ) const
{ {
atlasElem.setAttribute( "coverageLayer", "" ); atlasElem.setAttribute( "coverageLayer", "" );
} }
if ( mComposerMap )
{
atlasElem.setAttribute( "composerMap", mComposerMap->id() );
}
else
{
atlasElem.setAttribute( "composerMap", "" );
}
atlasElem.setAttribute( "hideCoverage", mHideCoverage ? "true" : "false" ); atlasElem.setAttribute( "hideCoverage", mHideCoverage ? "true" : "false" );
atlasElem.setAttribute( "fixedScale", mFixedScale ? "true" : "false" );
atlasElem.setAttribute( "singleFile", mSingleFile ? "true" : "false" ); atlasElem.setAttribute( "singleFile", mSingleFile ? "true" : "false" );
atlasElem.setAttribute( "margin", QString::number( mMargin ) );
atlasElem.setAttribute( "filenamePattern", mFilenamePattern ); atlasElem.setAttribute( "filenamePattern", mFilenamePattern );
atlasElem.setAttribute( "sortFeatures", mSortFeatures ? "true" : "false" ); atlasElem.setAttribute( "sortFeatures", mSortFeatures ? "true" : "false" );
@ -470,20 +596,36 @@ void QgsAtlasComposition::readXML( const QDomElement& atlasElem, const QDomDocum
break; break;
} }
} }
// look for stored composer map //look for stored composer map, to upgrade pre 2.1 projects
mComposerMap = 0; int composerMapNo = atlasElem.attribute( "composerMap", "0" ).toInt();
QList<const QgsComposerMap*> maps = mComposition->composerMapItems(); QgsComposerMap * composerMap = 0;
for ( QList<const QgsComposerMap*>::const_iterator it = maps.begin(); it != maps.end(); ++it ) if ( composerMapNo != 0 )
{ {
if (( *it )->id() == atlasElem.attribute( "composerMap" ).toInt() ) QList<QgsComposerMap*> maps;
mComposition->composerItems( maps );
for ( QList<QgsComposerMap*>::iterator it = maps.begin(); it != maps.end(); ++it )
{ {
mComposerMap = const_cast<QgsComposerMap*>( *it ); if (( *it )->id() == composerMapNo )
break; {
( *it )->setAtlasDriven( true );
break;
}
} }
} }
mMargin = atlasElem.attribute( "margin", "0.0" ).toDouble();
mHideCoverage = atlasElem.attribute( "hideCoverage", "false" ) == "true" ? true : false; mHideCoverage = atlasElem.attribute( "hideCoverage", "false" ) == "true" ? true : false;
mFixedScale = atlasElem.attribute( "fixedScale", "false" ) == "true" ? true : false;
//upgrade pre 2.1 projects
double margin = atlasElem.attribute( "margin", "0.0" ).toDouble();
if ( composerMap && margin != 0 )
{
composerMap->setAtlasMargin( margin );
}
bool fixedScale = atlasElem.attribute( "fixedScale", "false" ) == "true" ? true : false;
if ( composerMap && fixedScale )
{
composerMap->setAtlasFixedScale( true );
}
mSingleFile = atlasElem.attribute( "singleFile", "false" ) == "true" ? true : false; mSingleFile = atlasElem.attribute( "singleFile", "false" ) == "true" ? true : false;
mFilenamePattern = atlasElem.attribute( "filenamePattern", "" ); mFilenamePattern = atlasElem.attribute( "filenamePattern", "" );
@ -528,7 +670,7 @@ void QgsAtlasComposition::setHideCoverage( bool hide )
mRestoreLayer = false; mRestoreLayer = false;
} }
} }
mComposerMap->cache(); updateAtlasMaps();
mComposition->update(); mComposition->update();
} }

View File

@ -45,17 +45,35 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
bool enabled() const { return mEnabled; } bool enabled() const { return mEnabled; }
void setEnabled( bool e ); void setEnabled( bool e );
QgsComposerMap* composerMap() const { return mComposerMap; } /**Returns the map used by the atlas
void setComposerMap( QgsComposerMap* map ) { mComposerMap = map; } * @deprecated Use QgsComposerMap::atlasDriven() instead
*/
QgsComposerMap* composerMap() const;
/**Sets the map used by the atlas
* @deprecated Use QgsComposerMap::setAtlasDriven( true ) instead
*/
void setComposerMap( QgsComposerMap* map );
bool hideCoverage() const { return mHideCoverage; } bool hideCoverage() const { return mHideCoverage; }
void setHideCoverage( bool hide ); void setHideCoverage( bool hide );
bool fixedScale() const { return mFixedScale; } /**Returns whether the atlas map uses a fixed scale
void setFixedScale( bool fixed ) { mFixedScale = fixed; } * @deprecated Use QgsComposerMap::atlasFixedScale() instead
*/
bool fixedScale() const;
/**Sets whether the atlas map should use a fixed scale
* @deprecated Use QgsComposerMap::setAtlasFixedScale( bool ) instead
*/
void setFixedScale( bool fixed );
float margin() const { return mMargin; } /**Returns the margin for the atlas map
void setMargin( float margin ) { mMargin = margin; } * @deprecated Use QgsComposerMap::atlasMargin() instead
*/
float margin() const;
/**Sets the margin for the atlas map
* @deprecated Use QgsComposerMap::setAtlasMargin( double ) instead
*/
void setMargin( float margin );
QString filenamePattern() const { return mFilenamePattern; } QString filenamePattern() const { return mFilenamePattern; }
void setFilenamePattern( const QString& pattern ); void setFilenamePattern( const QString& pattern );
@ -113,6 +131,9 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
/** Returns the current atlas feature. Must be called after prepareForFeature( i ). */ /** Returns the current atlas feature. Must be called after prepareForFeature( i ). */
QgsFeature* currentFeature() { return &mCurrentFeature; } QgsFeature* currentFeature() { return &mCurrentFeature; }
/** Recalculates the bounds of an atlas driven map */
void prepareMap( QgsComposerMap* map );
signals: signals:
/** emitted when one of the parameters changes */ /** emitted when one of the parameters changes */
void parameterChanged(); void parameterChanged();
@ -123,6 +144,9 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
/**Is emitted when the atlas has an updated status bar message for the composer window*/ /**Is emitted when the atlas has an updated status bar message for the composer window*/
void statusMsgChanged( QString message ); void statusMsgChanged( QString message );
/**Is emitted when the coverage layer for an atlas changes*/
void coverageLayerChanged( QgsVectorLayer* layer );
private: private:
/**Updates the filename expression*/ /**Updates the filename expression*/
void updateFilenameExpression(); void updateFilenameExpression();
@ -133,10 +157,7 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
QgsComposition* mComposition; QgsComposition* mComposition;
bool mEnabled; bool mEnabled;
QgsComposerMap* mComposerMap;
bool mHideCoverage; bool mHideCoverage;
bool mFixedScale;
double mMargin;
QString mFilenamePattern; QString mFilenamePattern;
QgsVectorLayer* mCoverageLayer; QgsVectorLayer* mCoverageLayer;
bool mSingleFile; bool mSingleFile;
@ -170,6 +191,12 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
QgsFeature mCurrentFeature; QgsFeature mCurrentFeature;
bool mRestoreLayer; bool mRestoreLayer;
std::auto_ptr<QgsExpression> mFilenameExpr; std::auto_ptr<QgsExpression> mFilenameExpr;
// bounding box of the current feature transformed into map crs
QgsRectangle mTransformedFeatureBounds;
//forces all atlas enabled maps to redraw
void updateAtlasMaps();
}; };
#endif #endif

View File

@ -51,7 +51,7 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int w
mLeftGridAnnotationDirection( Horizontal ), mRightGridAnnotationDirection( Horizontal ), mTopGridAnnotationDirection( Horizontal ), mLeftGridAnnotationDirection( Horizontal ), mRightGridAnnotationDirection( Horizontal ), mTopGridAnnotationDirection( Horizontal ),
mBottomGridAnnotationDirection( Horizontal ), mGridFrameStyle( NoGridFrame ), mGridFrameWidth( 2.0 ), mBottomGridAnnotationDirection( Horizontal ), mGridFrameStyle( NoGridFrame ), mGridFrameWidth( 2.0 ),
mGridFramePenThickness( 0.5 ), mGridFramePenColor( QColor( 0, 0, 0 ) ), mGridFrameFillColor1( Qt::white ), mGridFrameFillColor2( Qt::black ), mGridFramePenThickness( 0.5 ), mGridFramePenColor( QColor( 0, 0, 0 ) ), mGridFrameFillColor1( Qt::white ), mGridFrameFillColor2( Qt::black ),
mCrossLength( 3 ), mMapCanvas( 0 ), mDrawCanvasItems( true ) mCrossLength( 3 ), mMapCanvas( 0 ), mDrawCanvasItems( true ), mAtlasDriven( false ), mAtlasFixedScale( false ), mAtlasMargin( 0.10 )
{ {
mComposition = composition; mComposition = composition;
mOverviewFrameMapSymbol = 0; mOverviewFrameMapSymbol = 0;
@ -106,7 +106,7 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition )
mLeftGridAnnotationDirection( Horizontal ), mRightGridAnnotationDirection( Horizontal ), mTopGridAnnotationDirection( Horizontal ), mLeftGridAnnotationDirection( Horizontal ), mRightGridAnnotationDirection( Horizontal ), mTopGridAnnotationDirection( Horizontal ),
mBottomGridAnnotationDirection( Horizontal ), mGridFrameStyle( NoGridFrame ), mGridFrameWidth( 2.0 ), mGridFramePenThickness( 0.5 ), mBottomGridAnnotationDirection( Horizontal ), mGridFrameStyle( NoGridFrame ), mGridFrameWidth( 2.0 ), mGridFramePenThickness( 0.5 ),
mGridFramePenColor( QColor( 0, 0, 0 ) ), mGridFrameFillColor1( Qt::white ), mGridFrameFillColor2( Qt::black ), mGridFramePenColor( QColor( 0, 0, 0 ) ), mGridFrameFillColor1( Qt::white ), mGridFrameFillColor2( Qt::black ),
mCrossLength( 3 ), mMapCanvas( 0 ), mDrawCanvasItems( true ) mCrossLength( 3 ), mMapCanvas( 0 ), mDrawCanvasItems( true ), mAtlasDriven( false ), mAtlasFixedScale( false ), mAtlasMargin( 0.10 )
{ {
mOverviewFrameMapSymbol = 0; mOverviewFrameMapSymbol = 0;
mGridLineSymbol = 0; mGridLineSymbol = 0;
@ -651,10 +651,7 @@ void QgsComposerMap::toggleAtlasPreview()
QgsRectangle* QgsComposerMap::currentMapExtent() QgsRectangle* QgsComposerMap::currentMapExtent()
{ {
//non-const version //non-const version
if ( mAtlasDriven && mComposition->atlasMode() != QgsComposition::AtlasOff )
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
if ( atlasMap->composerMap() == this && mComposition->atlasMode() != QgsComposition::AtlasOff )
{ {
//if atlas is enabled, and we are either exporting the composition or previewing the atlas, then //if atlas is enabled, and we are either exporting the composition or previewing the atlas, then
//return the current temporary atlas feature extent //return the current temporary atlas feature extent
@ -670,9 +667,7 @@ QgsRectangle* QgsComposerMap::currentMapExtent()
const QgsRectangle* QgsComposerMap::currentMapExtent() const const QgsRectangle* QgsComposerMap::currentMapExtent() const
{ {
//const version //const version
if ( mAtlasDriven && mComposition->atlasMode() != QgsComposition::AtlasOff )
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
if ( atlasMap->composerMap() == this && mComposition->atlasMode() != QgsComposition::AtlasOff )
{ {
//if atlas is enabled, and we are either exporting the composition or previewing the atlas, then //if atlas is enabled, and we are either exporting the composition or previewing the atlas, then
//return the current temporary atlas feature extent //return the current temporary atlas feature extent
@ -991,6 +986,13 @@ bool QgsComposerMap::writeXML( QDomElement& elem, QDomDocument & doc ) const
gridElem.appendChild( annotationElem ); gridElem.appendChild( annotationElem );
composerMapElem.appendChild( gridElem ); composerMapElem.appendChild( gridElem );
//atlas
QDomElement atlasElem = doc.createElement( "AtlasMap" );
atlasElem.setAttribute( "atlasDriven", mAtlasDriven );
atlasElem.setAttribute( "fixedScale", mAtlasFixedScale );
atlasElem.setAttribute( "margin", qgsDoubleToString( mAtlasMargin ) );
composerMapElem.appendChild( atlasElem );
elem.appendChild( composerMapElem ); elem.appendChild( composerMapElem );
return _writeXML( composerMapElem, doc ); return _writeXML( composerMapElem, doc );
} }
@ -1233,6 +1235,16 @@ bool QgsComposerMap::readXML( const QDomElement& itemElem, const QDomDocument& d
} }
} }
//atlas
QDomNodeList atlasNodeList = itemElem.elementsByTagName( "AtlasMap" );
if ( atlasNodeList.size() > 0 )
{
QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
mAtlasDriven = ( atlasElem.attribute( "atlasDriven", "0" ) != "0" );
mAtlasFixedScale = ( atlasElem.attribute( "fixedScale", "0" ) != "0" );
mAtlasMargin = atlasElem.attribute( "margin", "0.1" ).toDouble();
}
//restore general composer item properties //restore general composer item properties
QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" ); QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
if ( composerItemList.size() > 0 ) if ( composerItemList.size() > 0 )

View File

@ -420,6 +420,21 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
*/ */
void sizeChangedByRotation( double& width, double& height ); void sizeChangedByRotation( double& width, double& height );
/** Returns true if the map extent is set to follow the current atlas feature */
bool atlasDriven() const { return mAtlasDriven; }
/** Set to true if the map extents should be set by the current atlas feature */
void setAtlasDriven( bool enabled ) { mAtlasDriven = enabled; }
/** Returns true if the map uses a fixed scale when in atlas mode */
bool atlasFixedScale() const { return mAtlasFixedScale; }
/** Set to true if the map should use a fixed scale when in atlas mode */
void setAtlasFixedScale( bool fixed ) { mAtlasFixedScale = fixed; }
/** Returns the margin size (percentage) used when the map is in atlas mode */
double atlasMargin() const { return mAtlasMargin; }
/** Sets the margin size (percentage) used when the map is in atlas mode */
void setAtlasMargin( double margin ) { mAtlasMargin = margin; }
signals: signals:
void extentChanged(); void extentChanged();
@ -571,6 +586,13 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
* center of extent remains the same */ * center of extent remains the same */
void adjustExtentToItemShape( double itemWidth, double itemHeight, QgsRectangle& extent ) const; void adjustExtentToItemShape( double itemWidth, double itemHeight, QgsRectangle& extent ) const;
/**True if map is being controlled by an atlas*/
bool mAtlasDriven;
/**True if map uses a fixed scale when controlled by an atlas*/
bool mAtlasFixedScale;
/**Margin size for atlas driven extents (percentage of feature size)*/
double mAtlasMargin;
/**Draws the map grid*/ /**Draws the map grid*/
void drawGrid( QPainter* p ); void drawGrid( QPainter* p );
void drawGridFrame( QPainter* p, const QList< QPair< double, QLineF > >& hLines, const QList< QPair< double, QLineF > >& vLines ); void drawGridFrame( QPainter* p, const QList< QPair< double, QLineF > >& hLines, const QList< QPair< double, QLineF > >& vLines );

View File

@ -2347,9 +2347,16 @@ bool QgsComposition::setAtlasMode( QgsComposition::AtlasMode mode )
} }
} }
if ( mAtlasComposition.composerMap() ) QList<QgsComposerMap*> maps;
composerItems( maps );
for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
{ {
mAtlasComposition.composerMap()->toggleAtlasPreview(); QgsComposerMap* currentMap = ( *mit );
if ( !currentMap->atlasDriven() )
{
continue;
}
currentMap->toggleAtlasPreview();
} }
update(); update();

View File

@ -23,7 +23,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -32,15 +41,24 @@
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing"> <property name="horizontalSpacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="verticalSpacing"> <property name="verticalSpacing">
<number>3</number> <number>3</number>
</property> </property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QCheckBox" name="mUseAtlasCheckBox"> <widget class="QCheckBox" name="mUseAtlasCheckBox">
<property name="text"> <property name="text">
@ -91,7 +109,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>431</width> <width>431</width>
<height>568</height> <height>567</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="mainLayout"> <layout class="QVBoxLayout" name="mainLayout">
@ -123,27 +141,13 @@
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="mVerticalAlignementLabel">
<property name="text">
<string>Composer map</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QComboBox" name="mComposerMapComboBox"/>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mHorizontalAlignementLabel"> <widget class="QLabel" name="mHorizontalAlignementLabel">
<property name="text"> <property name="text">
<string>Coverage layer</string> <string>Coverage layer</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5"> <layout class="QHBoxLayout" name="horizontalLayout_5">
<item> <item>
<widget class="QComboBox" name="mAtlasCoverageLayerComboBox"/> <widget class="QComboBox" name="mAtlasCoverageLayerComboBox"/>
@ -280,60 +284,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QgsCollapsibleGroupBoxBasic" name="mScalingGroup">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Scaling</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="syncGroup" stdset="0">
<string notr="true">composeritem</string>
</property>
<property name="collapsed" stdset="0">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QRadioButton" name="mAtlasMarginRadio">
<property name="text">
<string>Margin around feature</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="mAtlasMarginSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix">
<string>%</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="mAtlasFixedScaleRadio">
<property name="text">
<string>Fixed scale</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QgsCollapsibleGroupBoxBasic" name="mOutputGroup"> <widget class="QgsCollapsibleGroupBoxBasic" name="mOutputGroup">
<property name="enabled"> <property name="enabled">

View File

@ -23,7 +23,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -54,9 +63,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>-420</y> <y>0</y>
<width>439</width> <width>439</width>
<height>1509</height> <height>1638</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -251,6 +260,66 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QgsCollapsibleGroupBoxBasic" name="mAtlasCheckBox">
<property name="title">
<string>Controlled by atlas</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="collapsed" stdset="0">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QRadioButton" name="mAtlasMarginRadio">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Margin around feature</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="mAtlasMarginSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix">
<string>%</string>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="mAtlasFixedScaleRadio">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Fixed scale</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QgsCollapsibleGroupBoxBasic" name="mGridCheckBox"> <widget class="QgsCollapsibleGroupBoxBasic" name="mGridCheckBox">
<property name="title"> <property name="title">

View File

@ -36,7 +36,7 @@ QgsCompositionChecker::~QgsCompositionChecker()
{ {
} }
bool QgsCompositionChecker::testComposition( QString &report, int page ) bool QgsCompositionChecker::testComposition( QString &report, int page, int pixelDiff )
{ {
if ( !mComposition ) if ( !mComposition )
{ {
@ -82,7 +82,7 @@ bool QgsCompositionChecker::testComposition( QString &report, int page )
QString diffFilePath = QDir::tempPath() + QDir::separator() + QFileInfo( mTestName ).baseName() + "_result_diff.png"; QString diffFilePath = QDir::tempPath() + QDir::separator() + QFileInfo( mTestName ).baseName() + "_result_diff.png";
bool testResult = compareImages( mTestName, 0, renderedFilePath ); bool testResult = compareImages( mTestName, pixelDiff, renderedFilePath );
QString myDashMessage = "<DartMeasurementFile name=\"Rendered Image " + mTestName + "\"" QString myDashMessage = "<DartMeasurementFile name=\"Rendered Image " + mTestName + "\""
" type=\"image/png\">" + renderedFilePath + " type=\"image/png\">" + renderedFilePath +

View File

@ -29,7 +29,7 @@ class QgsCompositionChecker : public QgsRenderChecker
QgsCompositionChecker( const QString& testName, QgsComposition* composition ); QgsCompositionChecker( const QString& testName, QgsComposition* composition );
~QgsCompositionChecker(); ~QgsCompositionChecker();
bool testComposition( QString &report, int page = 0 ); bool testComposition( QString &report, int page = 0, int pixelDiff = 0 );
private: private:
QgsCompositionChecker(); //forbidden QgsCompositionChecker(); //forbidden

View File

@ -43,8 +43,14 @@ class TestQgsAtlasComposition: public QObject
void filename(); void filename();
// test rendering with an autoscale atlas // test rendering with an autoscale atlas
void autoscale_render(); void autoscale_render();
// test rendering with an autoscale atlas using the old api
void autoscale_render_2_0_api();
// test rendering with a fixed scale atlas // test rendering with a fixed scale atlas
void fixedscale_render(); void fixedscale_render();
// test rendering with a fixed scale atlas using the old api
void fixedscale_render_2_0_api();
// test rendering with two atlas-driven maps
void two_map_autoscale_render();
// test rendering with a hidden coverage // test rendering with a hidden coverage
void hiding_render(); void hiding_render();
// test rendering with feature sorting // test rendering with feature sorting
@ -104,7 +110,6 @@ void TestQgsAtlasComposition::initTestCase()
mAtlas = &mComposition->atlasComposition(); mAtlas = &mComposition->atlasComposition();
mAtlas->setCoverageLayer( mVectorLayer ); mAtlas->setCoverageLayer( mVectorLayer );
mAtlas->setComposerMap( mAtlasMap );
mComposition->setAtlasMode( QgsComposition::ExportAtlas ); mComposition->setAtlasMode( QgsComposition::ExportAtlas );
// an overview // an overview
@ -180,6 +185,29 @@ void TestQgsAtlasComposition::filename()
void TestQgsAtlasComposition::autoscale_render() void TestQgsAtlasComposition::autoscale_render()
{ {
mAtlasMap->setAtlasDriven( true );
mAtlasMap->setAtlasFixedScale( false );
mAtlasMap->setAtlasMargin( 0.10 );
mAtlas->beginRender();
for ( int fit = 0; fit < 2; ++fit )
{
mAtlas->prepareForFeature( fit );
mLabel1->adjustSizeToText();
QgsCompositionChecker checker( QString( "atlas_autoscale%1" ).arg((( int )fit ) + 1 ), mComposition );
QVERIFY( checker.testComposition( mReport, 0, 10 ) );
}
mAtlas->endRender();
mAtlasMap->setAtlasDriven( false );
mAtlasMap->setAtlasFixedScale( false );
mAtlasMap->setAtlasMargin( 0 );
}
void TestQgsAtlasComposition::autoscale_render_2_0_api()
{
mAtlas->setComposerMap( mAtlasMap );
mAtlas->setFixedScale( false ); mAtlas->setFixedScale( false );
mAtlas->setMargin( 0.10f ); mAtlas->setMargin( 0.10f );
@ -190,16 +218,20 @@ void TestQgsAtlasComposition::autoscale_render()
mAtlas->prepareForFeature( fit ); mAtlas->prepareForFeature( fit );
mLabel1->adjustSizeToText(); mLabel1->adjustSizeToText();
QgsCompositionChecker checker( QString( "atlas_autoscale%1" ).arg((( int )fit ) + 1 ), mComposition ); QgsCompositionChecker checker( QString( "atlas_autoscale_old_api%1" ).arg((( int )fit ) + 1 ), mComposition );
QVERIFY( checker.testComposition( mReport, 0 ) ); QVERIFY( checker.testComposition( mReport, 0 ) );
} }
mAtlas->endRender(); mAtlas->endRender();
mAtlas->setComposerMap( 0 );
mAtlas->setFixedScale( false );
mAtlas->setMargin( 0 );
} }
void TestQgsAtlasComposition::fixedscale_render() void TestQgsAtlasComposition::fixedscale_render()
{ {
mAtlasMap->setAtlasDriven( true );
mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
mAtlas->setFixedScale( true ); mAtlasMap->setAtlasFixedScale( true );
mAtlas->beginRender(); mAtlas->beginRender();
@ -213,12 +245,61 @@ void TestQgsAtlasComposition::fixedscale_render()
} }
mAtlas->endRender(); mAtlas->endRender();
mAtlasMap->setAtlasDriven( false );
mAtlasMap->setAtlasFixedScale( false );
}
void TestQgsAtlasComposition::fixedscale_render_2_0_api()
{
mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
mAtlas->setComposerMap( mAtlasMap );
mAtlas->setFixedScale( true );
mAtlas->beginRender();
for ( int fit = 0; fit < 2; ++fit )
{
mAtlas->prepareForFeature( fit );
mLabel1->adjustSizeToText();
QgsCompositionChecker checker( QString( "atlas_fixedscale_old_api%1" ).arg((( int )fit ) + 1 ), mComposition );
QVERIFY( checker.testComposition( mReport, 0 ) );
}
mAtlas->endRender();
mAtlas->setComposerMap( 0 );
mAtlas->setFixedScale( false );
}
void TestQgsAtlasComposition::two_map_autoscale_render()
{
mAtlasMap->setAtlasDriven( true );
mAtlasMap->setAtlasFixedScale( false );
mAtlasMap->setAtlasMargin( 0.10 );
mOverview->setAtlasDriven( true );
mOverview->setAtlasFixedScale( false );
mOverview->setAtlasMargin( 2.0 );
mAtlas->beginRender();
for ( int fit = 0; fit < 2; ++fit )
{
mAtlas->prepareForFeature( fit );
mLabel1->adjustSizeToText();
QgsCompositionChecker checker( QString( "atlas_two_maps%1" ).arg((( int )fit ) + 1 ), mComposition );
QVERIFY( checker.testComposition( mReport, 0, 10 ) );
}
mAtlas->endRender();
mAtlasMap->setAtlasDriven( false );
mAtlasMap->setAtlasFixedScale( false );
mAtlasMap->setAtlasMargin( 0 );
mOverview->setAtlasDriven( false );
} }
void TestQgsAtlasComposition::hiding_render() void TestQgsAtlasComposition::hiding_render()
{ {
mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
mAtlas->setFixedScale( true ); mAtlasMap->setAtlasDriven( true );
mAtlasMap->setAtlasFixedScale( true );
mAtlas->setHideCoverage( true ); mAtlas->setHideCoverage( true );
mAtlas->beginRender(); mAtlas->beginRender();
@ -237,7 +318,8 @@ void TestQgsAtlasComposition::hiding_render()
void TestQgsAtlasComposition::sorting_render() void TestQgsAtlasComposition::sorting_render()
{ {
mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
mAtlas->setFixedScale( true ); mAtlasMap->setAtlasDriven( true );
mAtlasMap->setAtlasFixedScale( true );
mAtlas->setHideCoverage( false ); mAtlas->setHideCoverage( false );
mAtlas->setSortFeatures( true ); mAtlas->setSortFeatures( true );
@ -260,7 +342,8 @@ void TestQgsAtlasComposition::sorting_render()
void TestQgsAtlasComposition::filtering_render() void TestQgsAtlasComposition::filtering_render()
{ {
mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
mAtlas->setFixedScale( true ); mAtlasMap->setAtlasDriven( true );
mAtlasMap->setAtlasFixedScale( true );
mAtlas->setHideCoverage( false ); mAtlas->setHideCoverage( false );
mAtlas->setSortFeatures( false ); mAtlas->setSortFeatures( false );

View File

@ -27,7 +27,7 @@ class QgsCompositionChecker(QgsRenderChecker):
self.mTestName = mTestName self.mTestName = mTestName
super(QgsCompositionChecker, self).__init__() super(QgsCompositionChecker, self).__init__()
def testComposition(self, page=0 ): def testComposition(self, page=0, pixelDiff=0 ):
if ( self.mComposition == None): if ( self.mComposition == None):
myMessage = "Composition not valid" myMessage = "Composition not valid"
return False, myMessage return False, myMessage
@ -53,7 +53,7 @@ class QgsCompositionChecker(QgsRenderChecker):
outputImage.save( renderedFilePath, "PNG" ) outputImage.save( renderedFilePath, "PNG" )
diffFilePath = QDir.tempPath() + QDir.separator() + QFileInfo(self.mTestName).baseName() + "_result_diff.png" diffFilePath = QDir.tempPath() + QDir.separator() + QFileInfo(self.mTestName).baseName() + "_result_diff.png"
testResult = self.compareImages( self.mTestName, 0, renderedFilePath ) testResult = self.compareImages( self.mTestName, pixelDiff, renderedFilePath )
myDashMessage = (('<DartMeasurementFile name="Rendered Image ' myDashMessage = (('<DartMeasurementFile name="Rendered Image '
'%s" type="image/png">' '%s" type="image/png">'

View File

@ -63,7 +63,6 @@ class TestQgsAtlasComposition(unittest.TestCase):
# the atlas # the atlas
self.mAtlas = self.mComposition.atlasComposition() self.mAtlas = self.mComposition.atlasComposition()
self.mAtlas.setCoverageLayer( mVectorLayer ) self.mAtlas.setCoverageLayer( mVectorLayer )
self.mAtlas.setComposerMap( self.mAtlasMap )
self.mComposition.setAtlasMode( QgsComposition.ExportAtlas ) self.mComposition.setAtlasMode( QgsComposition.ExportAtlas )
# an overview # an overview
@ -99,6 +98,7 @@ class TestQgsAtlasComposition(unittest.TestCase):
self.filename_test() self.filename_test()
self.autoscale_render_test() self.autoscale_render_test()
self.autoscale_render_test_old_api()
self.fixedscale_render_test() self.fixedscale_render_test()
self.hidden_render_test() self.hidden_render_test()
@ -113,6 +113,28 @@ class TestQgsAtlasComposition(unittest.TestCase):
self.mAtlas.endRender() self.mAtlas.endRender()
def autoscale_render_test( self ): def autoscale_render_test( self ):
self.mAtlasMap.setAtlasDriven( True )
self.mAtlasMap.setAtlasFixedScale( False )
self.mAtlasMap.setAtlasMargin( 0.10 )
self.mAtlas.beginRender()
for i in range(0, 2):
self.mAtlas.prepareForFeature( i )
self.mLabel1.adjustSizeToText()
checker = QgsCompositionChecker('atlas_autoscale%d' % (i + 1), self.mComposition)
myTestResult, myMessage = checker.testComposition(0, 10)
assert myTestResult == True
self.mAtlas.endRender()
self.mAtlasMap.setAtlasDriven( False )
self.mAtlasMap.setAtlasFixedScale( True )
self.mAtlasMap.setAtlasMargin( 0 )
def autoscale_render_test_old_api( self ):
self.mAtlas.setComposerMap( self.mAtlasMap )
self.mAtlas.setFixedScale( False ) self.mAtlas.setFixedScale( False )
self.mAtlas.setMargin( 0.10 ) self.mAtlas.setMargin( 0.10 )
@ -122,15 +144,20 @@ class TestQgsAtlasComposition(unittest.TestCase):
self.mAtlas.prepareForFeature( i ) self.mAtlas.prepareForFeature( i )
self.mLabel1.adjustSizeToText() self.mLabel1.adjustSizeToText()
checker = QgsCompositionChecker('atlas_autoscale%d' % (i + 1), self.mComposition) checker = QgsCompositionChecker('atlas_autoscale_old_api%d' % (i + 1), self.mComposition)
myTestResult, myMessage = checker.testComposition() myTestResult, myMessage = checker.testComposition()
assert myTestResult == True assert myTestResult == True
self.mAtlas.endRender() self.mAtlas.endRender()
def fixedscale_render_test( self ):
self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
self.mAtlas.setFixedScale( True ) self.mAtlas.setFixedScale( True )
self.mAtlas.setMargin( 0 )
self.mAtlas.setComposerMap( None )
def fixedscale_render_test( self ):
self.mAtlasMap.setAtlasDriven( True )
self.mAtlasMap.setAtlasFixedScale( True )
self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
self.mAtlas.beginRender() self.mAtlas.beginRender()
@ -146,7 +173,7 @@ class TestQgsAtlasComposition(unittest.TestCase):
def hidden_render_test( self ): def hidden_render_test( self ):
self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
self.mAtlas.setFixedScale( True ) self.mAtlasMap.setAtlasFixedScale( True )
self.mAtlas.setHideCoverage( True ) self.mAtlas.setHideCoverage( True )
self.mAtlas.beginRender() self.mAtlas.beginRender()
@ -163,7 +190,7 @@ class TestQgsAtlasComposition(unittest.TestCase):
def sorting_render_test( self ): def sorting_render_test( self ):
self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
self.mAtlas.setFixedScale( True ) self.mAtlasMap.setAtlasFixedScale( True )
self.mAtlas.setHideCoverage( False ) self.mAtlas.setHideCoverage( False )
self.mAtlas.setSortFeatures( True ) self.mAtlas.setSortFeatures( True )
@ -184,7 +211,7 @@ class TestQgsAtlasComposition(unittest.TestCase):
def filtering_render_test( self ): def filtering_render_test( self ):
self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
self.mAtlas.setFixedScale( True ) self.mAtlasMap.setAtlasFixedScale( True )
self.mAtlas.setHideCoverage( False ) self.mAtlas.setHideCoverage( False )
self.mAtlas.setSortFeatures( False ) self.mAtlas.setSortFeatures( False )

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB