Skip to content

Commit

Permalink
Merge pull request #4491 from nyalldawson/proxy_sink
Browse files Browse the repository at this point in the history
Add QgsProxyFeatureSink
  • Loading branch information
nyalldawson committed May 3, 2017
2 parents a87e8d1 + e40cb07 commit 32ff092
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 1 deletion.
37 changes: 37 additions & 0 deletions python/core/qgsfeaturesink.sip
Expand Up @@ -49,6 +49,43 @@ class QgsFeatureSink

};


class QgsProxyFeatureSink : QgsFeatureSink
{
%Docstring
A simple feature sink which proxies feature addition on to another feature sink.

This class is designed to allow factory methods which always return new QgsFeatureSink
objects. Since it is not always possible to create an entirely new QgsFeatureSink
(e.g. if the feature sink is a layer's data provider), a new QgsProxyFeatureSink
can instead be returned which forwards features on to the destination sink. The
proxy sink can be safely deleted without affecting the destination sink.

.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgsfeaturesink.h"
%End
public:

QgsProxyFeatureSink( QgsFeatureSink *sink );
%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 );

QgsFeatureSink *destinationSink();
%Docstring
Returns the destination QgsFeatureSink which the proxy will forward features to.
:rtype: QgsFeatureSink
%End

};


/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
16 changes: 16 additions & 0 deletions python/core/qgsfeaturestore.sip
Expand Up @@ -58,6 +58,22 @@ Constructor
virtual bool addFeatures( QgsFeatureList &features );


int count() const;
%Docstring
Returns the number of features contained in the store.
:rtype: int
%End


int __len__() const;
%Docstring
Returns the number of features contained in the store.
:rtype: int
%End
%MethodCode
sipRes = sipCpp->count();
%End

QgsFeatureList features() const;
%Docstring
Returns the list of features contained in the store.
Expand Down
4 changes: 4 additions & 0 deletions src/core/qgsfeaturesink.cpp
Expand Up @@ -39,3 +39,7 @@ bool QgsFeatureSink::addFeatures( QgsFeatureIterator &iterator )
return result;
}


QgsProxyFeatureSink::QgsProxyFeatureSink( QgsFeatureSink *sink )
: mSink( sink )
{}
37 changes: 37 additions & 0 deletions src/core/qgsfeaturesink.h
Expand Up @@ -58,4 +58,41 @@ class CORE_EXPORT QgsFeatureSink

};


/**
* \class QgsProxyFeatureSink
* \ingroup core
* A simple feature sink which proxies feature addition on to another feature sink.
*
* This class is designed to allow factory methods which always return new QgsFeatureSink
* objects. Since it is not always possible to create an entirely new QgsFeatureSink
* (e.g. if the feature sink is a layer's data provider), a new QgsProxyFeatureSink
* can instead be returned which forwards features on to the destination sink. The
* proxy sink can be safely deleted without affecting the destination sink.
*
* \since QGIS 3.0
*/
class CORE_EXPORT QgsProxyFeatureSink : public QgsFeatureSink
{
public:

/**
* 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 ); }

/**
* Returns the destination QgsFeatureSink which the proxy will forward features to.
*/
QgsFeatureSink *destinationSink() { return mSink; }

private:

QgsFeatureSink *mSink;
};


#endif // QGSFEATURESINK_H
16 changes: 16 additions & 0 deletions src/core/qgsfeaturestore.h
Expand Up @@ -64,6 +64,22 @@ class CORE_EXPORT QgsFeatureStore : public QgsFeatureSink
bool addFeature( QgsFeature &feature ) override;
bool addFeatures( QgsFeatureList &features ) override;

/**
* Returns the number of features contained in the store.
*/
int count() const { return mFeatures.size(); }

#ifdef SIP_RUN

/**
* Returns the number of features contained in the store.
*/
int __len__() const;
% MethodCode
sipRes = sipCpp->count();
% End
#endif

/**
* Returns the list of features contained in the store.
*/
Expand Down
36 changes: 35 additions & 1 deletion tests/src/python/test_qgsfeaturesink.py
Expand Up @@ -19,7 +19,12 @@
QgsVectorLayer,
QgsFeature,
QgsGeometry,
QgsPoint)
QgsPoint,
QgsField,
QgsFields,
QgsCoordinateReferenceSystem,
QgsProxyFeatureSink)
from qgis.PyQt.QtCore import QVariant
from qgis.testing import start_app, unittest
start_app()

Expand Down Expand Up @@ -62,6 +67,35 @@ def testFromIterator(self):
vals = [f['fldint'] for f in store.features()]
self.assertEqual(vals, [123, 457, 888, -1, 0])

def testProxyFeatureSink(self):
fields = QgsFields()
fields.append(QgsField('fldtxt', QVariant.String))
fields.append(QgsField('fldint', QVariant.Int))

store = QgsFeatureStore(fields, QgsCoordinateReferenceSystem())
proxy = QgsProxyFeatureSink(store)
self.assertEqual(proxy.destinationSink(), store)

self.assertEqual(len(store), 0)

f = QgsFeature()
f.setAttributes(["test", 123])
f.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200)))
proxy.addFeature(f)
self.assertEqual(len(store), 1)
self.assertEqual(store.features()[0]['fldtxt'], 'test')

f2 = QgsFeature()
f2.setAttributes(["test2", 457])
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(200, 200)))
f3 = QgsFeature()
f3.setAttributes(["test3", 888])
f3.setGeometry(QgsGeometry.fromPoint(QgsPoint(300, 200)))
proxy.addFeatures([f2, f3])
self.assertEqual(len(store), 3)
self.assertEqual(store.features()[1]['fldtxt'], 'test2')
self.assertEqual(store.features()[2]['fldtxt'], 'test3')


if __name__ == '__main__':
unittest.main()

0 comments on commit 32ff092

Please sign in to comment.