QGIS API Documentation  3.15.0-Master (4fe3d2f4e6)
qgsvectordataproviderfeaturepool.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectordataproviderfeaturepool.h
3  --------------------------------------
4 Date : 3.9.2018
5 Copyright : (C) 2018 by Matthias Kuhn
6 email : [email protected]
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 
35  QgsFeatureIterator it = layer->getFeatures( req );
36  while ( it.nextFeature( feature ) )
37  {
38  if ( feature.hasGeometry() )
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 
91 bool 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 : qgis::as_const( features ) )
118  selectedFeatureIds.insert( feature.id() );
119  lyr->selectByIds( selectedFeatureIds );
120  }
121  } );
122  }
123 
124  for ( const QgsFeature &feature : qgis::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 }
QgsFeatureId id
Definition: qgsfeature.h:64
Wrapper for iterator of features from vector data provider or vector layer.
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:567
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:572
virtual bool deleteFeatures(const QgsFeatureIds &id)
Deletes one or more features from the provider.
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features ...
Definition: qgsfeatureid.h:28
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a single feature to the sink.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
QgsVectorLayer * layer() const
Gets a pointer to the underlying layer.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
bool getFeature(QgsFeatureId id, QgsFeature &feature)
Retrieves the feature with the specified id into feature.
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
void refreshCache(const QgsFeature &feature)
Changes a feature in the cache and the spatial index.
void updateFeature(QgsFeature &feature) override
Updates a feature in this pool.
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:38
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void setId(QgsFeatureId id)
Sets the feature ID for this feature.
Definition: qgsfeature.cpp:112
virtual bool changeGeometryValues(const QgsGeometryMap &geometry_map)
Changes geometries of existing features.
static bool runOnMainThread(const Func &func, QgsFeedback *feedback=nullptr)
Guarantees that func is executed on the main thread.
void insertFeature(const QgsFeature &feature, bool skipLock=false)
Inserts a feature into the cache and the spatial index.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets feature IDs that should be fetched.
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:558
A feature pool is based on a vector layer and caches features.
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
void setFeatureIds(const QgsFeatureIds &ids)
Sets all the feature ids governed by this feature pool.
Q_INVOKABLE void selectByIds(const QgsFeatureIds &ids, QgsVectorLayer::SelectBehavior behavior=QgsVectorLayer::SetSelection)
Selects matching features using a list of feature IDs.
void deleteFeature(QgsFeatureId fid) override
Removes a feature from this pool.
QgsVectorDataProviderFeaturePool(QgsVectorLayer *layer, bool selectedOnly=false)
Creates a new feature pool for the data provider of layer.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsGeometry geometry
Definition: qgsfeature.h:67
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer&#39;s data provider, it may be nullptr.
bool nextFeature(QgsFeature &f)
Represents a vector layer which manages a vector based data sets.
void removeFeature(const QgsFeatureId featureId)
Removes a feature from the cache and the spatial index.
QgsAttributes attributes
Definition: qgsfeature.h:65