Skip to content

Commit fc339f9

Browse files
committed
Add a flag argument to QgsFeatureSink::addFeatures
Flags can be used to control how features are added to the sink. For now, there's only a single flag available - FastInsert. When FastInsert is set, faster inserts will be use at the cost of updating the passed features to reflect changes made at the provider. This includes skipping the update of the passed feature IDs to match the resulting feature IDs for the feature within the data provider. Individual sink subclasses may or may not choose to respect this flag, depending on whether or not skipping this update represents a significant speed boost for the operation. QgsVectorLayer always ignores the flag - feature ids are required for the featureAdded signal to be correctly emitted, and it's expected that performance critical applications will add features directly to a data provider instead of via QgsVectorLayer's edit buffer.
1 parent 7aec4d1 commit fc339f9

35 files changed

Lines changed: 210 additions & 141 deletions

‎python/core/qgsfeaturesink.sip‎

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,44 @@ class QgsFeatureSink
2222
%End
2323
public:
2424

25+
enum Flag
26+
{
27+
28+
FastInsert,
29+
};
30+
typedef QFlags<QgsFeatureSink::Flag> Flags;
31+
32+
2533
virtual ~QgsFeatureSink();
2634

27-
virtual bool addFeature( QgsFeature &feature );
35+
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
2836
%Docstring
29-
Adds a single ``feature`` to the sink.
37+
Adds a single ``feature`` to the sink. Feature addition behavior is controlled by the specified ``flags``.
3038
.. seealso:: addFeatures()
3139
:return: true in case of success and false in case of failure
3240
:rtype: bool
3341
%End
3442

35-
virtual bool addFeatures( QgsFeatureList &features ) = 0;
43+
virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) = 0;
3644
%Docstring
37-
Adds a list of ``features`` to the sink.
45+
Adds a list of ``features`` to the sink. Feature addition behavior is controlled by the specified ``flags``.
3846
.. seealso:: addFeature()
3947
:return: true in case of success and false in case of failure
4048
:rtype: bool
4149
%End
4250

43-
virtual bool addFeatures( QgsFeatureIterator &iterator );
51+
virtual bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = 0 );
4452
%Docstring
45-
Adds all features from the specified ``iterator`` to the sink.
53+
Adds all features from the specified ``iterator`` to the sink. Feature addition behavior is controlled by the specified ``flags``.
4654
:return: true if all features were added successfully, or false if any feature could not be added
4755
:rtype: bool
4856
%End
4957

5058
};
5159

60+
QFlags<QgsFeatureSink::Flag> operator|(QgsFeatureSink::Flag f1, QFlags<QgsFeatureSink::Flag> f2);
61+
62+
5263

5364
class QgsProxyFeatureSink : QgsFeatureSink
5465
{
@@ -73,9 +84,9 @@ class QgsProxyFeatureSink : QgsFeatureSink
7384
%Docstring
7485
Constructs a new QgsProxyFeatureSink which forwards features onto a destination ``sink``.
7586
%End
76-
virtual bool addFeature( QgsFeature &feature );
77-
virtual bool addFeatures( QgsFeatureList &features );
78-
virtual bool addFeatures( QgsFeatureIterator &iterator );
87+
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
88+
virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
89+
virtual bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = 0 );
7990
8091
QgsFeatureSink *destinationSink();
8192
%Docstring

‎python/core/qgsfeaturestore.sip‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ Constructor
5353
.. seealso:: crs()
5454
%End
5555
56-
virtual bool addFeature( QgsFeature &feature );
56+
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
5757
58-
virtual bool addFeatures( QgsFeatureList &features );
58+
virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
5959
6060
6161
int count() const;

‎python/core/qgsvectordataprovider.sip‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ Bitmask of all provider's editing capabilities
197197
\param enumList reference to the list to fill
198198
%End
199199

200-
virtual bool addFeatures( QgsFeatureList &flist /In,Out/ );
200+
virtual bool addFeatures( QgsFeatureList &flist /In,Out/, QgsFeatureSink::Flags flags = 0 );
201201

202202
virtual bool deleteFeatures( const QgsFeatureIds &id );
203203
%Docstring

‎python/core/qgsvectorfilewriter.sip‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,9 +522,9 @@ Retrieves error message
522522
:rtype: str
523523
%End
524524

525-
virtual bool addFeature( QgsFeature &feature );
525+
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
526526

527-
virtual bool addFeatures( QgsFeatureList &features );
527+
virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
528528

529529

530530
bool addFeature( QgsFeature &feature, QgsFeatureRenderer *renderer, QgsUnitTypes::DistanceUnit outputUnit = QgsUnitTypes::DistanceMeters );

‎python/core/qgsvectorlayer.sip‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,7 @@ Return the provider type for this layer
928928
:rtype: QgsFeatureIterator
929929
%End
930930
931-
virtual bool addFeature( QgsFeature &feature );
931+
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
932932
933933
934934
bool updateFeature( QgsFeature &f );
@@ -1281,7 +1281,7 @@ Delete an attribute field (but does not commit it)
12811281
:rtype: bool
12821282
%End
12831283

1284-
virtual bool addFeatures( QgsFeatureList &features );
1284+
virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
12851285

12861286

12871287
bool deleteFeature( QgsFeatureId fid );

‎python/core/qgsvectorlayerexporter.sip‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ class QgsVectorLayerExporter : QgsFeatureSink
114114
:rtype: int
115115
%End
116116

117-
virtual bool addFeatures( QgsFeatureList &features );
117+
virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
118118

