Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4010d75

Browse files
committedJun 9, 2019
[layouts] Fix attribute table filtering to items within atlas feature
when atlas feature has a different CRS to table layer And greatly improve performance when using an attribute table filtered to the atlas feature
1 parent e3b4182 commit 4010d75

File tree

2 files changed

+88
-7
lines changed

2 files changed

+88
-7
lines changed
 

‎src/core/layout/qgslayoutitemattributetable.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,27 @@ bool QgsLayoutItemAttributeTable::getTableContents( QgsLayoutTableContents &cont
440440
}
441441
}
442442

443+
QgsGeometry atlasGeometry;
444+
std::unique_ptr< QgsGeometryEngine > atlasGeometryEngine;
445+
if ( mFilterToAtlasIntersection )
446+
{
447+
atlasGeometry = mLayout->reportContext().currentGeometry( layer->crs() );
448+
if ( !atlasGeometry.isNull() )
449+
{
450+
if ( selectionRect.isNull() )
451+
{
452+
selectionRect = atlasGeometry.boundingBox();
453+
}
454+
else
455+
{
456+
selectionRect = selectionRect.intersect( atlasGeometry.boundingBox() );
457+
}
458+
459+
atlasGeometryEngine.reset( QgsGeometry::createGeometryEngine( atlasGeometry.constGet() ) );
460+
atlasGeometryEngine->prepareGeometry();
461+
}
462+
}
463+
443464
if ( mSource == QgsLayoutItemAttributeTable::RelationChildren )
444465
{
445466
QgsRelation relation = mLayout->project()->relationManager()->relation( mRelationId );
@@ -479,20 +500,17 @@ bool QgsLayoutItemAttributeTable::getTableContents( QgsLayoutTableContents &cont
479500
//check against atlas feature intersection
480501
if ( mFilterToAtlasIntersection )
481502
{
482-
if ( !f.hasGeometry() )
503+
if ( !f.hasGeometry() || !atlasGeometryEngine )
483504
{
484505
continue;
485506
}
486-
QgsFeature atlasFeature = mLayout->reportContext().feature();
487-
if ( !atlasFeature.hasGeometry() ||
488-
!f.geometry().intersects( atlasFeature.geometry() ) )
489-
{
490-
//feature falls outside current atlas feature
507+
508+
if ( !atlasGeometryEngine->intersects( f.geometry().constGet() ) )
491509
continue;
492-
}
493510
}
494511

495512
QgsLayoutTableRow currentRow;
513+
currentRow.reserve( mColumns.count() );
496514

497515
for ( QgsLayoutTableColumn *column : qgis::as_const( mColumns ) )
498516
{
@@ -652,6 +670,7 @@ QVector<QPair<int, bool> > QgsLayoutItemAttributeTable::sortAttributes() const
652670

653671
//generate list of column index, bool for sort direction (to match 2.0 api)
654672
QVector<QPair<int, bool> > attributesBySortRank;
673+
attributesBySortRank.reserve( sortedColumns.size() );
655674
for ( auto &column : qgis::as_const( sortedColumns ) )
656675
{
657676
attributesBySortRank.append( qMakePair( column.first,

‎tests/src/core/testqgslayouttable.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class TestQgsLayoutTable : public QObject
5555
void attributeTableFilterFeatures(); //test filtering attribute table rows
5656
void attributeTableSetAttributes(); //test subset of attributes in table
5757
void attributeTableVisibleOnly(); //test displaying only visible attributes
58+
void attributeTableInsideAtlasOnly();
5859
void attributeTableRender(); //test rendering attribute table
5960
void manualColumnWidth(); //test setting manual column widths
6061
void attributeTableEmpty(); //test empty modes for attribute table
@@ -347,6 +348,67 @@ void TestQgsLayoutTable::attributeTableVisibleOnly()
347348
compareTable( table, expectedRows );
348349
}
349350

351+
void TestQgsLayoutTable::attributeTableInsideAtlasOnly()
352+
{
353+
//test displaying only visible attributes inside the atlas feature
354+
QgsLayout l( QgsProject::instance() );
355+
l.initializeDefaults();
356+
QgsLayoutItemAttributeTable *table = new QgsLayoutItemAttributeTable( &l );
357+
table->setVectorLayer( mVectorLayer );
358+
359+
QgsLayoutItemMap *map = new QgsLayoutItemMap( &l );
360+
map->attemptSetSceneRect( QRectF( 20, 20, 200, 100 ) );
361+
map->setFrameEnabled( true );
362+
map->setExtent( QgsRectangle( -95.537, 32.736, -84.389, 42.2920 ) );
363+
l.addLayoutItem( map );
364+
365+
table->setMap( map );
366+
table->setFilterToAtlasFeature( true );
367+
368+
// no atlas feature
369+
QVector<QStringList> expectedRows;
370+
compareTable( table, expectedRows );
371+
372+
//setup atlas
373+
std::unique_ptr< QgsVectorLayer > atlasLayer = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "Polygon?crs=EPSG:3857" ), QStringLiteral( "atlas" ), QStringLiteral( "memory" ) );
374+
QVERIFY( atlasLayer->isValid() );
375+
QgsGeometry atlasGeom( QgsGeometry::fromWkt( QStringLiteral( "Polygon ((-8863916.31126776337623596 4621257.48816855065524578, -9664269.45078738406300545 5097056.938785120844841, -10049249.44194872118532658 3765399.75924854446202517, -8985488.94005555473268032 3458599.17133777122944593, -8863916.31126776337623596 4621257.48816855065524578))" ) ) );
376+
QgsFeature f;
377+
f.setGeometry( atlasGeom );
378+
atlasLayer->dataProvider()->addFeature( f );
379+
l.reportContext().setLayer( atlasLayer.get() );
380+
381+
QgsFeatureIterator it = atlasLayer->getFeatures();
382+
it.nextFeature( f );
383+
l.reportContext().setFeature( f );
384+
385+
QStringList row;
386+
row << QStringLiteral( "Biplane" ) << QStringLiteral( "0" ) << QStringLiteral( "1" ) << QStringLiteral( "3" ) << QStringLiteral( "3" ) << QStringLiteral( "6" );
387+
expectedRows.append( row );
388+
row.clear();
389+
row << QStringLiteral( "Jet" ) << QStringLiteral( "90" ) << QStringLiteral( "3" ) << QStringLiteral( "1" ) << QStringLiteral( "0" ) << QStringLiteral( "1" );
390+
expectedRows.append( row );
391+
row.clear();
392+
row << QStringLiteral( "Biplane" ) << QStringLiteral( "340" ) << QStringLiteral( "1" ) << QStringLiteral( "3" ) << QStringLiteral( "3" ) << QStringLiteral( "6" );
393+
expectedRows.append( row );
394+
395+
//retrieve rows and check
396+
compareTable( table, expectedRows );
397+
398+
// combination of atlas and map extent visibility
399+
table->setDisplayOnlyVisibleFeatures( true );
400+
expectedRows.clear();
401+
row.clear();
402+
row << QStringLiteral( "Jet" ) << QStringLiteral( "90" ) << QStringLiteral( "3" ) << QStringLiteral( "1" ) << QStringLiteral( "0" ) << QStringLiteral( "1" );
403+
expectedRows.append( row );
404+
row.clear();
405+
row << QStringLiteral( "Biplane" ) << QStringLiteral( "340" ) << QStringLiteral( "1" ) << QStringLiteral( "3" ) << QStringLiteral( "3" ) << QStringLiteral( "6" );
406+
expectedRows.append( row );
407+
408+
//retrieve rows and check
409+
compareTable( table, expectedRows );
410+
}
411+
350412
void TestQgsLayoutTable::attributeTableRender()
351413
{
352414
QgsLayout l( QgsProject::instance() );

0 commit comments

Comments
 (0)
Please sign in to comment.