Skip to content
Permalink
Browse files

[API] added QgsFeatureIterator, changed QgsVectorProvider API

Vector data provider now has getFeatures() method to access features.
select(), nextFeature(), featureAtId(), rewind() were removed resp. moved to provider's feature iterator implementations.

Providers that currently do not implement the new API were disabled.
  • Loading branch information
wonder-sk committed Oct 8, 2012
1 parent 8c0a2b5 commit e110855e6cc3b73850d83fbd8b55224821c35f4f
Showing with 2,378 additions and 1,947 deletions.
  1. +1 −0 python/core/core.sip
  2. +47 −0 python/core/qgsfeatureiterator.sip
  3. +41 −23 python/core/qgsfeaturerequest.sip
  4. +0 −17 python/core/qgsvectordataprovider.sip
  5. +4 −4 src/analysis/interpolation/qgsinterpolator.cpp
  6. +5 −2 src/analysis/vector/qgszonalstatistics.cpp
  7. +2 −0 src/core/CMakeLists.txt
  8. +39 −0 src/core/qgsfeatureiterator.cpp
  9. +129 −0 src/core/qgsfeatureiterator.h
  10. +20 −0 src/core/qgsfeaturerequest.cpp
  11. +4 −4 src/core/qgsfeaturerequest.h
  12. +24 −32 src/core/qgsvectordataprovider.cpp
  13. +12 −41 src/core/qgsvectordataprovider.h
  14. +42 −25 src/core/qgsvectorlayer.cpp
  15. +3 −0 src/core/qgsvectorlayer.h
  16. +11 −18 src/mapserver/qgswfsserver.cpp
  17. +3 −8 src/mapserver/qgswmsserver.cpp
  18. +1 −1 src/plugins/CMakeLists.txt
  19. +55 −63 src/plugins/diagram_overlay/qgsdiagramoverlay.cpp
  20. +2 −2 src/plugins/grass/qgsgrassmodule.cpp
  21. +3 −9 src/plugins/heatmap/heatmap.cpp
  22. +6 −6 src/providers/CMakeLists.txt
  23. +1 −1 src/providers/grass/CMakeLists.txt
  24. +358 −0 src/providers/grass/qgsgrassfeatureiterator.cpp
  25. +58 −0 src/providers/grass/qgsgrassfeatureiterator.h
  26. +24 −306 src/providers/grass/qgsgrassprovider.cpp
  27. +6 −47 src/providers/grass/qgsgrassprovider.h
  28. +1 −1 src/providers/memory/CMakeLists.txt
  29. +158 −0 src/providers/memory/qgsmemoryfeatureiterator.cpp
  30. +42 −0 src/providers/memory/qgsmemoryfeatureiterator.h
  31. +3 −133 src/providers/memory/qgsmemoryprovider.cpp
  32. +2 −47 src/providers/memory/qgsmemoryprovider.h
  33. +1 −1 src/providers/ogr/CMakeLists.txt
  34. +260 −0 src/providers/ogr/qgsogrfeatureiterator.cpp
  35. +43 −0 src/providers/ogr/qgsogrfeatureiterator.h
  36. +3 −250 src/providers/ogr/qgsogrprovider.cpp
  37. +3 −39 src/providers/ogr/qgsogrprovider.h
  38. +1 −0 src/providers/postgres/CMakeLists.txt
  39. +442 −0 src/providers/postgres/qgspostgresfeatureiterator.cpp
  40. +55 −0 src/providers/postgres/qgspostgresfeatureiterator.h
  41. +8 −425 src/providers/postgres/qgspostgresprovider.cpp
  42. +3 −50 src/providers/postgres/qgspostgresprovider.h
  43. +1 −0 src/providers/spatialite/CMakeLists.txt
  44. +350 −0 src/providers/spatialite/qgsspatialitefeatureiterator.cpp
  45. +53 −0 src/providers/spatialite/qgsspatialitefeatureiterator.h
  46. +8 −344 src/providers/spatialite/qgsspatialiteprovider.cpp
  47. +3 −36 src/providers/spatialite/qgsspatialiteprovider.h
  48. +34 −8 tests/src/core/testqgsvectordataprovider.cpp
  49. +3 −4 tests/src/core/testqgsvectorlayer.cpp
@@ -26,6 +26,7 @@
%Include qgsdistancearea.sip
%Include qgsexpression.sip
%Include qgsfeature.sip
%Include qgsfeatureiterator.sip
%Include qgsfeaturerequest.sip
%Include qgsfield.sip
%Include qgsgeometry.sip
@@ -0,0 +1,47 @@


