35using namespace Qt::StringLiterals;
37#if !defined( USE_THREAD_LOCAL ) || defined( Q_OS_WIN )
38#include <QThreadStorage>
46 const QMutexLocker locker( &layer->mFeatureSourceConstructorMutex );
63 source.
joinSource = std::make_shared< QgsVectorLayerFeatureSource >( joinLayer );
90 if ( request.filterType() == QgsFeatureRequest::FilterFid )
94 if ( L->editBuffer()->addedFeatures().contains( request.filterFid() ) )
95 mAddedFeatures.insert( request.filterFid(), L->editBuffer()->addedFeatures()[ request.filterFid()] );
97 if ( L->editBuffer()->changedGeometries().contains( request.filterFid() ) )
98 mChangedGeometries.insert( request.filterFid(), L->editBuffer()->changedGeometries()[ request.filterFid()] );
100 if ( L->editBuffer()->deletedFeatureIds().contains( request.filterFid() ) )
103 if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
104 mChangedAttributeValues.insert( request.filterFid(), L->editBuffer()->changedAttributeValues()[ request.filterFid()] );
106 if ( L->editBuffer()->changedAttributeValues().contains( request.filterFid() ) )
107 mChangedFeaturesRequest.setFilterFids(
QgsFeatureIds() << request.filterFid() );
165 switch (
mRequest.spatialFilterType() )
167 case Qgis::SpatialFilterType::NoFilter:
168 case Qgis::SpatialFilterType::BoundingBox:
171 case Qgis::SpatialFilterType::DistanceWithin:
172 if ( !mRequest.referenceGeometry().isEmpty() )
178 mDistanceWithinGeom = mRequest.referenceGeometry();
179 mDistanceWithinEngine = mRequest.referenceGeometryEngine();
180 mDistanceWithinEngine->prepareGeometry();
181 mDistanceWithin = mRequest.distanceWithin();
186 bool canDelegateLimitToProvider =
true;
189 switch ( updateRequestToSourceCrs( mRequest, mTransform ) )
197 canDelegateLimitToProvider =
false;
202 mFilterRect = mRequest.filterRect();
212 mDelegatedOrderByToProvider = !mSource->mHasEditBuffer;
213 if ( !mRequest.orderBy().isEmpty() )
215 QSet<int> attributeIndexes;
216 const auto usedAttributeIndices = mRequest.orderBy().usedAttributeIndices( mSource->mFields );
217 for ( const int attrIndex : usedAttributeIndices )
219 if ( mSource->mFields.fieldOrigin( attrIndex ) != Qgis::FieldOrigin::Provider )
220 mDelegatedOrderByToProvider = false;
222 attributeIndexes << attrIndex;
227 attributeIndexes += qgis::listToSet( mRequest.subsetOfAttributes() );
228 mRequest.setSubsetOfAttributes( qgis::setToList( attributeIndexes ) );
234 mRequest.expressionContext()->setFields( mSource->mFields );
235 mRequest.filterExpression()->prepare( mRequest.expressionContext() );
237 if ( mRequest.flags() & Qgis::FeatureRequestFlag::SubsetOfAttributes )
240 QSet<int> attributeIndexes = mRequest.filterExpression()->referencedAttributeIndexes( mSource->mFields );
241 attributeIndexes += qgis::listToSet( mRequest.subsetOfAttributes() );
242 mRequest.setSubsetOfAttributes( qgis::setToList( attributeIndexes ) );
248 mHasVirtualAttributes = !mFetchJoinInfo.isEmpty() || !mExpressionFieldInfo.isEmpty();
251 mProviderRequest = mRequest;
255 if ( mRequest.coordinateTransform().isValid() || mRequest.destinationCrs().isValid() )
261 if ( !mDelegatedOrderByToProvider )
266 if ( !canDelegateLimitToProvider )
268 mProviderRequest.setLimit( -1 );
274 QSet<int> providerSubset;
276 const int nPendingFields = mSource->mFields.count();
277 for (
const int attrIndex : subset )
279 if ( attrIndex < 0 || attrIndex >= nPendingFields )
282 providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
290 if ( !mProviderRequest.orderBy().isEmpty() )
292 const auto usedAttributeIndices = mProviderRequest.orderBy().usedAttributeIndices( mSource->mFields );
293 for (
const int attrIndex : usedAttributeIndices )
295 providerSubset << attrIndex;
299 mProviderRequest.setSubsetOfAttributes( qgis::setToList( providerSubset ) );
304 const bool needsGeom = mProviderRequest.filterExpression()->needsGeometry();
305 const auto constReferencedColumns = mProviderRequest.filterExpression()->referencedColumns();
306 for (
const QString &field : constReferencedColumns )
308 const int idx = source->mFields.lookupField( field );
314 mProviderRequest.disableFilter();
316 mProviderRequest.setLimit( -1 );
327 if ( mSource->mHasEditBuffer )
329 mChangedFeaturesRequest = mProviderRequest;
331 QgsChangedAttributesMap::const_iterator attIt = mSource->mChangedAttributeValues.constBegin();
332 for ( ; attIt != mSource->mChangedAttributeValues.constEnd(); ++attIt )
334 changedIds << attIt.key();
336 mChangedFeaturesRequest.setFilterFids( changedIds );
338 if ( mChangedFeaturesRequest.limit() > 0 )
340 int providerLimit = mProviderRequest.limit();
343 providerLimit += mSource->mDeletedFeatureIds.size();
348 providerLimit += mSource->mChangedAttributeValues.size();
354 providerLimit += mSource->mChangedGeometries.size();
357 mProviderRequest.setLimit( providerLimit );
358 mChangedFeaturesRequest.setLimit( providerLimit );
368 if ( mSource->mProviderFeatureSource )
370 if ( mSource->mHasEditBuffer )
372 mChangedFeaturesIterator = mSource->mProviderFeatureSource->getFeatures( mChangedFeaturesRequest );
376 mProviderIterator = mSource->mProviderFeatureSource->getFeatures( mProviderRequest );
399class QgsThreadStackOverflowGuard
402#if !defined( USE_THREAD_LOCAL ) || defined( Q_OS_WIN )
403 QgsThreadStackOverflowGuard( QThreadStorage<std::deque<QString>> &storage,
const QString &stackFrameInformation,
int maxDepth )
405 QgsThreadStackOverflowGuard( std::deque<QString> &storage,
const QString &stackFrameInformation,
int maxDepth )
407 : mStorage( storage )
408 , mMaxDepth( maxDepth )
410#if !defined( USE_THREAD_LOCAL ) || defined( Q_OS_WIN )
411 if ( !storage.hasLocalData() )
413 storage.setLocalData( std::deque<QString>() );
416 storage.localData().emplace_back( stackFrameInformation );
418 storage.emplace_back( stackFrameInformation );
422 ~QgsThreadStackOverflowGuard()
424#if !defined( USE_THREAD_LOCAL ) || defined( Q_OS_WIN )
425 mStorage.localData().pop_back();
431 bool hasStackOverflow()
const
433#if !defined( USE_THREAD_LOCAL ) || defined( Q_OS_WIN )
434 if ( mStorage.localData().size() > mMaxDepth )
436 if ( mStorage.size() > mMaxDepth )
443 QString topFrames()
const
445 QStringList dumpStack;
446#if !defined( USE_THREAD_LOCAL ) || defined( Q_OS_WIN )
447 const std::deque<QString> &stack = mStorage.localData();
449 const std::deque<QString> &stack = mStorage;
452 const int dumpSize = std::min(
static_cast<int>( stack.size() ), 10 );
453 auto stackIt = stack.begin();
454 for (
int i = 0; i < dumpSize; ++i, stackIt++ )
456 dumpStack += *stackIt;
459 return dumpStack.join(
'\n' );
462 std::size_t depth()
const
464#if !defined( USE_THREAD_LOCAL ) || defined( Q_OS_WIN )
465 return mStorage.localData().size();
467 return mStorage.size();
472#if !defined( USE_THREAD_LOCAL ) || defined( Q_OS_WIN )
473 QThreadStorage<std::deque<QString>> &mStorage;
475 std::deque<QString> &mStorage;
477 std::size_t mMaxDepth;
489#if !defined( USE_THREAD_LOCAL ) || defined( Q_OS_WIN )
490 static QThreadStorage<std::deque<QString>> sStack;
492 static thread_local std::deque<QString> sStack;
495 const QgsThreadStackOverflowGuard guard( sStack,
mSource->id(), 4 );
497 if ( guard.hasStackOverflow() )
508 if ( res && postProcessFeature( f ) )
547 if (
mSource->mProviderFeatureSource )
574 mRequest.expressionContext()->setFeature( f );
575 if ( !
mRequest.filterExpression()->evaluate(
mRequest.expressionContext() ).toBool() )
587 if ( !postProcessFeature( f ) )
633 mInterruptionChecker = interruptionChecker;
660 if ( !postProcessFeature( f ) )
708 mRequest.expressionContext()->setFeature( f );
709 if ( !
mRequest.filterExpression()->evaluate(
mRequest.expressionContext() ).toBool() )
715 if ( postProcessFeature( f ) )
738 const auto changedGeometryIt =
mSource->mChangedGeometries.constFind( f.
id() );
739 if ( changedGeometryIt !=
mSource->mChangedGeometries.constEnd() )
751 mRequest.expressionContext()->setFeature( f );
752 if (
mRequest.filterExpression()->evaluate(
mRequest.expressionContext() ).toBool() && postProcessFeature( f ) )
774 if ( !subsetAttrs || !
mRequest.subsetOfAttributes().isEmpty() )
808 if ( !
mSource->mFields.exists( fieldIdx ) )
814 int sourceLayerIndex;
816 Q_ASSERT( joinInfo );
819 if ( joinSourceIt ==
mSource->mJoinSources.constEnd() )
843 mFetchJoinInfo[joinInfo].attributes.push_back( sourceLayerIndex );
844 mFetchJoinInfo[joinInfo].attributesSourceToDestLayerMap[sourceLayerIndex] = fieldIdx;
850#if !defined( USE_THREAD_LOCAL ) || defined( Q_OS_WIN )
851 static QThreadStorage<std::deque<QString>> sStack;
853 static thread_local std::deque<QString> sStack;
856 const QgsThreadStackOverflowGuard guard( sStack,
mSource->id(), 4 );
858 if ( guard.hasStackOverflow() )
865 const QList<QgsExpressionFieldBuffer::ExpressionField> &exps =
mSource->mExpressionFieldBuffer->expressions();
867 const int oi =
mSource->mFields.fieldOriginIndex( fieldIdx );
868 auto exp = std::make_unique<QgsExpression>( exps[oi].cachedExpression );
873 exp->setGeomCalculator( &da );
874 exp->setDistanceUnits(
mSource->mDistanceUnit );
875 exp->setAreaUnits(
mSource->mAreaUnit );
877 if ( !mExpressionContext )
878 createExpressionContext();
879 exp->prepare( mExpressionContext.get() );
880 const QSet<int> referencedColumns = exp->referencedAttributeIndexes(
mSource->fields() );
882 QSet<int> requestedAttributes = qgis::listToSet(
mRequest.subsetOfAttributes() );
884 for (
const int dependentFieldIdx : referencedColumns )
888 requestedAttributes += dependentFieldIdx;
891 if ( !mPreparedFields.contains( dependentFieldIdx ) && !mFieldsToPrepare.contains( dependentFieldIdx ) )
892 mFieldsToPrepare << dependentFieldIdx;
897 mRequest.setSubsetOfAttributes( qgis::setToList( requestedAttributes ) );
900 if ( exp->needsGeometry() )
910 mPreparedFields.clear();
911 mFieldsToPrepare.clear();
913 mOrderedJoinInfoList.clear();
915 mExpressionContext.reset();
919 while ( !mFieldsToPrepare.isEmpty() )
921 const int fieldIdx = mFieldsToPrepare.takeFirst();
922 if ( mPreparedFields.contains( fieldIdx ) )
925 mPreparedFields << fieldIdx;
932 createOrderedJoinList();
936void QgsVectorLayerFeatureIterator::createOrderedJoinList()
939 if ( mOrderedJoinInfoList.size() < 2 )
944 QSet<int> resolvedFields;
947 QList< int >::const_iterator prepFieldIt = mPreparedFields.constBegin();
948 for ( ; prepFieldIt != mPreparedFields.constEnd(); ++prepFieldIt )
952 resolvedFields.insert( *prepFieldIt );
959 const int maxIterations = ( mOrderedJoinInfoList.size() + 1 ) * mOrderedJoinInfoList.size() / 2.0;
960 int currentIteration = 0;
962 for (
int i = 0; i < mOrderedJoinInfoList.size() - 1; ++i )
964 if ( !resolvedFields.contains( mOrderedJoinInfoList.at( i ).targetField ) )
966 mOrderedJoinInfoList.append( mOrderedJoinInfoList.at( i ) );
967 mOrderedJoinInfoList.removeAt( i );
972 const int offset = mOrderedJoinInfoList.at( i ).indexOffset;
973 const int joinField = mOrderedJoinInfoList.at( i ).joinField;
975 const QgsAttributeList attributes = mOrderedJoinInfoList.at( i ).attributes;
976 for (
int n = 0; n < attributes.size(); n++ )
978 if ( n != joinField )
980 resolvedFields.insert( joinField < n ? n + offset - 1 : n + offset );
986 if ( currentIteration >= maxIterations )
993bool QgsVectorLayerFeatureIterator::postProcessFeature(
QgsFeature &feature )
995 bool result = checkGeometryValidity( feature );
1007bool QgsVectorLayerFeatureIterator::checkGeometryValidity(
const QgsFeature &feature )
1009 switch (
mRequest.invalidGeometryCheck() )
1022 if (
mRequest.invalidGeometryCallback() )
1024 mRequest.invalidGeometryCallback()( feature );
1039 if (
mRequest.invalidGeometryCallback() )
1041 mRequest.invalidGeometryCallback()( feature );
1053 switch (
mSource->mFields.fieldOrigin( fieldIdx ) )
1060 if (
mSource->mJoinBuffer->containsJoins() )
1075 QList< FetchJoinInfo >::const_iterator joinIt = mOrderedJoinInfoList.constBegin();
1076 for ( ; joinIt != mOrderedJoinInfoList.constEnd(); ++joinIt )
1078 const QVariant targetFieldValue = f.
attribute( joinIt->targetField );
1079 if ( !targetFieldValue.isValid() )
1082 const QHash< QString, QgsAttributes> &memoryCache = joinIt->joinInfo->cachedAttributes;
1083 if ( memoryCache.isEmpty() )
1085 if ( joinIt->joinInfo->isUsingMemoryCache() && !joinIt->joinInfo->cacheDirty )
1088 joinIt->addJoinedAttributesDirect( f, targetFieldValue );
1091 joinIt->addJoinedAttributesCached( f, targetFieldValue );
1099 attr.resize(
mSource->mFields.count() );
1105 QList< int > fetchedVirtualAttributes;
1107 QMap<const QgsVectorLayerJoinInfo *, FetchJoinInfo>::const_iterator joinIt =
mFetchJoinInfo.constBegin();
1114 fetchedVirtualAttributes << joinIt->targetField;
1127 if ( fetchedVirtualAttributes.contains( it.key() ) )
1140 if ( !mExpressionContext )
1141 createExpressionContext();
1143 mExpressionContext->setFeature( f );
1144 QVariant val = exp->
evaluate( mExpressionContext.get() );
1145 ( void )
mSource->mFields.at( attrIndex ).convertCompatible( val );
1156 Q_UNUSED( simplifyMethod )
1162 Q_UNUSED( methodType )
1169 const QHash<QString, QgsAttributes> &memoryCache =
joinInfo->cachedAttributes;
1170 const QHash<QString, QgsAttributes>::const_iterator it = memoryCache.find( joinValue.toString() );
1171 if ( it == memoryCache.constEnd() )
1177 for (
int i = 0; i < featureAttributes.count(); ++i )
1188 if ( joinLayer && ! joinLayer->hasFeatures() )
1195 QString subsetString;
1197 const QString joinFieldName =
joinInfo->joinFieldName();
1199 subsetString.append( u
"\"%1\""_s.arg( joinFieldName ) );
1203 subsetString +=
" IS NULL"_L1;
1207 QString v = joinValue.toString();
1208 switch ( joinValue.userType() )
1210 case QMetaType::Type::Int:
1211 case QMetaType::Type::LongLong:
1212 case QMetaType::Type::Double:
1216 case QMetaType::Type::QString:
1217 v.replace(
'\'',
"''"_L1 );
1218 v.prepend(
'\'' ).append(
'\'' );
1221 subsetString +=
'=' + v;
1224 QList<int> joinedAttributeIndices;
1232 joinedAttributeIndices = qgis::setToList( qgis::listToSet(
attributes ).intersect( qgis::listToSet( subsetIndices.toList() ) ) );
1240 joinedAttributeIndices.removeAll(
joinField );
1258 for (
const int sourceAttrIndex : sourceAttrIndexes )
1265 f.
setAttribute( destAttrIndex, attr.at( sourceAttrIndex ) );
1280 if (
mSource->mDeletedFeatureIds.contains( featureId ) )
1291 for ( QgsFeatureMap::ConstIterator iter =
mSource->mAddedFeatures.constBegin(); iter !=
mSource->mAddedFeatures.constEnd(); ++iter )
1293 if ( iter->id() == featureId )
1306 if (
mSource->mHasEditBuffer )
1325 for (
int idx =
mSource->mDeletedAttributeIds.count() - 1; idx >= 0; --idx )
1327 attrs.remove(
mSource->mDeletedAttributeIds[idx] );
1331 attrs.resize( attrs.count() +
mSource->mAddedAttributes.count() );
1334 if (
mSource->mChangedAttributeValues.contains( f.
id() ) )
1337 for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
1338 attrs[it.key()] = it.value();
1345 if (
mSource->mChangedGeometries.contains( f.
id() ) )
1349void QgsVectorLayerFeatureIterator::createExpressionContext()
1351 mExpressionContext = std::make_unique< QgsExpressionContext >();
1358bool QgsVectorLayerFeatureIterator::prepareOrderBy(
const QList<QgsFeatureRequest::OrderByClause> &orderBys )
1360 Q_UNUSED( orderBys )
1361 return mDelegatedOrderByToProvider;
1371 , mSelectedFeatureIds( layer->selectedFeatureIds() )
1372 , mWkbType( layer->
wkbType() )
1373 , mName( layer->name() )
1398 return QgsFeatureIterator(
new QgsVectorLayerSelectedFeatureIterator( mSelectedFeatureIds, req, mSource ) );
1403 return mSource.crs();
1408 return mSource.fields();
1418 return mSelectedFeatureIds.count();
1429 return mLayer->createExpressionContextScope();
1437 return mLayer->hasSpatialIndex();
1449 , mSelectedFeatureIds( selectedFeatureIds )
1457 sourceRequest.setLimit( -1 );
1462bool QgsVectorLayerSelectedFeatureIterator::rewind()
1464 return mIterator.
rewind();
1467bool QgsVectorLayerSelectedFeatureIterator::close()
1469 return mIterator.close();
1472bool QgsVectorLayerSelectedFeatureIterator::fetchFeature(
QgsFeature &f )
1474 while ( mIterator.nextFeature( f ) )
1476 if ( mSelectedFeatureIds.contains( f.
id() ) )
@ Fid
Filter using feature ID.
@ Expression
Filter using expression.
@ NoFilter
No filter is applied.
SpatialIndexPresence
Enumeration of spatial index presence states.
@ Unknown
Spatial index presence cannot be determined, index may or may not exist.
@ SubsetOfAttributes
Fetch only a subset of attributes (setSubsetOfAttributes sets this flag).
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ Critical
Critical/error message.
@ NoFilter
No spatial filtering of features.
@ Provider
Field originates from the underlying data provider of the vector layer.
@ Edit
Field has been temporarily added in editing mode.
@ Unknown
The field origin has not been specified.
@ Expression
Field is calculated from an expression.
@ Join
Field originates from a joined layer.
@ NoCheck
No invalid geometry checking.
@ AbortOnInvalid
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...
@ SkipInvalid
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
WkbType
The WKB type describes the number of dimensions a geometry has.
QgsVectorLayerFeatureSource * mSource
QgsAbstractFeatureIteratorFromSource(QgsVectorLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request)
Internal feature iterator to be implemented within data providers.
@ Success
Request was successfully updated to the source CRS, or no changes were required.
@ DistanceWithinMustBeCheckedManually
The distance within request cannot be losslessly updated to the source CRS, and callers will need to ...
friend class QgsFeatureIterator
void geometryToDestinationCrs(QgsFeature &feature, const QgsCoordinateTransform &transform) const
Transforms feature's geometry according to the specified coordinate transform.
QgsFeatureRequest mRequest
A copy of the feature request.
bool mClosed
Sets to true, as soon as the iterator is closed.
Represents a coordinate reference system (CRS).
Custom exception class for Coordinate Reference System related exceptions.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static std::unique_ptr< QgsExpressionContextScope > globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
static std::unique_ptr< QgsExpressionContextScope > layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static std::unique_ptr< QgsExpressionContextScope > projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
Handles parsing and evaluation of expressions (formerly called "search strings").
QVariant evaluate()
Evaluate the feature and return the result.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
bool rewind()
Resets the iterator to the starting position.
Represents a list of OrderByClauses, with the most important first and the least important last.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setLimit(long long limit)
Set the maximum number of features to request.
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly by the iterator to check if it should be ca...
QgsFeatureRequest & setRequestMayBeNested(bool requestMayBeNested)
In case this request may be run nested within another already running iteration on the same connectio...
long long limit() const
Returns the maximum number of features to request, or -1 if no limit set.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
Qgis::FeatureRequestFilterType filterType() const
Returns the attribute/ID filter type which is currently set on this request.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
const QgsFeatureIds & filterFids() const
Returns the feature IDs that should be fetched.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets the feature ID that should be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assigns a field map with the feature to allow attribute access by attribute name.
int attributeCount() const
Returns the number of attributes attached to the feature.
void padAttributes(int count)
Resizes the attributes attached to this feature by appending the specified count of NULL values to th...
void setId(QgsFeatureId id)
Sets the feature id for this feature.
void setValid(bool validity)
Sets the validity of the feature.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
QgsCoordinateReferenceSystem crs
QgsProject * project() const
Returns the parent project if this map layer is added to a project.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Qgis::DistanceUnit distanceUnits
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsCoordinateTransformContext transformContext
Contains information about how to simplify geometries fetched from a QgsFeatureIterator.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Base class for vector data providers.
virtual QgsAbstractFeatureSource * featureSource() const =0
Returns feature source object that can be used for querying provider's data.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
QgsFeatureIds deletedFeatureIds() const
Returns a list of deleted feature IDs which are not committed.
QgsChangedAttributesMap changedAttributeValues() const
Returns a map of features with changed attributes values which are not committed.
QgsFeatureMap addedFeatures() const
Returns a map of new features which are not committed.
QgsGeometryMap changedGeometries() const
Returns a map of features with changed geometries which are not committed.
QList< QgsField > addedAttributes() const
Returns a list of added attributes fields which are not committed.
QgsAttributeList deletedAttributeIds() const
Returns a list of deleted attributes fields which are not committed.
void updateChangedAttributes(QgsFeature &f)
Update feature with uncommitted attribute updates.
void prepareExpression(int fieldIdx)
void useAddedFeature(const QgsFeature &src, QgsFeature &f)
QMap< const QgsVectorLayerJoinInfo *, QgsVectorLayerFeatureIterator::FetchJoinInfo > mFetchJoinInfo
Information about joins used in the current select() statement.
void prepareField(int fieldIdx)
QgsFeatureMap::ConstIterator mFetchAddedFeaturesIt
bool mHasVirtualAttributes
QgsFeatureRequest mProviderRequest
QSet< QgsFeatureId > mFetchConsidered
void setInterruptionChecker(QgsFeedback *interruptionChecker) override
Attach an object that can be queried regularly by the iterator to check if it must stopped.
void addVirtualAttributes(QgsFeature &f)
Adds attributes that don't source from the provider but are added inside QGIS Includes.
bool close() override
end of iterating: free the resources / lock
void updateFeatureGeometry(QgsFeature &f)
Update feature with uncommitted geometry updates.
bool nextFeatureFid(QgsFeature &f)
QgsFeatureIterator mChangedFeaturesIterator
bool fetchNextAddedFeature(QgsFeature &f)
void addExpressionAttribute(QgsFeature &f, int attrIndex)
Adds an expression based attribute to a feature.
QMap< int, QgsExpression * > mExpressionFieldInfo
QgsGeometryMap::ConstIterator mFetchChangedGeomIt
bool prepareSimplification(const QgsSimplifyMethod &simplifyMethod) override
Setup the simplification of geometries to fetch using the specified simplify method.
void prepareJoin(int fieldIdx)
void useChangedAttributeFeature(QgsFeatureId fid, const QgsGeometry &geom, QgsFeature &f)
bool fetchFeature(QgsFeature &feature) override
fetch next feature, return true on success
~QgsVectorLayerFeatureIterator() override
std::shared_ptr< QgsGeometryEngine > mDistanceWithinEngine
void addJoinedAttributes(QgsFeature &f)
bool isValid() const override
Returns if this iterator is valid.
bool rewind() override
reset the iterator to the starting position
bool fetchNextChangedGeomFeature(QgsFeature &f)
QgsFeatureIterator mProviderIterator
QgsCoordinateTransform mTransform
bool fetchNextChangedAttributeFeature(QgsFeature &f)
QgsVectorLayerFeatureIterator(QgsVectorLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request)
Partial snapshot of vector layer's state (only the members necessary for access to features).
QgsCoordinateReferenceSystem crs() const
Returns the coordinate reference system for features retrieved from this source.
QgsChangedAttributesMap mChangedAttributeValues
QgsCoordinateReferenceSystem mCrs
QList< QgsField > mAddedAttributes
std::unique_ptr< QgsAbstractFeatureSource > mProviderFeatureSource
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) override
Gets an iterator for features matching the specified request.
QgsVectorLayerFeatureSource(const QgsVectorLayer *layer)
Constructor for QgsVectorLayerFeatureSource.
~QgsVectorLayerFeatureSource() override
QgsFeatureIds mDeletedFeatureIds
Qgis::DistanceUnit mDistanceUnit
QString id() const
Returns the layer id of the source layer.
QgsAttributeList mDeletedAttributeIds
QgsCoordinateTransformContext mTransformContext
QgsExpressionContextScope mLayerScope
QgsFields fields() const
Returns the fields that will be available for features that are retrieved from this source.
std::unique_ptr< QgsExpressionContextScope > mProjectScope
std::unique_ptr< QgsVectorLayerJoinBuffer > mJoinBuffer
std::unique_ptr< QgsExpressionFieldBuffer > mExpressionFieldBuffer
QMap< QString, JoinLayerSource > mJoinSources
Contains prepared join sources by layer ID.
friend class QgsVectorLayerFeatureIterator
QgsFeatureMap mAddedFeatures
QgsGeometryMap mChangedGeometries
bool containsJoins() const
Quick way to test if there is any join at all.
QgsVectorLayerJoinBuffer * clone() const
Create a copy of the join buffer.
void createJoinCaches()
Calls cacheJoinLayer() for all vector joins.
static QVector< int > joinSubsetIndices(QgsVectorLayer *joinLayer, const QStringList &joinFieldsSubset)
Returns a vector of indices for use in join based on field names from the layer.
Defines left outer join from our vector layer to some other vector layer.
QStringList * joinFieldNamesSubset() const
Returns the subset of fields to be used from joined layer.
QString joinFieldName() const
Returns name of the field of joined layer that will be used for join.
QString targetFieldName() const
Returns name of the field of our layer that will be used for join.
QString joinLayerId() const
ID of the joined layer - may be used to resolve reference to the joined layer.
long long featureCount() const override
Returns the number of features contained in the source, or -1 if the feature count is unknown.
Qgis::WkbType wkbType() const override
Returns the geometry type for features returned by this source.
Qgis::SpatialIndexPresence hasSpatialIndex() const override
Returns an enum value representing the presence of a valid spatial index on the source,...
QgsFields fields() const override
Returns the fields associated with features in the source.
QgsCoordinateReferenceSystem sourceCrs() const override
Returns the coordinate reference system for features in the source.
QgsVectorLayerSelectedFeatureSource(QgsVectorLayer *layer)
Constructor for QgsVectorLayerSelectedFeatureSource, for selected features from the specified layer.
QgsExpressionContextScope * createExpressionContextScope() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QString sourceName() const override
Returns a friendly display name for the source.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override
Returns an iterator for the features in the source.
Represents a vector layer which manages a vector based dataset.
Q_INVOKABLE QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
QMap< int, QVariant > QgsAttributeMap
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QList< int > QgsAttributeList
QMap< QgsFeatureId, QgsFeature > QgsFeatureMap
Join information prepared for fast attribute id mapping in QgsVectorLayerJoinBuffer::updateFeatureAtt...
QMap< int, int > attributesSourceToDestLayerMap
Mapping from original attribute index to the joined layer index.
void addJoinedAttributesDirect(QgsFeature &f, const QVariant &joinValue) const
std::shared_ptr< QgsVectorLayerFeatureSource > joinSource
Feature source for join.
QgsFields joinLayerFields
Fields from joined layer.
int targetField
Index of field (of this layer) that drives the join.
const QgsVectorLayerJoinInfo * joinInfo
Canonical source of information about the join.
QgsAttributeList attributes
Attributes to fetch.
int indexOffset
At what position the joined fields start.
void addJoinedAttributesCached(QgsFeature &f, const QVariant &joinValue) const
Contains join layer source information prepared in a thread-safe way, ready for vector layer feature ...
std::shared_ptr< QgsVectorLayerFeatureSource > joinSource
Feature source for join.
QgsFields joinLayerFields
Fields from joined layer.