Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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 e110855
Show file tree
Hide file tree
Showing 49 changed files with 2,378 additions and 1,947 deletions.
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -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
Expand Down
47 changes: 47 additions & 0 deletions python/core/qgsfeatureiterator.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();
};
64 changes: 41 additions & 23 deletions python/core/qgsfeaturerequest.sip
Expand Up @@ -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 );

};
17 changes: 0 additions & 17 deletions python/core/qgsvectordataprovider.sip
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/analysis/interpolation/qgsinterpolator.cpp
Expand Up @@ -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;
}
Expand All @@ -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 )
{
Expand Down
7 changes: 5 additions & 2 deletions src/analysis/vector/qgszonalstatistics.cpp
Expand Up @@ -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 )
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -65,6 +65,7 @@ SET(QGIS_CORE_SRCS
qgsdistancearea.cpp
qgsexpression.cpp
qgsfeature.cpp
qgsfeatureiterator.cpp
qgsfeaturerequest.cpp
qgsfield.cpp
qgsgeometry.cpp
Expand Down Expand Up @@ -353,6 +354,7 @@ SET(QGIS_CORE_HDRS
qgsexception.h
qgsexpression.h
qgsfeature.h
qgsfeatureiterator.h
qgsfeaturerequest.h
qgsfield.h
qgsgeometry.h
Expand Down
39 changes: 39 additions & 0 deletions src/core/qgsfeatureiterator.cpp
@@ -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;
}
129 changes: 129 additions & 0 deletions src/core/qgsfeatureiterator.h
@@ -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.