Skip to content
Permalink
Browse files

Merge pull request #4734 from nyalldawson/addfeatures

Add a flag argument to QgsFeatureSink::addFeatures, support fast feature insert
  • Loading branch information
nyalldawson committed Jun 22, 2017
2 parents e40f92c + ee04395 commit f1962468525b6117ae94c113f9ed7420dbaf2156
Showing with 284 additions and 201 deletions.
  1. +2 −0 doc/api_break.dox
  2. +20 −9 python/core/qgsfeaturesink.sip
  3. +2 −2 python/core/qgsfeaturestore.sip
  4. +1 −1 python/core/qgsvectordataprovider.sip
  5. +5 −4 python/core/qgsvectorfilewriter.sip
  6. +2 −2 python/core/qgsvectorlayer.sip
  7. +2 −2 python/core/qgsvectorlayerexporter.sip
  8. 0 src/app/qgisapp.cpp
  9. +7 −7 src/core/processing/qgsnativealgorithms.cpp
  10. +1 −1 src/core/providers/memory/qgsmemoryprovider.cpp
  11. +1 −1 src/core/providers/memory/qgsmemoryprovider.h
  12. +9 −6 src/core/qgsfeaturesink.cpp
  13. +26 −9 src/core/qgsfeaturesink.h
  14. +3 −3 src/core/qgsfeaturestore.cpp
  15. +2 −2 src/core/qgsfeaturestore.h
  16. +2 −1 src/core/qgsvectordataprovider.cpp
  17. +1 −1 src/core/qgsvectordataprovider.h
  18. +6 −6 src/core/qgsvectorfilewriter.cpp
  19. +7 −4 src/core/qgsvectorfilewriter.h
  20. +2 −2 src/core/qgsvectorlayer.cpp
  21. +2 −2 src/core/qgsvectorlayer.h
  22. +4 −4 src/core/qgsvectorlayerexporter.cpp
  23. +2 −2 src/core/qgsvectorlayerexporter.h
  24. +22 −19 src/providers/db2/qgsdb2provider.cpp
  25. +1 −1 src/providers/db2/qgsdb2provider.h
  26. +3 −3 src/providers/gpx/qgsgpxprovider.cpp
  27. +2 −2 src/providers/gpx/qgsgpxprovider.h
  28. +1 −1 src/providers/grass/qgsgrassprovider.h
  29. +21 −18 src/providers/mssql/qgsmssqlprovider.cpp
  30. +1 −1 src/providers/mssql/qgsmssqlprovider.h
  31. +4 −4 src/providers/ogr/qgsogrprovider.cpp
  32. +2 −2 src/providers/ogr/qgsogrprovider.h
  33. +39 −33 src/providers/oracle/qgsoracleprovider.cpp
  34. +1 −1 src/providers/oracle/qgsoracleprovider.h
  35. +35 −29 src/providers/postgres/qgspostgresprovider.cpp
  36. +1 −1 src/providers/postgres/qgspostgresprovider.h
  37. +5 −2 src/providers/spatialite/qgsspatialiteprovider.cpp
  38. +1 −1 src/providers/spatialite/qgsspatialiteprovider.h
  39. +14 −11 src/providers/wfs/qgswfsprovider.cpp
  40. +1 −1 src/providers/wfs/qgswfsprovider.h
  41. +21 −0 tests/src/python/providertestbase.py
@@ -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}
@@ -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}
@@ -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
{
@@ -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
@@ -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;
@@ -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
@@ -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

@@ -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 );
@@ -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 );
@@ -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();
0 src/app/qgisapp.cpp 100644 → 100755
Empty file.
@@ -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++;
@@ -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++;
@@ -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;
@@ -325,7 +325,7 @@ QVariantMap QgsDissolveAlgorithm::processAlgorithm( const QVariantMap &parameter
}

outputFeature.setGeometry( QgsGeometry::unaryUnion( geomQueue ) );
sink->addFeature( outputFeature );
sink->addFeature( outputFeature, QgsFeatureSink::FastInsert );
}
else
{
@@ -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++;
@@ -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 )
@@ -587,7 +587,7 @@ QVariantMap QgsTransformAlgorithm::processAlgorithm( const QVariantMap &paramete
break;
}

sink->addFeature( f );
sink->addFeature( f, QgsFeatureSink::FastInsert );
feedback->setProgress( current * step );
current++;
}
@@ -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();
@@ -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;
@@ -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;
}
@@ -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
@@ -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.
@@ -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;
}
@@ -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.
@@ -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;
}

@@ -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.

0 comments on commit f196246

Please sign in to comment.
You can’t perform that action at this time.