Skip to content

Commit cb35c89

Browse files
committed
wfs provider: remove old featureById and nextFeature
gml parsing: don't mistake attributes for features just because the have the same name and some cleanups
1 parent ca8fb71 commit cb35c89

File tree

4 files changed

+36
-148
lines changed

4 files changed

+36
-148
lines changed

src/core/qgsgml.cpp

+34-58
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ QgsGml::QgsGml(
4343
, mFinished( false )
4444
, mFeatureCount( 0 )
4545
, mCurrentWKBSize( 0 )
46+
, mCurrentFeature( 0 )
4647
{
4748
mThematicAttributes.clear();
4849
for ( int i = 0; i < fields.size(); i++ )
@@ -140,7 +141,6 @@ int QgsGml::getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangl
140141

141142
int QgsGml::getFeatures( const QByteArray &data, QGis::WkbType* wkbType, QgsRectangle* extent )
142143
{
143-
QgsDebugMsg( "Entered" );
144144
mWkbType = wkbType;
145145
mExtent.setMinimal();
146146

@@ -176,9 +176,11 @@ void QgsGml::handleProgressEvent( qint64 progress, qint64 totalSteps )
176176
void QgsGml::startElement( const XML_Char* el, const XML_Char** attr )
177177
{
178178
QString elementName( el );
179+
ParseMode theParseMode( mParseModeStack.isEmpty() ? none : mParseModeStack.top() );
179180
QStringList splitName = elementName.split( NS_SEPARATOR );
180181
QString localName = splitName.last();
181182
QString ns = splitName.size() > 1 ? splitName.first() : "";
183+
182184
if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "coordinates" )
183185
{
184186
mParseModeStack.push( QgsGml::coordinate );
@@ -203,16 +205,17 @@ void QgsGml::startElement( const XML_Char* el, const XML_Char** attr )
203205
{
204206
mParseModeStack.push( QgsGml::boundingBox );
205207
}
206-
else if ( localName == mTypeName )
208+
else if ( theParseMode == none && localName == mTypeName )
207209
{
210+
Q_ASSERT( !mCurrentFeature );
208211
mCurrentFeature = new QgsFeature( mFeatureCount );
209212
QgsAttributes attributes( mThematicAttributes.size() ); //add empty attributes
210213
mCurrentFeature->setAttributes( attributes );
211214
mParseModeStack.push( QgsGml::feature );
212215
mCurrentFeatureId = readAttribute( "fid", attr );
213216
}
214217

215-
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "Box" && mParseModeStack.top() == QgsGml::boundingBox )
218+
else if ( theParseMode == boundingBox && elementName == GML_NAMESPACE + NS_SEPARATOR + "Box" )
216219
{
217220
//read attribute srsName="EPSG:26910"
218221
int epsgNr;
@@ -244,7 +247,7 @@ void QgsGml::startElement( const XML_Char* el, const XML_Char** attr )
244247
{
245248
mParseModeStack.push( QgsGml::multiPolygon );
246249
}
247-
else if (( mParseModeStack.size() > 0 ) && ( mParseModeStack.top() == QgsGml::feature ) && ( mThematicAttributes.find( localName ) != mThematicAttributes.end() ) )
250+
else if ( theParseMode == feature && mThematicAttributes.contains( localName ) )
248251
{
249252
mParseModeStack.push( QgsGml::attribute );
250253
mAttributeName = localName;
@@ -255,22 +258,18 @@ void QgsGml::startElement( const XML_Char* el, const XML_Char** attr )
255258
void QgsGml::endElement( const XML_Char* el )
256259
{
257260
QString elementName( el );
261+
ParseMode theParseMode( mParseModeStack.isEmpty() ? none : mParseModeStack.top() );
258262
QStringList splitName = elementName.split( NS_SEPARATOR );
259263
QString localName = splitName.last();
260264
QString ns = splitName.size() > 1 ? splitName.first() : "";
261-
if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "coordinates" )
265+
266+
if ( theParseMode == coordinate && elementName == GML_NAMESPACE + NS_SEPARATOR + "coordinates" )
262267
{
263-
if ( !mParseModeStack.empty() )
264-
{
265-
mParseModeStack.pop();
266-
}
268+
mParseModeStack.pop();
267269
}
268-
else if ( localName == mAttributeName ) //add a thematic attribute to the feature
270+
else if ( theParseMode == attribute && localName == mAttributeName ) //add a thematic attribute to the feature
269271
{
270-
if ( !mParseModeStack.empty() )
271-
{
272-
mParseModeStack.pop();
273-
}
272+
mParseModeStack.pop();
274273

275274
//find index with attribute name
276275
QMap<QString, QPair<int, QgsField> >::const_iterator att_it = mThematicAttributes.find( mAttributeName );
@@ -292,31 +291,27 @@ void QgsGml::endElement( const XML_Char* el )
292291
var = QVariant( mStringCash );
293292
break;
294293
}
294+
Q_ASSERT( mCurrentFeature );
295295
mCurrentFeature->setAttribute( att_it.value().first, QVariant( mStringCash ) );
296296
}
297297
}
298-
else if ( localName == mGeometryAttribute )
298+
else if ( theParseMode == geometry && localName == mGeometryAttribute )
299299
{
300-
if ( !mParseModeStack.empty() )
301-
{
302-
mParseModeStack.pop();
303-
}
300+
mParseModeStack.pop();
304301
}
305-
else if ( !mParseModeStack.empty() && mParseModeStack.top() == QgsGml::boundingBox && elementName == GML_NAMESPACE + NS_SEPARATOR + "boundedBy" )
302+
else if ( theParseMode == boundingBox && elementName == GML_NAMESPACE + NS_SEPARATOR + "boundedBy" )
306303
{
307304
//create bounding box from mStringCash
308305
if ( createBBoxFromCoordinateString( mCurrentExtent, mStringCash ) != 0 )
309306
{
310307
QgsDebugMsg( "creation of bounding box failed" );
311308
}
312309

313-
if ( !mParseModeStack.empty() )
314-
{
315-
mParseModeStack.pop();
316-
}
310+
mParseModeStack.pop();
317311
}
318-
else if ( localName == mTypeName )
312+
else if ( theParseMode == feature && localName == mTypeName )
319313
{
314+
Q_ASSERT( mCurrentFeature );
320315
if ( mCurrentWKBSize > 0 )
321316
{
322317
mCurrentFeature->setGeometryAndOwnership( mCurrentWKB, mCurrentWKBSize );
@@ -336,11 +331,9 @@ void QgsGml::endElement( const XML_Char* el )
336331
{
337332
mIdMap.insert( mCurrentFeature->id(), mCurrentFeatureId );
338333
}
334+
mCurrentFeature = 0;
339335
++mFeatureCount;
340-
if ( !mParseModeStack.empty() )
341-
{
342-
mParseModeStack.pop();
343-
}
336+
mParseModeStack.pop();
344337
}
345338
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "Point" )
346339
{
@@ -350,7 +343,7 @@ void QgsGml::endElement( const XML_Char* el )
350343
//error
351344
}
352345

353-
if ( mParseModeStack.top() != QgsGml::multiPoint )
346+
if ( theParseMode == QgsGml::geometry )
354347
{
355348
//directly add WKB point to the feature
356349
if ( getPointWKB( &mCurrentWKB, &mCurrentWKBSize, *( pointList.begin() ) ) != 0 )
@@ -382,11 +375,6 @@ void QgsGml::endElement( const XML_Char* el )
382375
{
383376
QgsDebugMsg( "No wkb fragments" );
384377
}
385-
386-
//wkbList.push_back(wkb);
387-
//wkbSizeList.push_back(wkbSize);
388-
//mCurrentWKBFragments.push_back(wkbList);
389-
//mCurrentWKBFragmentSizes.push_back(wkbSizeList);
390378
}
391379
}
392380
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "LineString" )
@@ -398,7 +386,7 @@ void QgsGml::endElement( const XML_Char* el )
398386
{
399387
//error
400388
}
401-
if ( mParseModeStack.top() != QgsGml::multiLine )
389+
if ( theParseMode == QgsGml::geometry )
402390
{
403391
if ( getLineWKB( &mCurrentWKB, &mCurrentWKBSize, pointList ) != 0 )
404392
{
@@ -429,13 +417,9 @@ void QgsGml::endElement( const XML_Char* el )
429417
{
430418
QgsDebugMsg( "no wkb fragments" );
431419
}
432-
//wkbList.push_back(wkb);
433-
//wkbSizeList.push_back(wkbSize);
434-
//mCurrentWKBFragments.push_back(wkbList);
435-
//mCurrentWKBFragmentSizes.push_back(wkbSizeList);
436420
}
437421
}
438-
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "LinearRing" )
422+
else if (( theParseMode == geometry || theParseMode == multiPolygon ) && elementName == GML_NAMESPACE + NS_SEPARATOR + "LinearRing" )
439423
{
440424
QList<QgsPoint> pointList;
441425
if ( pointsFromCoordinateString( pointList, mStringCash ) != 0 )
@@ -458,42 +442,34 @@ void QgsGml::endElement( const XML_Char* el )
458442
QgsDebugMsg( "no wkb fragments" );
459443
}
460444
}
461-
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "Polygon" )
445+
else if (( theParseMode == geometry || theParseMode == multiPolygon ) && elementName == GML_NAMESPACE + NS_SEPARATOR + "Polygon" )
462446
{
463447
if ( *mWkbType != QGis::WKBMultiPolygon )//keep multitype in case of geometry type mix
464448
{
465449
*mWkbType = QGis::WKBPolygon;
466450
}
467-
if ( mParseModeStack.top() != QgsGml::multiPolygon )
451+
452+
if ( theParseMode == geometry )
468453
{
469454
createPolygonFromFragments();
470455
}
471456
}
472-
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPoint" )
457+
else if ( theParseMode == multiPoint && elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPoint" )
473458
{
474459
*mWkbType = QGis::WKBMultiPoint;
475-
if ( !mParseModeStack.empty() )
476-
{
477-
mParseModeStack.pop();
478-
}
460+
mParseModeStack.pop();
479461
createMultiPointFromFragments();
480462
}
481-
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiLineString" )
463+
else if ( theParseMode == multiLine && elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiLineString" )
482464
{
483465
*mWkbType = QGis::WKBMultiLineString;
484-
if ( !mParseModeStack.empty() )
485-
{
486-
mParseModeStack.pop();
487-
}
466+
mParseModeStack.pop();
488467
createMultiLineFromFragments();
489468
}
490-
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPolygon" )
469+
else if ( theParseMode == multiPolygon && elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPolygon" )
491470
{
492471
*mWkbType = QGis::WKBMultiPolygon;
493-
if ( !mParseModeStack.empty() )
494-
{
495-
mParseModeStack.pop();
496-
}
472+
mParseModeStack.pop();
497473
createMultiPolygonFromFragments();
498474
}
499475
}

src/core/qgsgml.h

+2-6
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class QgsCoordinateReferenceSystem;
3838
* uses the expat XML parser and an event based model to keep performance high.
3939
* The parsing starts when the first data arrives, it does not wait until the
4040
* request is finished */
41-
class CORE_EXPORT QgsGml: public QObject
41+
class CORE_EXPORT QgsGml : public QObject
4242
{
4343
Q_OBJECT
4444
public:
@@ -85,14 +85,10 @@ class CORE_EXPORT QgsGml: public QObject
8585
{
8686
none,
8787
boundingBox,
88-
//featureMember, // gml:featureMember
89-
feature, // feature element containint attrs and geo (inside gml:featureMember)
88+
feature, // feature element containing attrs and geo (inside gml:featureMember)
9089
attribute,
9190
geometry,
9291
coordinate,
93-
point,
94-
line,
95-
polygon,
9692
multiPoint,
9793
multiLine,
9894
multiPolygon

src/providers/wfs/qgswfsprovider.cpp

-61
Original file line numberDiff line numberDiff line change
@@ -192,67 +192,6 @@ void QgsWFSProvider::copyFeature( QgsFeature* f, QgsFeature& feature, bool fetch
192192
feature.setFields( &mFields ); // allow name-based attribute lookups
193193
}
194194

195-
bool QgsWFSProvider::featureAtId( QgsFeatureId featureId,
196-
QgsFeature& feature,
197-
bool fetchGeometry,
198-
QgsAttributeList fetchAttributes )
199-
{
200-
QMap<QgsFeatureId, QgsFeature* >::iterator it = mFeatures.find( featureId );
201-
if ( it == mFeatures.end() )
202-
{
203-
return false;
204-
}
205-
206-
QgsFeature* f = it.value();
207-
if ( !f )
208-
{
209-
return false;
210-
}
211-
212-
copyFeature( f, feature, fetchGeometry, fetchAttributes );
213-
return true;
214-
}
215-
216-
bool QgsWFSProvider::nextFeature( QgsFeature& feature )
217-
{
218-
feature.setValid( false );
219-
220-
while ( true ) //go through the loop until we find a feature in the filter
221-
{
222-
if ( mSelectedFeatures.size() == 0 || mFeatureIterator == mSelectedFeatures.end() )
223-
{
224-
return 0;
225-
}
226-
227-
QgsFeature* f = mFeatures[*mFeatureIterator];
228-
++mFeatureIterator;
229-
if ( !f )
230-
{
231-
continue;
232-
}
233-
234-
copyFeature( f, feature, mFetchGeom, mAttributesToFetch );
235-
236-
if ( mUseIntersect )
237-
{
238-
if ( feature.geometry() && feature.geometry()->intersects( mSpatialFilter ) )
239-
{
240-
return true;
241-
}
242-
else
243-
{
244-
continue; //go for the next feature
245-
}
246-
}
247-
else
248-
{
249-
return true;
250-
}
251-
}
252-
}
253-
254-
255-
256195
QGis::WkbType QgsWFSProvider::geometryType() const
257196
{
258197
return mWKBType;

src/providers/wfs/qgswfsprovider.h

-23
Original file line numberDiff line numberDiff line change
@@ -49,29 +49,6 @@ class QgsWFSProvider: public QgsVectorDataProvider
4949

5050
QgsFeatureIterator getFeatures( const QgsFeatureRequest& request = QgsFeatureRequest() );
5151

52-
/**
53-
* Gets the feature at the given feature ID.
54-
* @param featureId of the feature to be returned
55-
* @param feature which will receive the data
56-
* @param fetchGeometry flag which if true, will cause the geometry to be fetched from the provider
57-
* @param fetchAttributes a list containing the indexes of the attribute fields to copy
58-
* @return True when feature was found, otherwise false
59-
*
60-
* Default implementation traverses all features until it finds the one with correct ID.
61-
* In case the provider supports reading the feature directly, override this function.
62-
*/
63-
virtual bool featureAtId( QgsFeatureId featureId,
64-
QgsFeature& feature,
65-
bool fetchGeometry = true,
66-
QgsAttributeList fetchAttributes = QgsAttributeList() );
67-
68-
/**
69-
* Get the next feature resulting from a select operation.
70-
* @param feature feature which will receive data from the provider
71-
* @return true when there was a feature to fetch, false when end was hit
72-
*/
73-
virtual bool nextFeature( QgsFeature& feature );
74-
7552
QGis::WkbType geometryType() const;
7653
long featureCount() const;
7754

0 commit comments

Comments
 (0)