Skip to content

Commit

Permalink
Merge pull request #4734 from nyalldawson/addfeatures
Browse files Browse the repository at this point in the history
Add a flag argument to QgsFeatureSink::addFeatures, support fast feature insert
  • Loading branch information
nyalldawson committed Jun 22, 2017
2 parents e40f92c + ee04395 commit f196246
Show file tree
Hide file tree
Showing 41 changed files with 284 additions and 201 deletions.
2 changes: 2 additions & 0 deletions doc/api_break.dox
Expand Up @@ -2343,6 +2343,7 @@ QGIS 3.0 defaultValue() only returns literal, constant defaultValues. A new meth
has been added which returns the SQL clause fragments which must be evaluated by the provider itself.
- isSaveAndLoadStyleToDBSupported() was renamed to isSaveAndLoadStyleToDatabaseSupported()
- The c++ signature for uniqueValues() has changed (the PyQGIS method remains unchanged)
- addFeature and addFeatures now take an extra Flags argument dictating feature addition behavior


QgsVectorJoinInfo {#qgis_api_break_3_0_QgsVectorJoinInfo}
Expand Down Expand Up @@ -2472,6 +2473,7 @@ in code which previously passed a null pointer to QgsVectorFileWriter.
- writeAsVectorFormat() now takes a QgsCoordinateTransform reference, not a pointer. An invalid QgsCoordinateTransform should be used instead of a null pointer if no transformation is required.
- setSymbologyScaleDenominator() and symbologyScaleDenominator() were renamed to setSymbologyScale() and symbologyScale()
for consistency with other parts of the QGIS API.
- The addFeature which takes a renderer argument was renamed to addFeatureWithStyle.


QgsWMSLegendNode {#qgis_api_break_3_0_QgsWMSLegendNode}
Expand Down
29 changes: 20 additions & 9 deletions python/core/qgsfeaturesink.sip
Expand Up @@ -22,33 +22,44 @@ class QgsFeatureSink
%End
public:

enum Flag
{

FastInsert,
};
typedef QFlags<QgsFeatureSink::Flag> Flags;


virtual ~QgsFeatureSink();

virtual bool addFeature( QgsFeature &feature );
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
%Docstring
Adds a single ``feature`` to the sink.
Adds a single ``feature`` to the sink. Feature addition behavior is controlled by the specified ``flags``.
.. seealso:: addFeatures()
:return: true in case of success and false in case of failure
:rtype: bool
%End

virtual bool addFeatures( QgsFeatureList &features ) = 0;
virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) = 0;
%Docstring
Adds a list of ``features`` to the sink.
Adds a list of ``features`` to the sink. Feature addition behavior is controlled by the specified ``flags``.
.. seealso:: addFeature()
:return: true in case of success and false in case of failure
:rtype: bool
%End

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

};

QFlags<QgsFeatureSink::Flag> operator|(QgsFeatureSink::Flag f1, QFlags<QgsFeatureSink::Flag> f2);



class QgsProxyFeatureSink : QgsFeatureSink
{
Expand All @@ -73,9 +84,9 @@ class QgsProxyFeatureSink : QgsFeatureSink
%Docstring
Constructs a new QgsProxyFeatureSink which forwards features onto a destination ``sink``.
%End
virtual bool addFeature( QgsFeature &feature );
virtual bool addFeatures( QgsFeatureList &features );
virtual bool addFeatures( QgsFeatureIterator &iterator );
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
virtual bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = 0 );

QgsFeatureSink *destinationSink();
%Docstring
Expand Down
4 changes: 2 additions & 2 deletions python/core/qgsfeaturestore.sip
Expand Up @@ -53,9 +53,9 @@ Constructor
.. seealso:: crs()
%End

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

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


int count() const;
Expand Down
2 changes: 1 addition & 1 deletion python/core/qgsvectordataprovider.sip
Expand Up @@ -197,7 +197,7 @@ Bitmask of all provider's editing capabilities
\param enumList reference to the list to fill
%End

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

virtual bool deleteFeatures( const QgsFeatureIds &id );
%Docstring
Expand Down
9 changes: 5 additions & 4 deletions python/core/qgsvectorfilewriter.sip
Expand Up @@ -522,14 +522,15 @@ Retrieves error message
:rtype: str
%End

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

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


bool addFeature( QgsFeature &feature, QgsFeatureRenderer *renderer, QgsUnitTypes::DistanceUnit outputUnit = QgsUnitTypes::DistanceMeters );
bool addFeatureWithStyle( QgsFeature &feature, QgsFeatureRenderer *renderer, QgsUnitTypes::DistanceUnit outputUnit = QgsUnitTypes::DistanceMeters );
%Docstring
Add feature to the currently opened data source
Adds a ``feature`` to the currently opened data source, using the style from a specified ``renderer``.
.. versionadded:: 3.0
:rtype: bool
%End

