@@ -36,9 +36,8 @@ static const QString TEXT_PROVIDER_DESCRIPTION = "WFS data provider";
36
36
static const QString WFS_NAMESPACE = " http://www.opengis.net/wfs" ;
37
37
static const QString GML_NAMESPACE = " http://www.opengis.net/gml" ;
38
38
39
- QgsWFSProvider::QgsWFSProvider (const QString& uri): QgsVectorDataProvider(uri), mFilter( 0 ), mUseIntersect( false ), mSourceSRS (0 )
39
+ QgsWFSProvider::QgsWFSProvider (const QString& uri): QgsVectorDataProvider(uri), mUseIntersect( false ), mSourceSRS( 0 ), mSelectedFeatures( 0 ), mFeatureCount (0 )
40
40
{
41
- mFeatureIterator = mFeatures .begin ();
42
41
if (getFeature (uri) == 0 )
43
42
{
44
43
// provider valid
@@ -47,16 +46,20 @@ QgsWFSProvider::QgsWFSProvider(const QString& uri): QgsVectorDataProvider(uri),
47
46
{
48
47
// provider invalid
49
48
}
49
+ // set spatial filter to the whole extent
50
+ select (&mExtent , false );
50
51
}
51
52
52
53
QgsWFSProvider::~QgsWFSProvider ()
53
54
{
54
- for (std::vector<QgsFeature*>::iterator it = mFeatures .begin (); it != mFeatures .end (); ++it)
55
+ delete mSelectedFeatures ;
56
+ delete mSourceSRS ;
57
+ for (std::list<std::pair<geos::Envelope*, QgsFeature*> >::iterator it = mEnvelopesAndFeatures .begin ();\
58
+ it != mEnvelopesAndFeatures .end (); ++it)
55
59
{
56
- delete (*it);
60
+ delete it->first ;
61
+ delete it->second ;
57
62
}
58
- mFeatures .clear ();
59
- delete mFilter ;
60
63
}
61
64
62
65
QgsFeature* QgsWFSProvider::getFirstFeature (bool fetchAttributes)
@@ -80,29 +83,29 @@ QgsFeature* QgsWFSProvider::getNextFeature(std::list<int> const & attlist, int f
80
83
{
81
84
while (true ) // go through the loop until we find a feature in the filter
82
85
{
83
- if (mFeatureIterator == mFeatures . end ())
86
+ if (! mSelectedFeatures || mFeatureIterator == mSelectedFeatures -> end ())
84
87
{
85
88
return 0 ;
86
89
}
87
90
88
91
QgsFeature* f = new QgsFeature ();
89
- unsigned char * geom = (* mFeatureIterator )->getGeometry ();
90
- int geomSize = (* mFeatureIterator )->getGeometrySize ();
92
+ unsigned char * geom = ((QgsFeature*)(* mFeatureIterator ) )->getGeometry ();
93
+ int geomSize = ((QgsFeature*)(* mFeatureIterator ) )->getGeometrySize ();
91
94
92
95
unsigned char * copiedGeom = new unsigned char [geomSize];
93
96
memcpy (copiedGeom, geom, geomSize);
94
97
f->setGeometryAndOwnership (copiedGeom, geomSize);
95
- f->setFeatureId ((* mFeatureIterator )->featureId ());
98
+ f->setFeatureId (((QgsFeature*)(* mFeatureIterator ) )->featureId ());
96
99
97
- const std::vector<QgsFeatureAttribute> attributes = (* mFeatureIterator )->attributeMap ();
100
+ const std::vector<QgsFeatureAttribute> attributes = ((QgsFeature*)(* mFeatureIterator ) )->attributeMap ();
98
101
for (std::list<int >::const_iterator it = attlist.begin (); it != attlist.end (); ++it)
99
102
{
100
103
f->addAttribute (attributes[*it].fieldName (), attributes[*it].fieldValue (), attributes[*it].isNumeric ());
101
104
}
102
105
++mFeatureIterator ;
103
- if (mFilter && mUseIntersect )
106
+ if (mUseIntersect )
104
107
{
105
- if (f->geometry ()->fast_intersects (mFilter ))
108
+ if (f->geometry ()->fast_intersects (& mSpatialFilter ))
106
109
{
107
110
return f;
108
111
}
@@ -130,7 +133,7 @@ int QgsWFSProvider::geometryType() const
130
133
131
134
long QgsWFSProvider::featureCount () const
132
135
{
133
- return mFeatures . size () ;
136
+ return mFeatureCount ;
134
137
}
135
138
136
139
int QgsWFSProvider::fieldCount () const
@@ -145,9 +148,13 @@ std::vector<QgsField> const & QgsWFSProvider::fields() const
145
148
146
149
void QgsWFSProvider::reset ()
147
150
{
148
- mFeatureIterator = mFeatures .begin ();
149
- delete mFilter ;
150
- mFilter = 0 ;
151
+ geos::Envelope e (mExtent .xMin (), mExtent .xMax (), mExtent .yMin (), mExtent .yMax ());
152
+ delete mSelectedFeatures ;
153
+ mSelectedFeatures = mSpatialIndex .query (&e);
154
+ if (mSelectedFeatures )
155
+ {
156
+ mFeatureIterator = mSelectedFeatures ->begin ();
157
+ }
151
158
}
152
159
153
160
QString QgsWFSProvider::minValue (int position)
@@ -231,9 +238,12 @@ bool QgsWFSProvider::isValid()
231
238
232
239
void QgsWFSProvider::select (QgsRect *mbr, bool useIntersect)
233
240
{
234
- reset ();
235
- mFilter = new QgsRect (*mbr);
236
241
mUseIntersect = useIntersect;
242
+ delete mSelectedFeatures ;
243
+ mSpatialFilter = *mbr;
244
+ geos::Envelope filter (mbr->xMin (), mbr->xMax (), mbr->yMin (), mbr->yMax ());
245
+ mSelectedFeatures = mSpatialIndex .query (&filter);
246
+ mFeatureIterator = mSelectedFeatures ->begin ();
237
247
}
238
248
239
249
int QgsWFSProvider::getCapabilities (const QString& uri, QgsWFSProvider::REQUEST_ENCODING e, std::list<QString>& typenames, std::list< std::list<QString> >& crs)
@@ -404,7 +414,7 @@ int QgsWFSProvider::getFeatureGET(const QString& uri, const QString& geometryAtt
404
414
405
415
setSRSFromGML2 (featureCollectionElement);
406
416
407
- if (getFeaturesFromGML2 (featureCollectionElement, geometryAttribute, mFeatures ) != 0 )
417
+ if (getFeaturesFromGML2 (featureCollectionElement, geometryAttribute) != 0 )
408
418
{
409
419
return 4 ;
410
420
}
@@ -638,7 +648,7 @@ int QgsWFSProvider::setSRSFromGML2(const QDomElement& wfsCollectionElement)
638
648
return 0 ;
639
649
}
640
650
641
- int QgsWFSProvider::getFeaturesFromGML2 (const QDomElement& wfsCollectionElement, const QString& geometryAttribute, std::vector<QgsFeature*>& features) const
651
+ int QgsWFSProvider::getFeaturesFromGML2 (const QDomElement& wfsCollectionElement, const QString& geometryAttribute)
642
652
{
643
653
QDomNodeList featureTypeNodeList = wfsCollectionElement.elementsByTagNameNS (GML_NAMESPACE, " featureMember" );
644
654
QDomElement currentFeatureMemberElem;
@@ -650,6 +660,9 @@ int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement,
650
660
unsigned char * wkb = 0 ;
651
661
int wkbSize = 0 ;
652
662
QGis::WKBTYPE currentType;
663
+ QgsRect featureBBox;
664
+ geos::Envelope* geosBBox;
665
+ mFeatureCount = 0 ;
653
666
654
667
for (int i = 0 ; i < featureTypeNodeList.size (); ++i)
655
668
{
@@ -679,7 +692,12 @@ int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement,
679
692
}
680
693
if (wkb && wkbSize > 0 )
681
694
{
682
- features.push_back (f);
695
+ // insert bbox and pointer to feature into search tree
696
+ featureBBox = f->boundingBox ();
697
+ geosBBox = new geos::Envelope (featureBBox.xMin (), featureBBox.xMax (), featureBBox.yMin (), featureBBox.yMax ());
698
+ mSpatialIndex .insert (geosBBox, (void *)f);
699
+ mEnvelopesAndFeatures .push_back (std::make_pair (geosBBox, f));
700
+ ++mFeatureCount ;
683
701
}
684
702
++counter;
685
703
}
0 commit comments