Skip to content

Commit

Permalink
Merge pull request #422 from Oslandia/atlas
Browse files Browse the repository at this point in the history
Feature sorting and filtering for atlas generation
  • Loading branch information
mhugent committed Feb 12, 2013
2 parents b45d8cb + d1a05f7 commit 8e11e5f
Show file tree
Hide file tree
Showing 12 changed files with 467 additions and 23 deletions.
12 changes: 12 additions & 0 deletions python/core/composer/qgsatlascomposition.sip
Expand Up @@ -38,6 +38,18 @@ public:
bool singleFile() const;
void setSingleFile( bool single );

bool sortFeatures() const;
void setSortFeatures( bool doSort );

bool sortAscending() const;
void setSortAscending( bool ascending );

QString featureFilter() const;
void setFeatureFilter( const QString& expression );

size_t sortKeyAttributeIndex() const;
void setSortKeyAttributeIndex( size_t idx );

/** Begins the rendering. */
void beginRender();
/** Ends the rendering. Restores original extent */
Expand Down
119 changes: 119 additions & 0 deletions src/app/composer/qgsatlascompositionwidget.cpp
Expand Up @@ -39,6 +39,8 @@ QgsAtlasCompositionWidget::QgsAtlasCompositionWidget( QWidget* parent, QgsCompos
mAtlasCoverageLayerComboBox->insertItem( idx++, it.value()->name(), /* userdata */ qVariantFromValue(( void* )it.value() ) );
}
}
// update sort columns
fillSortColumns();

// Connect to addition / removal of layers
QgsMapLayerRegistry* layerRegistry = QgsMapLayerRegistry::instance();
Expand All @@ -58,6 +60,11 @@ QgsAtlasCompositionWidget::QgsAtlasCompositionWidget( QWidget* parent, QgsCompos
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* ) ) );
Expand Down Expand Up @@ -159,11 +166,17 @@ void QgsAtlasCompositionWidget::on_mAtlasCoverageLayerComboBox_currentIndexChang
if ( index == -1 )
{
atlasMap->setCoverageLayer( 0 );

// clean up the sorting columns
mAtlasSortFeatureKeyComboBox->clear();
}
else
{
QgsVectorLayer* layer = reinterpret_cast<QgsVectorLayer*>( mAtlasCoverageLayerComboBox->itemData( index ).value<void*>() );
atlasMap->setCoverageLayer( layer );

// update sorting columns
fillSortColumns();
}
}

Expand Down Expand Up @@ -254,9 +267,111 @@ void QgsAtlasCompositionWidget::on_mAtlasSingleFileCheckBox_stateChanged( int st
{
return;
}
if ( state == Qt::Checked ) {
mAtlasFilenamePatternEdit->setEnabled( false );
mAtlasFilenameExpressionButton->setEnabled( false );
}
else {
mAtlasFilenamePatternEdit->setEnabled( true );
mAtlasFilenameExpressionButton->setEnabled( true );
}
atlasMap->setSingleFile( state == Qt::Checked );
}

void QgsAtlasCompositionWidget::on_mAtlasSortFeatureCheckBox_stateChanged( int state )
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
if ( !atlasMap )
{
return;
}

if ( state == Qt::Checked ) {
mAtlasSortFeatureDirectionButton->setEnabled( true );
mAtlasSortFeatureKeyComboBox->setEnabled( true );
}
else {
mAtlasSortFeatureDirectionButton->setEnabled( false );
mAtlasSortFeatureKeyComboBox->setEnabled( false );
}
atlasMap->setSortFeatures( state == Qt::Checked );
}

void QgsAtlasCompositionWidget::on_mAtlasSortFeatureKeyComboBox_currentIndexChanged( int index )
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
if ( !atlasMap )
{
return;
}

if ( index != -1 ) {
atlasMap->setSortKeyAttributeIndex( index );
}
}

void QgsAtlasCompositionWidget::on_mAtlasFeatureFilterEdit_textChanged( const QString& text )
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
if ( !atlasMap )
{
return;
}

