Skip to content

Commit

Permalink
Implement featureAtId for wfs provider
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk@14246 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Sep 18, 2010
1 parent c7b8f3b commit aa9aa01
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 19 deletions.
5 changes: 2 additions & 3 deletions src/providers/wfs/qgswfsdata.cpp
Expand Up @@ -111,18 +111,17 @@ int QgsWFSData::getWFSData()
progressDialog->show();
}

QByteArray readData;
int atEnd = 0;
while ( !atEnd )
{
if ( mFinished )
{
atEnd = 1;
}
readData = reply->readAll();
QByteArray readData = reply->readAll();
if ( readData.size() > 0 )
{
XML_Parse( p, readData.data(), readData.size(), atEnd );
XML_Parse( p, readData.constData(), readData.size(), atEnd );
}
QCoreApplication::processEvents();
}
Expand Down
71 changes: 55 additions & 16 deletions src/providers/wfs/qgswfsprovider.cpp
Expand Up @@ -76,6 +76,54 @@ QgsWFSProvider::~QgsWFSProvider()
delete mSpatialIndex;
}

void QgsWFSProvider::copyFeature( QgsFeature* f, QgsFeature& feature, bool fetchGeometry, QgsAttributeList fetchAttributes )
{
if ( !f )
{
return;
}

//copy the geometry
QgsGeometry* geometry = f->geometry();
unsigned char *geom = geometry->asWkb();
int geomSize = geometry->wkbSize();
unsigned char* copiedGeom = new unsigned char[geomSize];
memcpy( copiedGeom, geom, geomSize );
feature.setGeometryAndOwnership( copiedGeom, geomSize );

//and the attributes
const QgsAttributeMap& attributes = f->attributeMap();
for ( QgsAttributeList::const_iterator it = fetchAttributes.begin(); it != fetchAttributes.end(); ++it )
{
feature.addAttribute( *it, attributes[*it] );
}

//id and valid
feature.setValid( true );
feature.setFeatureId( f->id() );
}

bool QgsWFSProvider::featureAtId( int featureId,
QgsFeature& feature,
bool fetchGeometry,
QgsAttributeList fetchAttributes )
{
QMap<int, QgsFeature* >::iterator it = mFeatures.find( featureId );
if ( it == mFeatures.end() )
{
return false;
}

QgsFeature* f = it.value();
if ( !f )
{
return false;
}

copyFeature( f, feature, fetchGeometry, fetchAttributes );
return true;
}

bool QgsWFSProvider::nextFeature( QgsFeature& feature )
{
feature.setValid( false );
Expand All @@ -87,27 +135,19 @@ bool QgsWFSProvider::nextFeature( QgsFeature& feature )
return 0;
}

feature.setFeatureId( mFeatures[*mFeatureIterator]->id() );

//we need geometry anyway, e.g. for intersection tests
QgsGeometry* geometry = mFeatures[*mFeatureIterator]->geometry();
unsigned char *geom = geometry->asWkb();
int geomSize = geometry->wkbSize();
unsigned char* copiedGeom = new unsigned char[geomSize];
memcpy( copiedGeom, geom, geomSize );
feature.setGeometryAndOwnership( copiedGeom, geomSize );

const QgsAttributeMap& attributes = mFeatures[*mFeatureIterator]->attributeMap();
for ( QgsAttributeList::const_iterator it = mAttributesToFetch.begin(); it != mAttributesToFetch.end(); ++it )
QgsFeature* f = mFeatures[*mFeatureIterator];
++mFeatureIterator;
if ( !f )
{
feature.addAttribute( *it, attributes[*it] );
continue;
}
++mFeatureIterator;

copyFeature( f, feature, true, mAttributesToFetch );

if ( mUseIntersect )
{
if ( feature.geometry() && feature.geometry()->intersects( mSpatialFilter ) )
{
feature.setValid( true );
return true;
}
else
Expand All @@ -117,7 +157,6 @@ bool QgsWFSProvider::nextFeature( QgsFeature& feature )
}
else
{
feature.setValid( true );
return true;
}
}
Expand Down
19 changes: 19 additions & 0 deletions src/providers/wfs/qgswfsprovider.h
Expand Up @@ -56,6 +56,22 @@ class QgsWFSProvider: public QgsVectorDataProvider
bool fetchGeometry = true,
bool useIntersect = false );

/**
* Gets the feature at the given feature ID.
* @param featureId of the feature to be returned
* @param feature which will receive the data
* @param fetchGeometry flag which if true, will cause the geometry to be fetched from the provider
* @param fetchAttributes a list containing the indexes of the attribute fields to copy
* @return True when feature was found, otherwise false
*
* Default implementation traverses all features until it finds the one with correct ID.
* In case the provider supports reading the feature directly, override this function.
*/
virtual bool featureAtId( int featureId,
QgsFeature& feature,
bool fetchGeometry = true,
QgsAttributeList fetchAttributes = QgsAttributeList() );

/**
* Get the next feature resulting from a select operation.
* @param feature feature which will receive data from the provider
Expand Down Expand Up @@ -189,6 +205,9 @@ class QgsWFSProvider: public QgsVectorDataProvider
/**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*/
int guessAttributesFromFile( const QString& uri, QString& geometryAttribute, std::list<QString>& thematicAttributes ) const;

/**Copies feature attributes / geometry from f to feature*/
void copyFeature( QgsFeature* f, QgsFeature& feature, bool fetchGeometry, QgsAttributeList fetchAttributes );

//GML2 specific methods
int getExtentFromGML2( QgsRectangle* extent, const QDomElement& wfsCollectionElement ) const;

Expand Down

0 comments on commit aa9aa01

Please sign in to comment.