Skip to content

Commit bb21d39

Browse files
author
mhugent
committed
Implement featureAtId for wfs provider
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@14246 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 3cdf4dd commit bb21d39

File tree

3 files changed

+76
-19
lines changed

3 files changed

+76
-19
lines changed

src/providers/wfs/qgswfsdata.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -111,18 +111,17 @@ int QgsWFSData::getWFSData()
111111
progressDialog->show();
112112
}
113113

114-
QByteArray readData;
115114
int atEnd = 0;
116115
while ( !atEnd )
117116
{
118117
if ( mFinished )
119118
{
120119
atEnd = 1;
121120
}
122-
readData = reply->readAll();
121+
QByteArray readData = reply->readAll();
123122
if ( readData.size() > 0 )
124123
{
125-
XML_Parse( p, readData.data(), readData.size(), atEnd );
124+
XML_Parse( p, readData.constData(), readData.size(), atEnd );
126125
}
127126
QCoreApplication::processEvents();
128127
}

src/providers/wfs/qgswfsprovider.cpp

+55-16
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,54 @@ QgsWFSProvider::~QgsWFSProvider()
7676
delete mSpatialIndex;
7777
}
7878

79+
void QgsWFSProvider::copyFeature( QgsFeature* f, QgsFeature& feature, bool fetchGeometry, QgsAttributeList fetchAttributes )
80+
{
81+
if ( !f )
82+
{
83+
return;
84+
}
85+
86+
//copy the geometry
87+
QgsGeometry* geometry = f->geometry();
88+
unsigned char *geom = geometry->asWkb();
89+
int geomSize = geometry->wkbSize();
90+
unsigned char* copiedGeom = new unsigned char[geomSize];
91+
memcpy( copiedGeom, geom, geomSize );
92+
feature.setGeometryAndOwnership( copiedGeom, geomSize );
93+
94+
//and the attributes
95+
const QgsAttributeMap& attributes = f->attributeMap();
96+
for ( QgsAttributeList::const_iterator it = fetchAttributes.begin(); it != fetchAttributes.end(); ++it )
97+
{
98+
feature.addAttribute( *it, attributes[*it] );
99+
}
100+
101+
//id and valid
102+
feature.setValid( true );
103+
feature.setFeatureId( f->id() );
104+
}
105+
106+
bool QgsWFSProvider::featureAtId( int featureId,
107+
QgsFeature& feature,
108+
bool fetchGeometry,
109+
QgsAttributeList fetchAttributes )
110+
{
111+
QMap<int, QgsFeature* >::iterator it = mFeatures.find( featureId );
112+
if ( it == mFeatures.end() )
113+
{
114+
return false;
115+
}
116+
117+
QgsFeature* f = it.value();
118+
if ( !f )
119+
{
120+
return false;
121+
}
122+
123+
copyFeature( f, feature, fetchGeometry, fetchAttributes );
124+
return true;
125+
}
126+
79127
bool QgsWFSProvider::nextFeature( QgsFeature& feature )
80128
{
81129
feature.setValid( false );
@@ -87,27 +135,19 @@ bool QgsWFSProvider::nextFeature( QgsFeature& feature )
87135
return 0;
88136
}
89137

90-
feature.setFeatureId( mFeatures[*mFeatureIterator]->id() );
91-
92-
//we need geometry anyway, e.g. for intersection tests
93-
QgsGeometry* geometry = mFeatures[*mFeatureIterator]->geometry();
94-
unsigned char *geom = geometry->asWkb();
95-
int geomSize = geometry->wkbSize();
96-
unsigned char* copiedGeom = new unsigned char[geomSize];
97-
memcpy( copiedGeom, geom, geomSize );
98-
feature.setGeometryAndOwnership( copiedGeom, geomSize );
99-
100-
const QgsAttributeMap& attributes = mFeatures[*mFeatureIterator]->attributeMap();
101-
for ( QgsAttributeList::const_iterator it = mAttributesToFetch.begin(); it != mAttributesToFetch.end(); ++it )
138+
QgsFeature* f = mFeatures[*mFeatureIterator];
139+
++mFeatureIterator;
140+
if ( !f )
102141
{
103-
feature.addAttribute( *it, attributes[*it] );
142+
continue;
104143
}
105-
++mFeatureIterator;
144+
145+
copyFeature( f, feature, true, mAttributesToFetch );
146+
106147
if ( mUseIntersect )
107148
{
108149
if ( feature.geometry() && feature.geometry()->intersects( mSpatialFilter ) )
109150
{
110-
feature.setValid( true );
111151
return true;
112152
}
113153
else
@@ -117,7 +157,6 @@ bool QgsWFSProvider::nextFeature( QgsFeature& feature )
117157
}
118158
else
119159
{
120-
feature.setValid( true );
121160
return true;
122161
}
123162
}

src/providers/wfs/qgswfsprovider.h

+19
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,22 @@ class QgsWFSProvider: public QgsVectorDataProvider
5656
bool fetchGeometry = true,
5757
bool useIntersect = false );
5858

59+
/**
60+
* Gets the feature at the given feature ID.
61+
* @param featureId of the feature to be returned
62+
* @param feature which will receive the data
63+
* @param fetchGeometry flag which if true, will cause the geometry to be fetched from the provider
64+
* @param fetchAttributes a list containing the indexes of the attribute fields to copy
65+
* @return True when feature was found, otherwise false
66+
*
67+
* Default implementation traverses all features until it finds the one with correct ID.
68+
* In case the provider supports reading the feature directly, override this function.
69+
*/
70+
virtual bool featureAtId( int featureId,
71+
QgsFeature& feature,
72+
bool fetchGeometry = true,
73+
QgsAttributeList fetchAttributes = QgsAttributeList() );
74+
5975
/**
6076
* Get the next feature resulting from a select operation.
6177
* @param feature feature which will receive data from the provider
@@ -189,6 +205,9 @@ class QgsWFSProvider: public QgsVectorDataProvider
189205
/**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*/
190206
int guessAttributesFromFile( const QString& uri, QString& geometryAttribute, std::list<QString>& thematicAttributes ) const;
191207

208+
/**Copies feature attributes / geometry from f to feature*/
209+
void copyFeature( QgsFeature* f, QgsFeature& feature, bool fetchGeometry, QgsAttributeList fetchAttributes );
210+
192211
//GML2 specific methods
193212
int getExtentFromGML2( QgsRectangle* extent, const QDomElement& wfsCollectionElement ) const;
194213

0 commit comments

Comments
 (0)