class QgsFeatureIterator
{
%TypeHeaderCode
#include <qgsfeatureiterator.h>
%End

public:


QgsFeatureIterator* __iter__();
%MethodCode
sipRes = sipCpp;
%End

SIP_PYOBJECT __next__();
%MethodCode
QgsFeature* f = new QgsFeature;
if (sipCpp->nextFeature(*f))
sipRes = sipConvertFromInstance(f, sipClass_QgsFeature, Py_None);
else
{
delete f;
PyErr_SetString(PyExc_StopIteration,"");
}
%End


//! construct invalid iterator
QgsFeatureIterator();
//! construct a valid iterator
//QgsFeatureIterator(QgsAbstractFeatureIterator* iter);
//! copy constructor copies the iterator, increases ref.count
QgsFeatureIterator(const QgsFeatureIterator& fi);
//! destructor deletes the iterator if it has no more references
~QgsFeatureIterator();

//QgsFeatureIterator& operator=(const QgsFeatureIterator& other);

bool nextFeature(QgsFeature& f);
bool rewind();
bool close();

//! find out whether the iterator is still valid or closed already
bool isClosed();
};
@@ -5,28 +5,46 @@ class QgsFeatureRequest
#include <qgsfeaturerequest.h>
%End

public:
enum Flag {
NoGeometry = 0x01, //!< Do not fetch geometry
NoAttributes = 0x02, //!< Do not fetch any attributes
ExactIntersect = 0x04 //!< Use exact geometry intersection (slower) instead of bounding boxes
};
typedef QFlags<QgsFeatureRequest::Flag> Flags;

//! construct a default request: for all features get attributes and geometries
QgsFeatureRequest();

//! Set rectangle from which features will be taken. Empty rectangle removes the filter.
QgsFeatureRequest& setExtent(const QgsRectangle& rect);
const QgsRectangle& extent() const;

//! Set flags that affect how features will be fetched
QgsFeatureRequest& setFlags(Flags flags);
const Flags& flags() const;

//! Set a subset of attributes that will be fetched. Empty list means that all attributes are used.
//! To disable fetching attributes, reset the FetchAttributes flag (which is set by default)
QgsFeatureRequest& setAttributes(const QgsAttributeList& attrs);
const QgsAttributeList& attributes() const;
public:
enum Flag
{
NoGeometry = 0x01, //!< Do not fetch geometry
SubsetOfAttributes = 0x02, //!< Fetch only a subset of attributes (setSubsetOfAttributes sets this flag)
ExactIntersect = 0x04 //!< Use exact geometry intersection (slower) instead of bounding boxes
};
typedef QFlags<QgsFeatureRequest::Flag> Flags;

enum FilterType
{
FilterNone, //!< No filter is applied
FilterRect, //!< Filter using a rectangle
FilterFid //!< Filter using feature ID
};

//! construct a default request: for all features get attributes and geometries
QgsFeatureRequest();

FilterType filterType() const;

//! Set rectangle from which features will be taken. Empty rectangle removes the filter.
//!
QgsFeatureRequest& setFilterRect( const QgsRectangle& rect );
const QgsRectangle& filterRect() const;

//! Set feature ID that should be fetched.
QgsFeatureRequest& setFilterFid( qint64 fid );
const qint64& filterFid() const;

//! Set flags that affect how features will be fetched
QgsFeatureRequest& setFlags( Flags flags );
const Flags& flags() const;

//! Set a subset of attributes that will be fetched. Empty list means that all attributes are used.
//! To disable fetching attributes, reset the FetchAttributes flag (which is set by default)
QgsFeatureRequest& setSubsetOfAttributes( const QgsAttributeList& attrs );
const QgsAttributeList& subsetOfAttributes() const;

//! Set a subset of attributes by names that will be fetched
QgsFeatureRequest& setSubsetOfAttributes( const QStringList& attrNames, const QgsFieldMap& fields );

};
@@ -7,23 +7,6 @@ class QgsVectorDataProvider : QgsDataProvider

public:

QgsVectorDataProvider* __iter__();
%MethodCode
sipRes = sipCpp;
%End

SIP_PYOBJECT __next__();
%MethodCode
QgsFeature* f = new QgsFeature;
if (sipCpp->nextFeature(*f))
sipRes = sipConvertFromInstance(f, sipClass_QgsFeature, Py_None);
else
{
delete f;
PyErr_SetString(PyExc_StopIteration,"");
}
%End

