Skip to content

Commit

Permalink
QgsFeatureRequest: New filters FilterExpression and FilterFids
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Sep 18, 2013
1 parent 6d485d9 commit 0c90f32
Show file tree
Hide file tree
Showing 39 changed files with 341 additions and 78 deletions.
7 changes: 6 additions & 1 deletion python/core/qgsfeatureiterator.sip
Expand Up @@ -11,13 +11,18 @@ class QgsAbstractFeatureIterator
virtual ~QgsAbstractFeatureIterator();

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

protected:
virtual bool nextFeatureFilterExpression( QgsFeature &f );

virtual bool nextFeatureFilterFids( QgsFeature & f );

virtual bool fetchFeature( QgsFeature& f ) = 0;
void ref(); // add reference
void deref(); // remove reference, delete if refs == 0
};
Expand Down
16 changes: 13 additions & 3 deletions python/core/qgsfeaturerequest.sip
Expand Up @@ -17,9 +17,11 @@ class QgsFeatureRequest

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

//! construct a default request: for all features get attributes and geometries
Expand All @@ -40,6 +42,14 @@ class QgsFeatureRequest
QgsFeatureRequest& setFilterFid( qint64 fid );
qint64 filterFid() const;

//! Set feature ID that should be fetched.
QgsFeatureRequest& setFilterFids( QgsFeatureIds fids );
const QgsFeatureIds& filterFids() const;

//! Set filter expression. Ownership is taken.
QgsFeatureRequest& setFilterExpression( const QString& expression );
QgsExpression* filterExpression() const;

//! Set flags that affect how features will be fetched
QgsFeatureRequest& setFlags( Flags flags );
const Flags& flags() const;
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgscachedfeatureiterator.cpp
Expand Up @@ -24,7 +24,7 @@ QgsCachedFeatureIterator::QgsCachedFeatureIterator( QgsVectorLayerCache *vlCache
mFeatureIdIterator = featureIds.begin();
}

