Skip to content
Permalink
Browse files

Ensure both attribute table cache & master model request respect

geometry fetching

If request needs geometry but cache isn't fetching it then cache
is bypassed. This is a performance hit, so ensure that cache
and request are always in sync wrt to fetching geoms.

On behalf of Faunalia, sponsored by ENEL
  • Loading branch information
nyalldawson committed Mar 5, 2017
1 parent 5b0e84a commit dadd6133e0f1931709e29e69f519b60a1caeff3d
@@ -33,19 +33,10 @@ class QgsVectorLayerCache : QObject
*/
int cacheSize();

/**
* Enable or disable the caching of geometries
*
* @param cacheGeometry Enable or disable the caching of geometries
*/
void setCacheGeometry( bool cacheGeometry );

bool cacheGeometry() const;

/**
* Set the subset of attributes to be cached
*
* @param attributes The attributes to be cached
*/
void setCacheSubsetOfAttributes( const QgsAttributeList& attributes );

/**
@@ -106,9 +106,16 @@ class CORE_EXPORT QgsVectorLayerCache : public QObject
* Enable or disable the caching of geometries
*
* @param cacheGeometry Enable or disable the caching of geometries
* @see cacheGeometry()
*/
void setCacheGeometry( bool cacheGeometry );

/**
* Returns true if the cache will fetch and cache feature geometries.
* @note added in QGIS 3.0
* @see setCacheGeometry()
*/
bool cacheGeometry() const { return mCacheGeometry; }

/**
* Set the subset of attributes to be cached
@@ -82,7 +82,7 @@ void QgsDualView::init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const Qg
connect( mTableView->horizontalHeader(), &QHeaderView::customContextMenuRequested, this, &QgsDualView::showViewHeaderMenu );
connect( mTableView, &QgsAttributeTableView::columnResized, this, &QgsDualView::tableColumnResized );

initLayerCache( !request.filterRect().isNull() );
initLayerCache( !( request.flags() & QgsFeatureRequest::NoGeometry ) || !request.filterRect().isNull() );
initModels( mapCanvas, request );

mConditionalFormatWidget->setLayer( mLayer );
@@ -56,6 +56,7 @@ class TestQgsDualView : public QObject
void testSort();

void testAttributeFormSharedValueScanning();
void testNoGeom();

private:
QgsMapCanvas *mCanvas = nullptr;
@@ -270,5 +271,35 @@ void TestQgsDualView::testAttributeFormSharedValueScanning()
QVERIFY( mixedValueFields.isEmpty() );
}

void TestQgsDualView::testNoGeom()
{
//test that both the master model and cache for the dual view either both request geom or both don't request geom
std::unique_ptr< QgsDualView > dv( new QgsDualView() );

// request with geometry
QgsFeatureRequest req;
dv->init( mPointsLayer, mCanvas, req );
// check that both master model AND cache are using geometry
QgsAttributeTableModel* model = dv->masterModel();
QVERIFY( model->layerCache()->cacheGeometry() );
QVERIFY( !( model->request().flags() & QgsFeatureRequest::NoGeometry ) );

// request with NO geometry, but using filter rect (which should override and request geom)
req = QgsFeatureRequest().setFilterRect( QgsRectangle( 1, 2, 3, 4 ) );
dv.reset( new QgsDualView() );
dv->init( mPointsLayer, mCanvas, req );
model = dv->masterModel();
QVERIFY( model->layerCache()->cacheGeometry() );
QVERIFY( !( model->request().flags() & QgsFeatureRequest::NoGeometry ) );

// request with NO geometry
req = QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry );
dv.reset( new QgsDualView() );
dv->init( mPointsLayer, mCanvas, req );
model = dv->masterModel();
QVERIFY( !model->layerCache()->cacheGeometry() );
QVERIFY(( model->request().flags() & QgsFeatureRequest::NoGeometry ) );
}

QGSTEST_MAIN( TestQgsDualView )
#include "testqgsdualview.moc"

0 comments on commit dadd613

Please sign in to comment.
You can’t perform that action at this time.