QGIS API Documentation 3.27.0-Master (a46f227e17)
qgsvectordataproviderfeaturepool.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectordataproviderfeaturepool.h
3 --------------------------------------
4Date : 3.9.2018
5Copyright : (C) 2018 by Matthias Kuhn
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17#include "qgsthreadingutils.h"
18
19#include "qgsfeaturerequest.h"
20
22 : QgsFeaturePool( layer )
23 , mSelectedOnly( selectedOnly )
24{
25 // Build spatial index
26 QgsFeature feature;
28 QgsFeatureIds featureIds;
29 if ( selectedOnly )
30 {
31 featureIds = layer->selectedFeatureIds();
32 req.setFilterFids( featureIds );
33 }
34
36 while ( it.nextFeature( feature ) )
37 {
38 if ( feature.hasGeometry() && !feature.geometry().isEmpty() )
39 {
40 insertFeature( feature );
41 featureIds.insert( feature.id() );
42 }
43 else
44 {
45 featureIds.remove( feature.id() );
46 }
47 }
48 setFeatureIds( featureIds );
49}
50
52{
53 Q_UNUSED( flags )
54 QgsFeatureList features;
55 features.append( feature );
56
57 bool res = false;
58
59 auto addFeatureSynchronized = [ this, &features, &res ]()
60 {
61 QgsVectorLayer *lyr = layer();
62 if ( lyr )
63 res = lyr->dataProvider()->addFeatures( features );
64 };
65
66 QgsThreadingUtils::runOnMainThread( addFeatureSynchronized );
67
68 if ( !res )
69 return false;
70
71 feature.setId( features.front().id() );
72 if ( mSelectedOnly )
73 {
74 QgsThreadingUtils::runOnMainThread( [ this, feature ]()
75 {
76 QgsVectorLayer *lyr = layer();
77 if ( lyr )
78 {
79 QgsFeatureIds selectedFeatureIds = lyr->selectedFeatureIds();
80 selectedFeatureIds.insert( feature.id() );
81 lyr->selectByIds( selectedFeatureIds );
82 }
83 } );
84 }
85
86 insertFeature( feature );
87
88 return res;
89}
90
91bool QgsVectorDataProviderFeaturePool::addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags )
92{
93 Q_UNUSED( flags )
94
95 bool res = false;
96
97 auto addFeatureSynchronized = [ this, &features, &res ]()
98 {
99 QgsVectorLayer *lyr = layer();
100 if ( lyr )
101 res = lyr->dataProvider()->addFeatures( features );
102 };
103
104 QgsThreadingUtils::runOnMainThread( addFeatureSynchronized );
105
106 if ( !res )
107 return false;
108
109 if ( mSelectedOnly )
110 {
111 QgsThreadingUtils::runOnMainThread( [ this, features ]()
112 {
113 QgsVectorLayer *lyr = layer();
114 if ( lyr )
115 {
116 QgsFeatureIds selectedFeatureIds = lyr->selectedFeatureIds();
117 for ( const QgsFeature &feature : std::as_const( features ) )
118 selectedFeatureIds.insert( feature.id() );
119 lyr->selectByIds( selectedFeatureIds );
120 }
121 } );
122 }
123
124 for ( const QgsFeature &feature : std::as_const( features ) )
125 insertFeature( feature );
126
127 return res;
128}
129
131{
132 QgsFeature origFeature;
133 getFeature( feature.id(), origFeature );
134
135 QgsGeometryMap geometryMap;
136 geometryMap.insert( feature.id(), feature.geometry() );
137 QgsChangedAttributesMap changedAttributesMap;
138 QgsAttributeMap attribMap;
139 for ( int i = 0, n = feature.attributes().size(); i < n; ++i )
140 {
141 attribMap.insert( i, feature.attributes().at( i ) );
142 }
143 changedAttributesMap.insert( feature.id(), attribMap );
144
145 QgsThreadingUtils::runOnMainThread( [this, geometryMap, changedAttributesMap]()
146 {
147 QgsVectorLayer *lyr = layer();
148 if ( lyr )
149 {
150 lyr->dataProvider()->changeGeometryValues( geometryMap );
151 lyr->dataProvider()->changeAttributeValues( changedAttributesMap );
152 }
153 } );
154
155 refreshCache( feature );
156}
157
159{
160 removeFeature( fid );
162 {
163 QgsVectorLayer *lyr = layer();
164 if ( lyr )
165 {
166 lyr->dataProvider()->deleteFeatures( QgsFeatureIds() << fid );
167 }
168 } );
169}
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
A feature pool is based on a vector layer and caches features.
void refreshCache(const QgsFeature &feature)
Changes a feature in the cache and the spatial index.
void insertFeature(const QgsFeature &feature, bool skipLock=false)
Inserts a feature into the cache and the spatial index.
void setFeatureIds(const QgsFeatureIds &ids)
Sets all the feature ids governed by this feature pool.
void removeFeature(const QgsFeatureId featureId)
Removes a feature from the cache and the spatial index.
QgsVectorLayer * layer() const
Gets a pointer to the underlying layer.
bool getFeature(QgsFeatureId id, QgsFeature &feature)
Retrieves the feature with the specified id into feature.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsAttributes attributes
Definition: qgsfeature.h:65
void setId(QgsFeatureId id)
Sets the feature id for this feature.
Definition: qgsfeature.cpp:122
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
static bool runOnMainThread(const Func &func, QgsFeedback *feedback=nullptr)
Guarantees that func is executed on the main thread.
void deleteFeature(QgsFeatureId fid) override
Removes a feature from this pool.
void updateFeature(QgsFeature &feature) override
Updates a feature in this pool.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a single feature to the sink.
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
QgsVectorDataProviderFeaturePool(QgsVectorLayer *layer, bool selectedOnly=false)
Creates a new feature pool for the data provider of layer.
virtual bool changeGeometryValues(const QgsGeometryMap &geometry_map)
Changes geometries of existing features.
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
virtual bool deleteFeatures(const QgsFeatureIds &id)
Deletes one or more features from the provider.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
Represents a vector layer which manages a vector based data sets.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Q_INVOKABLE void selectByIds(const QgsFeatureIds &ids, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection)
Selects matching features using a list of feature IDs.
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:42
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:917
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:908
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:922
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28