Skip to content

Commit 19dbd66

Browse files
authoredJul 13, 2016
Merge pull request #3305 from nyalldawson/processing_get_features
[processing] Allow modification of feature request when using vector.features
2 parents f34c79c + 9e1ddcb commit 19dbd66

File tree

3 files changed

+101
-10
lines changed

3 files changed

+101
-10
lines changed
 

‎python/plugins/processing/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ PLUGIN_INSTALL(processing tests/data ${TEST_DATA_FILES})
77
IF(ENABLE_TESTS)
88
INCLUDE(UsePythonTest)
99
ADD_PYTHON_TEST(ProcessingParametersTest ParametersTest.py)
10+
ADD_PYTHON_TEST(ProcessingToolsTest ToolsTest.py)
1011
ADD_PYTHON_TEST(ProcessingQgisAlgorithmsTest QgisAlgorithmsTest.py)
1112
ADD_PYTHON_TEST(ProcessingGdalAlgorithmsTest GdalAlgorithmsTest.py)
1213
ADD_PYTHON_TEST(ProcessingGrass7AlgorithmsImageryTest Grass7AlgorithmsImageryTest.py)
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
***************************************************************************
5+
ToolsTest
6+
---------------------
7+
Date : July 2017
8+
Copyright : (C) 2017 by Nyall Dawson
9+
Email : nyall dot dawson at gmail dot com
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************
18+
"""
19+
20+
__author__ = 'Nyall Dawson'
21+
__date__ = 'July 2016'
22+
__copyright__ = '(C) 2016, Nyall Dawson'
23+
24+
# This will get replaced with a git SHA1 when you do a git archive
25+
26+
__revision__ = '$Format:%H$'
27+
28+
from qgis.testing import start_app, unittest
29+
from processing.tests.TestData import points2
30+
from processing.tools import vector
31+
from qgis.core import (QgsVectorLayer, QgsFeatureRequest)
32+
from processing.core.ProcessingConfig import ProcessingConfig
33+
34+
start_app()
35+
36+
37+
class VectorTest(unittest.TestCase):
38+
39+
def testFeatures(self):
40+
ProcessingConfig.initialize()
41+
42+
test_data = points2()
43+
test_layer = QgsVectorLayer(test_data, 'test', 'ogr')
44+
45+
# test with all features
46+
features = vector.features(test_layer)
47+
self.assertEqual(len(features), 8)
48+
self.assertEqual(set([f.id() for f in features]), set([0, 1, 2, 3, 4, 5, 6, 7]))
49+
50+
# test with selected features
51+
previous_value = ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED)
52+
ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, True)
53+
test_layer.selectByIds([2, 4, 6])
54+
features = vector.features(test_layer)
55+
self.assertEqual(len(features), 3)
56+
self.assertEqual(set([f.id() for f in features]), set([2, 4, 6]))
57+
58+
# selection, but not using selected features
59+
ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, False)
60+
test_layer.selectByIds([2, 4, 6])
61+
features = vector.features(test_layer)
62+
self.assertEqual(len(features), 8)
63+
self.assertEqual(set([f.id() for f in features]), set([0, 1, 2, 3, 4, 5, 6, 7]))
64+
65+
# using selected features, but no selection
66+
ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, True)
67+
test_layer.removeSelection()
68+
features = vector.features(test_layer)
69+
self.assertEqual(len(features), 8)
70+
self.assertEqual(set([f.id() for f in features]), set([0, 1, 2, 3, 4, 5, 6, 7]))
71+
72+
# test that feature request is honored
73+
ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, False)
74+
features = vector.features(test_layer, QgsFeatureRequest().setFilterFids([1, 3, 5]))
75+
self.assertEqual(set([f.id() for f in features]), set([1, 3, 5]))
76+
77+
# test that feature request is honored when using selections
78+
ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, True)
79+
test_layer.selectByIds([2, 4, 6])
80+
features = vector.features(test_layer, QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry))
81+
self.assertTrue(all([f.geometry() == None for f in features]))
82+
features = vector.features(test_layer, QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry))
83+
self.assertEqual(set([f.id() for f in features]), set([2, 4, 6]))
84+
85+
ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, previous_value)
86+
87+
88+
if __name__ == '__main__':
89+
unittest.main()

‎python/plugins/processing/tools/vector.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
from qgis.PyQt.QtCore import QVariant, QSettings
3838
from qgis.core import (QGis, QgsFields, QgsField, QgsGeometry, QgsRectangle,
3939
QgsSpatialIndex, QgsMapLayerRegistry, QgsMapLayer, QgsVectorLayer,
40-
QgsVectorFileWriter, QgsDistanceArea, QgsDataSourceURI, QgsCredentials)
40+
QgsVectorFileWriter, QgsDistanceArea, QgsDataSourceURI, QgsCredentials,
41+
QgsFeatureRequest)
4142

4243
from processing.core.ProcessingConfig import ProcessingConfig
4344
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
@@ -86,7 +87,7 @@
8687
}
8788

8889

89-
def features(layer):
90+
def features(layer, request=QgsFeatureRequest()):
9091
"""This returns an iterator over features in a vector layer,
9192
considering the selection that might exist in the layer, and the
9293
configuration that indicates whether to use only selected feature
@@ -97,15 +98,15 @@ def features(layer):
9798
"""
9899
class Features:
99100

100-
def __init__(self, layer):
101+
def __init__(self, layer, request):
101102
self.layer = layer
102103
self.selection = False
103-
self.iter = layer.getFeatures()
104-
if ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED):
105-
selected = layer.selectedFeatures()
106-
if len(selected) > 0:
107-
self.selection = True
108-
self.iter = iter(selected)
104+
if ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED)\
105+
and layer.selectedFeatureCount() > 0:
106+
self.iter = layer.selectedFeaturesIterator(request)
107+
self.selection = True
108+
else:
109+
self.iter = layer.getFeatures(request)
109110

110111
def __iter__(self):
111112
return self.iter
@@ -116,7 +117,7 @@ def __len__(self):
116117
else:
117118
return int(self.layer.featureCount())
118119

119-
return Features(layer)
120+
return Features(layer, request)
120121

121122

122123
def uniqueValues(layer, attribute):

0 commit comments

Comments
 (0)
Please sign in to comment.