QGIS API Documentation 3.43.0-Master (3ee7834ace6)
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#include "moc_qgsvectorlayercache.cpp"
20#include "qgscacheindex.h"
24#include "qgsvectorlayer.h"
25
26#include <QElapsedTimer>
27
28QgsVectorLayerCache::QgsVectorLayerCache( QgsVectorLayer *layer, int cacheSize, QObject *parent )
29 : QObject( parent )
30 , mLayer( layer )
31{
32 mCache.setMaxCost( cacheSize );
33
34 connect( mLayer, &QgsVectorLayer::featureDeleted, this, &QgsVectorLayerCache::featureDeleted );
35 connect( mLayer, &QgsVectorLayer::featureAdded, this, &QgsVectorLayerCache::onFeatureAdded );
36 connect( mLayer, &QgsVectorLayer::destroyed, this, &QgsVectorLayerCache::layerDeleted );
37
38 setCacheGeometry( true );
41
42 connect( mLayer, &QgsVectorLayer::attributeDeleted, this, &QgsVectorLayerCache::attributeDeleted );
43 connect( mLayer, &QgsVectorLayer::updatedFields, this, &QgsVectorLayerCache::invalidate );
44 connect( mLayer, &QgsVectorLayer::dataChanged, this, &QgsVectorLayerCache::invalidate );
45 connect( mLayer, &QgsVectorLayer::attributeValueChanged, this, &QgsVectorLayerCache::onAttributeValueChanged );
46
47 connectJoinedLayers();
48}
49
51{
52 qDeleteAll( mCacheIndices );
53 mCacheIndices.clear();
54}
55
57{
58 mCache.setMaxCost( cacheSize );
59}
60
62{
63 return mCache.maxCost();
64}
65
66void QgsVectorLayerCache::setCacheGeometry( bool cacheGeometry )
67{
68 bool shouldCacheGeometry = cacheGeometry && mLayer->isSpatial();
69 bool mustInvalidate = shouldCacheGeometry && !mCacheGeometry; // going from no geometry -> geometry, so have to clear existing cache entries
70 mCacheGeometry = shouldCacheGeometry;
71 if ( cacheGeometry )
72 {
73 connect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsVectorLayerCache::geometryChanged, Qt::UniqueConnection );
74 }
75 else
76 {
77 disconnect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsVectorLayerCache::geometryChanged );
78 }
79 if ( mustInvalidate )
80 {
81 invalidate();
82 }
83}
84
86{
87 if ( ! mCache.isEmpty() && ! QSet<int>( mCachedAttributes.cbegin(), mCachedAttributes.cend() )
88 .contains( QSet<int>( attributes.cbegin(), attributes.cend( ) ) ) )
89 invalidate();
90 mCachedAttributes = attributes;
91}
92
94{
95 return mCachedAttributes;
96}
97
99{
100 mFullCache = fullCache;
101
102 if ( mFullCache )
103 {
104 // Add a little more than necessary...
105 setCacheSize( mLayer->featureCount() + 100 );
106
107 // Initialize the cache...
109 .setSubsetOfAttributes( mCachedAttributes )
111
112 int i = 0;
113
114 QElapsedTimer t;
115 t.start();
116
117 QgsFeature f;
118 while ( it.nextFeature( f ) )
119 {
120 ++i;
121
122 if ( t.elapsed() > 1000 )
123 {
124 bool cancel = false;
125 emit progress( i, cancel );
126 if ( cancel )
127 break;
128
129 t.restart();
130 }
131 }
132
133 it.close();
134
135 emit finished();
136 }
137}
138
140{
141 mCacheIndices.append( cacheIndex );
142}
143
144void QgsVectorLayerCache::setCacheAddedAttributes( bool cacheAddedAttributes )
145{
146 if ( cacheAddedAttributes )
147 {
148 connect( mLayer, &QgsVectorLayer::attributeAdded, this, &QgsVectorLayerCache::attributeAdded );
149 }
150 else
151 {
152 disconnect( mLayer, &QgsVectorLayer::attributeAdded, this, &QgsVectorLayerCache::attributeAdded );
153 }
154}
155
156bool QgsVectorLayerCache::featureAtId( QgsFeatureId featureId, QgsFeature &feature, bool skipCache )
157{
158 bool featureFound = false;
159
160 QgsCachedFeature *cachedFeature = nullptr;
161
162 if ( !skipCache )
163 {
164 cachedFeature = mCache[ featureId ];
165 }
166
167 if ( cachedFeature )
168 {
169 feature = QgsFeature( *cachedFeature->feature() );
170 featureFound = true;
171 }
172 else
173 {
174 QgsFeatureRequest request { featureId };
175 const bool allAttrsFetched { mCachedAttributes.count( ) == mLayer->fields().count() };
176 if ( ! allAttrsFetched )
177 {
178 request.setSubsetOfAttributes( mCachedAttributes );
179 }
180 if ( !mCacheGeometry )
181 {
182 request.setFlags( request.flags().setFlag( Qgis::FeatureRequestFlag::NoGeometry ) );
183 }
184 if ( mLayer->getFeatures( request ).nextFeature( feature ) )
185 {
186 cacheFeature( feature, allAttrsFetched );
187 featureFound = true;
188 }
189 }
190
191 return featureFound;
192}
193
195{
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()
212 .setFilterFid( featureId )
213 .setFlags( !mCacheGeometry ? Qgis::FeatureRequestFlag::NoGeometry : Qgis::FeatureRequestFlags() ) )
214 .nextFeature( feature ) )
215 {
216 cacheFeature( feature, true );
217 featureFound = true;
218 }
219
220 return featureFound;
221}
222
223bool QgsVectorLayerCache::completeFeatureAtId( QgsFeatureId featureId, QgsFeature &feature, bool skipCache )
224{
225 bool featureFound = false;
226
227 QgsCachedFeature *cachedFeature = nullptr;
228
229 if ( !skipCache )
230 {
231 cachedFeature = mCache[ featureId ];
232 }
233
234 if ( cachedFeature && cachedFeature->allAttributesFetched() && cachedFeature->geometryFetched() )
235 {
236 feature = QgsFeature( *cachedFeature->feature() );
237 featureFound = true;
238 }
239 else if ( mLayer->getFeatures( QgsFeatureRequest()
240 .setFilterFid( featureId ) )
241 .nextFeature( feature ) )
242 {
243 cacheFeature( feature, true, true );
244 featureFound = true;
245 }
246
247 return featureFound;
248}
249
251{
252 bool removed = mCache.remove( fid );
253 if ( removed )
254 {
255 if ( auto unorderedIt = std::find( mCacheUnorderedKeys.begin(), mCacheUnorderedKeys.end(), fid ); unorderedIt != mCacheUnorderedKeys.end() )
256 {
257 mCacheUnorderedKeys.erase( unorderedIt );
258
259 if ( auto orderedIt = std::find( mCacheOrderedKeys.begin(), mCacheOrderedKeys.end(), fid ); orderedIt != mCacheOrderedKeys.end() )
260 mCacheOrderedKeys.erase( orderedIt );
261 }
262 }
263 return removed;
264}
265
267{
268 return mLayer;
269}
270
275
277{
278 return mLayer->wkbType();
279}
280
282{
283 return mLayer->fields();
284}
285
287{
288 return mLayer->featureCount();
289}
290
292{
293 // If a request is too large for the cache don't notify to prevent from indexing incomplete requests
294 if ( fids.count() <= mCache.size() )
295 {
296 for ( const auto &idx : std::as_const( mCacheIndices ) )
297 {
298 idx->requestCompleted( featureRequest, fids );
299 }
300 if ( featureRequest.filterType() == Qgis::FeatureRequestFilterType::NoFilter &&
301 ( featureRequest.spatialFilterType() == Qgis::SpatialFilterType::NoFilter || featureRequest.filterRect().contains( mLayer->extent() ) ) )
302 {
303 mFullCache = true;
304 }
305 }
306}
307
309{
310 const auto constMCacheIndices = mCacheIndices;
311 for ( QgsAbstractCacheIndex *idx : constMCacheIndices )
312 {
313 idx->flushFeature( fid );
314 }
315}
316
317void QgsVectorLayerCache::onAttributeValueChanged( QgsFeatureId fid, int field, const QVariant &value )
318{
319 QgsCachedFeature *cachedFeat = mCache[ fid ];
320
321 if ( cachedFeat )
322 {
323 cachedFeat->mFeature->setAttribute( field, value );
324 }
325
326 emit attributeValueChanged( fid, field, value );
327}
328
329void QgsVectorLayerCache::onJoinAttributeValueChanged( QgsFeatureId fid, int field, const QVariant &value )
330{
331 const QgsVectorLayer *joinLayer = qobject_cast<const QgsVectorLayer *>( sender() );
332
333 const auto constVectorJoins = mLayer->vectorJoins();
334 for ( const QgsVectorLayerJoinInfo &info : constVectorJoins )
335 {
336 if ( joinLayer == info.joinLayer() )
337 {
338 const QgsFeature feature = mLayer->joinBuffer()->targetedFeatureOf( &info, joinLayer->getFeature( fid ) );
339
340 const QString fieldName = info.prefixedFieldName( joinLayer->fields().field( field ) );
341 const int fieldIndex = mLayer->fields().indexFromName( fieldName );
342
343 if ( feature.isValid() && fieldIndex != -1 )
344 {
345 onAttributeValueChanged( feature.id(), fieldIndex, value );
346 return;
347 }
348 }
349 }
350}
351
352void QgsVectorLayerCache::featureDeleted( QgsFeatureId fid )
353{
354 mCache.remove( fid );
355
356 if ( auto it = mCacheUnorderedKeys.find( fid ); it != mCacheUnorderedKeys.end() )
357 {
358 mCacheUnorderedKeys.erase( it );
359 if ( auto orderedIt = std::find( mCacheOrderedKeys.begin(), mCacheOrderedKeys.end(), fid ); orderedIt != mCacheOrderedKeys.end() )
360 mCacheOrderedKeys.erase( orderedIt );
361 }
362}
363
364void QgsVectorLayerCache::onFeatureAdded( QgsFeatureId fid )
365{
366 if ( mFullCache )
367 {
368 if ( cacheSize() <= mLayer->featureCount() )
369 {
370 setCacheSize( mLayer->featureCount() + 100 );
371 }
372
373 QgsFeature feat;
374 featureAtId( fid, feat );
375 }
376 emit featureAdded( fid );
377}
378
379void QgsVectorLayerCache::attributeAdded( int field )
380{
381 Q_UNUSED( field )
382 mCachedAttributes.append( field );
383 invalidate();
384}
385
386void QgsVectorLayerCache::attributeDeleted( int field )
387{
388 const QgsAttributeList attrs = mCachedAttributes;
389 mCachedAttributes.clear();
390
391 for ( int attr : attrs )
392 {
393 if ( attr < field )
394 mCachedAttributes << attr;
395 else if ( attr > field )
396 mCachedAttributes << attr - 1;
397 }
398}
399
400void QgsVectorLayerCache::geometryChanged( QgsFeatureId fid, const QgsGeometry &geom )
401{
402 QgsCachedFeature *cachedFeat = mCache[ fid ];
403
404 if ( cachedFeat )
405 {
406 cachedFeat->mFeature->setGeometry( geom );
407 }
408}
409
410void QgsVectorLayerCache::layerDeleted()
411{
412 emit cachedLayerDeleted();
413 mLayer = nullptr;
414}
415
416void QgsVectorLayerCache::invalidate()
417{
418 if ( ! mCache.isEmpty() )
419 {
420 mCache.clear();
421 mCacheOrderedKeys.clear();
422 mCacheUnorderedKeys.clear();
423 mFullCache = false;
424 emit invalidated();
425 }
426}
427
428bool QgsVectorLayerCache::canUseCacheForRequest( const QgsFeatureRequest &featureRequest, QgsFeatureIterator &it )
429{
430 // check first for available indices
431 const auto constMCacheIndices = mCacheIndices;
432 for ( QgsAbstractCacheIndex *idx : constMCacheIndices )
433 {
434 if ( idx->getCacheIterator( it, featureRequest ) )
435 {
436 return true;
437 }
438 }
439
440 // no indexes available, but maybe we have already cached all required features anyway?
441 switch ( featureRequest.filterType() )
442 {
444 {
445 if ( mCache.contains( featureRequest.filterFid() ) )
446 {
447 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
448 return true;
449 }
450 break;
451 }
453 {
454 if ( cachedFeatureIds().contains( featureRequest.filterFids() ) )
455 {
456 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
457 return true;
458 }
459 break;
460 }
463 {
464 if ( mFullCache )
465 {
466 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
467 return true;
468 }
469 break;
470 }
471
472 }
473 return false;
474}
475
477{
479 bool requiresWriterIt = true; // If a not yet cached, but cacheable request is made, this stays true.
480
481 if ( checkInformationCovered( featureRequest ) )
482 {
483 // If we have a full cache available, run on this
484 if ( mFullCache )
485 {
486 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
487 requiresWriterIt = false;
488 }
489 else
490 {
491 // may still be able to satisfy request using cache
492 requiresWriterIt = !canUseCacheForRequest( featureRequest, it );
493 }
494 }
495 else
496 {
497 // Let the layer answer the request, so no caching of requests
498 // we don't want to cache is done
499 requiresWriterIt = false;
500 it = mLayer->getFeatures( featureRequest );
501 }
502
503 if ( requiresWriterIt && mLayer->dataProvider() )
504 {
505 // No index was able to satisfy the request
506 QgsFeatureRequest myRequest = QgsFeatureRequest( featureRequest );
507
508 // Make sure if we cache the geometry, it gets fetched
509 if ( mCacheGeometry && mLayer->isSpatial() )
510 myRequest.setFlags( featureRequest.flags() & ~( static_cast< int >( Qgis::FeatureRequestFlag::NoGeometry ) ) );
511
512 // Make sure all the cached attributes are requested as well if requesting a subset
513 if ( myRequest.flags().testFlag( Qgis::FeatureRequestFlag::SubsetOfAttributes ) )
514 {
515 if ( mCachedAttributes.count( ) != mLayer->fields().count() )
516 {
517 const QgsAttributeList requestSubset = featureRequest.subsetOfAttributes();
518 QSet<int> attrs( requestSubset.begin(), requestSubset.end() );
519 for ( int attr : std::as_const( mCachedAttributes ) )
520 attrs.insert( attr );
521 myRequest.setSubsetOfAttributes( attrs.values() );
522 }
523 else // we are already caching all attributes
524 {
526 myRequest.setFlags( myRequest.flags().setFlag( Qgis::FeatureRequestFlag::SubsetOfAttributes, false ) );
527 }
528 }
529
530 it = QgsFeatureIterator( new QgsCachedFeatureWriterIterator( this, myRequest ) );
531 }
532
533 return it;
534}
535
537{
538 return mCache.contains( fid );
539}
540
542{
543 const QList< QgsFeatureId > keys = mCache.keys();
544 return QgsFeatureIds( keys.begin(), keys.end() );
545}
546
548{
549 QgsAttributeList requestedAttributes;
550
551 if ( !featureRequest.flags().testFlag( Qgis::FeatureRequestFlag::SubsetOfAttributes ) )
552 {
553 requestedAttributes = mLayer->attributeList();
554 }
555 else
556 {
557 requestedAttributes = featureRequest.subsetOfAttributes();
558 }
559
560 // Check if we even cache the information requested
561 const auto constRequestedAttributes = requestedAttributes;
562 for ( int attr : constRequestedAttributes )
563 {
564 if ( !mCachedAttributes.contains( attr ) )
565 {
566 return false;
567 }
568 }
569
570 // If the request needs geometry but we don't cache this...
571 return !( !featureRequest.flags().testFlag( Qgis::FeatureRequestFlag::NoGeometry )
572 && !mCacheGeometry );
573}
574
575void QgsVectorLayerCache::connectJoinedLayers() const
576{
577 const auto constVectorJoins = mLayer->vectorJoins();
578 for ( const QgsVectorLayerJoinInfo &info : constVectorJoins )
579 {
580 const QgsVectorLayer *vl = info.joinLayer();
581 if ( vl )
582 connect( vl, &QgsVectorLayer::attributeValueChanged, this, &QgsVectorLayerCache::onJoinAttributeValueChanged );
583 }
584}
585
586bool QgsVectorLayerCache::QgsCachedFeature::allAttributesFetched() const
587{
588 return mAllAttributesFetched;
589}
590
591bool QgsVectorLayerCache::QgsCachedFeature::geometryFetched() const
592{
593 return mGeometryFetched;
594}
@ Fid
Filter using feature ID.
@ Fids
Filter using feature IDs.
@ Expression
Filter using expression.
@ NoFilter
No filter is applied.
@ 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.
@ NoFlags
No flags are set.
@ NoFilter
No spatial filtering of features.
QFlags< FeatureRequestFlag > FeatureRequestFlags
Flags for controlling feature requests.
Definition qgis.h:2161
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:256
Abstract base class for cache indices.
This class 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.
This class 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:58
QgsFeatureId id
Definition qgsfeature.h:66
bool isValid() const
Returns the validity of this feature.
Container of fields for a vector layer.
Definition qgsfields.h:46
int count
Definition qgsfields.h:50
Q_INVOKABLE int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
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.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:83
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.
QgsFeature targetedFeatureOf(const QgsVectorLayerJoinInfo *info, const QgsFeature &feature) const
Returns the targeted feature corresponding to the joined feature.
Defines left outer join from our vector layer to some other vector layer.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsAttributeList attributeList() const
Returns list of attribute indexes.
void attributeAdded(int idx)
Will be emitted, when a new attribute has been added to this vector layer.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Q_INVOKABLE Qgis::WkbType wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
void attributeDeleted(int idx)
Will be emitted, when an attribute has been deleted from this vector layer.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
QgsVectorLayerJoinBuffer * joinBuffer()
Returns the join buffer object.
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &value)
Emitted whenever an attribute value change is done in the edit buffer.
QgsRectangle extent() const FINAL
Returns the extent of the layer.
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:27