29 QgsMemoryFeatureIterator::QgsMemoryFeatureIterator( QgsMemoryFeatureSource *source, 
bool ownSource, 
const QgsFeatureRequest &request )
    32   if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mSource->mCrs )
    34     mTransform = 
QgsCoordinateTransform( mSource->mCrs, mRequest.destinationCrs(), mRequest.transformContext() );
    38     mFilterRect = filterRectToSourceCrs( mTransform );
    47   if ( !mSource->mSubsetString.isEmpty() )
    49     mSubsetExpression = qgis::make_unique< QgsExpression >( mSource->mSubsetString );
    50     mSubsetExpression->prepare( &mSource->mExpressionContext );
    57     mSelectRectEngine->prepareGeometry();
    62   if ( !mFilterRect.isNull() && mSource->mSpatialIndex )
    64     mUsingFeatureIdList = 
true;
    65     mFeatureIdList = mSource->mSpatialIndex->intersects( mFilterRect );
    66     QgsDebugMsg( 
"Features returned by spatial index: " + QString::number( mFeatureIdList.count() ) );
    70     mUsingFeatureIdList = 
true;
    71     QgsFeatureMap::const_iterator it = mSource->mFeatures.constFind( mRequest.filterFid() );
    72     if ( it != mSource->mFeatures.constEnd() )
    73       mFeatureIdList.append( mRequest.filterFid() );
    77     mUsingFeatureIdList = 
true;
    78     mFeatureIdList = mRequest.filterFids().toList();
    82     mUsingFeatureIdList = 
false;
    88 QgsMemoryFeatureIterator::~QgsMemoryFeatureIterator()
    93 bool QgsMemoryFeatureIterator::fetchFeature( 
QgsFeature &feature )
   100   if ( mUsingFeatureIdList )
   101     return nextFeatureUsingList( feature );
   103     return nextFeatureTraverseAll( feature );
   107 bool QgsMemoryFeatureIterator::nextFeatureUsingList( 
QgsFeature &feature )
   109   bool hasFeature = 
false;
   113   while ( mFeatureIdListIterator != mFeatureIdList.constEnd() )
   115     candidate = mSource->mFeatures.value( *mFeatureIdListIterator );
   116     if ( !mFilterRect.isNull() )
   124       else if ( mSource->mSpatialIndex )
   139     if ( hasFeature && mSubsetExpression )
   141       mSource->mExpressionContext.setFeature( candidate );
   142       if ( !mSubsetExpression->evaluate( &mSource->mExpressionContext ).toBool() )
   149     ++mFeatureIdListIterator;
   156     ++mFeatureIdListIterator;
   164     geometryToDestinationCrs( feature, mTransform );
   171 bool QgsMemoryFeatureIterator::nextFeatureTraverseAll( 
QgsFeature &feature )
   173   bool hasFeature = 
false;
   176   while ( mSelectIterator != mSource->mFeatures.constEnd() )
   178     if ( mFilterRect.isNull() )
   188         if ( mSelectIterator->hasGeometry() && mSelectRectEngine->intersects( mSelectIterator->geometry().constGet() ) )
   194         if ( mSelectIterator->hasGeometry() && mSelectIterator->geometry().boundingBox().intersects( mFilterRect ) )
   199     if ( mSubsetExpression )
   201       mSource->mExpressionContext.setFeature( *mSelectIterator );
   202       if ( !mSubsetExpression->evaluate( &mSource->mExpressionContext ).toBool() )
   215     feature = mSelectIterator.value();
   219     geometryToDestinationCrs( feature, mTransform );
   227 bool QgsMemoryFeatureIterator::rewind()
   232   if ( mUsingFeatureIdList )
   233     mFeatureIdListIterator = mFeatureIdList.constBegin();
   235     mSelectIterator = mSource->mFeatures.constBegin();
   240 bool QgsMemoryFeatureIterator::close()
   253 QgsMemoryFeatureSource::QgsMemoryFeatureSource( 
const QgsMemoryProvider *p )
   254   : mFields( p->mFields )
   255   , mFeatures( p->mFeatures )
   256   , mSpatialIndex( p->mSpatialIndex ? qgis::make_unique< 
QgsSpatialIndex >( *p->mSpatialIndex ) : nullptr ) 
   257   , mSubsetString( p->mSubsetString )
   262   mExpressionContext.setFields( mFields );
 bool boundingBoxIntersects(const QgsRectangle &rectangle) const
Returns true if the bounding box of this geometry intersects with a rectangle. 
 
Wrapper for iterator of features from vector data provider or vector layer. 
 
Filter using feature IDs. 
 
void setFields(const QgsFields &fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name. 
 
Use exact geometry intersection (slower) instead of bounding boxes. 
 
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project. 
 
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
 
bool hasGeometry() const
Returns true if the feature has an associated geometry. 
 
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle. 
 
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
 
This class wraps a request for features to a vector layer (or directly its vector data provider)...
 
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine. 
 
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive. 
 
void setValid(bool validity)
Sets the validity of the feature. 
 
A spatial index for QgsFeature objects. 
 
static QgsProject * instance()
Returns the QgsProject singleton instance. 
 
Custom exception class for Coordinate Reference System related exceptions. 
 
Helper template that cares of two things: 1.