atlasMap->setFeatureFilter( text );
}

void QgsAtlasCompositionWidget::on_mAtlasFeatureFilterButton_clicked()
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
if ( !atlasMap || !atlasMap->coverageLayer() )
{
return;
}

QgsExpressionBuilderDialog exprDlg( atlasMap->coverageLayer(), mAtlasFeatureFilterEdit->text(), this );
exprDlg.setWindowTitle( tr( "Expression based filter" ) );
if ( exprDlg.exec() == QDialog::Accepted )
{
QString expression = exprDlg.expressionText();
if ( !expression.isEmpty() )
{
// will emit a textChanged signal
mAtlasFeatureFilterEdit->setText( expression );
}
}
}

void QgsAtlasCompositionWidget::on_mAtlasSortFeatureDirectionButton_clicked()
{
Qt::ArrowType at = mAtlasSortFeatureDirectionButton->arrowType();
at = (at == Qt::UpArrow) ? Qt::DownArrow : Qt::UpArrow;
mAtlasSortFeatureDirectionButton->setArrowType( at );

QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
if ( !atlasMap ) {
return;
}

atlasMap->setSortAscending( at == Qt::UpArrow );
}

void QgsAtlasCompositionWidget::fillSortColumns()
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
if ( !atlasMap || !atlasMap->coverageLayer() )
{
return;
}

mAtlasSortFeatureKeyComboBox->clear();
// Get fields of the selected coverage layer
const QgsFields& fields = atlasMap->coverageLayer()->pendingFields();
for ( int i = 0; i < fields.count(); ++i ) {
mAtlasSortFeatureKeyComboBox->insertItem( i, fields.at(i).name() );
}
}

void QgsAtlasCompositionWidget::updateGuiElements()
{
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
Expand Down Expand Up @@ -285,6 +400,10 @@ void QgsAtlasCompositionWidget::updateGuiElements()
mAtlasFixedScaleCheckBox->setCheckState( atlasMap->fixedScale() ? Qt::Checked : Qt::Unchecked );
mAtlasHideCoverageCheckBox->setCheckState( atlasMap->hideCoverage() ? Qt::Checked : Qt::Unchecked );
mAtlasSingleFileCheckBox->setCheckState( atlasMap->singleFile() ? Qt::Checked : Qt::Unchecked );
mAtlasSortFeatureCheckBox->setCheckState( atlasMap->sortFeatures() ? Qt::Checked : Qt::Unchecked );
mAtlasSortFeatureKeyComboBox->setCurrentIndex( atlasMap->sortKeyAttributeIndex() );
mAtlasSortFeatureDirectionButton->setArrowType( atlasMap->sortAscending() ? Qt::UpArrow : Qt::DownArrow );
mAtlasFeatureFilterEdit->setText( atlasMap->featureFilter() );
}

void QgsAtlasCompositionWidget::blockAllSignals( bool b )
Expand Down
8 changes: 8 additions & 0 deletions src/app/composer/qgsatlascompositionwidget.h
Expand Up @@ -43,6 +43,14 @@ class QgsAtlasCompositionWidget:
void on_mAtlasFixedScaleCheckBox_stateChanged( int state );
void on_mAtlasSingleFileCheckBox_stateChanged( int state );

void on_mAtlasSortFeatureCheckBox_stateChanged( int state );
void on_mAtlasSortFeatureKeyComboBox_currentIndexChanged( int index );
void on_mAtlasSortFeatureDirectionButton_clicked();
void on_mAtlasFeatureFilterEdit_textChanged( const QString& text );
void on_mAtlasFeatureFilterButton_clicked();

// extract fields from the current coverage layer and populate the corresponding combo box
void fillSortColumns();
private slots:
void onLayerRemoved( QString );
void onLayerAdded( QgsMapLayer* );
Expand Down
64 changes: 56 additions & 8 deletions src/app/composer/qgscomposer.cpp
Expand Up @@ -655,7 +655,18 @@ void QgsComposer::on_mActionExportAsPDF_triggered()

