18
18
#include " qgsmessagelog.h"
19
19
#include " qgsgeometry.h"
20
20
21
- QgsWFSFeatureIterator::QgsWFSFeatureIterator ( QgsWFSProvider* provider, const QgsFeatureRequest& request )
22
- : QgsAbstractFeatureIterator( request )
23
- , mProvider( provider )
21
+ QgsWFSFeatureIterator::QgsWFSFeatureIterator ( QgsWFSFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )
22
+ : QgsAbstractFeatureIteratorFromSource( source, ownSource, request )
24
23
{
25
- // select ids
26
- // get iterator
27
- if ( !mProvider )
28
- {
29
- return ;
30
- }
31
-
32
- mProvider ->mActiveIterators << this ;
33
-
34
24
switch ( request.filterType () )
35
25
{
36
26
case QgsFeatureRequest::FilterRect:
37
- if ( mProvider ->mSpatialIndex )
27
+ if ( mSource ->mSpatialIndex )
38
28
{
39
- mSelectedFeatures = mProvider ->mSpatialIndex ->intersects ( request.filterRect () );
29
+ mSelectedFeatures = mSource ->mSpatialIndex ->intersects ( request.filterRect () );
40
30
}
41
31
break ;
42
32
case QgsFeatureRequest::FilterFid:
43
33
mSelectedFeatures .push_back ( request.filterFid () );
44
34
break ;
45
35
case QgsFeatureRequest::FilterNone:
46
- mSelectedFeatures = mProvider ->mFeatures .keys ();
47
- default : // QgsFeatureRequest::FilterNone
48
- mSelectedFeatures = mProvider ->mFeatures .keys ();
36
+ default :
37
+ mSelectedFeatures = mSource ->mFeatures .keys ();
49
38
}
50
39
51
40
mFeatureIterator = mSelectedFeatures .constBegin ();
@@ -58,22 +47,20 @@ QgsWFSFeatureIterator::~QgsWFSFeatureIterator()
58
47
59
48
bool QgsWFSFeatureIterator::fetchFeature ( QgsFeature& f )
60
49
{
61
- if ( !mProvider )
62
- {
50
+ if ( mClosed )
63
51
return false ;
64
- }
65
52
66
53
if ( mFeatureIterator == mSelectedFeatures .constEnd () )
67
54
{
68
55
return false ;
69
56
}
70
57
71
- QgsFeature *fet = 0 ;
58
+ const QgsFeature *fet = 0 ;
72
59
73
60
for ( ;; )
74
61
{
75
- QMap<QgsFeatureId, QgsFeature* >::iterator it = mProvider ->mFeatures .find ( *mFeatureIterator );
76
- if ( it == mProvider ->mFeatures .end () )
62
+ QgsFeaturePtrMap::const_iterator it = mSource ->mFeatures .constFind ( *mFeatureIterator );
63
+ if ( it == mSource ->mFeatures .constEnd () )
77
64
return false ;
78
65
79
66
fet = it.value ();
@@ -87,17 +74,15 @@ bool QgsWFSFeatureIterator::fetchFeature( QgsFeature& f )
87
74
}
88
75
89
76
90
- mProvider -> copyFeature ( fet, f, !( mRequest .flags () & QgsFeatureRequest::NoGeometry ) );
77
+ copyFeature ( fet, f, !( mRequest .flags () & QgsFeatureRequest::NoGeometry ) );
91
78
++mFeatureIterator ;
92
79
return true ;
93
80
}
94
81
95
82
bool QgsWFSFeatureIterator::rewind ()
96
83
{
97
- if ( !mProvider )
98
- {
84
+ if ( mClosed )
99
85
return false ;
100
- }
101
86
102
87
mFeatureIterator = mSelectedFeatures .constBegin ();
103
88
@@ -106,11 +91,74 @@ bool QgsWFSFeatureIterator::rewind()
106
91
107
92
bool QgsWFSFeatureIterator::close ()
108
93
{
109
- if ( ! mProvider )
94
+ if ( mClosed )
110
95
return false ;
111
96
112
- mProvider -> mActiveIterators . remove ( this );
97
+ iteratorClosed ( );
113
98
114
- mProvider = 0 ;
99
+ mClosed = true ;
115
100
return true ;
116
101
}
102
+
103
+
104
+
105
+ void QgsWFSFeatureIterator::copyFeature ( const QgsFeature* f, QgsFeature& feature, bool fetchGeometry )
106
+ {
107
+ Q_UNUSED ( fetchGeometry );
108
+
109
+ if ( !f )
110
+ {
111
+ return ;
112
+ }
113
+
114
+ // copy the geometry
115
+ QgsGeometry* geometry = f->geometry ();
116
+ if ( geometry && fetchGeometry )
117
+ {
118
+ const unsigned char *geom = geometry->asWkb ();
119
+ int geomSize = geometry->wkbSize ();
120
+ unsigned char * copiedGeom = new unsigned char [geomSize];
121
+ memcpy ( copiedGeom, geom, geomSize );
122
+ feature.setGeometryAndOwnership ( copiedGeom, geomSize );
123
+ }
124
+ else
125
+ {
126
+ feature.setGeometry ( 0 );
127
+ }
128
+
129
+ // and the attributes
130
+ feature.initAttributes ( mSource ->mFields .size () );
131
+ for ( int i = 0 ; i < mSource ->mFields .size (); i++ )
132
+ {
133
+ const QVariant &v = f->attributes ().value ( i );
134
+ if ( v.type () != mSource ->mFields [i].type () )
135
+ feature.setAttribute ( i, QgsVectorDataProvider::convertValue ( mSource ->mFields [i].type (), v.toString () ) );
136
+ else
137
+ feature.setAttribute ( i, v );
138
+ }
139
+
140
+ // id and valid
141
+ feature.setValid ( true );
142
+ feature.setFeatureId ( f->id () );
143
+ feature.setFields ( &mSource ->mFields ); // allow name-based attribute lookups
144
+ }
145
+
146
+
147
+ // -------------------------
148
+
149
+ QgsWFSFeatureSource::QgsWFSFeatureSource ( const QgsWFSProvider* p )
150
+ : mFields( p->mFields )
151
+ , mFeatures( p->mFeatures )
152
+ , mSpatialIndex( p->mSpatialIndex ? new QgsSpatialIndex( *p->mSpatialIndex ) : 0 ) // just shallow copy
153
+ {
154
+ }
155
+
156
+ QgsWFSFeatureSource::~QgsWFSFeatureSource ()
157
+ {
158
+ delete mSpatialIndex ;
159
+ }
160
+
161
+ QgsFeatureIterator QgsWFSFeatureSource::getFeatures ( const QgsFeatureRequest& request )
162
+ {
163
+ return QgsFeatureIterator ( new QgsWFSFeatureIterator ( this , false , request ) );
164
+ }
0 commit comments