Skip to content

Commit b99e93c

Browse files
committedDec 3, 2013
Updated memory provider to support feature source (untested yet)
1 parent 5386324 commit b99e93c

File tree

4 files changed

+67
-33
lines changed

4 files changed

+67
-33
lines changed
 

‎src/providers/memory/qgsmemoryfeatureiterator.cpp

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@
2121
#include "qgsmessagelog.h"
2222

2323

24-
QgsMemoryFeatureIterator::QgsMemoryFeatureIterator( QgsMemoryProvider* p, const QgsFeatureRequest& request )
25-
: QgsAbstractFeatureIterator( request )
26-
, P( p )
24+
25+
QgsMemoryFeatureIterator::QgsMemoryFeatureIterator( QgsMemoryFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )
26+
: QgsAbstractFeatureIteratorFromSource( source, ownSource, request )
2727
, mSelectRectGeom( 0 )
2828
{
29-
P->mActiveIterators << this;
3029

3130
if ( mRequest.filterType() == QgsFeatureRequest::FilterRect && mRequest.flags() & QgsFeatureRequest::ExactIntersect )
3231
{
@@ -35,17 +34,17 @@ QgsMemoryFeatureIterator::QgsMemoryFeatureIterator( QgsMemoryProvider* p, const
3534

3635
// if there's spatial index, use it!
3736
// (but don't use it when selection rect is not specified)
38-
if ( mRequest.filterType() == QgsFeatureRequest::FilterRect && P->mSpatialIndex )
37+
if ( mRequest.filterType() == QgsFeatureRequest::FilterRect && mSource->mSpatialIndex )
3938
{
4039
mUsingFeatureIdList = true;
41-
mFeatureIdList = P->mSpatialIndex->intersects( mRequest.filterRect() );
40+
mFeatureIdList = mSource->mSpatialIndex->intersects( mRequest.filterRect() );
4241
QgsDebugMsg( "Features returned by spatial index: " + QString::number( mFeatureIdList.count() ) );
4342
}
4443
else if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )
4544
{
4645
mUsingFeatureIdList = true;
47-
QgsFeatureMap::iterator it = P->mFeatures.find( mRequest.filterFid() );
48-
if ( it != P->mFeatures.end() )
46+
QgsFeatureMap::const_iterator it = mSource->mFeatures.find( mRequest.filterFid() );
47+
if ( it != mSource->mFeatures.end() )
4948
mFeatureIdList.append( mRequest.filterFid() );
5049
}
5150
else
@@ -81,12 +80,12 @@ bool QgsMemoryFeatureIterator::nextFeatureUsingList( QgsFeature& feature )
8180
bool hasFeature = false;
8281

8382
// option 1: we have a list of features to traverse
84-
while ( mFeatureIdListIterator != mFeatureIdList.end() )
83+
while ( mFeatureIdListIterator != mFeatureIdList.constEnd() )
8584
{
8685
if ( mRequest.filterType() == QgsFeatureRequest::FilterRect && mRequest.flags() & QgsFeatureRequest::ExactIntersect )
8786
{
8887
// do exact check in case we're doing intersection
89-
if ( P->mFeatures[*mFeatureIdListIterator].geometry()->intersects( mSelectRectGeom ) )
88+
if ( mSource->mFeatures[*mFeatureIdListIterator].geometry()->intersects( mSelectRectGeom ) )
9089
hasFeature = true;
9190
}
9291
else
@@ -101,14 +100,14 @@ bool QgsMemoryFeatureIterator::nextFeatureUsingList( QgsFeature& feature )
101100
// copy feature
102101
if ( hasFeature )
103102
{
104-
feature = P->mFeatures[*mFeatureIdListIterator];
103+
feature = mSource->mFeatures[*mFeatureIdListIterator];
105104
mFeatureIdListIterator++;
106105
}
107106
else
108107
close();
109108

110109
if ( hasFeature )
111-
feature.setFields( &P->mFields ); // allow name-based attribute lookups
110+
feature.setFields( &mSource->mFields ); // allow name-based attribute lookups
112111

113112
return hasFeature;
114113
}
@@ -119,7 +118,7 @@ bool QgsMemoryFeatureIterator::nextFeatureTraverseAll( QgsFeature& feature )
119118
bool hasFeature = false;
120119

121120
// option 2: traversing the whole layer
122-
while ( mSelectIterator != P->mFeatures.end() )
121+
while ( mSelectIterator != mSource->mFeatures.constEnd() )
123122
{
124123
if ( mRequest.filterType() != QgsFeatureRequest::FilterRect )
125124
{
@@ -154,7 +153,7 @@ bool QgsMemoryFeatureIterator::nextFeatureTraverseAll( QgsFeature& feature )
154153
feature = mSelectIterator.value();
155154
mSelectIterator++;
156155
feature.setValid( true );
157-
feature.setFields( &P->mFields ); // allow name-based attribute lookups
156+
feature.setFields( &mSource->mFields ); // allow name-based attribute lookups
158157
}
159158
else
160159
close();
@@ -168,9 +167,9 @@ bool QgsMemoryFeatureIterator::rewind()
168167
return false;
169168

170169
if ( mUsingFeatureIdList )
171-
mFeatureIdListIterator = mFeatureIdList.begin();
170+
mFeatureIdListIterator = mFeatureIdList.constBegin();
172171
else
173-
mSelectIterator = P->mFeatures.begin();
172+
mSelectIterator = mSource->mFeatures.constBegin();
174173

175174
return true;
176175
}
@@ -180,11 +179,30 @@ bool QgsMemoryFeatureIterator::close()
180179
if ( mClosed )
181180
return false;
182181

183-
P->mActiveIterators.remove( this );
182+
iteratorClosed();
184183

185184
delete mSelectRectGeom;
186185
mSelectRectGeom = NULL;
187186

188187
mClosed = true;
189188
return true;
190189
}
190+
191+
// -------------------------
192+
193+
QgsMemoryFeatureSource::QgsMemoryFeatureSource( const QgsMemoryProvider* p )
194+
: mFields( p->mFields )
195+
, mFeatures( p->mFeatures )
196+
, mSpatialIndex( p->mSpatialIndex ? new QgsSpatialIndex( *p->mSpatialIndex ) : 0 ) // just shallow copy
197+
{
198+
}
199+
200+
QgsMemoryFeatureSource::~QgsMemoryFeatureSource()
201+
{
202+
delete mSpatialIndex;
203+
}
204+
205+
QgsFeatureIterator QgsMemoryFeatureSource::getFeatures( const QgsFeatureRequest& request )
206+
{
207+
return QgsFeatureIterator( new QgsMemoryFeatureIterator( this, false, request ) );
208+
}

‎src/providers/memory/qgsmemoryfeatureiterator.h

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,30 @@ class QgsMemoryProvider;
2121

2222
typedef QMap<QgsFeatureId, QgsFeature> QgsFeatureMap;
2323

24+
class QgsSpatialIndex;
2425

25-
class QgsMemoryFeatureIterator : public QgsAbstractFeatureIterator
26+
27+
class QgsMemoryFeatureSource : public QgsAbstractFeatureSource
28+
{
29+
public:
30+
QgsMemoryFeatureSource( const QgsMemoryProvider* p );
31+
~QgsMemoryFeatureSource();
32+
33+
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request );
34+
35+
protected:
36+
QgsFields mFields;
37+
QgsFeatureMap mFeatures;
38+
QgsSpatialIndex* mSpatialIndex;
39+
40+
friend class QgsMemoryFeatureIterator;
41+
};
42+
43+
44+
class QgsMemoryFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsMemoryFeatureSource>
2645
{
2746
public:
28-
QgsMemoryFeatureIterator( QgsMemoryProvider* p, const QgsFeatureRequest& request );
47+
QgsMemoryFeatureIterator( QgsMemoryFeatureSource* source, bool ownSource, const QgsFeatureRequest& request );
2948

3049
~QgsMemoryFeatureIterator();
3150

@@ -43,13 +62,11 @@ class QgsMemoryFeatureIterator : public QgsAbstractFeatureIterator
4362
bool nextFeatureUsingList( QgsFeature& feature );
4463
bool nextFeatureTraverseAll( QgsFeature& feature );
4564

46-
QgsMemoryProvider* P;
47-
4865
QgsGeometry* mSelectRectGeom;
49-
QgsFeatureMap::iterator mSelectIterator;
66+
QgsFeatureMap::const_iterator mSelectIterator;
5067
bool mUsingFeatureIdList;
5168
QList<QgsFeatureId> mFeatureIdList;
52-
QList<QgsFeatureId>::iterator mFeatureIdListIterator;
69+
QList<QgsFeatureId>::const_iterator mFeatureIdListIterator;
5370

5471
};
5572

