Skip to content

Commit 3687ac1

Browse files
committed
WFS: added featureSource() - now it is possible to do rendering
1 parent ffb815b commit 3687ac1

File tree

4 files changed

+113
-86
lines changed

4 files changed

+113
-86
lines changed

src/providers/wfs/qgswfsfeatureiterator.cpp

+78-30
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,23 @@
1818
#include "qgsmessagelog.h"
1919
#include "qgsgeometry.h"
2020

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 )
2423
{
25-
//select ids
26-
//get iterator
27-
if ( !mProvider )
28-
{
29-
return;
30-
}
31-
32-
mProvider->mActiveIterators << this;
33-
3424
switch ( request.filterType() )
3525
{
3626
case QgsFeatureRequest::FilterRect:
37-
if ( mProvider->mSpatialIndex )
27+
if ( mSource->mSpatialIndex )
3828
{
39-
mSelectedFeatures = mProvider->mSpatialIndex->intersects( request.filterRect() );
29+
mSelectedFeatures = mSource->mSpatialIndex->intersects( request.filterRect() );
4030
}
4131
break;
4232
case QgsFeatureRequest::FilterFid:
4333
mSelectedFeatures.push_back( request.filterFid() );
4434
break;
4535
case QgsFeatureRequest::FilterNone:
46-
mSelectedFeatures = mProvider->mFeatures.keys();
47-
default: //QgsFeatureRequest::FilterNone
48-
mSelectedFeatures = mProvider->mFeatures.keys();
36+
default:
37+
mSelectedFeatures = mSource->mFeatures.keys();
4938
}
5039

5140
mFeatureIterator = mSelectedFeatures.constBegin();
@@ -58,22 +47,20 @@ QgsWFSFeatureIterator::~QgsWFSFeatureIterator()
5847

5948
bool QgsWFSFeatureIterator::fetchFeature( QgsFeature& f )
6049
{
61-
if ( !mProvider )
62-
{
50+
if ( mClosed )
6351
return false;
64-
}
6552

6653
if ( mFeatureIterator == mSelectedFeatures.constEnd() )
6754
{
6855
return false;
6956
}
7057

71-
QgsFeature *fet = 0;
58+
const QgsFeature *fet = 0;
7259

7360
for ( ;; )
7461
{
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() )
7764
return false;
7865

7966
fet = it.value();
@@ -87,17 +74,15 @@ bool QgsWFSFeatureIterator::fetchFeature( QgsFeature& f )
8774
}
8875

8976

90-
mProvider->copyFeature( fet, f, !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) );
77+
copyFeature( fet, f, !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) );
9178
++mFeatureIterator;
9279
return true;
9380
}
9481

9582
bool QgsWFSFeatureIterator::rewind()
9683
{
97-
if ( !mProvider )
98-
{
84+
if ( mClosed )
9985
return false;
100-
}
10186

10287
mFeatureIterator = mSelectedFeatures.constBegin();
10388

@@ -106,11 +91,74 @@ bool QgsWFSFeatureIterator::rewind()
10691

10792
bool QgsWFSFeatureIterator::close()
10893
{
109-
if ( !mProvider )
94+
if ( mClosed )
11095
return false;
11196

112-
mProvider->mActiveIterators.remove( this );
97+
iteratorClosed();
11398

114-
mProvider = 0;
99+
mClosed = true;
115100
return true;
116101
}
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+
}

src/providers/wfs/qgswfsfeatureiterator.h

+26-3
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,31 @@
1818
#include "qgsfeatureiterator.h"
1919

2020
class QgsWFSProvider;
21+
class QgsSpatialIndex;
22+
typedef QMap<QgsFeatureId, QgsFeature*> QgsFeaturePtrMap;
2123

22-
class QgsWFSFeatureIterator: public QgsAbstractFeatureIterator
24+
25+
class QgsWFSFeatureSource : public QgsAbstractFeatureSource
26+
{
27+
public:
28+
QgsWFSFeatureSource( const QgsWFSProvider* p );
29+
~QgsWFSFeatureSource();
30+
31+
QgsFeatureIterator getFeatures( const QgsFeatureRequest& request );
32+
33+
protected:
34+
35+
QgsFields mFields;
36+
QgsFeaturePtrMap mFeatures;
37+
QgsSpatialIndex* mSpatialIndex;
38+
39+
friend class QgsWFSFeatureIterator;
40+
};
41+
42+
class QgsWFSFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsWFSFeatureSource>
2343
{
2444
public:
25-
QgsWFSFeatureIterator( QgsWFSProvider* provider, const QgsFeatureRequest& request );
45+
QgsWFSFeatureIterator( QgsWFSFeatureSource* source, bool ownSource, const QgsFeatureRequest& request );
2646
~QgsWFSFeatureIterator();
2747

2848
bool rewind();
@@ -31,10 +51,13 @@ class QgsWFSFeatureIterator: public QgsAbstractFeatureIterator
3151
protected:
3252
bool fetchFeature( QgsFeature& f );
3353

54+
/**Copies feature attributes / geometry from f to feature*/
55+
void copyFeature( const QgsFeature* f, QgsFeature& feature, bool fetchGeometry );
56+
3457
private:
35-
QgsWFSProvider* mProvider;
3658
QList<QgsFeatureId> mSelectedFeatures;
3759
QList<QgsFeatureId>::const_iterator mFeatureIterator;
60+
3861
};
3962