bool QgsCachedFeatureIterator::nextFeature( QgsFeature& f )
bool QgsCachedFeatureIterator::fetchFeature( QgsFeature& f )
{
mFeatureIdIterator++;

Expand Down Expand Up @@ -58,7 +58,7 @@ QgsCachedFeatureWriterIterator::QgsCachedFeatureWriterIterator( QgsVectorLayerCa
mFeatIt = vlCache->layer()->getFeatures( featureRequest );
}

bool QgsCachedFeatureWriterIterator::nextFeature( QgsFeature& f )
bool QgsCachedFeatureWriterIterator::fetchFeature( QgsFeature& f )
{
if ( mFeatIt.nextFeature( f ) )
{
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgscachedfeatureiterator.h
Expand Up @@ -46,7 +46,7 @@ class CORE_EXPORT QgsCachedFeatureIterator : public QgsAbstractFeatureIterator
* @param f
* @return bool
*/
virtual bool nextFeature( QgsFeature& f );
virtual bool fetchFeature( QgsFeature& f );

/**
* @brief
Expand Down Expand Up @@ -91,7 +91,7 @@ class CORE_EXPORT QgsCachedFeatureWriterIterator : public QgsAbstractFeatureIter
* @param f
* @return bool
*/
virtual bool nextFeature( QgsFeature& f );
virtual bool fetchFeature( QgsFeature& f );

/**
* @brief
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsexpression.h
Expand Up @@ -29,6 +29,7 @@ class QgsFeature;
class QgsGeometry;
class QgsOgcUtils;
class QgsVectorLayer;
class QgsVectorDataProvider;

class QDomElement;

Expand Down Expand Up @@ -535,6 +536,7 @@ class CORE_EXPORT QgsExpression

virtual QStringList referencedColumns() const { return QStringList( mName ); }
virtual bool needsGeometry() const { return false; }

virtual void accept( Visitor& v ) const { v.visit( *this ); }

protected:
Expand Down
40 changes: 39 additions & 1 deletion src/core/qgsfeatureiterator.cpp
Expand Up @@ -13,7 +13,7 @@
* *
***************************************************************************/
#include "qgsfeatureiterator.h"

#include "qgslogger.h"

QgsAbstractFeatureIterator::QgsAbstractFeatureIterator( const QgsFeatureRequest& request )
: mRequest( request )
Expand All @@ -26,6 +26,44 @@ QgsAbstractFeatureIterator::~QgsAbstractFeatureIterator()
{
}

bool QgsAbstractFeatureIterator::nextFeature( QgsFeature& f )
{
switch ( mRequest.filterType() )
{
case QgsFeatureRequest::FilterExpression:
return nextFeatureFilterExpression( f );
break;

case QgsFeatureRequest::FilterFids:
return nextFeatureFilterFids( f );
break;

default:
return fetchFeature( f );
break;
}
}

bool QgsAbstractFeatureIterator::nextFeatureFilterExpression( QgsFeature& f )
{
while ( fetchFeature( f ) )
{
if ( mRequest.filterExpression()->evaluate( f ).toBool() )
return true;
}
return false;
}

bool QgsAbstractFeatureIterator::nextFeatureFilterFids( QgsFeature& f )
{
while ( fetchFeature( f ) )
{
if ( mRequest.filterFids().contains( f.id() ) )
return true;
}
return false;
}

void QgsAbstractFeatureIterator::ref()
{
refs++;
Expand Down
10 changes: 9 additions & 1 deletion src/core/qgsfeatureiterator.h
Expand Up @@ -16,6 +16,7 @@
#define QGSFEATUREITERATOR_H

#include "qgsfeaturerequest.h"
#include "qgslogger.h"


/** \ingroup core
Expand All @@ -31,13 +32,20 @@ class CORE_EXPORT QgsAbstractFeatureIterator
virtual ~QgsAbstractFeatureIterator();

//! fetch next feature, return true on success
virtual bool nextFeature( QgsFeature& f ) = 0;
virtual bool nextFeature( QgsFeature& f );

//! reset the iterator to the starting position
virtual bool rewind() = 0;
//! end of iterating: free the resources / lock
virtual bool close() = 0;

protected:
virtual bool nextFeatureFilterExpression( QgsFeature &f );

virtual bool nextFeatureFilterFids( QgsFeature & f );

virtual bool fetchFeature( QgsFeature& f ) = 0;

QgsFeatureRequest mRequest;

bool mClosed;
Expand Down
78 changes: 78 additions & 0 deletions src/core/qgsfeaturerequest.cpp
Expand Up @@ -15,38 +15,61 @@
#include "qgsfeaturerequest.h"

#include "qgsfield.h"
#include "qgsgeometry.h"

#include <QStringList>

QgsFeatureRequest::QgsFeatureRequest()
: mFilter( FilterNone )
, mFilterExpression( 0 )
, mFlags( 0 )
{
}

QgsFeatureRequest::QgsFeatureRequest( QgsFeatureId fid )
: mFilter( FilterFid )
, mFilterFid( fid )
, mFilterExpression( 0 )
, mFlags( 0 )
{
}

QgsFeatureRequest::QgsFeatureRequest( const QgsRectangle& rect )
: mFilter( FilterRect )
, mFilterRect( rect )
, mFilterExpression( 0 )
, mFlags( 0 )
{
}

QgsFeatureRequest::QgsFeatureRequest( const QgsFeatureRequest &rh )
{
operator=( rh );
}

QgsFeatureRequest& QgsFeatureRequest::operator=( const QgsFeatureRequest & rh )
{
mFlags = rh.mFlags;
mFilter = rh.mFilter;
mFilterRect = rh.mFilterRect;
mFilterFid = rh.mFilterFid;
mFilterFids = rh.mFilterFids;
if ( rh.mFilterExpression )
{
mFilterExpression = new QgsExpression( rh.mFilterExpression->expression() );
}
else
{
mFilterExpression = 0;
}
mAttrs = rh.mAttrs;
return *this;
}

QgsFeatureRequest::~QgsFeatureRequest()
{
delete mFilterExpression;
}

QgsFeatureRequest& QgsFeatureRequest::setFilterRect( const QgsRectangle& rect )
{
Expand All @@ -62,6 +85,21 @@ QgsFeatureRequest& QgsFeatureRequest::setFilterFid( QgsFeatureId fid )
return *this;
}

QgsFeatureRequest&QgsFeatureRequest::setFilterFids( QgsFeatureIds fids )
{
mFilter = FilterFids;
mFilterFids = fids;
return *this;
}

QgsFeatureRequest& QgsFeatureRequest::setFilterExpression( const QString& expression )
{
mFilter = FilterExpression;
delete mFilterExpression;
mFilterExpression = new QgsExpression( expression );
return *this;
}

QgsFeatureRequest& QgsFeatureRequest::setFlags( QgsFeatureRequest::Flags flags )
{
mFlags = flags;
Expand Down Expand Up @@ -89,3 +127,43 @@ QgsFeatureRequest& QgsFeatureRequest::setSubsetOfAttributes( const QStringList&

return *this;
}

bool QgsFeatureRequest::acceptFeature( const QgsFeature& feature )
{
switch ( mFilter )
{
case QgsFeatureRequest::FilterNone:
return true;
break;

case QgsFeatureRequest::FilterRect:
if ( feature.geometry() && feature.geometry()->intersects( mFilterRect ) )
return true;
else
return false;
break;

case QgsFeatureRequest::FilterFid:
if ( feature.id () == mFilterFid )
return true;
else
return false;
break;

case QgsFeatureRequest::FilterExpression:
if ( mFilterExpression->evaluate( feature ).toBool() )
return true;
else
return false;
break;

case QgsFeatureRequest::FilterFids:
if ( mFilterFids.contains ( feature.id () ) )
return true;
else
return false;
break;
}

return true;
}
34 changes: 31 additions & 3 deletions src/core/qgsfeaturerequest.h
Expand Up @@ -19,6 +19,7 @@

#include "qgsfeature.h"
#include "qgsrectangle.h"
#include "qgsexpression.h"

#include <QList>
typedef QList<int> QgsAttributeList;
Expand Down Expand Up @@ -66,9 +67,11 @@ class CORE_EXPORT QgsFeatureRequest

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

//! construct a default request: for all features get attributes and geometries
Expand All @@ -80,6 +83,10 @@ class CORE_EXPORT QgsFeatureRequest
//! copy constructor
QgsFeatureRequest( const QgsFeatureRequest& rh );

QgsFeatureRequest& operator=( const QgsFeatureRequest& rh );

~QgsFeatureRequest();

FilterType filterType() const { return mFilter; }

//! Set rectangle from which features will be taken. Empty rectangle removes the filter.
Expand All @@ -91,6 +98,14 @@ class CORE_EXPORT QgsFeatureRequest
QgsFeatureRequest& setFilterFid( QgsFeatureId fid );
const QgsFeatureId& filterFid() const { return mFilterFid; }

//! Set feature ID that should be fetched.
QgsFeatureRequest& setFilterFids( QgsFeatureIds fids );
const QgsFeatureIds& filterFids() const { return mFilterFids; }

//! Set filter expression. {@see QgsExpression}
QgsFeatureRequest& setFilterExpression( const QString& expression );
QgsExpression* filterExpression() const { return mFilterExpression; }

//! Set flags that affect how features will be fetched
QgsFeatureRequest& setFlags( Flags flags );
const Flags& flags() const { return mFlags; }
Expand All @@ -102,6 +117,17 @@ class CORE_EXPORT QgsFeatureRequest

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

/**
* Check if a feature is accepted by this requests filter
*
* @param feature The feature which will be tested
*
* @return true, if the filter accepts the feature
*
* @note added in 2.1
*/
bool acceptFeature( const QgsFeature& feature );

// TODO: in future
// void setFilterExpression(const QString& expression); // using QgsExpression
Expand All @@ -112,6 +138,8 @@ class CORE_EXPORT QgsFeatureRequest
FilterType mFilter;
QgsRectangle mFilterRect;
QgsFeatureId mFilterFid;
QgsFeatureIds mFilterFids;
QgsExpression* mFilterExpression;
Flags mFlags;
QgsAttributeList mAttrs;
};
Expand Down

0 comments on commit 0c90f32

Please sign in to comment.