Skip to content

Commit

Permalink
Add a method to QgsFeatureSink to add all features from an iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Apr 26, 2017
1 parent e273ec7 commit dd7be73
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 0 deletions.
7 changes: 7 additions & 0 deletions python/core/qgsfeaturesink.sip
Expand Up @@ -40,6 +40,13 @@ class QgsFeatureSink
:rtype: bool
%End

virtual bool addFeatures( QgsFeatureIterator &iterator );
%Docstring
Adds all features from the specified ``iterator`` to the sink.
:return: true if all features were added successfully, or false if any feature could not be added
:rtype: bool
%End

};

/************************************************************************
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -136,6 +136,7 @@ SET(QGIS_CORE_SRCS
qgsfeature.cpp
qgsfeatureiterator.cpp
qgsfeaturerequest.cpp
qgsfeaturesink.cpp
qgsfeaturestore.cpp
qgsfield.cpp
qgsfieldconstraints.cpp
Expand Down
30 changes: 30 additions & 0 deletions src/core/qgsfeaturesink.cpp
@@ -0,0 +1,30 @@
/***************************************************************************
qgsfeaturesink.cpp
------------------
begin : April 2017
copyright : (C) 2017 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsfeaturestore.h"

bool QgsFeatureSink::addFeatures( QgsFeatureIterator &iterator )
{
QgsFeature f;
bool result = true;
while ( iterator.nextFeature( f ) )
{
result = result && addFeature( f );
}
return result;
}

7 changes: 7 additions & 0 deletions src/core/qgsfeaturesink.h
Expand Up @@ -21,6 +21,7 @@
#include "qgis_core.h"
#include "qgis.h"
#include "qgsfeature.h"
#include "qgsfeatureiterator.h"

/**
* \class QgsFeatureSink
Expand Down Expand Up @@ -49,6 +50,12 @@ class CORE_EXPORT QgsFeatureSink
*/
virtual bool addFeatures( QgsFeatureList &features ) = 0;

/**
* Adds all features from the specified \a iterator to the sink.
* \returns true if all features were added successfully, or false if any feature could not be added
*/
virtual bool addFeatures( QgsFeatureIterator &iterator );

};

#endif // QGSFEATURESINK_H
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Expand Up @@ -49,6 +49,7 @@ ADD_PYTHON_TEST(PyQgsEllipsoidUtils test_qgsellipsoidutils.py)
ADD_PYTHON_TEST(PyQgsExpression test_qgsexpression.py)
ADD_PYTHON_TEST(PyQgsExpressionLineEdit test_qgsexpressionlineedit.py)
ADD_PYTHON_TEST(PyQgsFeature test_qgsfeature.py)
ADD_PYTHON_TEST(PyQgsFeatureSink test_qgsfeaturesink.py)
ADD_PYTHON_TEST(PyQgsFieldFormattersTest test_qgsfieldformatters.py)
ADD_PYTHON_TEST(PyQgsFillSymbolLayers test_qgsfillsymbollayers.py)
ADD_PYTHON_TEST(PyQgsProject test_qgsproject.py)
Expand Down
67 changes: 67 additions & 0 deletions tests/src/python/test_qgsfeaturesink.py
@@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsFeatureSink.
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = '(C) 2017 by Nyall Dawson'
__date__ = '26/04/2017'
__copyright__ = 'Copyright 2017, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import qgis # NOQA

import os

from qgis.core import (QgsFeatureStore,
QgsVectorLayer,
QgsFeature,
QgsGeometry,
QgsPoint)
from qgis.testing import start_app, unittest
start_app()


def createLayerWithFivePoints():
layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
"addfeat", "memory")
pr = layer.dataProvider()
f = QgsFeature()
f.setAttributes(["test", 123])
f.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200)))
f2 = QgsFeature()
f2.setAttributes(["test2", 457])
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(200, 200)))
f3 = QgsFeature()
f3.setAttributes(["test2", 888])
f3.setGeometry(QgsGeometry.fromPoint(QgsPoint(300, 200)))
f4 = QgsFeature()
f4.setAttributes(["test3", -1])
f4.setGeometry(QgsGeometry.fromPoint(QgsPoint(400, 300)))
f5 = QgsFeature()
f5.setAttributes(["test4", 0])
f5.setGeometry(QgsGeometry.fromPoint(QgsPoint(0, 0)))
assert pr.addFeatures([f, f2, f3, f4, f5])
assert layer.featureCount() == 5
return layer


class TestQgsFeatureSink(unittest.TestCase):

def testFromIterator(self):
"""
Test adding features from an iterator
:return:
"""
layer = createLayerWithFivePoints()
store = QgsFeatureStore(layer.fields(), layer.crs())

self.assertTrue(store.addFeatures(layer.getFeatures()))
vals = [f['fldint'] for f in store.features()]
self.assertEqual(vals, [123, 457, 888, -1, 0])


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

0 comments on commit dd7be73

Please sign in to comment.