4063
#endif // QGSWFSFEATUREITERATOR_H

src/providers/wfs/qgswfsprovider.cpp

+6-48
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,15 @@ QgsWFSProvider::QgsWFSProvider( const QString& uri )
124124

125125
QgsWFSProvider::~QgsWFSProvider()
126126
{
127-
while ( !mActiveIterators.empty() )
128-
{
129-
QgsWFSFeatureIterator *it = *mActiveIterators.begin();
130-
QgsDebugMsg( "closing active iterator" );
131-
it->close();
132-
}
133-
134127
deleteData();
135128
delete mSpatialIndex;
136129
}
137130

131+
QgsAbstractFeatureSource* QgsWFSProvider::featureSource() const
132+
{
133+
return new QgsWFSFeatureSource( this );
134+
}
135+
138136
void QgsWFSProvider::reloadData()
139137
{
140138
deleteData();
@@ -153,46 +151,6 @@ void QgsWFSProvider::deleteData()
153151
mFeatures.clear();
154152
}
155153

156-
void QgsWFSProvider::copyFeature( QgsFeature* f, QgsFeature& feature, bool fetchGeometry )
157-
{
158-
Q_UNUSED( fetchGeometry );
159-
160-
if ( !f )
161-
{
162-
return;
163-
}
164-
165-
//copy the geometry
166-
QgsGeometry* geometry = f->geometry();
167-
if ( geometry && fetchGeometry )
168-
{
169-
const unsigned char *geom = geometry->asWkb();
170-
int geomSize = geometry->wkbSize();
171-
unsigned char* copiedGeom = new unsigned char[geomSize];
172-
memcpy( copiedGeom, geom, geomSize );
173-
feature.setGeometryAndOwnership( copiedGeom, geomSize );
174-
}
175-
else
176-
{
177-
feature.setGeometry( 0 );
178-
}
179-
180-
//and the attributes
181-
feature.initAttributes( mFields.size() );
182-
for ( int i = 0; i < mFields.size(); i++ )
183-
{
184-
const QVariant &v = f->attributes().value( i );
185-
if ( v.type() != mFields[i].type() )
186-
feature.setAttribute( i, convertValue( mFields[i].type(), v.toString() ) );
187-
else
188-
feature.setAttribute( i, v );
189-
}
190-
191-
//id and valid
192-
feature.setValid( true );
193-
feature.setFeatureId( f->id() );
194-
feature.setFields( &mFields ); // allow name-based attribute lookups
195-
}
196154

197155
QGis::WkbType QgsWFSProvider::geometryType() const
198156
{
@@ -299,7 +257,7 @@ QgsFeatureIterator QgsWFSProvider::getFeatures( const QgsFeatureRequest& request
299257
}
300258

301259
}
302-
return QgsFeatureIterator( new QgsWFSFeatureIterator( this, request ) );
260+
return QgsFeatureIterator( new QgsWFSFeatureIterator( new QgsWFSFeatureSource( this ), true, request ) );
303261
}
304262

305263
int QgsWFSProvider::getFeature( const QString& uri )

src/providers/wfs/qgswfsprovider.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class QgsWFSProvider: public QgsVectorDataProvider
4747

4848
/* Inherited from QgsVectorDataProvider */
4949

50+
virtual QgsAbstractFeatureSource* featureSource() const;
51+
5052
QgsFeatureIterator getFeatures( const QgsFeatureRequest& request = QgsFeatureRequest() );
5153

5254
QGis::WkbType geometryType() const;
@@ -127,8 +129,7 @@ class QgsWFSProvider: public QgsVectorDataProvider
127129

128130
private:
129131
bool mNetworkRequestFinished;
130-
friend class QgsWFSFeatureIterator;
131-
QSet< QgsWFSFeatureIterator * > mActiveIterators;
132+
friend class QgsWFSFeatureSource;
132133

133134
protected:
134135
/**Thematic attributes*/
@@ -189,9 +190,6 @@ class QgsWFSProvider: public QgsVectorDataProvider
189190
/**This method tries to guess the geometry attribute and the other attribute names from the .gml file if no schema is present. Returns 0 in case of success*/
190191
int guessAttributesFromFile( const QString& uri, QString& geometryAttribute, std::list<QString>& thematicAttributes, QGis::WkbType& geomType ) const;
191192

192-
/**Copies feature attributes / geometry from f to feature*/
193-
void copyFeature( QgsFeature* f, QgsFeature& feature, bool fetchGeometry );
194-
195193
//GML2 specific methods
196194
int getExtentFromGML2( QgsRectangle* extent, const QDomElement& wfsCollectionElement ) const;
197195

0 commit comments

Comments
 (0)