QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource( source, ownSource, request ) , mEditGeometrySimplifier( 0 ) { // prepare joins: may add more attributes to fetch (in order to allow join) if ( mSource->mJoinBuffer->containsJoins() ) prepareJoins(); prepareExpressions(); // by default provider's request is the same mProviderRequest = mRequest; if ( mProviderRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { // prepare list of attributes to match provider fields QgsAttributeList providerSubset; QgsAttributeList subset = mProviderRequest.subsetOfAttributes(); int nPendingFields = mSource->mFields.count(); for ( int i = 0; i < subset.count(); ++i ) { int attrIndex = subset[i]; if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue; if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider ) providerSubset << mSource->mFields.fieldOriginIndex( attrIndex ); } mProviderRequest.setSubsetOfAttributes( providerSubset ); } if ( mSource->mHasEditBuffer ) { mChangedFeaturesRequest = mProviderRequest; mChangedFeaturesRequest.setFilterFids( mSource->mChangedAttributeValues.keys().toSet() ); } if ( request.filterType() == QgsFeatureRequest::FilterFid ) { mFetchedFid = false; } else // no filter or filter by rect { if ( mSource->mHasEditBuffer ) { mChangedFeaturesIterator = mSource->mProviderFeatureSource->getFeatures( mChangedFeaturesRequest ); } else { mProviderIterator = mSource->mProviderFeatureSource->getFeatures( mProviderRequest ); } rewindEditBuffer(); } if ( mRequest.filterType() == QgsFeatureRequest::FilterExpression ) { mRequest.filterExpression()->prepare( mSource->mFields ); } }
QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayer* layer, const QgsFeatureRequest& request ) : QgsAbstractFeatureIterator( request ), L( layer ) { QgsVectorLayerJoinBuffer* joinBuffer = L->mJoinBuffer; if ( L->editBuffer() ) { mAddedFeatures = QgsFeatureMap( L->editBuffer()->addedFeatures() ); mChangedGeometries = QgsGeometryMap( L->editBuffer()->changedGeometries() ); mDeletedFeatureIds = QgsFeatureIds( L->editBuffer()->deletedFeatureIds() ); mChangedAttributeValues = QgsChangedAttributesMap( L->editBuffer()->changedAttributeValues() ); mAddedAttributes = QList<QgsField>( L->editBuffer()->addedAttributes() ); mDeletedAttributeIds = QgsAttributeList( L->editBuffer()->deletedAttributeIds() ); } // prepare joins: may add more attributes to fetch (in order to allow join) if ( joinBuffer->containsJoins() ) prepareJoins(); // by default provider's request is the same mProviderRequest = mRequest; if ( mProviderRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { // prepare list of attributes to match provider fields QgsAttributeList providerSubset; QgsAttributeList subset = mProviderRequest.subsetOfAttributes(); const QgsFields &pendingFields = L->pendingFields(); int nPendingFields = pendingFields.count(); for ( int i = 0; i < subset.count(); ++i ) { int attrIndex = subset[i]; if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue; if ( L->pendingFields().fieldOrigin( attrIndex ) == QgsFields::OriginProvider ) providerSubset << L->pendingFields().fieldOriginIndex( attrIndex ); } mProviderRequest.setSubsetOfAttributes( providerSubset ); } if ( request.filterType() == QgsFeatureRequest::FilterFid ) { mFetchedFid = false; } else // no filter or filter by rect { mProviderIterator = L->dataProvider()->getFeatures( mProviderRequest ); rewindEditBuffer(); } }
QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource<QgsVectorLayerFeatureSource>( source, ownSource, request ) , mFetchedFid( false ) , mEditGeometrySimplifier( 0 ) { prepareExpressions(); // prepare joins: may add more attributes to fetch (in order to allow join) if ( mSource->mJoinBuffer->containsJoins() ) prepareJoins(); mHasVirtualAttributes = !mFetchJoinInfo.isEmpty() || !mExpressionFieldInfo.isEmpty(); // by default provider's request is the same mProviderRequest = mRequest; if ( mProviderRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { // prepare list of attributes to match provider fields QgsAttributeList providerSubset; QgsAttributeList subset = mProviderRequest.subsetOfAttributes(); int nPendingFields = mSource->mFields.count(); for ( int i = 0; i < subset.count(); ++i ) { int attrIndex = subset[i]; if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue; if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider ) providerSubset << mSource->mFields.fieldOriginIndex( attrIndex ); } mProviderRequest.setSubsetOfAttributes( providerSubset ); } if ( mProviderRequest.filterType() == QgsFeatureRequest::FilterExpression ) { Q_FOREACH ( const QString& field, mProviderRequest.filterExpression()->referencedColumns() ) { int idx = source->mFields.fieldNameIndex( field ); // If there are fields in the expression which are not of origin provider, the provider will not be able to filter based on them. // In this case we disable the expression filter. if ( source->mFields.fieldOrigin( idx ) != QgsFields::OriginProvider ) { mProviderRequest.disableFilter(); } } }