23
23
#include " qgsspatialrefsys.h"
24
24
#include " qgswfsdata.h"
25
25
#include " qgswfsprovider.h"
26
+ #include " qgsspatialindex.h"
26
27
#include " qgslogger.h"
27
28
#include < QDomDocument>
28
29
#include < QDomNodeList>
@@ -37,8 +38,9 @@ static const QString WFS_NAMESPACE = "http://www.opengis.net/wfs";
37
38
static const QString GML_NAMESPACE = " http://www.opengis.net/gml" ;
38
39
39
40
QgsWFSProvider::QgsWFSProvider (const QString& uri)
40
- : QgsVectorDataProvider(uri), mUseIntersect(false ), mSelectedFeatures( 0 ), mSourceSRS(0 ), mFeatureCount(0 ), mValid(true )
41
+ : QgsVectorDataProvider(uri), mUseIntersect(false ), mSourceSRS(0 ), mFeatureCount(0 ), mValid(true )
41
42
{
43
+ mSpatialIndex = new QgsSpatialIndex;
42
44
if (getFeature (uri) == 0 )
43
45
{
44
46
mValid = true ;
@@ -54,58 +56,56 @@ QgsWFSProvider::QgsWFSProvider(const QString& uri)
54
56
55
57
QgsWFSProvider::~QgsWFSProvider ()
56
58
{
57
- delete mSelectedFeatures ;
58
- for (std::list<std::pair<GEOS_GEOM::Envelope*, QgsFeature*> >::iterator it = mEnvelopesAndFeatures .begin ();\
59
- it != mEnvelopesAndFeatures .end (); ++it)
60
- {
61
- delete it->first ;
62
- delete it->second ;
63
- }
59
+ mSelectedFeatures .clear ();
60
+ for (int i=0 ; i<mFeatures .size (); i++)
61
+ delete mFeatures [i];
62
+ mFeatures .clear ();
63
+ delete mSpatialIndex ;
64
64
}
65
65
66
66
bool QgsWFSProvider::getNextFeature (QgsFeature& feature)
67
67
{
68
68
while (true ) // go through the loop until we find a feature in the filter
69
+ {
70
+ if (mSelectedFeatures .size ()==0 || mFeatureIterator ==mSelectedFeatures .end ())
69
71
{
70
- if (!mSelectedFeatures || mFeatureIterator == mSelectedFeatures ->end ())
71
- {
72
- return 0 ;
73
- }
72
+ return 0 ;
73
+ }
74
74
75
- feature.setFeatureId (((QgsFeature*)(*mFeatureIterator ))->featureId ());
76
- if (mFetchGeom )
77
- {
78
- QgsGeometry* geometry = ((QgsFeature*)(*mFeatureIterator ))->geometry ();
79
- unsigned char * geom = geometry->wkbBuffer ();
80
- int geomSize = geometry->wkbSize ();
81
-
82
- unsigned char * copiedGeom = new unsigned char [geomSize];
83
- memcpy (copiedGeom, geom, geomSize);
84
- feature.setGeometryAndOwnership (copiedGeom, geomSize);
85
- }
86
-
87
- const QgsAttributeMap& attributes = ((QgsFeature*)(*mFeatureIterator ))->attributeMap ();
88
- for (QgsAttributeList::const_iterator it = mAttributesToFetch .begin (); it != mAttributesToFetch .end (); ++it)
89
- {
90
- feature.addAttribute (*it, attributes[*it]);
91
- }
92
- ++mFeatureIterator ;
93
- if (mUseIntersect )
94
- {
95
- if (feature.geometry ()->intersects (mSpatialFilter ))
96
- {
97
- return true ;
98
- }
99
- else
100
- {
101
- continue ; // go for the next feature
102
- }
103
- }
75
+ feature.setFeatureId ( mFeatures [*mFeatureIterator ]->featureId () );
76
+ if (mFetchGeom )
77
+ {
78
+ QgsGeometry* geometry = mFeatures [*mFeatureIterator ]->geometry ();
79
+ unsigned char *geom = geometry->wkbBuffer ();
80
+ int geomSize = geometry->wkbSize ();
81
+
82
+ unsigned char * copiedGeom = new unsigned char [geomSize];
83
+ memcpy (copiedGeom, geom, geomSize);
84
+ feature.setGeometryAndOwnership (copiedGeom, geomSize);
85
+ }
86
+
87
+ const QgsAttributeMap& attributes = mFeatures [*mFeatureIterator ]->attributeMap ();
88
+ for (QgsAttributeList::const_iterator it = mAttributesToFetch .begin (); it != mAttributesToFetch .end (); ++it)
89
+ {
90
+ feature.addAttribute (*it, attributes[*it]);
91
+ }
92
+ ++mFeatureIterator ;
93
+ if (mUseIntersect )
94
+ {
95
+ if (feature.geometry ()->intersects (mSpatialFilter ))
96
+ {
97
+ return true ;
98
+ }
104
99
else
105
- {
106
- return true ;
107
- }
100
+ {
101
+ continue ; // go for the next feature
102
+ }
103
+ }
104
+ else
105
+ {
106
+ return true ;
108
107
}
108
+ }
109
109
}
110
110
111
111
@@ -132,10 +132,7 @@ const QgsFieldMap & QgsWFSProvider::fields() const
132
132
133
133
void QgsWFSProvider::reset ()
134
134
{
135
- if (mSelectedFeatures )
136
- {
137
- mFeatureIterator = mSelectedFeatures ->begin ();
138
- }
135
+ mFeatureIterator = mSelectedFeatures .begin ();
139
136
}
140
137
141
138
QgsSpatialRefSys QgsWFSProvider::getSRS ()
@@ -162,24 +159,17 @@ void QgsWFSProvider::select(QgsAttributeList fetchAttributes,
162
159
mAttributesToFetch = fetchAttributes;
163
160
mFetchGeom = fetchGeometry;
164
161
165
- delete mSelectedFeatures ;
166
162
if (rect.isEmpty ())
167
- {
168
- mSpatialFilter = mExtent ;
169
- }
163
+ {
164
+ mSpatialFilter = mExtent ;
165
+ }
170
166
else
171
- {
172
- mSpatialFilter = rect;
173
- }
167
+ {
168
+ mSpatialFilter = rect;
169
+ }
174
170
175
- GEOS_GEOM::Envelope filter (mSpatialFilter .xMin (), mSpatialFilter .xMax (), mSpatialFilter .yMin (), mSpatialFilter .yMax ());
176
- #if GEOS_VERSION_MAJOR < 3
177
- mSelectedFeatures = mSpatialIndex .query (&filter);
178
- #else
179
- mSelectedFeatures = new std::vector<void *>;
180
- mSpatialIndex .query (&filter, *mSelectedFeatures );
181
- #endif
182
- mFeatureIterator = mSelectedFeatures ->begin ();
171
+ mSelectedFeatures = mSpatialIndex ->intersects (mSpatialFilter );
172
+ mFeatureIterator = mSelectedFeatures .begin ();
183
173
}
184
174
185
175
int QgsWFSProvider::getFeature (const QString& uri)
@@ -249,20 +239,20 @@ int QgsWFSProvider::getFeatureGET(const QString& uri, const QString& geometryAtt
249
239
QByteArray result;
250
240
QgsHttpTransaction http(request);
251
241
http.getSynchronously(result);
252
-
242
+
253
243
QDomDocument getFeatureDocument;
254
244
if(!getFeatureDocument.setContent(result, true))
255
- {
256
- return 1; //error
257
- }
245
+ {
246
+ return 1; //error
247
+ }
258
248
259
249
QDomElement featureCollectionElement = getFeatureDocument.documentElement();
260
-
250
+
261
251
//get and set Extent
262
252
if(getExtentFromGML2(&mExtent, featureCollectionElement) != 0)
263
- {
264
- return 3;
265
- }
253
+ {
254
+ return 3;
255
+ }
266
256
267
257
setSRSFromGML2(featureCollectionElement);
268
258
@@ -275,58 +265,52 @@ int QgsWFSProvider::getFeatureGET(const QString& uri, const QString& geometryAtt
275
265
#endif
276
266
277
267
// the new and faster method with the expat parser
278
- std::list<QgsFeature*> dataFeatures;
279
- std::set<QString> thematicAttributes;
268
+ QSet<QString> thematicAttributes;
280
269
for (QgsFieldMap::const_iterator it = mFields .begin (); it != mFields .end (); ++it)
281
- {
282
- thematicAttributes. insert ( it->name () );
283
- }
284
-
285
- QgsWFSData dataReader (uri, &mExtent , &mSourceSRS , &dataFeatures , geometryAttribute, thematicAttributes, &mWKBType );
270
+ {
271
+ thematicAttributes << it->name ();
272
+ }
273
+
274
+ QgsWFSData dataReader (uri, &mExtent , &mSourceSRS , mFeatures , geometryAttribute, thematicAttributes, &mWKBType );
286
275
QObject::connect (dataReader.http (), SIGNAL (dataReadProgress (int , int )), this , SLOT (handleWFSProgressMessage (int , int )));
287
276
288
277
// also connect to setStatus signal of qgisapp (if it exists)
289
278
QWidget* mainWindow = 0 ;
290
-
279
+
291
280
QWidgetList topLevelWidgets = qApp->topLevelWidgets ();
292
281
QWidgetList::iterator it = topLevelWidgets.begin ();
293
282
for (; it != topLevelWidgets.end (); ++it)
283
+ {
284
+ if ((*it)->objectName () == " QgisApp" )
294
285
{
295
- if ((*it)->objectName () == " QgisApp" )
296
- {
297
- mainWindow = *it;
298
- break ;
299
- }
286
+ mainWindow = *it;
287
+ break ;
300
288
}
301
-
289
+ }
290
+
302
291
if (mainWindow)
303
- {
304
- QObject::connect (this , SIGNAL (dataReadProgressMessage (QString)), mainWindow, SLOT (showStatusMessage (QString)));
305
- }
292
+ {
293
+ QObject::connect (this , SIGNAL (dataReadProgressMessage (QString)), mainWindow, SLOT (showStatusMessage (QString)));
294
+ }
306
295
307
296
if (dataReader.getWFSData () != 0 )
308
- {
309
- qWarning (" getWFSData returned with error" );
310
- return 1 ;
311
- }
297
+ {
298
+ qWarning (" getWFSData returned with error" );
299
+ return 1 ;
300
+ }
312
301
313
302
qWarning (" feature count after request is:" );
314
- qWarning (QString::number (dataFeatures .size ()).toLocal8Bit ().data ());
303
+ qWarning (QString::number (mFeatures .size ()).toLocal8Bit ().data ());
315
304
qWarning (" mExtent after request is:" );
316
305
qWarning (mExtent .stringRep ().toLocal8Bit ().data ());
317
306
318
- mFeatureCount = 0 ;
307
+ for (QList<QgsFeature*>::iterator it = mFeatures .begin (); it != mFeatures .end (); ++it) {
308
+ QgsDebugMsg (" feature " + QString::number ((*it)->featureId ()));
309
+ mSpatialIndex ->insertFeature (**it);
310
+ }
311
+
312
+ mFeatureCount = mFeatures .size ();
319
313
320
- QgsRect featureBBox;
321
- GEOS_GEOM::Envelope* geosBBox;
322
- for (std::list<QgsFeature*>::const_iterator it = dataFeatures.begin (); it != dataFeatures.end (); ++it)
323
- {
324
- featureBBox = (*it)->geometry ()->boundingBox ();
325
- geosBBox = new GEOS_GEOM::Envelope (featureBBox.xMin (), featureBBox.xMax (), featureBBox.yMin (), featureBBox.yMax ());
326
- mSpatialIndex .insert (geosBBox, (void *)(*it));
327
- mEnvelopesAndFeatures .push_back (std::make_pair (geosBBox, (*it)));
328
- ++mFeatureCount ;
329
- }
330
314
return 0 ;
331
315
}
332
316
@@ -755,8 +739,6 @@ int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement,
755
739
unsigned char * wkb = 0 ;
756
740
int wkbSize = 0 ;
757
741
QGis::WKBTYPE currentType;
758
- QgsRect featureBBox;
759
- GEOS_GEOM::Envelope* geosBBox;
760
742
mFeatureCount = 0 ;
761
743
762
744
for (int i = 0 ; i < featureTypeNodeList.size (); ++i)
@@ -800,10 +782,8 @@ int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement,
800
782
if (wkb && wkbSize > 0 )
801
783
{
802
784
// insert bbox and pointer to feature into search tree
803
- featureBBox = f->geometry ()->boundingBox ();
804
- geosBBox = new GEOS_GEOM::Envelope (featureBBox.xMin (), featureBBox.xMax (), featureBBox.yMin (), featureBBox.yMax ());
805
- mSpatialIndex .insert (geosBBox, (void *)f);
806
- mEnvelopesAndFeatures .push_back (std::make_pair (geosBBox, f));
785
+ mSpatialIndex ->insertFeature (*f);
786
+ mFeatures << f;
807
787
++mFeatureCount ;
808
788
}
809
789
++counter;
0 commit comments