Skip to content

Commit 11c4444

Browse files
committedMar 5, 2017
Clear existing cache when QgsVectorLayerCache is set to cache geom
Any features inside the cache must be cleared, because they won't necessarily have the feature's geometry cached On behalf of Faunalia, sponsored by ENEL
1 parent f0d2f6d commit 11c4444

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed
 

‎src/core/qgsvectorlayercache.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ int QgsVectorLayerCache::cacheSize()
5858

5959
void QgsVectorLayerCache::setCacheGeometry( bool cacheGeometry )
6060
{
61-
mCacheGeometry = cacheGeometry && mLayer->hasGeometryType();
61+
bool shouldCache = cacheGeometry && mLayer->hasGeometryType();
62+
bool mustInvalidate = shouldCache && !mCacheGeometry; // going from no geometry -> geometry, so have to clear existing cache entries
63+
mCacheGeometry = shouldCache;
6264
if ( cacheGeometry )
6365
{
6466
connect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsVectorLayerCache::geometryChanged );
@@ -67,6 +69,10 @@ void QgsVectorLayerCache::setCacheGeometry( bool cacheGeometry )
6769
{
6870
disconnect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsVectorLayerCache::geometryChanged );
6971
}
72+
if ( mustInvalidate )
73+
{
74+
invalidate();
75+
}
7076
}
7177

7278
void QgsVectorLayerCache::setCacheSubsetOfAttributes( const QgsAttributeList &attributes )

‎tests/src/core/testqgsvectorlayercache.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class TestVectorLayerCache : public QObject
5555
void testFullCache();
5656
void testFullCacheThroughRequest();
5757
void testCanUseCacheForRequest();
58+
void testCacheGeom();
5859

5960
void onCommittedFeaturesAdded( const QString &, const QgsFeatureList & );
6061

@@ -331,6 +332,51 @@ void TestVectorLayerCache::testCanUseCacheForRequest()
331332
QVERIFY( cache.canUseCacheForRequest( QgsFeatureRequest().setFilterExpression( "$x<5" ), it ) );
332333
}
333334

335+
void TestVectorLayerCache::testCacheGeom()
336+
{
337+
QgsVectorLayerCache cache( mPointsLayer, 2 );
338+
// cache geometry
339+
cache.setCacheGeometry( true );
340+
341+
//first get some feature ids from layer
342+
QgsFeature f;
343+
QgsFeatureIterator it = mPointsLayer->getFeatures();
344+
it.nextFeature( f );
345+
QgsFeatureId id1 = f.id();
346+
it.nextFeature( f );
347+
QgsFeatureId id2 = f.id();
348+
349+
QgsFeatureRequest req;
350+
req.setFlags( QgsFeatureRequest::NoGeometry ); // should be ignored by cache
351+
req.setFilterFids( QgsFeatureIds() << id1 << id2 );
352+
353+
it = cache.getFeatures( req );
354+
while ( it.nextFeature( f ) )
355+
{
356+
QVERIFY( f.hasGeometry() );
357+
}
358+
359+
// disabled geometry caching
360+
cache.setCacheGeometry( false );
361+
// we should still have cached features... no need to lose these!
362+
QCOMPARE( cache.cachedFeatureIds(), QgsFeatureIds() << id1 << id2 );
363+
it = cache.getFeatures( req );
364+
while ( it.nextFeature( f ) )
365+
{
366+
QVERIFY( f.hasGeometry() );
367+
}
368+
369+
// now upgrade cache from no geometry -> geometry, should be cleared since we
370+
// cannot be confident that features existing in the cache have geometry
371+
cache.setCacheGeometry( true );
372+
QVERIFY( cache.cachedFeatureIds().isEmpty() );
373+
it = cache.getFeatures( req );
374+
while ( it.nextFeature( f ) )
375+
{
376+
QVERIFY( f.hasGeometry() );
377+
}
378+
}
379+
334380
void TestVectorLayerCache::onCommittedFeaturesAdded( const QString &layerId, const QgsFeatureList &features )
335381
{
336382
Q_UNUSED( layerId )

0 commit comments

Comments
 (0)
Please sign in to comment.