‎src/providers/memory/qgsmemoryprovider.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,14 @@ QgsMemoryProvider::QgsMemoryProvider( QString uri )
151151

152152
QgsMemoryProvider::~QgsMemoryProvider()
153153
{
154-
while ( !mActiveIterators.empty() )
155-
{
156-
QgsMemoryFeatureIterator *it = *mActiveIterators.begin();
157-
QgsDebugMsg( "closing active iterator" );
158-
it->close();
159-
}
160-
161154
delete mSpatialIndex;
162155
}
163156

157+
QgsAbstractFeatureSource* QgsMemoryProvider::featureSource() const
158+
{
159+
return new QgsMemoryFeatureSource( this );
160+
}
161+
164162
QString QgsMemoryProvider::dataSourceUri() const
165163
{
166164
QUrl uri( "memory" );
@@ -238,7 +236,7 @@ QString QgsMemoryProvider::storageType() const
238236

239237
QgsFeatureIterator QgsMemoryProvider::getFeatures( const QgsFeatureRequest& request )
240238
{
241-
return QgsFeatureIterator( new QgsMemoryFeatureIterator( this, request ) );
239+
return QgsFeatureIterator( new QgsMemoryFeatureIterator( new QgsMemoryFeatureSource( this ), true, request ) );
242240
}
243241

244242

‎src/providers/memory/qgsmemoryprovider.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class QgsMemoryProvider : public QgsVectorDataProvider
3434

3535
/* Implementation of functions from QgsVectorDataProvider */
3636

37+
virtual QgsAbstractFeatureSource* featureSource() const;
38+
3739
/**
3840
* Returns the permanent storage type for this layer as a friendly name.
3941
*/
@@ -168,6 +170,5 @@ class QgsMemoryProvider : public QgsVectorDataProvider
168170
// indexing
169171
QgsSpatialIndex* mSpatialIndex;
170172

171-
friend class QgsMemoryFeatureIterator;
172-
QSet< QgsMemoryFeatureIterator *> mActiveIterators;
173+
friend class QgsMemoryFeatureSource;
173174
};

0 commit comments

Comments
 (0)
Please sign in to comment.