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 = std::make_unique< QgsExpression >( mSource->mSubsetString );
 
   50     mSubsetExpression->prepare( mSource->expressionContext() );
 
   57     mSelectRectEngine->prepareGeometry();
 
   62   if ( !mFilterRect.isNull() && mSource->mSpatialIndex )
 
   64     mUsingFeatureIdList = 
true;
 
   65     mFeatureIdList = mSource->mSpatialIndex->intersects( mFilterRect );
 
   66     QgsDebugMsgLevel( 
"Features returned by spatial index: " + QString::number( mFeatureIdList.count() ), 2 );
 
   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 = qgis::setToList( mRequest.filterFids() );
 
   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->expressionContext()->setFeature( candidate );
 
  142       if ( !mSubsetExpression->evaluate( mSource->expressionContext() ).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->expressionContext()->setFeature( *mSelectIterator );
 
  202       if ( !mSubsetExpression->evaluate( mSource->expressionContext() ).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 ? std::make_unique< 
QgsSpatialIndex >( *p->mSpatialIndex ) : nullptr ) 
 
  257   , mSubsetString( p->mSubsetString )
 
  271   if ( !mExpressionContext )
 
  273     mExpressionContext = std::make_unique< QgsExpressionContext >(
 
  274                            QList<QgsExpressionContextScope *>()
 
  277     mExpressionContext->setFields( mFields );
 
  279   return mExpressionContext.get();
 
Helper template that cares of two things: 1.
Custom exception class for Coordinate Reference System related exceptions.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Wrapper for iterator of features from vector data provider or vector layer.
This class wraps a request for features to a vector layer (or directly its vector data provider).
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
@ FilterFid
Filter using feature ID.
@ FilterFids
Filter using feature IDs.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
void setFields(const QgsFields &fields, bool initAttributes=false)
Assigns a field map with the feature to allow attribute access by attribute name.
void setValid(bool validity)
Sets the validity of the feature.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool boundingBoxIntersects(const QgsRectangle &rectangle) const
Returns true if the bounding box of this geometry intersects with a rectangle.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
static QgsProject * instance()
Returns the QgsProject singleton instance.
A spatial index for QgsFeature objects.
#define QgsDebugMsgLevel(str, level)