Expand Down
4 changes: 2 additions & 2 deletions python/core/qgsvectorlayer.sip
Expand Up @@ -928,7 +928,7 @@ Return the provider type for this layer
:rtype: QgsFeatureIterator
%End

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


bool updateFeature( QgsFeature &f );
Expand Down Expand Up @@ -1281,7 +1281,7 @@ Delete an attribute field (but does not commit it)
:rtype: bool
%End

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


bool deleteFeature( QgsFeatureId fid );
Expand Down
4 changes: 2 additions & 2 deletions python/core/qgsvectorlayerexporter.sip
Expand Up @@ -114,9 +114,9 @@ class QgsVectorLayerExporter : QgsFeatureSink
:rtype: int
%End

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

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


~QgsVectorLayerExporter();
Expand Down
Empty file modified src/app/qgisapp.cpp 100644 → 100755
Empty file.
14 changes: 7 additions & 7 deletions src/core/processing/qgsnativealgorithms.cpp 100644 → 100755
Expand Up @@ -120,7 +120,7 @@ QVariantMap QgsCentroidAlgorithm::processAlgorithm( const QVariantMap &parameter
QgsMessageLog::logMessage( QObject::tr( "Error calculating centroid for feature %1" ).arg( f.id() ), QObject::tr( "Processing" ), QgsMessageLog::WARNING );
}
}
sink->addFeature( out );
sink->addFeature( out, QgsFeatureSink::FastInsert );

feedback->setProgress( current * step );
current++;
Expand Down Expand Up @@ -223,7 +223,7 @@ QVariantMap QgsBufferAlgorithm::processAlgorithm( const QVariantMap &parameters,
}

if ( !dissolve )
sink->addFeature( out );
sink->addFeature( out, QgsFeatureSink::FastInsert );

feedback->setProgress( current * step );
current++;
Expand All @@ -235,7 +235,7 @@ QVariantMap QgsBufferAlgorithm::processAlgorithm( const QVariantMap &parameters,
QgsFeature f;
f.setGeometry( finalGeometry );
f.setAttributes( dissolveAttrs );
sink->addFeature( f );
sink->addFeature( f, QgsFeatureSink::FastInsert );
}

QVariantMap outputs;
Expand Down Expand Up @@ -325,7 +325,7 @@ QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap &parameter
}

outputFeature.setGeometry( QgsGeometry::unaryUnion( geomQueue ) );
sink->addFeature( outputFeature );
sink->addFeature( outputFeature, QgsFeatureSink::FastInsert );
}
else
{
Expand Down Expand Up @@ -376,7 +376,7 @@ QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap &parameter
QgsFeature outputFeature;
outputFeature.setGeometry( QgsGeometry::unaryUnion( geomIt.value() ) );
outputFeature.setAttributes( attributeHash.value( geomIt.key() ) );
sink->addFeature( outputFeature );
sink->addFeature( outputFeature, QgsFeatureSink::FastInsert );

feedback->setProgress( current * 100.0 / numberFeatures );
current++;
Expand Down Expand Up @@ -519,7 +519,7 @@ QVariantMap QgsClipAlgorithm::processAlgorithm( const QVariantMap &parameters, Q
QgsFeature outputFeature;
outputFeature.setGeometry( newGeometry );
outputFeature.setAttributes( inputFeature.attributes() );
sink->addFeature( outputFeature );
sink->addFeature( outputFeature, QgsFeatureSink::FastInsert );


if ( singleClipFeature )
Expand Down Expand Up @@ -587,7 +587,7 @@ QVariantMap QgsTransformAlgorithm::processAlgorithm( const QVariantMap &paramete
break;
}

sink->addFeature( f );
sink->addFeature( f, QgsFeatureSink::FastInsert );
feedback->setProgress( current * step );
current++;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/providers/memory/qgsmemoryprovider.cpp
Expand Up @@ -323,7 +323,7 @@ QgsCoordinateReferenceSystem QgsMemoryProvider::crs() const
}


bool QgsMemoryProvider::addFeatures( QgsFeatureList &flist )
bool QgsMemoryProvider::addFeatures( QgsFeatureList &flist, Flags )
{
// whether or not to update the layer extent on the fly as we add features
bool updateExtent = mFeatures.isEmpty() || !mExtent.isEmpty();
Expand Down
2 changes: 1 addition & 1 deletion src/core/providers/memory/qgsmemoryprovider.h
Expand Up @@ -50,7 +50,7 @@ class QgsMemoryProvider : public QgsVectorDataProvider
virtual QgsWkbTypes::Type wkbType() const override;
virtual long featureCount() const override;
virtual QgsFields fields() const override;
virtual bool addFeatures( QgsFeatureList &flist ) override;
virtual bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
virtual bool deleteFeatures( const QgsFeatureIds &id ) override;
virtual bool addAttributes( const QList<QgsField> &attributes ) override;
virtual bool renameAttributes( const QgsFieldNameMap &renamedAttributes ) override;
Expand Down
15 changes: 9 additions & 6 deletions src/core/qgsfeaturesink.cpp
Expand Up @@ -17,24 +17,27 @@

#include "qgsfeaturestore.h"

bool QgsFeatureSink::addFeature( QgsFeature &feature )
bool QgsFeatureSink::addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags )
{
QgsFeatureList features;
features << feature;
bool result = addFeatures( features );
bool result = addFeatures( features, flags );

// need to update the passed feature reference to the updated copy from the features list
feature = features.at( 0 );
if ( !( flags & FastInsert ) )
{
// need to update the passed feature reference to the updated copy from the features list
feature = features.at( 0 );
}
return result;
}

bool QgsFeatureSink::addFeatures( QgsFeatureIterator &iterator )
bool QgsFeatureSink::addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags )
{
QgsFeature f;
bool result = true;
while ( iterator.nextFeature( f ) )
{
result = result && addFeature( f );
result = result && addFeature( f, flags );
}
return result;
}
Expand Down
35 changes: 26 additions & 9 deletions src/core/qgsfeaturesink.h
Expand Up @@ -34,30 +34,47 @@ class CORE_EXPORT QgsFeatureSink
{
public:

//! Flags controlling how features are added to a sink.
enum Flag
{

/**
* Use faster inserts, 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.
*/
FastInsert = 1 << 1,
};
Q_DECLARE_FLAGS( Flags, Flag )

virtual ~QgsFeatureSink() = default;

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

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

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

};

