[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)
@ -17,16 +17,34 @@ public:
|
||||
bool enabled() const;
|
||||
void setEnabled( bool e );
|
||||
|
||||
/**Returns the map used by the atlas
|
||||
* @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;
|
||||
void setHideCoverage( bool hide );
|
||||
|
||||
/**Returns whether the atlas map uses a fixed scale
|
||||
* @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 );
|
||||
|
||||
/**Returns the margin for the atlas map
|
||||
* @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;
|
||||
@ -66,6 +84,21 @@ public:
|
||||
|
||||
/** Returns the current filename. Must be called after prepareForFeature( i ) */
|
||||
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 readXML( const QDomElement& elem, const QDomDocument& doc );
|
||||
|
@ -366,7 +366,22 @@ class QgsComposerMap : QgsComposerItem
|
||||
* @deprecated Use QgsComposerItem::sizeChangedByRotation( double& width, double& height, double rotation )
|
||||
* 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:
|
||||
void extentChanged();
|
||||
|
@ -49,27 +49,10 @@ QgsAtlasCompositionWidget::QgsAtlasCompositionWidget( QWidget* parent, QgsCompos
|
||||
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
|
||||
mAtlasSortFeatureDirectionButton->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( &mComposition->atlasComposition(), SIGNAL( parameterChanged() ), this, SLOT( updateGuiElements() ) );
|
||||
|
||||
@ -90,7 +73,6 @@ void QgsAtlasCompositionWidget::on_mUseAtlasCheckBox_stateChanged( int state )
|
||||
mVisibilityGroup->setEnabled( true );
|
||||
mSortingGroup->setEnabled( true );
|
||||
mFilteringGroup->setEnabled( true );
|
||||
mScalingGroup->setEnabled( true );
|
||||
mOutputGroup->setEnabled( true );
|
||||
}
|
||||
else
|
||||
@ -100,7 +82,6 @@ void QgsAtlasCompositionWidget::on_mUseAtlasCheckBox_stateChanged( int state )
|
||||
mVisibilityGroup->setEnabled( false );
|
||||
mSortingGroup->setEnabled( false );
|
||||
mFilteringGroup->setEnabled( false );
|
||||
mScalingGroup->setEnabled( false );
|
||||
mOutputGroup->setEnabled( false );
|
||||
}
|
||||
}
|
||||
@ -137,39 +118,10 @@ void QgsAtlasCompositionWidget::onLayerAdded( QgsMapLayer* map )
|
||||
{
|
||||
atlasMap->setCoverageLayer( vectorLayer );
|
||||
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 )
|
||||
{
|
||||
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
|
||||
@ -190,7 +142,6 @@ void QgsAtlasCompositionWidget::on_mAtlasCoverageLayerComboBox_currentIndexChang
|
||||
|
||||
if ( layer )
|
||||
{
|
||||
checkLayerType( layer );
|
||||
atlasMap->setCoverageLayer( layer );
|
||||
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 )
|
||||
{
|
||||
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
|
||||
@ -280,22 +193,6 @@ void QgsAtlasCompositionWidget::on_mAtlasHideCoverageCheckBox_stateChanged( int
|
||||
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 )
|
||||
{
|
||||
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
|
||||
@ -487,26 +384,9 @@ void QgsAtlasCompositionWidget::updateGuiElements()
|
||||
if ( idx != -1 )
|
||||
{
|
||||
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() );
|
||||
if ( atlasMap->fixedScale() )
|
||||
{
|
||||
mAtlasFixedScaleRadio->setChecked( true );
|
||||
mAtlasMarginSpinBox->setEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
mAtlasMarginRadio->setChecked( true );
|
||||
mAtlasMarginSpinBox->setEnabled( true );
|
||||
}
|
||||
mAtlasHideCoverageCheckBox->setCheckState( atlasMap->hideCoverage() ? Qt::Checked : Qt::Unchecked );
|
||||
mAtlasSingleFileCheckBox->setCheckState( atlasMap->singleFile() ? Qt::Checked : Qt::Unchecked );
|
||||
mAtlasSortFeatureCheckBox->setCheckState( atlasMap->sortFeatures() ? Qt::Checked : Qt::Unchecked );
|
||||
@ -523,6 +403,5 @@ void QgsAtlasCompositionWidget::blockAllSignals( bool b )
|
||||
mVisibilityGroup->blockSignals( b );
|
||||
mSortingGroup->blockSignals( b );
|
||||
mFilteringGroup->blockSignals( b );
|
||||
mScalingGroup->blockSignals( b );
|
||||
mOutputGroup->blockSignals( b );
|
||||
}
|
||||
|
@ -36,12 +36,10 @@ class QgsAtlasCompositionWidget:
|
||||
|
||||
public slots:
|
||||
void on_mUseAtlasCheckBox_stateChanged( int state );
|
||||
void on_mComposerMapComboBox_currentIndexChanged( int index );
|
||||
void on_mAtlasCoverageLayerComboBox_currentIndexChanged( int index );
|
||||
void on_mAtlasFilenamePatternEdit_textChanged( const QString& text );
|
||||
void on_mAtlasFilenameExpressionButton_clicked();
|
||||
void on_mAtlasHideCoverageCheckBox_stateChanged( int state );
|
||||
void on_mAtlasFixedScaleRadio_toggled( bool checked );
|
||||
void on_mAtlasSingleFileCheckBox_stateChanged( int state );
|
||||
|
||||
void on_mAtlasSortFeatureCheckBox_stateChanged( int state );
|
||||
@ -50,15 +48,12 @@ class QgsAtlasCompositionWidget:
|
||||
void on_mAtlasFeatureFilterEdit_editingFinished();
|
||||
void on_mAtlasFeatureFilterButton_clicked();
|
||||
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
|
||||
void fillSortColumns();
|
||||
private slots:
|
||||
void onLayerRemoved( QString );
|
||||
void onLayerAdded( QgsMapLayer* );
|
||||
void onComposerMapAdded( QgsComposerMap* );
|
||||
void onItemRemoved( QgsComposerItem* );
|
||||
|
||||
void updateGuiElements();
|
||||
|
||||
|
@ -90,9 +90,21 @@ 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() ) );
|
||||
|
||||
//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();
|
||||
@ -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 )
|
||||
{
|
||||
Q_UNUSED( i );
|
||||
@ -402,10 +519,73 @@ void QgsComposerMapWidget::updateGuiElements()
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if ( !mComposerMap )
|
||||
@ -480,6 +660,10 @@ void QgsComposerMapWidget::blockAllSignals( bool b )
|
||||
mOverviewBlendModeComboBox->blockSignals( b );
|
||||
mOverviewInvertCheckbox->blockSignals( b );
|
||||
mOverviewCenterCheckbox->blockSignals( b );
|
||||
mAtlasCheckBox->blockSignals( b );
|
||||
mAtlasMarginSpinBox->blockSignals( b );
|
||||
mAtlasFixedScaleRadio->blockSignals( b );
|
||||
mAtlasMarginRadio->blockSignals( b );
|
||||
}
|
||||
|
||||
void QgsComposerMapWidget::on_mUpdatePreviewButton_clicked()
|
||||
@ -1173,3 +1357,14 @@ void QgsComposerMapWidget::refreshMapComboBox()
|
||||
|
||||
mOverviewFrameMapComboBox->blockSignals( false );
|
||||
}
|
||||
|
||||
void QgsComposerMapWidget::atlasLayerChanged( QgsVectorLayer* layer )
|
||||
{
|
||||
// enable or disable fixed scale control based on layer type
|
||||
if ( !layer || !mAtlasCheckBox->isChecked() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
toggleAtlasMarginByLayerType();
|
||||
}
|
||||
|
@ -90,6 +90,13 @@ 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 );
|
||||
|
||||
protected:
|
||||
void showEvent( QShowEvent * event );
|
||||
|
||||
@ -103,6 +110,12 @@ class QgsComposerMapWidget: public QWidget, private Ui::QgsComposerMapWidgetBase
|
||||
/**Sets the GUI elements to the values of mPicture*/
|
||||
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:
|
||||
QgsComposerMap* mComposerMap;
|
||||
|
||||
@ -129,6 +142,13 @@ 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();
|
||||
|
||||
/**Recalculates the bounds for an atlas map when atlas properties change*/
|
||||
void updateMapForAtlas();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -31,8 +31,7 @@
|
||||
QgsAtlasComposition::QgsAtlasComposition( QgsComposition* composition ) :
|
||||
mComposition( composition ),
|
||||
mEnabled( false ),
|
||||
mComposerMap( 0 ),
|
||||
mHideCoverage( false ), mFixedScale( false ), mMargin( 0.10 ), mFilenamePattern( "'output_'||$feature" ),
|
||||
mHideCoverage( false ), mFilenamePattern( "'output_'||$feature" ),
|
||||
mCoverageLayer( 0 ), mSingleFile( false ),
|
||||
mSortFeatures( false ), mSortAscending( true ), mCurrentFeatureNo( 0 ),
|
||||
mFilterFeatures( false ), mFeatureFilter( "" )
|
||||
@ -70,6 +69,87 @@ void QgsAtlasComposition::setCoverageLayer( QgsVectorLayer* layer )
|
||||
layer->getFeatures().nextFeature( fet );
|
||||
QgsExpression::setSpecialColumn( "$atlasfeatureid", fet.id() );
|
||||
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
|
||||
|
||||
if ( !mComposerMap || !mCoverageLayer )
|
||||
if ( !mCoverageLayer )
|
||||
{
|
||||
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();
|
||||
|
||||
// select all features with all attributes
|
||||
@ -184,7 +258,7 @@ int QgsAtlasComposition::updateFeatures()
|
||||
|
||||
bool QgsAtlasComposition::beginRender()
|
||||
{
|
||||
if ( !mComposerMap || !mCoverageLayer )
|
||||
if ( !mCoverageLayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -218,7 +292,7 @@ bool QgsAtlasComposition::beginRender()
|
||||
|
||||
void QgsAtlasComposition::endRender()
|
||||
{
|
||||
if ( !mComposerMap || !mCoverageLayer )
|
||||
if ( !mCoverageLayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -239,7 +313,24 @@ void QgsAtlasComposition::endRender()
|
||||
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
|
||||
@ -283,7 +374,7 @@ void QgsAtlasComposition::lastFeature()
|
||||
|
||||
void QgsAtlasComposition::prepareForFeature( int featureI )
|
||||
{
|
||||
if ( !mComposerMap || !mCoverageLayer )
|
||||
if ( !mCoverageLayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -304,70 +395,6 @@ void QgsAtlasComposition::prepareForFeature( int featureI )
|
||||
// generate filename for current feature
|
||||
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
|
||||
QList<QgsComposerLabel*> labels;
|
||||
mComposition->composerItems( labels );
|
||||
@ -392,10 +419,118 @@ void QgsAtlasComposition::prepareForFeature( int featureI )
|
||||
( *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() ) );
|
||||
|
||||
//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
|
||||
@ -420,18 +555,9 @@ void QgsAtlasComposition::writeXML( QDomElement& elem, QDomDocument& doc ) const
|
||||
{
|
||||
atlasElem.setAttribute( "coverageLayer", "" );
|
||||
}
|
||||
if ( mComposerMap )
|
||||
{
|
||||
atlasElem.setAttribute( "composerMap", mComposerMap->id() );
|
||||
}
|
||||
else
|
||||
{
|
||||
atlasElem.setAttribute( "composerMap", "" );
|
||||
}
|
||||
|
||||
atlasElem.setAttribute( "hideCoverage", mHideCoverage ? "true" : "false" );
|
||||
atlasElem.setAttribute( "fixedScale", mFixedScale ? "true" : "false" );
|
||||
atlasElem.setAttribute( "singleFile", mSingleFile ? "true" : "false" );
|
||||
atlasElem.setAttribute( "margin", QString::number( mMargin ) );
|
||||
atlasElem.setAttribute( "filenamePattern", mFilenamePattern );
|
||||
|
||||
atlasElem.setAttribute( "sortFeatures", mSortFeatures ? "true" : "false" );
|
||||
@ -470,20 +596,36 @@ void QgsAtlasComposition::readXML( const QDomElement& atlasElem, const QDomDocum
|
||||
break;
|
||||
}
|
||||
}
|
||||
// look for stored composer map
|
||||
mComposerMap = 0;
|
||||
QList<const QgsComposerMap*> maps = mComposition->composerMapItems();
|
||||
for ( QList<const QgsComposerMap*>::const_iterator it = maps.begin(); it != maps.end(); ++it )
|
||||
//look for stored composer map, to upgrade pre 2.1 projects
|
||||
int composerMapNo = atlasElem.attribute( "composerMap", "0" ).toInt();
|
||||
QgsComposerMap * composerMap = 0;
|
||||
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 );
|
||||
break;
|
||||
if (( *it )->id() == composerMapNo )
|
||||
{
|
||||
( *it )->setAtlasDriven( true );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mMargin = atlasElem.attribute( "margin", "0.0" ).toDouble();
|
||||
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;
|
||||
mFilenamePattern = atlasElem.attribute( "filenamePattern", "" );
|
||||
|
||||
@ -528,7 +670,7 @@ void QgsAtlasComposition::setHideCoverage( bool hide )
|
||||
mRestoreLayer = false;
|
||||
}
|
||||
}
|
||||
mComposerMap->cache();
|
||||
updateAtlasMaps();
|
||||
mComposition->update();
|
||||
}
|
||||
|
||||
|
@ -45,17 +45,35 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
|
||||
bool enabled() const { return mEnabled; }
|
||||
void setEnabled( bool e );
|
||||
|
||||
QgsComposerMap* composerMap() const { return mComposerMap; }
|
||||
void setComposerMap( QgsComposerMap* map ) { mComposerMap = map; }
|
||||
/**Returns the map used by the atlas
|
||||
* @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; }
|
||||
void setHideCoverage( bool hide );
|
||||
|
||||
bool fixedScale() const { return mFixedScale; }
|
||||
void setFixedScale( bool fixed ) { mFixedScale = fixed; }
|
||||
/**Returns whether the atlas map uses a fixed scale
|
||||
* @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; }
|
||||
void setMargin( float margin ) { mMargin = margin; }
|
||||
/**Returns the margin for the atlas map
|
||||
* @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; }
|
||||
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 ). */
|
||||
QgsFeature* currentFeature() { return &mCurrentFeature; }
|
||||
|
||||
/** Recalculates the bounds of an atlas driven map */
|
||||
void prepareMap( QgsComposerMap* map );
|
||||
|
||||
signals:
|
||||
/** emitted when one of the parameters changes */
|
||||
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*/
|
||||
void statusMsgChanged( QString message );
|
||||
|
||||
/**Is emitted when the coverage layer for an atlas changes*/
|
||||
void coverageLayerChanged( QgsVectorLayer* layer );
|
||||
|
||||
private:
|
||||
/**Updates the filename expression*/
|
||||
void updateFilenameExpression();
|
||||
@ -133,10 +157,7 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
|
||||
QgsComposition* mComposition;
|
||||
|
||||
bool mEnabled;
|
||||
QgsComposerMap* mComposerMap;
|
||||
bool mHideCoverage;
|
||||
bool mFixedScale;
|
||||
double mMargin;
|
||||
QString mFilenamePattern;
|
||||
QgsVectorLayer* mCoverageLayer;
|
||||
bool mSingleFile;
|
||||
@ -170,6 +191,12 @@ class CORE_EXPORT QgsAtlasComposition : public QObject
|
||||
QgsFeature mCurrentFeature;
|
||||
bool mRestoreLayer;
|
||||
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
|
||||
|
@ -51,7 +51,7 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int w
|
||||
mLeftGridAnnotationDirection( Horizontal ), mRightGridAnnotationDirection( Horizontal ), mTopGridAnnotationDirection( Horizontal ),
|
||||
mBottomGridAnnotationDirection( Horizontal ), mGridFrameStyle( NoGridFrame ), mGridFrameWidth( 2.0 ),
|
||||
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;
|
||||
mOverviewFrameMapSymbol = 0;
|
||||
@ -106,7 +106,7 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition )
|
||||
mLeftGridAnnotationDirection( Horizontal ), mRightGridAnnotationDirection( Horizontal ), mTopGridAnnotationDirection( Horizontal ),
|
||||
mBottomGridAnnotationDirection( Horizontal ), mGridFrameStyle( NoGridFrame ), mGridFrameWidth( 2.0 ), 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 )
|
||||
{
|
||||
mOverviewFrameMapSymbol = 0;
|
||||
mGridLineSymbol = 0;
|
||||
@ -651,10 +651,7 @@ void QgsComposerMap::toggleAtlasPreview()
|
||||
QgsRectangle* QgsComposerMap::currentMapExtent()
|
||||
{
|
||||
//non-const version
|
||||
|
||||
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
|
||||
|
||||
if ( atlasMap->composerMap() == this && mComposition->atlasMode() != QgsComposition::AtlasOff )
|
||||
if ( mAtlasDriven && mComposition->atlasMode() != QgsComposition::AtlasOff )
|
||||
{
|
||||
//if atlas is enabled, and we are either exporting the composition or previewing the atlas, then
|
||||
//return the current temporary atlas feature extent
|
||||
@ -670,9 +667,7 @@ QgsRectangle* QgsComposerMap::currentMapExtent()
|
||||
const QgsRectangle* QgsComposerMap::currentMapExtent() const
|
||||
{
|
||||
//const version
|
||||
|
||||
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
|
||||
if ( atlasMap->composerMap() == this && mComposition->atlasMode() != QgsComposition::AtlasOff )
|
||||
if ( mAtlasDriven && mComposition->atlasMode() != QgsComposition::AtlasOff )
|
||||
{
|
||||
//if atlas is enabled, and we are either exporting the composition or previewing the atlas, then
|
||||
//return the current temporary atlas feature extent
|
||||
@ -991,6 +986,13 @@ bool QgsComposerMap::writeXML( QDomElement& elem, QDomDocument & doc ) const
|
||||
gridElem.appendChild( annotationElem );
|
||||
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 );
|
||||
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
|
||||
QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
|
||||
if ( composerItemList.size() > 0 )
|
||||
|
@ -420,6 +420,21 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
*/
|
||||
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:
|
||||
void extentChanged();
|
||||
|
||||
@ -571,6 +586,13 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
|
||||
* center of extent remains the same */
|
||||
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*/
|
||||
void drawGrid( QPainter* p );
|
||||
void drawGridFrame( QPainter* p, const QList< QPair< double, QLineF > >& hLines, const QList< QPair< double, QLineF > >& vLines );
|
||||
|
@ -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();
|
||||
|
@ -23,7 +23,16 @@
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</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>
|
||||
</property>
|
||||
<item>
|
||||
@ -32,15 +41,24 @@
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<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">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="mUseAtlasCheckBox">
|
||||
<property name="text">
|
||||
@ -91,7 +109,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>431</width>
|
||||
<height>568</height>
|
||||
<height>567</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="mainLayout">
|
||||
@ -123,27 +141,13 @@
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<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">
|
||||
<property name="text">
|
||||
<string>Coverage layer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QComboBox" name="mAtlasCoverageLayerComboBox"/>
|
||||
@ -280,60 +284,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</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>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="mOutputGroup">
|
||||
<property name="enabled">
|
||||
|
@ -23,7 +23,16 @@
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</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>
|
||||
</property>
|
||||
<item>
|
||||
@ -54,9 +63,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-420</y>
|
||||
<y>0</y>
|
||||
<width>439</width>
|
||||
<height>1509</height>
|
||||
<height>1638</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -251,6 +260,66 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</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>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="mGridCheckBox">
|
||||
<property name="title">
|
||||
|
@ -36,7 +36,7 @@ QgsCompositionChecker::~QgsCompositionChecker()
|
||||
{
|
||||
}
|
||||
|
||||
bool QgsCompositionChecker::testComposition( QString &report, int page )
|
||||
bool QgsCompositionChecker::testComposition( QString &report, int page, int pixelDiff )
|
||||
{
|
||||
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";
|
||||
|
||||
bool testResult = compareImages( mTestName, 0, renderedFilePath );
|
||||
bool testResult = compareImages( mTestName, pixelDiff, renderedFilePath );
|
||||
|
||||
QString myDashMessage = "<DartMeasurementFile name=\"Rendered Image " + mTestName + "\""
|
||||
" type=\"image/png\">" + renderedFilePath +
|
||||
|
@ -29,7 +29,7 @@ class QgsCompositionChecker : public QgsRenderChecker
|
||||
QgsCompositionChecker( const QString& testName, QgsComposition* composition );
|
||||
~QgsCompositionChecker();
|
||||
|
||||
bool testComposition( QString &report, int page = 0 );
|
||||
bool testComposition( QString &report, int page = 0, int pixelDiff = 0 );
|
||||
|
||||
private:
|
||||
QgsCompositionChecker(); //forbidden
|
||||
|
@ -43,8 +43,14 @@ class TestQgsAtlasComposition: public QObject
|
||||
void filename();
|
||||
// test rendering with an autoscale atlas
|
||||
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
|
||||
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
|
||||
void hiding_render();
|
||||
// test rendering with feature sorting
|
||||
@ -104,7 +110,6 @@ void TestQgsAtlasComposition::initTestCase()
|
||||
|
||||
mAtlas = &mComposition->atlasComposition();
|
||||
mAtlas->setCoverageLayer( mVectorLayer );
|
||||
mAtlas->setComposerMap( mAtlasMap );
|
||||
mComposition->setAtlasMode( QgsComposition::ExportAtlas );
|
||||
|
||||
// an overview
|
||||
@ -180,6 +185,29 @@ void TestQgsAtlasComposition::filename()
|
||||
|
||||
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->setMargin( 0.10f );
|
||||
|
||||
@ -190,16 +218,20 @@ void TestQgsAtlasComposition::autoscale_render()
|
||||
mAtlas->prepareForFeature( fit );
|
||||
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 ) );
|
||||
}
|
||||
mAtlas->endRender();
|
||||
mAtlas->setComposerMap( 0 );
|
||||
mAtlas->setFixedScale( false );
|
||||
mAtlas->setMargin( 0 );
|
||||
}
|
||||
|
||||
void TestQgsAtlasComposition::fixedscale_render()
|
||||
{
|
||||
mAtlasMap->setAtlasDriven( true );
|
||||
mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
|
||||
mAtlas->setFixedScale( true );
|
||||
mAtlasMap->setAtlasFixedScale( true );
|
||||
|
||||
mAtlas->beginRender();
|
||||
|
||||
@ -213,12 +245,61 @@ void TestQgsAtlasComposition::fixedscale_render()
|
||||
}
|
||||
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()
|
||||
{
|
||||
mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
|
||||
mAtlas->setFixedScale( true );
|
||||
mAtlasMap->setAtlasDriven( true );
|
||||
mAtlasMap->setAtlasFixedScale( true );
|
||||
mAtlas->setHideCoverage( true );
|
||||
|
||||
mAtlas->beginRender();
|
||||
@ -237,7 +318,8 @@ void TestQgsAtlasComposition::hiding_render()
|
||||
void TestQgsAtlasComposition::sorting_render()
|
||||
{
|
||||
mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
|
||||
mAtlas->setFixedScale( true );
|
||||
mAtlasMap->setAtlasDriven( true );
|
||||
mAtlasMap->setAtlasFixedScale( true );
|
||||
mAtlas->setHideCoverage( false );
|
||||
|
||||
mAtlas->setSortFeatures( true );
|
||||
@ -260,7 +342,8 @@ void TestQgsAtlasComposition::sorting_render()
|
||||
void TestQgsAtlasComposition::filtering_render()
|
||||
{
|
||||
mAtlasMap->setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
|
||||
mAtlas->setFixedScale( true );
|
||||
mAtlasMap->setAtlasDriven( true );
|
||||
mAtlasMap->setAtlasFixedScale( true );
|
||||
mAtlas->setHideCoverage( false );
|
||||
|
||||
mAtlas->setSortFeatures( false );
|
||||
|
@ -27,7 +27,7 @@ class QgsCompositionChecker(QgsRenderChecker):
|
||||
self.mTestName = mTestName
|
||||
super(QgsCompositionChecker, self).__init__()
|
||||
|
||||
def testComposition(self, page=0 ):
|
||||
def testComposition(self, page=0, pixelDiff=0 ):
|
||||
if ( self.mComposition == None):
|
||||
myMessage = "Composition not valid"
|
||||
return False, myMessage
|
||||
@ -53,7 +53,7 @@ class QgsCompositionChecker(QgsRenderChecker):
|
||||
outputImage.save( renderedFilePath, "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 '
|
||||
'%s" type="image/png">'
|
||||
|
@ -63,7 +63,6 @@ class TestQgsAtlasComposition(unittest.TestCase):
|
||||
# the atlas
|
||||
self.mAtlas = self.mComposition.atlasComposition()
|
||||
self.mAtlas.setCoverageLayer( mVectorLayer )
|
||||
self.mAtlas.setComposerMap( self.mAtlasMap )
|
||||
self.mComposition.setAtlasMode( QgsComposition.ExportAtlas )
|
||||
|
||||
# an overview
|
||||
@ -99,6 +98,7 @@ class TestQgsAtlasComposition(unittest.TestCase):
|
||||
|
||||
self.filename_test()
|
||||
self.autoscale_render_test()
|
||||
self.autoscale_render_test_old_api()
|
||||
self.fixedscale_render_test()
|
||||
self.hidden_render_test()
|
||||
|
||||
@ -113,6 +113,28 @@ class TestQgsAtlasComposition(unittest.TestCase):
|
||||
self.mAtlas.endRender()
|
||||
|
||||
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.setMargin( 0.10 )
|
||||
|
||||
@ -122,15 +144,20 @@ class TestQgsAtlasComposition(unittest.TestCase):
|
||||
self.mAtlas.prepareForFeature( i )
|
||||
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()
|
||||
|
||||
assert myTestResult == True
|
||||
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.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()
|
||||
|
||||
@ -146,7 +173,7 @@ class TestQgsAtlasComposition(unittest.TestCase):
|
||||
|
||||
def hidden_render_test( self ):
|
||||
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.beginRender()
|
||||
@ -163,7 +190,7 @@ class TestQgsAtlasComposition(unittest.TestCase):
|
||||
|
||||
def sorting_render_test( self ):
|
||||
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.setSortFeatures( True )
|
||||
@ -184,7 +211,7 @@ class TestQgsAtlasComposition(unittest.TestCase):
|
||||
|
||||
def filtering_render_test( self ):
|
||||
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.setSortFeatures( False )
|
||||
|
After Width: | Height: | Size: 159 KiB |
BIN
tests/testdata/control_images/expected_atlas_autoscale_old_api1/osgeo4w_nightly.anomoly.png
vendored
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
tests/testdata/control_images/expected_atlas_autoscale_old_api1/ubuntu_13.04.anomaly.png
vendored
Normal file
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 194 KiB |
BIN
tests/testdata/control_images/expected_atlas_autoscale_old_api2/ubuntu_13.04.anomaly.png
vendored
Normal file
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 169 KiB |
BIN
tests/testdata/control_images/expected_atlas_fixedscale_old_api1/osgeo4w_nightly.anomoly.png
vendored
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/testdata/control_images/expected_atlas_fixedscale_old_api1/ubuntu_12.04.anomaly.png
vendored
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
tests/testdata/control_images/expected_atlas_fixedscale_old_api1/ubuntu_13.04.anomaly.png
vendored
Normal file
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 186 KiB |
BIN
tests/testdata/control_images/expected_atlas_fixedscale_old_api2/ubuntu_13.04.anomaly.png
vendored
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
tests/testdata/control_images/expected_atlas_two_maps1/expected_atlas_two_maps1.png
vendored
Normal file
After Width: | Height: | Size: 161 KiB |
BIN
tests/testdata/control_images/expected_atlas_two_maps2/expected_atlas_two_maps2.png
vendored
Normal file
After Width: | Height: | Size: 182 KiB |