119-
virtual bool addFeature( QgsFeature &feature );
119+
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
120120

121121

122122
~QgsVectorLayerExporter();

‎src/core/providers/memory/qgsmemoryprovider.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ QgsCoordinateReferenceSystem QgsMemoryProvider::crs() const
323323
}
324324

325325

326-
bool QgsMemoryProvider::addFeatures( QgsFeatureList &flist )
326+
bool QgsMemoryProvider::addFeatures( QgsFeatureList &flist, Flags )
327327
{
328328
// whether or not to update the layer extent on the fly as we add features
329329
bool updateExtent = mFeatures.isEmpty() || !mExtent.isEmpty();

‎src/core/providers/memory/qgsmemoryprovider.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class QgsMemoryProvider : public QgsVectorDataProvider
5050
virtual QgsWkbTypes::Type wkbType() const override;
5151
virtual long featureCount() const override;
5252
virtual QgsFields fields() const override;
53-
virtual bool addFeatures( QgsFeatureList &flist ) override;
53+
virtual bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
5454
virtual bool deleteFeatures( const QgsFeatureIds &id ) override;
5555
virtual bool addAttributes( const QList<QgsField> &attributes ) override;
5656
virtual bool renameAttributes( const QgsFieldNameMap &renamedAttributes ) override;

‎src/core/qgsfeaturesink.cpp‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,27 @@
1717

1818
#include "qgsfeaturestore.h"
1919

20-
bool QgsFeatureSink::addFeature( QgsFeature &feature )
20+
bool QgsFeatureSink::addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags )
2121
{
2222
QgsFeatureList features;
2323
features << feature;
24-
bool result = addFeatures( features );
24+
bool result = addFeatures( features, flags );
2525

26-
// need to update the passed feature reference to the updated copy from the features list
27-
feature = features.at( 0 );
26+
if ( !( flags & FastInsert ) )
27+
{
28+
// need to update the passed feature reference to the updated copy from the features list
29+
feature = features.at( 0 );
30+
}
2831
return result;
2932
}
3033

31-
bool QgsFeatureSink::addFeatures( QgsFeatureIterator &iterator )
34+
bool QgsFeatureSink::addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags )
3235
{
3336
QgsFeature f;
3437
bool result = true;
3538
while ( iterator.nextFeature( f ) )
3639
{
37-
result = result && addFeature( f );
40+
result = result && addFeature( f, flags );
3841
}
3942
return result;
4043
}

‎src/core/qgsfeaturesink.h‎

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,30 +34,47 @@ class CORE_EXPORT QgsFeatureSink
3434
{
3535
public:
3636

37+
//! Flags controlling how features are added to a sink.
38+
enum Flag
39+
{
40+
41+
/**
42+
* Use faster inserts, at the cost of updating the passed features to reflect changes made at the provider.
43+
* This includes skipping the update of the passed feature IDs to match the resulting feature IDs for the
44+
* feature within the data provider.
45+
* Individual sink subclasses may or may not choose to respect this flag, depending on whether or not
46+
* skipping this update represents a significant speed boost for the operation.
47+
*/
48+
FastInsert = 1 << 1,
49+
};
50+
Q_DECLARE_FLAGS( Flags, Flag )
51+
3752
virtual ~QgsFeatureSink() = default;
3853

3954
/**
40-
* Adds a single \a feature to the sink.
55+
* Adds a single \a feature to the sink. Feature addition behavior is controlled by the specified \a flags.
4156
* \see addFeatures()
4257
* \returns true in case of success and false in case of failure
4358
*/
44-
virtual bool addFeature( QgsFeature &feature );
59+
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
4560

4661
/**
47-
* Adds a list of \a features to the sink.
62+
* Adds a list of \a features to the sink. Feature addition behavior is controlled by the specified \a flags.
4863
* \see addFeature()
4964
* \returns true in case of success and false in case of failure
5065
*/
51-
virtual bool addFeatures( QgsFeatureList &features ) = 0;
66+
virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) = 0;
5267

5368
/**
54-
* Adds all features from the specified \a iterator to the sink.
69+
* Adds all features from the specified \a iterator to the sink. Feature addition behavior is controlled by the specified \a flags.
5570
* \returns true if all features were added successfully, or false if any feature could not be added
5671
*/
57-
virtual bool addFeatures( QgsFeatureIterator &iterator );
72+
virtual bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = 0 );
5873

5974
};
6075

76+
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsFeatureSink::Flags )
77+
6178

6279
/**
6380
* \class QgsProxyFeatureSink
@@ -80,9 +97,9 @@ class CORE_EXPORT QgsProxyFeatureSink : public QgsFeatureSink
8097
* Constructs a new QgsProxyFeatureSink which forwards features onto a destination \a sink.
8198
*/
8299
QgsProxyFeatureSink( QgsFeatureSink *sink );
83-
bool addFeature( QgsFeature &feature ) override { return mSink->addFeature( feature ); }
84-
bool addFeatures( QgsFeatureList &features ) override { return mSink->addFeatures( features ); }
85-
bool addFeatures( QgsFeatureIterator &iterator ) override { return mSink->addFeatures( iterator ); }
100+
bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 ) override { return mSink->addFeature( feature, flags ); }
101+
bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) override { return mSink->addFeatures( features, flags ); }
102+
bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = 0 ) override { return mSink->addFeatures( iterator, flags ); }
86103

87104
/**
88105
* Returns the destination QgsFeatureSink which the proxy will forward features to.

0 commit comments

Comments
 (0)