Skip to content

Commit 3cad7ed

Browse files
committedJun 10, 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 182b1e1 commit 3cad7ed

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
@@ -450,6 +450,27 @@ bool QgsLayoutItemAttributeTable::getTableContents( QgsLayoutTableContents &cont
450450
visibleMapEngine->prepareGeometry();
451451
}
452452

453+
QgsGeometry atlasGeometry;
454+
std::unique_ptr< QgsGeometryEngine > atlasGeometryEngine;
455+
if ( mFilterToAtlasIntersection )
456+
{
457+
atlasGeometry = mLayout->reportContext().currentGeometry( layer->crs() );
458+
if ( !atlasGeometry.isNull() )
459+
{
460+
if ( selectionRect.isNull() )
461+
{
462+
selectionRect = atlasGeometry.boundingBox();
463+
}
464+
else
465+
{
466+
selectionRect = selectionRect.intersect( atlasGeometry.boundingBox() );
467+
}
468+
469+
atlasGeometryEngine.reset( QgsGeometry::createGeometryEngine( atlasGeometry.constGet() ) );
470+
atlasGeometryEngine->prepareGeometry();
471+
}
472+
}
473+
453474
if ( mSource == QgsLayoutItemAttributeTable::RelationChildren )
454475
{
455476
QgsRelation relation = mLayout->project()->relationManager()->relation( mRelationId );
@@ -500,20 +521,17 @@ bool QgsLayoutItemAttributeTable::getTableContents( QgsLayoutTableContents &cont
500521
//check against atlas feature intersection
501522
if ( mFilterToAtlasIntersection )
502523
{
503-
if ( !f.hasGeometry() )
524+
if ( !f.hasGeometry() || !atlasGeometryEngine )
504525
{
505526
continue;
506527
}
507-
QgsFeature atlasFeature = mLayout->reportContext().feature();
508-
if ( !atlasFeature.hasGeometry() ||
509-
!f.geometry().intersects( atlasFeature.geometry() ) )
510-
{
511-
//feature falls outside current atlas feature
528+
529+
if ( !atlasGeometryEngine->intersects( f.geometry().constGet() ) )
512530
continue;
513-
}
514531
}
515532

516533
QgsLayoutTableRow currentRow;
534+
currentRow.reserve( mColumns.count() );
517535

518536
for ( QgsLayoutTableColumn *column : qgis::as_const( mColumns ) )
519537
{
@@ -674,6 +692,7 @@ QVector<QPair<int, bool> > QgsLayoutItemAttributeTable::sortAttributes() const
674692

675693
//generate list of column index, bool for sort direction (to match 2.0 api)
676694
QVector<QPair<int, bool> > attributesBySortRank;
695+
attributesBySortRank.reserve( sortedColumns.size() );
677696
for ( auto &column : qgis::as_const( sortedColumns ) )
678697
{
679698
attributesBySortRank.append( qMakePair( column.first,

‎tests/src/core/testqgslayouttable.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class TestQgsLayoutTable : public QObject
5656
void attributeTableFilterFeatures(); //test filtering attribute table rows
5757
void attributeTableSetAttributes(); //test subset of attributes in table
5858
void attributeTableVisibleOnly(); //test displaying only visible attributes
59+
void attributeTableInsideAtlasOnly();
5960
void attributeTableRender(); //test rendering attribute table
6061
void manualColumnWidth(); //test setting manual column widths
6162
void attributeTableEmpty(); //test empty modes for attribute table
@@ -356,6 +357,67 @@ void TestQgsLayoutTable::attributeTableVisibleOnly()
356357
compareTable( table, expectedRows );
357358
}
358359

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

0 commit comments

Comments
 (0)
Please sign in to comment.