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

(cherry-picked from dadd613)
  • Loading branch information
nyalldawson committed Mar 7, 2017
1 parent 7daeca6 commit 9bb0c84227d4d59e31264fc1301815a7074a9437
@@ -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 );

/**
@@ -103,9 +103,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
@@ -81,7 +81,7 @@ void QgsDualView::init( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, const Qg
connect( mTableView->horizontalHeader(), SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( showViewHeaderMenu( QPoint ) ) );
connect( mTableView, SIGNAL( columnResized( int, int ) ), this, SLOT( tableColumnResized( int, int ) ) );

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

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

void testAttributeFormSharedValueScanning();
void testNoGeom();

private:
QgsMapCanvas* mCanvas;
@@ -266,6 +267,36 @@ 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
QScopedPointer< 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 ) );
}

QTEST_MAIN( TestQgsDualView )
#include "testqgsdualview.moc"

0 comments on commit 9bb0c84

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