QPainter painter;

atlasMap->beginRender();
try {
atlasMap->beginRender();
}
catch ( std::exception& e )
{
QMessageBox::warning( this, tr( "Atlas processing error" ),
e.what(),
QMessageBox::Ok,
QMessageBox::Ok );
mView->setPaintingEnabled( true );
return;
}
if ( atlasOnASingleFile )
{
mComposition->beginPrintAsPDF( printer, outputFileName );
Expand Down Expand Up @@ -687,7 +698,8 @@ void QgsComposer::on_mActionExportAsPDF_triggered()
e.what(),
QMessageBox::Ok,
QMessageBox::Ok );
break;
mView->setPaintingEnabled( true );
return;
}
if ( !atlasOnASingleFile )
{
Expand Down Expand Up @@ -755,7 +767,18 @@ void QgsComposer::on_mActionPrint_triggered()

mComposition->beginPrint( mPrinter );
QPainter painter( &mPrinter );
atlasMap->beginRender();
try {
atlasMap->beginRender();
}
catch ( std::exception& e )
{
QMessageBox::warning( this, tr( "Atlas processing error" ),
e.what(),
QMessageBox::Ok,
QMessageBox::Ok );
mView->setPaintingEnabled( true );
return;
}
QProgressDialog progress( tr( "Rendering maps..." ), tr( "Abort" ), 0, atlasMap->numFeatures(), this );

for ( size_t i = 0; i < atlasMap->numFeatures(); ++i )
Expand All @@ -779,7 +802,8 @@ void QgsComposer::on_mActionPrint_triggered()
e.what(),
QMessageBox::Ok,
QMessageBox::Ok );
break;
mView->setPaintingEnabled( true );
return;
}


Expand Down Expand Up @@ -939,7 +963,18 @@ void QgsComposer::on_mActionExportAsImage_triggered()
mView->setPaintingEnabled( false );
QApplication::setOverrideCursor( Qt::BusyCursor );

atlasMap->beginRender();
try {
atlasMap->beginRender();
}
catch ( std::exception& e )
{
QMessageBox::warning( this, tr( "Atlas processing error" ),
e.what(),
QMessageBox::Ok,
QMessageBox::Ok );
mView->setPaintingEnabled( true );
return;
}

QProgressDialog progress( tr( "Rendering maps..." ), tr( "Abort" ), 0, atlasMap->numFeatures(), this );

Expand All @@ -964,7 +999,8 @@ void QgsComposer::on_mActionExportAsImage_triggered()
e.what(),
QMessageBox::Ok,
QMessageBox::Ok );
break;
mView->setPaintingEnabled( true );
return;
}

QString filename = QDir( dir ).filePath( atlasMap->currentFilename() ) + fileExt;
Expand Down Expand Up @@ -1096,7 +1132,18 @@ void QgsComposer::on_mActionExportAsSVG_triggered()
size_t featureI = 0;
if ( hasAnAtlas )
{
atlasMap->beginRender();
try {
atlasMap->beginRender();
}
catch ( std::exception& e )
{
QMessageBox::warning( this, tr( "Atlas processing error" ),
e.what(),
QMessageBox::Ok,
QMessageBox::Ok );
mView->setPaintingEnabled( true );
return;
}
}
QProgressDialog progress( tr( "Rendering maps..." ), tr( "Abort" ), 0, atlasMap->numFeatures(), this );

Expand Down Expand Up @@ -1125,7 +1172,8 @@ void QgsComposer::on_mActionExportAsSVG_triggered()
e.what(),
QMessageBox::Ok,
QMessageBox::Ok );
break;
mView->setPaintingEnabled( true );
return;
}
outputFileName = QDir( outputDir ).filePath( atlasMap->currentFilename() ) + ".svg";
}
Expand Down

0 comments on commit 8e11e5f

Please sign in to comment.