From 6b638aae0fa4d6c0f4e16a47c187d727fd3256d2 Mon Sep 17 00:00:00 2001 From: nirvn Date: Mon, 9 Nov 2020 11:39:12 +0700 Subject: [PATCH] [temporal] Update the attribute table's show feature visible on map to take temporal range context into account --- .../qgsattributetablefiltermodel.cpp | 16 +++++++ tests/src/app/testqgsattributetable.cpp | 43 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/gui/attributetable/qgsattributetablefiltermodel.cpp b/src/gui/attributetable/qgsattributetablefiltermodel.cpp index b56043ebaa5f..dcf774ffb51d 100644 --- a/src/gui/attributetable/qgsattributetablefiltermodel.cpp +++ b/src/gui/attributetable/qgsattributetablefiltermodel.cpp @@ -20,6 +20,7 @@ #include "qgsattributetablemodel.h" #include "qgsfeatureiterator.h" #include "qgsvectorlayer.h" +#include "qgsvectorlayertemporalproperties.h" #include "qgsfeature.h" #include "qgsmapcanvas.h" #include "qgslogger.h" @@ -343,6 +344,7 @@ void QgsAttributeTableFilterModel::disconnectFilterModeConnections() { case ShowVisible: disconnect( mCanvas, &QgsMapCanvas::extentsChanged, this, &QgsAttributeTableFilterModel::startTimedReloadVisible ); + disconnect( mCanvas, &QgsMapCanvas::temporalRangeChanged, this, &QgsAttributeTableFilterModel::startTimedReloadVisible ); disconnect( layer(), &QgsVectorLayer::featureAdded, this, &QgsAttributeTableFilterModel::startTimedReloadVisible ); disconnect( layer(), &QgsVectorLayer::geometryChanged, this, &QgsAttributeTableFilterModel::startTimedReloadVisible ); break; @@ -365,6 +367,7 @@ void QgsAttributeTableFilterModel::connectFilterModeConnections( QgsAttributeTab { case ShowVisible: connect( mCanvas, &QgsMapCanvas::extentsChanged, this, &QgsAttributeTableFilterModel::startTimedReloadVisible ); + connect( mCanvas, &QgsMapCanvas::temporalRangeChanged, this, &QgsAttributeTableFilterModel::startTimedReloadVisible ); connect( layer(), &QgsVectorLayer::featureAdded, this, &QgsAttributeTableFilterModel::startTimedReloadVisible ); connect( layer(), &QgsVectorLayer::geometryChanged, this, &QgsAttributeTableFilterModel::startTimedReloadVisible ); generateListOfVisibleFeatures(); @@ -607,6 +610,19 @@ void QgsAttributeTableFilterModel::generateListOfVisibleFeatures() { r.setFilterRect( rect ); } + + if ( mCanvas->mapSettings().isTemporal() ) + { + if ( !layer()->temporalProperties()->isVisibleInTemporalRange( mCanvas->mapSettings().temporalRange() ) ) + return; + + QgsVectorLayerTemporalContext temporalContext; + temporalContext.setLayer( layer() ); + const QString temporalFilter = qobject_cast< const QgsVectorLayerTemporalProperties * >( layer()->temporalProperties() )->createFilterString( temporalContext, mCanvas->mapSettings().temporalRange() ); + if ( !temporalFilter.isEmpty() ) + r.setFilterExpression( temporalFilter ); + } + QgsFeatureIterator features = masterModel()->layerCache()->getFeatures( r ); QgsFeature f; diff --git a/tests/src/app/testqgsattributetable.cpp b/tests/src/app/testqgsattributetable.cpp index 92e2b33ebdb9..9d2d0c0cdd3d 100644 --- a/tests/src/app/testqgsattributetable.cpp +++ b/tests/src/app/testqgsattributetable.cpp @@ -20,6 +20,7 @@ #include "qgsfeature.h" #include "qgsgeometry.h" #include "qgsvectordataprovider.h" +#include "qgsvectorlayertemporalproperties.h" #include "qgsattributetabledialog.h" #include "qgsproject.h" #include "qgsmapcanvas.h" @@ -54,6 +55,7 @@ class TestQgsAttributeTable : public QObject void testSortByDisplayExpression(); void testOrderColumn(); void testFilteredFeatures(); + void testVisibleTemporal(); private: QgisApp *mQgisApp = nullptr; @@ -210,6 +212,47 @@ void TestQgsAttributeTable::testNoGeom() } +void TestQgsAttributeTable::testVisibleTemporal() +{ + // test attribute table opening in show feature visible mode + std::unique_ptr< QgsVectorLayer> tempLayer( new QgsVectorLayer( QStringLiteral( "LineString?crs=epsg:4326&field=pk:int&field=col1:date" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + QVERIFY( tempLayer->isValid() ); + + QgsPolylineXY line; + line << QgsPointXY( 0, 0 ) << QgsPointXY( 1, 1 ); + QgsGeometry geometry = QgsGeometry::fromPolylineXY( line ) ; + QgsFeature f1( tempLayer->dataProvider()->fields(), 1 ); + f1.setGeometry( geometry ); + f1.setAttributes( QgsAttributes() << 1 << QDate( 2020, 1, 1 ) ); + QgsFeature f2( tempLayer->dataProvider()->fields(), 2 ); + f2.setGeometry( geometry ); + f2.setAttributes( QgsAttributes() << 2 << QDate( 2020, 3, 1 ) ); + QgsFeature f3( tempLayer->dataProvider()->fields(), 3 ); + line.clear(); + line << QgsPointXY( -3, -3 ) << QgsPointXY( -2, -2 ); + geometry = QgsGeometry::fromPolylineXY( line ); + f3.setGeometry( geometry ); + f3.setAttributes( QgsAttributes() << 3 << QDate( 2020, 1, 1 ) ); + QVERIFY( tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 << f3 ) ); + + QgsVectorLayerTemporalProperties *temporalProperties = qobject_cast< QgsVectorLayerTemporalProperties *>( tempLayer->temporalProperties() ); + temporalProperties->setIsActive( true ); + temporalProperties->setMode( QgsVectorLayerTemporalProperties::ModeFeatureDateTimeStartAndEndFromFields ); + temporalProperties->setStartField( QStringLiteral( "col1" ) ); + + mQgisApp->mapCanvas()->setDestinationCrs( QgsCoordinateReferenceSystem( "EPSG:4326" ) ); + mQgisApp->mapCanvas()->resize( 500, 500 ); + mQgisApp->mapCanvas()->setLayers( QList< QgsMapLayer *>() << tempLayer.get() ); + mQgisApp->mapCanvas()->setExtent( QgsRectangle( -1, -1, 1, 1 ) ); + mQgisApp->mapCanvas()->setTemporalRange( QgsDateTimeRange( QDateTime( QDate( 2020, 1, 1 ) ), QDateTime( QDate( 2020, 2, 1 ) ) ) ); + + std::unique_ptr< QgsAttributeTableDialog > dlg( new QgsAttributeTableDialog( tempLayer.get(), QgsAttributeTableFilterModel::ShowVisible ) ); + + // feature id 2 is filtered out due to being out of temporal range + // feature id 3 is filtered out due to being out of visible extent + QCOMPARE( dlg->mMainView->filteredFeatures(), QgsFeatureIds() << 1 ); +} + void TestQgsAttributeTable::testSelected() { // test attribute table opening in show selected mode