QGIS API Documentation 4.3.0-Master (91d4a333d5d)
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 "qgsthreadingutils.h"
23#include "qgsvectorlayer.h"
26
27#include <QElapsedTimer>
28
29#include "moc_qgsvectorlayercache.cpp"
30
32 : QObject( parent )
33 , mLayer( layer )
34{
36
37 mCache.setMaxCost( cacheSize );
38
39 connect( mLayer, &QgsVectorLayer::featureDeleted, this, &QgsVectorLayerCache::onFeatureDeleted );
40 connect( mLayer, &QgsVectorLayer::featureAdded, this, &QgsVectorLayerCache::onFeatureAdded );
41 connect( mLayer, &QgsVectorLayer::destroyed, this, &QgsVectorLayerCache::layerDeleted );
42
43 setCacheGeometry( true );
44 setCacheSubsetOfAttributes( mLayer->attributeList() );
46
47 connect( mLayer, &QgsVectorLayer::attributeDeleted, this, &QgsVectorLayerCache::attributeDeleted );
48 connect( mLayer, &QgsVectorLayer::updatedFields, this, &QgsVectorLayerCache::invalidate );
49 connect( mLayer, &QgsVectorLayer::dataChanged, this, &QgsVectorLayerCache::invalidate );
50 connect( mLayer, &QgsVectorLayer::attributeValueChanged, this, &QgsVectorLayerCache::onAttributeValueChanged );
51
52 connectJoinedLayers();
53}
54
56{
57 qDeleteAll( mCacheIndices );
58 mCacheIndices.clear();
59}
60
62{
64
65 mCache.setMaxCost( cacheSize );
66}
67
69{
71
72 return mCache.maxCost();
73}
74
76{
78
79 bool shouldCacheGeometry = cacheGeometry && mLayer->isSpatial();
80 bool mustInvalidate = shouldCacheGeometry && !mCacheGeometry; // going from no geometry -> geometry, so have to clear existing cache entries
81 mCacheGeometry = shouldCacheGeometry;
82 if ( cacheGeometry )
83 {
84 connect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsVectorLayerCache::geometryChanged, Qt::UniqueConnection );
85 }
86 else
87 {
88 disconnect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsVectorLayerCache::geometryChanged );
89 }
90 if ( mustInvalidate )
91 {
92 invalidate();
93 }
94}
95
97{
99
100 if ( !mCache.isEmpty() && !QSet<int>( mCachedAttributes.cbegin(), mCachedAttributes.cend() ).contains( QSet<int>( attributes.cbegin(), attributes.cend() ) ) )
101 invalidate();
102 mCachedAttributes = attributes;
103}
104
111
113{
115
116 mFullCache = fullCache;
117
118 if ( mFullCache )
119 {
120 // Add a little more than necessary...
121 setCacheSize( mLayer->featureCount() + 100 );
122
123 // Initialize the cache...
125 new QgsCachedFeatureWriterIterator( this, QgsFeatureRequest().setSubsetOfAttributes( mCachedAttributes ).setFlags( mCacheGeometry ? Qgis::FeatureRequestFlag::NoFlags : Qgis::FeatureRequestFlag::NoGeometry ) )
126 );
127
128 int i = 0;
129
130 QElapsedTimer t;
131 t.start();
132
133 QgsFeature f;
134 while ( it.nextFeature( f ) )
135 {
136 ++i;
137
138 if ( t.elapsed() > 1000 )
139 {
140 bool cancel = false;
141 emit progress( i, cancel );
142 if ( cancel )
143 break;
144
145 t.restart();
146 }
147 }
148
149 it.close();
150
151 emit finished();
152 }
153}
154
156{
158
159 mCacheIndices.append( cacheIndex );
160}
161
162void QgsVectorLayerCache::setCacheAddedAttributes( bool cacheAddedAttributes )
163{
165
166 if ( cacheAddedAttributes == mCacheAddedAttributes )
167 return;
168
169 mCacheAddedAttributes = cacheAddedAttributes;
170 if ( mCacheAddedAttributes )
171 {
172 connect( mLayer, &QgsVectorLayer::attributeAdded, this, &QgsVectorLayerCache::attributeAdded );
173 }
174 else
175 {
176 disconnect( mLayer, &QgsVectorLayer::attributeAdded, this, &QgsVectorLayerCache::attributeAdded );
177 }
178}
179
180bool QgsVectorLayerCache::featureAtId( QgsFeatureId featureId, QgsFeature &feature, bool skipCache )
181{
183
184 bool featureFound = false;
185
186 QgsCachedFeature *cachedFeature = nullptr;
187
188 if ( !skipCache )
189 {
190 cachedFeature = mCache[featureId];
191 }
192
193 if ( cachedFeature )
194 {
195 feature = cachedFeature->feature();
196 featureFound = true;
197 }
198 else
199 {
200 QgsFeatureRequest request { featureId };
201 const bool allAttrsFetched { mCachedAttributes.count() == mLayer->fields().count() };
202 if ( !allAttrsFetched )
203 {
204 request.setSubsetOfAttributes( mCachedAttributes );
205 }
206 if ( !mCacheGeometry )
207 {
208 request.setFlags( request.flags().setFlag( Qgis::FeatureRequestFlag::NoGeometry ) );
209 }
210 if ( mLayer->getFeatures( request ).nextFeature( feature ) )
211 {
212 cacheFeature( feature, allAttrsFetched );
213 featureFound = true;
214 }
215 }
216
217 return featureFound;
218}
219
221{
223
224 bool featureFound = false;
225
226 QgsCachedFeature *cachedFeature = nullptr;
227
228 if ( !skipCache )
229 {
230 cachedFeature = mCache[featureId];
231 }
232
233 if ( cachedFeature && cachedFeature->allAttributesFetched() )
234 {
235 feature = cachedFeature->feature();
236 featureFound = true;
237 }
238 else if ( mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setFlags( !mCacheGeometry ? Qgis::FeatureRequestFlag::NoGeometry : Qgis::FeatureRequestFlags() ) ).nextFeature( feature ) )
239 {
240 cacheFeature( feature, true );
241 featureFound = true;
242 }
243
244 return featureFound;
245}
246
247bool QgsVectorLayerCache::completeFeatureAtId( QgsFeatureId featureId, QgsFeature &feature, bool skipCache )
248{
250
251 bool featureFound = false;
252
253 QgsCachedFeature *cachedFeature = nullptr;
254
255 if ( !skipCache )
256 {
257 cachedFeature = mCache[featureId];
258 }
259
260 if ( cachedFeature && cachedFeature->allAttributesFetched() && cachedFeature->geometryFetched() )
261 {
262 feature = cachedFeature->feature();
263 featureFound = true;
264 }
265 else if ( mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ) ).nextFeature( feature ) )
266 {
267 cacheFeature( feature, true, true );
268 featureFound = true;
269 }
270
271 return featureFound;
272}
273
275{
277
278 bool removed = mCache.remove( fid );
279 if ( removed )
280 {
281 if ( auto unorderedIt = std::find( mCacheUnorderedKeys.begin(), mCacheUnorderedKeys.end(), fid ); unorderedIt != mCacheUnorderedKeys.end() )
282 {
283 mCacheUnorderedKeys.erase( unorderedIt );
284
285 if ( auto orderedIt = std::find( mCacheOrderedKeys.begin(), mCacheOrderedKeys.end(), fid ); orderedIt != mCacheOrderedKeys.end() )
286 mCacheOrderedKeys.erase( orderedIt );
287 }
288 }
289 return removed;
290}
291
298
305
307{
309
310 return mLayer->wkbType();
311}
312
314{
316
317 return mLayer->fields();
318}
319
321{
323
324 return mLayer->featureCount();
325}
326
328{
330
331 // If a request is too large for the cache don't notify to prevent from indexing incomplete requests
332 if ( fids.count() <= mCache.maxCost() )
333 {
334 for ( const auto &idx : std::as_const( mCacheIndices ) )
335 {
336 idx->requestCompleted( featureRequest, fids );
337 }
339 && ( featureRequest.spatialFilterType() == Qgis::SpatialFilterType::NoFilter || featureRequest.filterRect().contains( mLayer->extent() ) ) )
340 {
341 mFullCache = true;
342 }
343 }
344}
345
347{
349
350 const auto constMCacheIndices = mCacheIndices;
351 for ( QgsAbstractCacheIndex *idx : constMCacheIndices )
352 {
353 idx->flushFeature( fid );
354 }
355}
356
357void QgsVectorLayerCache::onAttributeValueChanged( QgsFeatureId fid, int field, const QVariant &value )
358{
360
361 QgsCachedFeature *cachedFeat = mCache[fid];
362
363 if ( cachedFeat )
364 {
365 cachedFeat->mFeature.setAttribute( field, value );
366 }
367
368 emit attributeValueChanged( fid, field, value );
369}
370
371void QgsVectorLayerCache::onJoinAttributeValueChanged( QgsFeatureId fid, int field, const QVariant &value )
372{
374
375 const QgsVectorLayer *joinLayer = qobject_cast<const QgsVectorLayer *>( sender() );
376
377 const auto constVectorJoins = mLayer->vectorJoins();
378 for ( const QgsVectorLayerJoinInfo &info : constVectorJoins )
379 {
380 if ( joinLayer == info.joinLayer() )
381 {
382 const QgsFeature feature = mLayer->joinBuffer()->targetedFeatureOf( &info, joinLayer->getFeature( fid ) );
383
384 const QString fieldName = info.prefixedFieldName( joinLayer->fields().field( field ) );
385 const int fieldIndex = mLayer->fields().indexFromName( fieldName );
386
387 if ( feature.isValid() && fieldIndex != -1 )
388 {
389 onAttributeValueChanged( feature.id(), fieldIndex, value );
390 return;
391 }
392 }
393 }
394}
395
396void QgsVectorLayerCache::onFeatureDeleted( QgsFeatureId fid )
397{
399
400 emit featureAboutToBeDeleted( fid );
401 mCache.remove( fid );
402
403 if ( auto it = mCacheUnorderedKeys.find( fid ); it != mCacheUnorderedKeys.end() )
404 {
405 mCacheUnorderedKeys.erase( it );
406 if ( auto orderedIt = std::find( mCacheOrderedKeys.begin(), mCacheOrderedKeys.end(), fid ); orderedIt != mCacheOrderedKeys.end() )
407 mCacheOrderedKeys.erase( orderedIt );
408 }
409 emit featureDeleted( fid );
410}
411
412void QgsVectorLayerCache::onFeatureAdded( QgsFeatureId fid )
413{
415
416 emit featureAboutToBeAdded( fid );
417
418 if ( mFullCache )
419 {
420 if ( cacheSize() <= mLayer->featureCount() )
421 {
422 setCacheSize( mLayer->featureCount() + 100 );
423 }
424
425 QgsFeature feat;
426 featureAtId( fid, feat );
427 }
428 emit featureAdded( fid );
429}
430
431void QgsVectorLayerCache::attributeAdded( int field )
432{
434
435 if ( !mCachedAttributes.contains( field ) )
436 {
437 mCachedAttributes.append( field );
438 }
439 invalidate();
440}
441
442void QgsVectorLayerCache::attributeDeleted( int field )
443{
445
446 const QgsAttributeList attrs = mCachedAttributes;
447 mCachedAttributes.clear();
448
449 for ( int attr : attrs )
450 {
451 if ( attr < field )
452 mCachedAttributes << attr;
453 else if ( attr > field )
454 mCachedAttributes << attr - 1;
455 }
456 invalidate();
457}
458
459void QgsVectorLayerCache::geometryChanged( QgsFeatureId fid, const QgsGeometry &geom )
460{
462
463 QgsCachedFeature *cachedFeat = mCache[fid];
464
465 if ( cachedFeat )
466 {
467 cachedFeat->mFeature.setGeometry( geom );
468 }
469}
470
471void QgsVectorLayerCache::layerDeleted()
472{
474
475 emit cachedLayerDeleted();
476 mLayer = nullptr;
477}
478
479void QgsVectorLayerCache::invalidate()
480{
482
483 if ( !mCache.isEmpty() )
484 {
485 mCache.clear();
486 mCacheOrderedKeys.clear();
487 mCacheUnorderedKeys.clear();
488 mFullCache = false;
489 emit invalidated();
490 }
491}
492
493bool QgsVectorLayerCache::canUseCacheForRequest( const QgsFeatureRequest &featureRequest, QgsFeatureIterator &it )
494{
496
497 // check first for available indices
498 const auto constMCacheIndices = mCacheIndices;
499 for ( QgsAbstractCacheIndex *idx : constMCacheIndices )
500 {
501 if ( idx->getCacheIterator( it, featureRequest ) )
502 {
503 return true;
504 }
505 }
506
507 // no indexes available, but maybe we have already cached all required features anyway?
508 switch ( featureRequest.filterType() )
509 {
511 {
512 if ( mCache.contains( featureRequest.filterFid() ) )
513 {
514 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
515 return true;
516 }
517 break;
518 }
520 {
521 if ( cachedFeatureIds().contains( featureRequest.filterFids() ) )
522 {
523 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
524 return true;
525 }
526 break;
527 }
530 {
531 if ( mFullCache )
532 {
533 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
534 return true;
535 }
536 break;
537 }
538 }
539 return false;
540}
541
543{
545
547 bool requiresWriterIt = true; // If a not yet cached, but cacheable request is made, this stays true.
548
549 if ( checkInformationCovered( featureRequest ) )
550 {
551 // If we have a full cache available, run on this
552 if ( mFullCache )
553 {
554 it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
555 requiresWriterIt = false;
556 }
557 else
558 {
559 // may still be able to satisfy request using cache
560 requiresWriterIt = !canUseCacheForRequest( featureRequest, it );
561 }
562 }
563 else
564 {
565 // Let the layer answer the request, so no caching of requests
566 // we don't want to cache is done
567 requiresWriterIt = false;
568 it = mLayer->getFeatures( featureRequest );
569 }
570
571 if ( requiresWriterIt && mLayer->dataProvider() )
572 {
573 // No index was able to satisfy the request
574 QgsFeatureRequest myRequest = QgsFeatureRequest( featureRequest );
575
576 // Make sure if we cache the geometry, it gets fetched
577 if ( mCacheGeometry && mLayer->isSpatial() )
578 myRequest.setFlags( featureRequest.flags() & ~( static_cast< int >( Qgis::FeatureRequestFlag::NoGeometry ) ) );
579
580 // Make sure all the cached attributes are requested as well if requesting a subset
581 if ( myRequest.flags().testFlag( Qgis::FeatureRequestFlag::SubsetOfAttributes ) )
582 {
583 if ( mCachedAttributes.count() != mLayer->fields().count() )
584 {
585 const QgsAttributeList requestSubset = featureRequest.subsetOfAttributes();
586 QSet<int> attrs( requestSubset.begin(), requestSubset.end() );
587 for ( int attr : std::as_const( mCachedAttributes ) )
588 attrs.insert( attr );
589 myRequest.setSubsetOfAttributes( attrs.values() );
590 }
591 else // we are already caching all attributes
592 {
594 myRequest.setFlags( myRequest.flags().setFlag( Qgis::FeatureRequestFlag::SubsetOfAttributes, false ) );
595 }
596 }
597
598 it = QgsFeatureIterator( new QgsCachedFeatureWriterIterator( this, myRequest ) );
599 }
600
601 return it;
602}
603
605{
607
608 return mCache.contains( fid );
609}
610
612{
614
615 const QList< QgsFeatureId > keys = mCache.keys();
616 return QgsFeatureIds( keys.begin(), keys.end() );
617}
618
620{
622
623 QgsAttributeList requestedAttributes;
624
625 if ( !featureRequest.flags().testFlag( Qgis::FeatureRequestFlag::SubsetOfAttributes ) )
626 {
627 requestedAttributes = mLayer->attributeList();
628 }
629 else
630 {
631 requestedAttributes = featureRequest.subsetOfAttributes();
632 }
633
634 // Check if we even cache the information requested
635 const auto constRequestedAttributes = requestedAttributes;
636 for ( int attr : constRequestedAttributes )
637 {
638 if ( !mCachedAttributes.contains( attr ) )
639 {
640 return false;
641 }
642 }
643
644 // If the request needs geometry but we don't cache this...
645 return !( !featureRequest.flags().testFlag( Qgis::FeatureRequestFlag::NoGeometry ) && !mCacheGeometry );
646}
647
648void QgsVectorLayerCache::connectJoinedLayers() const
649{
651
652 const auto constVectorJoins = mLayer->vectorJoins();
653 for ( const QgsVectorLayerJoinInfo &info : constVectorJoins )
654 {
655 const QgsVectorLayer *vl = info.joinLayer();
656 if ( vl )
657 connect( vl, &QgsVectorLayer::attributeValueChanged, this, &QgsVectorLayerCache::onJoinAttributeValueChanged );
658 }
659}
660
661bool QgsVectorLayerCache::QgsCachedFeature::allAttributesFetched() const
662{
663 return mAllAttributesFetched;
664}
665
666bool QgsVectorLayerCache::QgsCachedFeature::geometryFetched() const
667{
668 return mGeometryFetched;
669}
@ Fid
Filter using feature ID.
Definition qgis.h:2409
@ Fids
Filter using feature IDs.
Definition qgis.h:2411
@ Expression
Filter using expression.
Definition qgis.h:2410
@ NoFilter
No filter is applied.
Definition qgis.h:2408
@ SubsetOfAttributes
Fetch only a subset of attributes (setSubsetOfAttributes sets this flag).
Definition qgis.h:2381
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition qgis.h:2380
@ NoFlags
No flags are set.
Definition qgis.h:2379
@ NoFilter
No spatial filtering of features.
Definition qgis.h:2437
QFlags< FeatureRequestFlag > FeatureRequestFlags
Flags for controlling feature requests.
Definition qgis.h:2396
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:314
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:63
bool isValid() const
Returns the validity of this feature.
Container of fields for a vector layer.
Definition qgsfields.h:45
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 featureAboutToBeAdded(QgsFeatureId fid)
Emitted when a new feature is about to be added to the cache (as a result of feature addition to the ...
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 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.
void featureDeleted(QgsFeatureId fid)
Emitted when a feature has been deleted from the layer and this cache.
QgsFields fields() const
Returns the fields associated with features in the cache.
void setCacheSize(long long cacheSize)
Sets the maximum number of features to keep 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.
void featureAboutToBeDeleted(QgsFeatureId fid)
Emitted when a feature is about to be deleted from this cache (as a result of a feature deletion from...
friend class QgsCachedFeatureIterator
long long cacheSize() const
Returns the maximum number of features this cache will hold.
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.
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
#define QGIS_CHECK_QOBJECT_THREAD_EQUALITY(other)
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS