2020#include " qgsgeometry.h"
2121#include " qgsvectorlayer.h"
2222#include " qgsvectordataprovider.h"
23+ #include " qgsvectorlayerutils.h"
24+ #include " qgsreadwritelocker.h"
2325
2426#include < QMutexLocker>
2527
26- QgsFeaturePool::QgsFeaturePool ( QgsVectorLayer *layer, double layerToMapUnits, const QgsCoordinateTransform &layerToMapTransform, bool selectedOnly )
28+
29+ QgsFeaturePool::QgsFeaturePool ( QgsVectorLayer *layer, double layerToMapUnits, const QgsCoordinateTransform &layerToMapTransform )
2730 : mFeatureCache( CACHE_SIZE )
2831 , mLayer( layer )
2932 , mLayerToMapUnits( layerToMapUnits )
3033 , mLayerToMapTransform( layerToMapTransform )
31- , mSelectedOnly( selectedOnly )
34+ , mLayerId( layer->id () )
35+ , mGeometryType( layer->geometryType () )
3236{
33- // Build spatial index
34- QgsFeature feature;
35- QgsFeatureRequest req;
36- req.setSubsetOfAttributes ( QgsAttributeList () );
37- if ( selectedOnly )
38- {
39- mFeatureIds = layer->selectedFeatureIds ();
40- req.setFilterFids ( mFeatureIds );
41- }
4237
43- QgsFeatureIterator it = layer->getFeatures ( req );
44- while ( it.nextFeature ( feature ) )
45- {
46- if ( feature.geometry () )
47- {
48- mIndex .insertFeature ( feature );
49- mFeatureIds .insert ( feature.id () );
50- }
51- else
52- {
53- mFeatureIds .remove ( feature.id () );
54- }
55- }
5638}
5739
5840bool QgsFeaturePool::get ( QgsFeatureId id, QgsFeature &feature )
5941{
60- QMutexLocker lock ( & mLayerMutex );
42+ QgsReadWriteLocker locker ( mCacheLock , QgsReadWriteLocker::Read );
6143 QgsFeature *cachedFeature = mFeatureCache .object ( id );
6244 if ( cachedFeature )
6345 {
@@ -66,78 +48,82 @@ bool QgsFeaturePool::get( QgsFeatureId id, QgsFeature &feature )
6648 }
6749 else
6850 {
51+ std::unique_ptr<QgsVectorLayerFeatureSource> source = QgsVectorLayerUtils::getFeatureSource ( mLayer );
52+
6953 // Feature not in cache, retrieve from layer
7054 // TODO: avoid always querying all attributes (attribute values are needed when merging by attribute)
71- if ( !mLayer ->getFeatures ( QgsFeatureRequest ( id ) ).nextFeature ( feature ) )
55+ if ( !source ->getFeatures ( QgsFeatureRequest ( id ) ).nextFeature ( feature ) )
7256 {
7357 return false ;
7458 }
59+ locker.changeMode ( QgsReadWriteLocker::Write );
7560 mFeatureCache .insert ( id, new QgsFeature ( feature ) );
61+ mIndex .insertFeature ( feature );
7662 }
7763 return true ;
7864}
7965
80- void QgsFeaturePool::addFeature ( QgsFeature &feature )
66+ QgsFeatureIds QgsFeaturePool::getFeatureIds () const
8167{
82- QgsFeatureList features;
83- features.append ( feature );
84- mLayerMutex .lock ();
85- mLayer ->dataProvider ()->addFeatures ( features );
86- feature.setId ( features.front ().id () );
87- if ( mSelectedOnly )
88- {
89- QgsFeatureIds selectedFeatureIds = mLayer ->selectedFeatureIds ();
90- selectedFeatureIds.insert ( feature.id () );
91- mLayer ->selectByIds ( selectedFeatureIds );
92- }
93- mLayerMutex .unlock ();
94- mIndexMutex .lock ();
95- mIndex .insertFeature ( feature );
96- mIndexMutex .unlock ();
68+ return mFeatureIds ;
9769}
9870
99- void QgsFeaturePool::updateFeature ( QgsFeature &feature )
71+ QgsFeatureIds QgsFeaturePool::getIntersects ( const QgsRectangle &rect ) const
10072{
101- QgsFeature origFeature;
102- get ( feature.id (), origFeature );
73+ QgsReadWriteLocker locker ( mCacheLock , QgsReadWriteLocker::Read );
74+ QgsFeatureIds ids = QgsFeatureIds::fromList ( mIndex .intersects ( rect ) );
75+ return ids;
76+ }
10377
104- QgsGeometryMap geometryMap;
105- geometryMap.insert ( feature.id (), feature.geometry () );
106- QgsChangedAttributesMap changedAttributesMap;
107- QgsAttributeMap attribMap;
108- for ( int i = 0 , n = feature.attributes ().size (); i < n; ++i )
109- {
110- attribMap.insert ( i, feature.attributes ().at ( i ) );
111- }
112- changedAttributesMap.insert ( feature.id (), attribMap );
113- mLayerMutex .lock ();
114- mFeatureCache .remove ( feature.id () ); // Remove to force reload on next get()
115- mLayer ->dataProvider ()->changeGeometryValues ( geometryMap );
116- mLayer ->dataProvider ()->changeAttributeValues ( changedAttributesMap );
117- mLayerMutex .unlock ();
118- mIndexMutex .lock ();
119- mIndex .deleteFeature ( origFeature );
78+ QgsVectorLayer *QgsFeaturePool::layer () const
79+ {
80+ Q_ASSERT ( QThread::currentThread () == qApp->thread () );
81+
82+ return mLayer .data ();
83+ }
84+
85+ void QgsFeaturePool::insertFeature ( const QgsFeature &feature )
86+ {
87+ QgsReadWriteLocker locker ( mCacheLock , QgsReadWriteLocker::Write );
88+ mFeatureCache .insert ( feature.id (), new QgsFeature ( feature ) );
12089 mIndex .insertFeature ( feature );
121- mIndexMutex .unlock ();
12290}
12391
124- void QgsFeaturePool::deleteFeature ( QgsFeatureId fid )
92+ void QgsFeaturePool::refreshCache ( const QgsFeature &feature )
93+ {
94+ QgsReadWriteLocker locker ( mCacheLock , QgsReadWriteLocker::Write );
95+ mFeatureCache .remove ( feature.id () );
96+ mIndex .deleteFeature ( feature );
97+ locker.unlock ();
98+
99+ QgsFeature tempFeature;
100+ get ( feature.id (), tempFeature );
101+ }
102+
103+ void QgsFeaturePool::removeFeature ( const QgsFeatureId featureId )
125104{
126105 QgsFeature origFeature;
127- if ( get ( fid, origFeature ) )
106+ QgsReadWriteLocker locker ( mCacheLock , QgsReadWriteLocker::Unlocked );
107+ if ( get ( featureId, origFeature ) )
128108 {
129- mIndexMutex . lock ( );
109+ locker. changeMode ( QgsReadWriteLocker::Write );
130110 mIndex .deleteFeature ( origFeature );
131- mIndexMutex .unlock ();
132111 }
133- mLayerMutex . lock ( );
112+ locker. changeMode ( QgsReadWriteLocker::Write );
134113 mFeatureCache .remove ( origFeature.id () );
135- mLayer ->dataProvider ()->deleteFeatures ( QgsFeatureIds () << fid );
136- mLayerMutex .unlock ();
137114}
138115
139- QgsFeatureIds QgsFeaturePool::getIntersects ( const QgsRectangle &rect ) const
116+ void QgsFeaturePool::setFeatureIds ( const QgsFeatureIds &ids )
117+ {
118+ mFeatureIds = ids;
119+ }
120+
121+ QgsWkbTypes::GeometryType QgsFeaturePool::geometryType () const
122+ {
123+ return mGeometryType ;
124+ }
125+
126+ QString QgsFeaturePool::layerId () const
140127{
141- QMutexLocker lock ( &mIndexMutex );
142- return QgsFeatureIds::fromList ( mIndex .intersects ( rect ) );
128+ return mLayerId ;
143129}
0 commit comments