20
20
#include " qgsgeometry.h"
21
21
#include " qgsvectorlayer.h"
22
22
#include " qgsvectordataprovider.h"
23
+ #include " qgsvectorlayerutils.h"
23
24
24
25
#include < QMutexLocker>
25
26
26
- QgsFeaturePool::QgsFeaturePool ( QgsVectorLayer *layer, double layerToMapUnits, const QgsCoordinateTransform &layerToMapTransform, bool selectedOnly )
27
+ QgsFeaturePool::QgsFeaturePool ( QgsVectorLayer *layer, double layerToMapUnits, const QgsCoordinateTransform &layerToMapTransform )
27
28
: mFeatureCache( CACHE_SIZE )
28
29
, mLayer( layer )
29
30
, mLayerToMapUnits( layerToMapUnits )
30
31
, mLayerToMapTransform( layerToMapTransform )
31
- , mSelectedOnly( selectedOnly )
32
+ , mLayerId( layer->id () )
33
+ , mGeometryType( layer->geometryType () )
32
34
{
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
- }
42
35
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
- }
56
36
}
57
37
58
38
bool QgsFeaturePool::get ( QgsFeatureId id, QgsFeature &feature )
59
39
{
60
- QMutexLocker lock ( & mLayerMutex );
40
+ mCacheLock . lockForRead ( );
61
41
QgsFeature *cachedFeature = mFeatureCache .object ( id );
62
42
if ( cachedFeature )
63
43
{
@@ -66,78 +46,83 @@ bool QgsFeaturePool::get( QgsFeatureId id, QgsFeature &feature )
66
46
}
67
47
else
68
48
{
49
+ std::unique_ptr<QgsVectorLayerFeatureSource> source = QgsVectorLayerUtils::getFeatureSource ( mLayer );
50
+
69
51
// Feature not in cache, retrieve from layer
70
52
// TODO: avoid always querying all attributes (attribute values are needed when merging by attribute)
71
- if ( !mLayer ->getFeatures ( QgsFeatureRequest ( id ) ).nextFeature ( feature ) )
53
+ if ( !source ->getFeatures ( QgsFeatureRequest ( id ) ).nextFeature ( feature ) )
72
54
{
73
55
return false ;
74
56
}
57
+ mCacheLock .unlock ();
58
+ mCacheLock .lockForWrite ();
75
59
mFeatureCache .insert ( id, new QgsFeature ( feature ) );
76
60
}
61
+ mCacheLock .unlock ();
77
62
return true ;
78
63
}
79
64
80
- void QgsFeaturePool::addFeature ( QgsFeature &feature )
65
+ QgsFeatureIds QgsFeaturePool::getFeatureIds () const
81
66
{
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 ();
67
+ return mFeatureIds ;
97
68
}
98
69
99
- void QgsFeaturePool::updateFeature ( QgsFeature &feature )
70
+ QgsFeatureIds QgsFeaturePool::getIntersects ( const QgsRectangle &rect ) const
100
71
{
101
- QgsFeature origFeature;
102
- get ( feature.id (), origFeature );
72
+ mIndexLock .lockForRead ();
73
+ QgsFeatureIds ids = QgsFeatureIds::fromList ( mIndex .intersects ( rect ) );
74
+ mIndexLock .unlock ();
75
+ return ids;
76
+ }
103
77
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
+ mCacheLock .lockForWrite ();
88
+ mFeatureCache .insert ( feature.id (), new QgsFeature ( feature ) );
89
+ mIndex .insertFeature ( feature );
90
+ mCacheLock .unlock ();
91
+ }
92
+
93
+ void QgsFeaturePool::changeFeature ( const QgsFeature &feature )
94
+ {
95
+ mCacheLock .lockForWrite ();
96
+ mFeatureCache .remove ( feature.id () );
97
+ mFeatureCache .insert ( feature.id (), new QgsFeature ( feature ) );
98
+ mIndex .deleteFeature ( feature );
120
99
mIndex .insertFeature ( feature );
121
- mIndexMutex .unlock ();
100
+ mCacheLock .unlock ();
122
101
}
123
102
124
- void QgsFeaturePool::deleteFeature ( QgsFeatureId fid )
103
+ void QgsFeaturePool::removeFeature ( const QgsFeatureId featureId )
125
104
{
126
105
QgsFeature origFeature;
127
- if ( get ( fid, origFeature ) )
106
+ mCacheLock .lockForWrite ();
107
+ if ( get ( featureId, origFeature ) )
128
108
{
129
- mIndexMutex .lock ();
130
109
mIndex .deleteFeature ( origFeature );
131
- mIndexMutex .unlock ();
132
110
}
133
- mLayerMutex .lock ();
134
111
mFeatureCache .remove ( origFeature.id () );
135
- mLayer ->dataProvider ()->deleteFeatures ( QgsFeatureIds () << fid );
136
- mLayerMutex .unlock ();
112
+ mCacheLock .unlock ();
137
113
}
138
114
139
- QgsFeatureIds QgsFeaturePool::getIntersects ( const QgsRectangle &rect ) const
115
+ void QgsFeaturePool::setFeatureIds ( const QgsFeatureIds &ids )
116
+ {
117
+ mFeatureIds = ids;
118
+ }
119
+
120
+ QgsWkbTypes::GeometryType QgsFeaturePool::geometryType () const
121
+ {
122
+ return mGeometryType ;
123
+ }
124
+
125
+ QString QgsFeaturePool::layerId () const
140
126
{
141
- QMutexLocker lock ( &mIndexMutex );
142
- return QgsFeatureIds::fromList ( mIndex .intersects ( rect ) );
127
+ return mLayerId ;
143
128
}
0 commit comments