// If you add to this, please also add to capabilitiesString()
/**
* enumeration with capabilities that providers might implement
@@ -55,8 +55,8 @@ int QgsInterpolator::cacheBaseData()
continue;
}

QgsVectorDataProvider* provider = v_it->vectorLayer->dataProvider();
if ( !provider )
QgsVectorLayer* vlayer = v_it->vectorLayer;
if ( !vlayer )
{
return 2;
}
@@ -67,13 +67,13 @@ int QgsInterpolator::cacheBaseData()
attList.push_back( v_it->interpolationAttribute );
}

provider->select( attList );
vlayer->select( attList );

QgsFeature theFeature;
double attributeValue = 0.0;
bool attributeConversionOk = false;

while ( provider->nextFeature( theFeature ) )
while ( vlayer->nextFeature( theFeature ) )
{
if ( !v_it->zCoordInterpolation )
{
@@ -136,14 +136,17 @@ int QgsZonalStatistics::calculateStatistics( QProgressDialog* p )


//iterate over each polygon
vectorProvider->select( QgsAttributeList(), QgsRectangle(), true, false );
QgsFeatureRequest request;
request.setSubsetOfAttributes( QgsAttributeList() );
QgsFeatureIterator fi = vectorProvider->getFeatures( request );
//vectorProvider->select( QgsAttributeList(), QgsRectangle(), true, false );
QgsFeature f;
double count = 0;
double sum = 0;
double mean = 0;
int featureCounter = 0;

while ( vectorProvider->nextFeature( f ) )
while ( fi.nextFeature( f ) )
{
qWarning( "%d", featureCounter );
if ( p )
@@ -65,6 +65,7 @@ SET(QGIS_CORE_SRCS
qgsdistancearea.cpp
qgsexpression.cpp
qgsfeature.cpp
qgsfeatureiterator.cpp
qgsfeaturerequest.cpp
qgsfield.cpp
qgsgeometry.cpp
@@ -353,6 +354,7 @@ SET(QGIS_CORE_HDRS
qgsexception.h
qgsexpression.h
qgsfeature.h
qgsfeatureiterator.h
qgsfeaturerequest.h
qgsfield.h
qgsgeometry.h
@@ -0,0 +1,39 @@
#include "qgsfeatureiterator.h"


QgsAbstractFeatureIterator::QgsAbstractFeatureIterator( const QgsFeatureRequest& request )
: mRequest( request ),
mClosed( false ),
refs( 0 )
{
}

QgsAbstractFeatureIterator::~QgsAbstractFeatureIterator()
{
}

void QgsAbstractFeatureIterator::ref()
{
refs++;
}
void QgsAbstractFeatureIterator::deref()
{
refs--;
if ( !refs )
delete this;
}

///////

QgsFeatureIterator& QgsFeatureIterator::operator=( const QgsFeatureIterator & other )
{
if ( this != &other )
{
if ( mIter )
mIter->deref();
mIter = other.mIter;
if ( mIter )
mIter->ref();
}
return *this;
}
@@ -0,0 +1,129 @@
#ifndef QGSFEATUREITERATOR_H
#define QGSFEATUREITERATOR_H

#include "qgsfeaturerequest.h"


/** \ingroup core
* Internal feature iterator to be implemented within data providers
*/
class QgsAbstractFeatureIterator
{
public:
//! base class constructor - stores the iteration parameters
QgsAbstractFeatureIterator( const QgsFeatureRequest& request );

//! destructor makes sure that the iterator is closed properly
virtual ~QgsAbstractFeatureIterator();

//! fetch next feature, return true on success
virtual bool nextFeature( QgsFeature& f ) = 0;
//! reset the iterator to the starting position
virtual bool rewind() = 0;
//! end of iterating: free the resources / lock
virtual bool close() = 0;

protected:
QgsFeatureRequest mRequest;

bool mClosed;

// reference counting (to allow seamless copying of QgsFeatureIterator instances)
int refs;
void ref(); // add reference
void deref(); // remove reference, delete if refs == 0
friend class QgsFeatureIterator;
};


/**
* \ingroup core
* Wrapper for iterator of features from vector data provider or vector layer
*/
class QgsFeatureIterator
{
public:
//! construct invalid iterator
QgsFeatureIterator();
//! construct a valid iterator
QgsFeatureIterator( QgsAbstractFeatureIterator* iter );
//! copy constructor copies the iterator, increases ref.count
QgsFeatureIterator( const QgsFeatureIterator& fi );
//! destructor deletes the iterator if it has no more references
~QgsFeatureIterator();

QgsFeatureIterator& operator=( const QgsFeatureIterator& other );

bool nextFeature( QgsFeature& f );
bool rewind();
bool close();

//! find out whether the iterator is still valid or closed already
bool isClosed();

friend bool operator== ( const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2 );
friend bool operator!= ( const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2 );

protected:
QgsAbstractFeatureIterator* mIter;
};

////////

inline QgsFeatureIterator::QgsFeatureIterator()
: mIter( NULL )
{
}

inline QgsFeatureIterator::QgsFeatureIterator( QgsAbstractFeatureIterator* iter )
: mIter( iter )
{
if ( iter )
iter->ref();
}

inline QgsFeatureIterator::QgsFeatureIterator( const QgsFeatureIterator& fi )
: mIter( fi.mIter )
{
if ( mIter )
mIter->ref();
}

inline QgsFeatureIterator::~QgsFeatureIterator()
{
if ( mIter )
mIter->deref();
}

inline bool QgsFeatureIterator::nextFeature( QgsFeature& f )
{
return mIter ? mIter->nextFeature( f ) : false;
}

inline bool QgsFeatureIterator::rewind()
{
return mIter ? mIter->rewind() : false;
}

inline bool QgsFeatureIterator::close()
{
return mIter ? mIter->close() : false;
}

inline bool QgsFeatureIterator::isClosed()
{
return mIter ? mIter->mClosed : true;
}


inline bool operator== ( const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2 )
{
return ( fi1.mIter == fi2.mIter );
}
inline bool operator!= ( const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2 )
{
return !( fi1 == fi2 );
}


#endif // QGSFEATUREITERATOR_H

0 comments on commit e110855

Please sign in to comment.
You can’t perform that action at this time.