QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
Loading...
Searching...
No Matches
qgsvectorlayercache.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectorlayercache.cpp
3 Cache features of a vector layer
4 -------------------
5 begin : January 2013
6 copyright : (C) Matthias Kuhn
7 email : matthias at opengis dot ch
8
9 ***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgsvectorlayercache.h"
19
21#include "qgscacheindex.h"
22#include "qgsvectorlayer.h"
25
26#include <QElapsedTimer>
27
28#include "moc_qgsvectorlayercache.cpp"
29
31 : QObject( parent )
32 , mLayer( layer )
33{
34 mCache.setMaxCost( cacheSize );
35
36 connect( mLayer, &QgsVectorLayer::featureDeleted, this, &QgsVectorLayerCache::featureDeleted );
37 connect( mLayer, &QgsVectorLayer::featureAdded, this, &QgsVectorLayerCache::onFeatureAdded );
38 connect( mLayer, &QgsVectorLayer::destroyed, this, &QgsVectorLayerCache::layerDeleted );
39
40 setCacheGeometry( true );
41 setCacheSubsetOfAttributes( mLayer->attributeList() );
43
44 connect( mLayer, &QgsVectorLayer::attributeDeleted, this, &QgsVectorLayerCache::attributeDeleted );
45 connect( mLayer, &QgsVectorLayer::updatedFields, this, &QgsVectorLayerCache::invalidate );
46 connect( mLayer, &QgsVectorLayer::dataChanged, this, &QgsVectorLayerCache::invalidate );
47 connect( mLayer, &QgsVectorLayer::attributeValueChanged, this, &QgsVectorLayerCache::onAttributeValueChanged );
48
49 connectJoinedLayers();
50}
51
53{
54 qDeleteAll( mCacheIndices );
55 mCacheIndices.clear();
56}
57
59{
60 mCache.setMaxCost( cacheSize );
61}
62
64{
65 return mCache.maxCost();
66}
67
69{
70 bool shouldCacheGeometry = cacheGeometry && mLayer->isSpatial();
71 bool mustInvalidate = shouldCacheGeometry && !mCacheGeometry; // going from no geometry -> geometry, so have to clear existing cache entries
72 mCacheGeometry = shouldCacheGeometry;
73 if ( cacheGeometry )
74 {
75 connect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsVectorLayerCache::geometryChanged, Qt::UniqueConnection );
76 }
77 else
78 {
79 disconnect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsVectorLayerCache::geometryChanged );
80 }
81 if ( mustInvalidate )
82 {
83 invalidate();
84 }
85}
86
88{
89 if ( !mCache.isEmpty() && !QSet<int>( mCachedAttributes.cbegin(), mCachedAttributes.cend() ).contains( QSet<int>( attributes.cbegin(), attributes.cend() ) ) )
90 invalidate();
91 mCachedAttributes = attributes;
92}
93
95{
96 return mCachedAttributes;
97}
98
100{
101 mFullCache = fullCache;
102
103 if ( mFullCache )
104 {
105 // Add a little more than necessary...
106 setCacheSize( mLayer->featureCount() + 100 );
107
108 // Initialize the cache...
110 new QgsCachedFeatureWriterIterator( this, QgsFeatureRequest().setSubsetOfAttributes( mCachedAttributes ).setFlags( mCacheGeometry ? Qgis::FeatureRequestFlag::NoFlags : Qgis::FeatureRequestFlag::NoGeometry ) )
111 );
112
113 int i = 0;
114
115 QElapsedTimer t;
116 t.start();
117
118 QgsFeature f;
119 while ( it.nextFeature( f ) )
120 {
121 ++i;
122
123 if ( t.elapsed() > 1000 )
124 {
125 bool cancel = false;
126 emit progress( i, cancel );
127 if ( cancel )
128 break;
129
130 t.restart();
131 }
132 }
133
134 it.close();
135
136 emit finished();
137 }
138}
139
141{
142 mCacheIndices.append( cacheIndex );
143}
144
145void QgsVectorLayerCache::setCacheAddedAttributes( bool cacheAddedAttributes )
146{
147 if ( cacheAddedAttributes )
148 {
149 connect( mLayer, &QgsVectorLayer::attributeAdded, this, &QgsVectorLayerCache::attributeAdded );
150 }
151 else
152 {
153 disconnect( mLayer, &QgsVectorLayer::attributeAdded, this, &QgsVectorLayerCache::attributeAdded );
154 }
155}
156
157bool QgsVectorLayerCache::featureAtId( QgsFeatureId featureId, QgsFeature &feature, bool skipCache )
158{
159 bool featureFound = false;
160
161 QgsCachedFeature *cachedFeature = nullptr;
162
163 if ( !skipCache )
164 {
165 cachedFeature = mCache[featureId];
166 }
167
168 if ( cachedFeature )
169 {
170 feature = QgsFeature( *cachedFeature->feature() );
171 featureFound = true;
172 }
173 else
174 {
175 QgsFeatureRequest request { featureId };
176 const bool allAttrsFetched { mCachedAttributes.count() == mLayer->fields().count() };
177 if ( !allAttrsFetched )
178 {
179 request.setSubsetOfAttributes( mCachedAttributes );
180 }
181 if ( !mCacheGeometry )
182 {
183 request.setFlags( request.flags().setFlag( Qgis::FeatureRequestFlag::NoGeometry ) );
184 }
185 if ( mLayer->getFeatures( request ).nextFeature( feature ) )
186 {
187 cacheFeature( feature, allAttrsFetched );
188 featureFound = true;
189 }
190 }
191
192 return featureFound;
193}
194
196{
197 bool featureFound = false;
198
199 QgsCachedFeature *cachedFeature = nullptr;
200
201 if ( !skipCache )
202 {
203 cachedFeature = mCache[featureId];
204 }
205
206 if ( cachedFeature && cachedFeature->allAttributesFetched() )
207 {
208 feature = QgsFeature( *cachedFeature->feature() );
209 featureFound = true;
210 }
211 else if ( mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setFlags( !mCacheGeometry ? Qgis::FeatureRequestFlag::NoGeometry : Qgis::FeatureRequestFlags() ) ).nextFeature( feature ) )
212 {
213 cacheFeature( feature, true );
214 featureFound = true;
215 }
216
217 return featureFound;
218}
219
220bool QgsVectorLayerCache::completeFeatureAtId( QgsFeatureId featureId, QgsFeature &feature, bool skipCache )
221{
222 bool featureFound = false;
223
224 QgsCachedFeature *cachedFeature = nullptr;
225
226 if ( !skipCache )
227 {
228 cachedFeature = mCache[featureId];
229 }
230
231 if ( cachedFeature && cachedFeature->allAttributesFetched() && cachedFeature->geometryFetched() )
232 {
233 feature = QgsFeature( *cachedFeature->feature() );
234 featureFound = true;
235 }
236 else if ( mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ) ).nextFeature( feature ) )
237 {
238 cacheFeature( feature, true, true );
239 featureFound = true;
240 }
241
242 return featureFound;
243}
244
246{
247 bool removed = mCache.remove( fid );
248 if ( removed )
249 {
250 if ( auto unorderedIt = std::find( mCacheUnorderedKeys.begin(), mCacheUnorderedKeys.end(), fid ); unorderedIt != mCacheUnorderedKeys.end() )
251 {
252 mCacheUnorderedKeys.erase( unorderedIt );
253
254 if ( auto orderedIt = std::find( mCacheOrderedKeys.begin(), mCacheOrderedKeys.end(), fid ); orderedIt != mCacheOrderedKeys.end() )
255 mCacheOrderedKeys.erase( orderedIt );
256 }
257 }
258 return removed;
259}
260
262{
263 return mLayer;
264}
265
267{
268 return mLayer->crs();
269}
270
272{
273 return mLayer->wkbType();
274}
275
277{
278 return mLayer->fields();
279}
280
282{
283 return mLayer->featureCount();
284}
285
287{
288 // If a request is too large for the cache don't notify to prevent from indexing incomplete requests
289 if ( fids.count() <= mCache.size() )
290 {
291 for ( const auto &idx : std::as_const( mCacheIndices ) )
292 {
293 idx->requestCompleted( featureRequest, fids );
294 }
296 && ( featureRequest.spatialFilterType() == Qgis::SpatialFilterType::NoFilter || featureRequest.filterRect().contains( mLayer->extent() ) ) )
297 {
298 mFullCache = true;
299 }
300 }
301}
302
304{
305 const auto constMCacheIndices = mCacheIndices;
306 for ( QgsAbstractCacheIndex *idx : constMCacheIndices )
307 {
308 idx->flushFeature( fid );
309 }
310}
311
312void QgsVectorLayerCache::onAttributeValueChanged( QgsFeatureId fid, int field, const QVariant &value )
313{
314 QgsCachedFeature *cachedFeat = mCache[fid];
315
316 if ( cachedFeat )
317 {
318 cachedFeat->mFeature->setAttribute( field, value );
319 }
320
321 emit attributeValueChanged( fid, field, value );
322}
323
324void QgsVectorLayerCache::onJoinAttributeValueChanged( QgsFeatureId fid, int field, const QVariant &value )
325{
326 const QgsVectorLayer *joinLayer = qobject_cast<const QgsVectorLayer *>( sender() );
327
328 const auto constVectorJoins = mLayer->vectorJoins();
329 for ( const QgsVectorLayerJoinInfo &info : constVectorJoins )
330 {
331 if ( joinLayer == info.joinLayer() )
332 {
333 const QgsFeature feature = mLayer->joinBuffer()->targetedFeatureOf( &info, joinLayer->getFeature( fid ) );
334
335 const QString fieldName = info.prefixedFieldName( joinLayer->fields().field( field ) );
336 const int fieldIndex = mLayer->fields().indexFromName( fieldName );
337
338 if ( feature.isValid() && fieldIndex != -1 )
339 {
340 onAttributeValueChanged( feature.id(), fieldIndex, value );
341 return;
342 }
343 }
344 }
345}
346
347void QgsVectorLayerCache::featureDeleted( QgsFeatureId fid )
348{
349 mCache.remove( fid );
350
351 if ( auto it = mCacheUnorderedKeys.find( fid ); it != mCacheUnorderedKeys.end() )
352 {
353 mCacheUnorderedKeys.erase( it );
354 if ( auto orderedIt = std::find( mCacheOrderedKeys.begin(), mCacheOrderedKeys.end(), fid ); orderedIt != mCacheOrderedKeys.end() )
355 mCacheOrderedKeys.erase( orderedIt );
356 }
357}
358
359void QgsVectorLayerCache::onFeatureAdded( QgsFeatureId fid )
360{
361 if ( mFullCache )
362 {
363 if ( cacheSize() <= mLayer->featureCount() )
364 {
365 setCacheSize( mLayer->featureCount() + 100 );
366 }
367
368 QgsFeature feat;
369 featureAtId( fid, feat );
370 }
371 emit featureAdded( fid );
372}
373
374void QgsVectorLayerCache::attributeAdded( int field )
375{
376 Q_UNUSED( field )
377 mCachedAttributes.append( field );
378 invalidate();
379}
380
381void QgsVectorLayerCache::attributeDeleted( int field )
382{
383 const QgsAttributeList attrs = mCachedAttributes;
384 mCachedAttributes.clear();
385
386 for ( int attr : attrs )
387 {
388 if ( attr < field )
389 mCachedAttributes << attr;
390 else if ( attr > field )
391 mCachedAttributes << attr - 1;
392 }
393}
394
395void QgsVectorLayerCache::geometryChanged( QgsFeatureId fid, const QgsGeometry &geom )
396{
397 QgsCachedFeature *cachedFeat = mCache[fid];
398
399 if ( cachedFeat )
400 {
401 cachedFeat->mFeature->setGeometry( geom );
402 }
403}
404
405void QgsVectorLayerCache::layerDeleted()
406{
407 emit cachedLayerDeleted();
408 mLayer = nullptr;
409}
410
411void QgsVectorLayerCache::invalidate()
412{
413 if ( !mCache.isEmpty() )
414 {
415 mCache.clear();
416 mCacheOrderedKeys.clear();
417 mCacheUnorderedKeys.clear();
418 mFullCache = false;
419 emit invalidated();
420 }
421}
422
423bool QgsVectorLayerCache::canUseCacheForRequest( const QgsFeatureRequest &featureRequest, QgsFeatureIterator &it )
424{
425 // check first for available indices
426 const auto constMCacheIndices = mCacheIndices;
427 for ( QgsAbstractCacheIndex *idx : constMCacheIndices )
428 {
429 if ( idx->getCacheIterator( it, featureRequest ) )
430 {
431 return true;
432 }
433 }
434
435 // no indexes available, but maybe we have already cached all required features anyway?
436 switch ( featureRequest.filterType() )
437 {
439 {
440 if ( mCache.contains( featureRequest.filterFid() ) )
441 {
442 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
443 return true;
444 }
445 break;
446 }
448 {
449 if ( cachedFeatureIds().contains( featureRequest.filterFids() ) )
450 {
451 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
452 return true;
453 }
454 break;
455 }
458 {
459 if ( mFullCache )
460 {
461 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
462 return true;
463 }
464 break;
465 }
466 }
467 return false;
468}
469
471{
473 bool requiresWriterIt = true; // If a not yet cached, but cacheable request is made, this stays true.
474
475 if ( checkInformationCovered( featureRequest ) )
476 {
477 // If we have a full cache available, run on this
478 if ( mFullCache )
479 {
480 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
481 requiresWriterIt = false;
482 }
483 else
484 {
485 // may still be able to satisfy request using cache
486 requiresWriterIt = !canUseCacheForRequest( featureRequest, it );
487 }
488 }
489 else
490 {
491 // Let the layer answer the request, so no caching of requests
492 // we don't want to cache is done
493 requiresWriterIt = false;
494 it = mLayer->getFeatures( featureRequest );
495 }
496
497 if ( requiresWriterIt && mLayer->dataProvider() )
498 {
499 // No index was able to satisfy the request
500 QgsFeatureRequest myRequest = QgsFeatureRequest( featureRequest );
501
502 // Make sure if we cache the geometry, it gets fetched
503 if ( mCacheGeometry && mLayer->isSpatial() )
504 myRequest.setFlags( featureRequest.flags() & ~( static_cast< int >( Qgis::FeatureRequestFlag::NoGeometry ) ) );
505
506 // Make sure all the cached attributes are requested as well if requesting a subset
507 if ( myRequest.flags().testFlag( Qgis::FeatureRequestFlag::SubsetOfAttributes ) )
508 {
509 if ( mCachedAttributes.count() != mLayer->fields().count() )
510 {
511 const QgsAttributeList requestSubset = featureRequest.subsetOfAttributes();
512 QSet<int> attrs( requestSubset.begin(), requestSubset.end() );
513 for ( int attr : std::as_const( mCachedAttributes ) )
514 attrs.insert( attr );
515 myRequest.setSubsetOfAttributes( attrs.values() );
516 }
517 else // we are already caching all attributes
518 {
520 myRequest.setFlags( myRequest.flags().setFlag( Qgis::FeatureRequestFlag::SubsetOfAttributes, false ) );
521 }
522 }
523
524 it = QgsFeatureIterator( new QgsCachedFeatureWriterIterator( this, myRequest ) );
525 }
526
527 return it;
528}
529
531{
532 return mCache.contains( fid );
533}
534
536{
537 const QList< QgsFeatureId > keys = mCache.keys();
538 return QgsFeatureIds( keys.begin(), keys.end() );
539}
540
542{
543 QgsAttributeList requestedAttributes;
544
545 if ( !featureRequest.flags().testFlag( Qgis::FeatureRequestFlag::SubsetOfAttributes ) )
546 {
547 requestedAttributes = mLayer->attributeList();
548 }
549 else
550 {
551 requestedAttributes = featureRequest.subsetOfAttributes();
552 }
553
554 // Check if we even cache the information requested
555 const auto constRequestedAttributes = requestedAttributes;
556 for ( int attr : constRequestedAttributes )
557 {
558 if ( !mCachedAttributes.contains( attr ) )
559 {
560 return false;
561 }
562 }
563
564 // If the request needs geometry but we don't cache this...
565 return !( !featureRequest.flags().testFlag( Qgis::FeatureRequestFlag::NoGeometry ) && !mCacheGeometry );
566}
567
568void QgsVectorLayerCache::connectJoinedLayers() const
569{
570 const auto constVectorJoins = mLayer->vectorJoins();
571 for ( const QgsVectorLayerJoinInfo &info : constVectorJoins )
572 {
573 const QgsVectorLayer *vl = info.joinLayer();
574 if ( vl )
575 connect( vl, &QgsVectorLayer::attributeValueChanged, this, &QgsVectorLayerCache::onJoinAttributeValueChanged );
576 }
577}
578
579bool QgsVectorLayerCache::QgsCachedFeature::allAttributesFetched() const
580{
581 return mAllAttributesFetched;
582}
583
584bool QgsVectorLayerCache::QgsCachedFeature::geometryFetched() const
585{
586 return mGeometryFetched;
587}
@ Fid
Filter using feature ID.
Definition qgis.h:2305
@ Fids
Filter using feature IDs.
Definition qgis.h:2307
@ Expression
Filter using expression.
Definition qgis.h:2306
@ NoFilter
No filter is applied.
Definition qgis.h:2304
@ SubsetOfAttributes
Fetch only a subset of attributes (setSubsetOfAttributes sets this flag).
Definition qgis.h:2277
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition qgis.h:2276
@ NoFlags
No flags are set.
Definition qgis.h:2275
@ NoFilter
No spatial filtering of features.
Definition qgis.h:2333
QFlags< FeatureRequestFlag > FeatureRequestFlags
Flags for controlling feature requests.
Definition qgis.h:2292
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:294
Abstract base class for cache indices.
Represents a coordinate reference system (CRS).
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 close()
Call to end the iteration.
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.
QgsRectangle filterRect() const
Returns the rectangle from which features will be taken.
Qgis::FeatureRequestFilterType filterType() const
Returns the attribute/ID filter type which is currently set on this request.
Qgis::FeatureRequestFlags flags() const
Returns the flags which affect how features are fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Qgis::SpatialFilterType spatialFilterType() const
Returns the spatial filter type which is currently set on this request.
QgsAttributeList subsetOfAttributes() const
Returns the subset of attributes which at least need to be fetched.
const QgsFeatureIds & filterFids() const
Returns the feature IDs that should be fetched.
QgsFeatureId filterFid() const
Returns the feature ID that should be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
QgsFeatureId id
Definition qgsfeature.h:68
bool isValid() const
Returns the validity of this feature.
Container of fields for a vector layer.
Definition qgsfields.h:46
QgsField field(int fieldIdx) const
Returns the field at particular index (must be in range 0..N-1).
A geometry is the spatial representation of a feature.
void dataChanged()
Data of layer changed.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
bool isFidCached(QgsFeatureId fid) const
Check if a certain feature id is cached.
void setFullCache(bool fullCache)
This enables or disables full caching.
void finished()
When filling the cache, this signal gets emitted once the cache is fully initialized.
void featureRemoved(QgsFeatureId fid)
Gets called, whenever a feature has been removed.
void setCacheAddedAttributes(bool cacheAddedAttributes)
If this is enabled, the subset of cached attributes will automatically be extended to also include ne...
void invalidated()
The cache has been invalidated and cleared.
void setCacheSize(int cacheSize)
Sets the maximum number of features to keep in the cache.
void setCacheSubsetOfAttributes(const QgsAttributeList &attributes)
Set the list (possibly a subset) of attributes to be cached.
void featureAdded(QgsFeatureId fid)
Emitted when a new feature has been added to the layer and this cache.
QgsFields fields() const
Returns the fields associated with features in the cache.
void cachedLayerDeleted()
Is emitted when the cached layer is deleted.
friend class QgsCachedFeatureWriterIterator
void requestCompleted(const QgsFeatureRequest &featureRequest, const QgsFeatureIds &fids)
Gets called, whenever the full list of feature ids for a certain request is known.
void attributeValueChanged(QgsFeatureId fid, int field, const QVariant &value)
Emitted when an attribute is changed.
bool removeCachedFeature(QgsFeatureId fid)
Removes the feature identified by fid from the cache if present.
void progress(int i, bool &cancel)
When filling the cache, this signal gets emitted periodically to notify about the progress and to be ...
QgsVectorLayer * layer()
Returns the layer to which this cache belongs.
long long featureCount() const
Returns the number of features contained in the source, or -1 if the feature count is unknown.
QgsCoordinateReferenceSystem sourceCrs() const
Returns the coordinate reference system for features in the cache.
bool checkInformationCovered(const QgsFeatureRequest &featureRequest)
Checks if the information required to complete the request is cached.
QgsFeatureIds cachedFeatureIds() const
Returns the set of feature IDs for features which are cached.
bool featureAtIdWithAllAttributes(QgsFeatureId featureId, QgsFeature &feature, bool skipCache=false)
Gets the feature at the given feature id with all attributes, if the cached feature already contains ...
bool cacheGeometry() const
Returns true if the cache will fetch and cache feature geometries.
Qgis::WkbType wkbType() const
Returns the geometry type for features in the cache.
int cacheSize()
Returns the maximum number of features this cache will hold.
friend class QgsCachedFeatureIterator
QgsAttributeList cacheSubsetOfAttributes() const
Returns the list (possibly a subset) of cached attributes.
void addCacheIndex(QgsAbstractCacheIndex *cacheIndex)
Adds a QgsAbstractCacheIndex to this cache.
QgsVectorLayerCache(QgsVectorLayer *layer, int cacheSize, QObject *parent=nullptr)
void setCacheGeometry(bool cacheGeometry)
Enable or disable the caching of geometries.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &featureRequest=QgsFeatureRequest())
Query this VectorLayerCache for features.
bool completeFeatureAtId(QgsFeatureId featureId, QgsFeature &feature, bool skipCache=false)
Gets the feature at the given feature id with all attributes and geometry, if the cached feature alre...
bool featureAtId(QgsFeatureId featureId, QgsFeature &feature, bool skipCache=false)
Gets the feature at the given feature id.
Defines left outer join from our vector layer to some other vector layer.
Represents a vector layer which manages a vector based dataset.
void attributeAdded(int idx)
Will be emitted, when a new attribute has been added to this vector layer.
void attributeDeleted(int idx)
Will be emitted, when an attribute has been deleted from this vector layer.
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &value)
Emitted whenever an attribute value change is done in the edit buffer.
void updatedFields()
Emitted whenever the fields available from this layer have been changed.
void featureAdded(QgsFeatureId fid)
Emitted when a new feature has been added to the layer.
void featureDeleted(QgsFeatureId fid)
Emitted when a feature has been deleted.
const QList< QgsVectorLayerJoinInfo > vectorJoins() const
void geometryChanged(QgsFeatureId fid, const QgsGeometry &geometry)
Emitted whenever a geometry change is done in the edit buffer.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QList< int > QgsAttributeList
Definition qgsfield.h:30