Q_DECLARE_OPERATORS_FOR_FLAGS( QgsFeatureSink::Flags )


/**
* \class QgsProxyFeatureSink
Expand All @@ -80,9 +97,9 @@ class CORE_EXPORT QgsProxyFeatureSink : public QgsFeatureSink
* Constructs a new QgsProxyFeatureSink which forwards features onto a destination \a sink.
*/
QgsProxyFeatureSink( QgsFeatureSink *sink );
bool addFeature( QgsFeature &feature ) override { return mSink->addFeature( feature ); }
bool addFeatures( QgsFeatureList &features ) override { return mSink->addFeatures( features ); }
bool addFeatures( QgsFeatureIterator &iterator ) override { return mSink->addFeatures( iterator ); }
bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 ) override { return mSink->addFeature( feature, flags ); }
bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) override { return mSink->addFeatures( features, flags ); }
bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = 0 ) override { return mSink->addFeatures( iterator, flags ); }

/**
* Returns the destination QgsFeatureSink which the proxy will forward features to.
Expand Down
6 changes: 3 additions & 3 deletions src/core/qgsfeaturestore.cpp
Expand Up @@ -35,20 +35,20 @@ void QgsFeatureStore::setFields( const QgsFields &fields )
}
}

bool QgsFeatureStore::addFeature( QgsFeature &feature )
bool QgsFeatureStore::addFeature( QgsFeature &feature, Flags )
{
QgsFeature f( feature );
f.setFields( mFields );
mFeatures.append( f );
return true;
}

bool QgsFeatureStore::addFeatures( QgsFeatureList &features )
bool QgsFeatureStore::addFeatures( QgsFeatureList &features, Flags flags )
{
QgsFeatureList::iterator fIt = features.begin();
for ( ; fIt != features.end(); ++fIt )
{
addFeature( *fIt );
addFeature( *fIt, flags );
}
return true;
}
4 changes: 2 additions & 2 deletions src/core/qgsfeaturestore.h
Expand Up @@ -61,8 +61,8 @@ class CORE_EXPORT QgsFeatureStore : public QgsFeatureSink
*/
void setCrs( const QgsCoordinateReferenceSystem &crs ) { mCrs = crs; }

bool addFeature( QgsFeature &feature ) override;
bool addFeatures( QgsFeatureList &features ) override;
bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 ) override;
bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) override;

/**
* Returns the number of features contained in the store.
Expand Down
3 changes: 2 additions & 1 deletion src/core/qgsvectordataprovider.cpp
Expand Up @@ -62,9 +62,10 @@ QString QgsVectorDataProvider::dataComment() const
return QString();
}

bool QgsVectorDataProvider::addFeatures( QgsFeatureList &flist )
bool QgsVectorDataProvider::addFeatures( QgsFeatureList &flist, Flags flags )
{
Q_UNUSED( flist );
Q_UNUSED( flags );
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectordataprovider.h
Expand Up @@ -224,7 +224,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
*/
virtual void enumValues( int index, QStringList &enumList SIP_OUT ) const { Q_UNUSED( index ); enumList.clear(); }

virtual bool addFeatures( QgsFeatureList &flist SIP_INOUT ) override;
virtual bool addFeatures( QgsFeatureList &flist SIP_INOUT, QgsFeatureSink::Flags flags = 0 ) override;

/**
* Deletes one or more features from the provider. This requires the DeleteFeatures capability.
Expand Down

0 comments on commit f196246

Please sign in to comment.