Skip to content

Commit f208191

Browse files
authoredSep 20, 2018
Merge pull request #7946 from elpaso/bugfix-19617-processing-checkvalidity
Fix processing algorithm checkvalidity reason
2 parents b62048d + 82a5c8f commit f208191

File tree

3 files changed

+136
-3
lines changed

3 files changed

+136
-3
lines changed
 

‎python/plugins/processing/algs/qgis/CheckValidity.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,6 @@ def doCheck(self, method, parameters, context, feedback):
157157
if not geom.isNull() and not geom.isEmpty():
158158
errors = list(geom.validateGeometry(method))
159159
if errors:
160-
# QGIS method return a summary at the end
161-
if method == 1:
162-
errors.pop()
163160
valid = False
164161
reasons = []
165162
for error in errors:

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ IF(ENABLE_TESTS)
1717
ADD_PYTHON_TEST(ProcessingGrass7AlgorithmsRasterTest Grass7AlgorithmsRasterTest.py)
1818
ADD_PYTHON_TEST(ProcessingGrass7AlgorithmsVectorTest Grass7AlgorithmsVectorTest.py)
1919
ADD_PYTHON_TEST(ProcessingSagaAlgorithmsTest SagaAlgorithmsTest.py)
20+
ADD_PYTHON_TEST(ProcessingCheckValidityAlgorithmTest CheckValidityAlgorithm.py)
2021
ENDIF(ENABLE_TESTS)
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# -*- coding: utf-8 -*-
2+
"""QGIS Unit tests for Processing CheckValidity algorithm.
3+
4+
.. note:: This program is free software; you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation; either version 2 of the License, or
7+
(at your option) any later version.
8+
"""
9+
__author__ = 'Alessandro Pasotti'
10+
__date__ = '2018-09'
11+
__copyright__ = 'Copyright 2018, The QGIS Project'
12+
# This will get replaced with a git SHA1 when you do a git archive
13+
__revision__ = '$Format:%H$'
14+
15+
from qgis.PyQt.QtCore import QCoreApplication, QVariant
16+
from qgis.core import (
17+
QgsFeature,
18+
QgsGeometry,
19+
QgsApplication,
20+
QgsMemoryProviderUtils,
21+
QgsWkbTypes,
22+
QgsField,
23+
QgsFields,
24+
QgsProcessingContext,
25+
QgsProcessingFeedback,
26+
QgsCoordinateReferenceSystem,
27+
QgsProject,
28+
QgsProcessingException,
29+
QgsProcessingUtils,
30+
QgsSettings
31+
)
32+
from processing.core.Processing import Processing
33+
from processing.gui.AlgorithmExecutor import execute
34+
from qgis.testing import start_app, unittest
35+
from qgis.PyQt.QtTest import QSignalSpy
36+
from qgis.analysis import QgsNativeAlgorithms
37+
38+
start_app()
39+
40+
41+
class ConsoleFeedBack(QgsProcessingFeedback):
42+
43+
def reportError(self, error, fatalError=False):
44+
print(error)
45+
46+
47+
class TestQgsProcessingCheckValidity(unittest.TestCase):
48+
49+
@classmethod
50+
def setUpClass(cls):
51+
"""Run before all tests"""
52+
QCoreApplication.setOrganizationName("QGIS_Test")
53+
QCoreApplication.setOrganizationDomain(
54+
"QGIS_TestPyQgsProcessingCheckValidity.com")
55+
QCoreApplication.setApplicationName(
56+
"QGIS_TestPyQgsProcessingCheckValidity")
57+
QgsSettings().clear()
58+
Processing.initialize()
59+
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
60+
cls.registry = QgsApplication.instance().processingRegistry()
61+
62+
def _make_layer(self, layer_wkb_name):
63+
fields = QgsFields()
64+
wkb_type = getattr(QgsWkbTypes, layer_wkb_name)
65+
fields.append(QgsField('int_f', QVariant.Int))
66+
layer = QgsMemoryProviderUtils.createMemoryLayer(
67+
'%s_layer' % layer_wkb_name, fields, wkb_type, QgsCoordinateReferenceSystem(4326))
68+
self.assertTrue(layer.isValid())
69+
self.assertEqual(layer.wkbType(), wkb_type)
70+
return layer
71+
72+
def test_check_validity(self):
73+
"""Test that the output invalid contains the error reason"""
74+
75+
polygon_layer = self._make_layer('Polygon')
76+
self.assertTrue(polygon_layer.startEditing())
77+
f = QgsFeature(polygon_layer.fields())
78+
f.setAttributes([1])
79+
# Flake!
80+
f.setGeometry(QgsGeometry.fromWkt(
81+
'POLYGON ((0 0, 2 2, 0 2, 2 0, 0 0))'))
82+
self.assertTrue(f.isValid())
83+
f2 = QgsFeature(polygon_layer.fields())
84+
f2.setAttributes([1])
85+
f2.setGeometry(QgsGeometry.fromWkt(
86+
'POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))'))
87+
self.assertTrue(f2.isValid())
88+
self.assertTrue(polygon_layer.addFeatures([f, f2]))
89+
polygon_layer.commitChanges()
90+
polygon_layer.rollBack()
91+
self.assertEqual(polygon_layer.featureCount(), 2)
92+
93+
QgsProject.instance().addMapLayers([polygon_layer])
94+
95+
alg = self.registry.createAlgorithmById('qgis:checkvalidity')
96+
97+
context = QgsProcessingContext()
98+
context.setProject(QgsProject.instance())
99+
feedback = ConsoleFeedBack()
100+
101+
self.assertIsNotNone(alg)
102+
parameters = {}
103+
parameters['INPUT_LAYER'] = polygon_layer.id()
104+
parameters['VALID_OUTPUT'] = 'memory:'
105+
parameters['INVALID_OUTPUT'] = 'memory:'
106+
parameters['ERROR_OUTPUT'] = 'memory:'
107+
108+
# QGIS method
109+
parameters['METHOD'] = 1
110+
ok, results = execute(
111+
alg, parameters, context=context, feedback=feedback)
112+
self.assertTrue(ok)
113+
invalid_layer = QgsProcessingUtils.mapLayerFromString(
114+
results['INVALID_OUTPUT'], context)
115+
self.assertEqual(invalid_layer.fields().names()[-1], '_errors')
116+
self.assertEqual(invalid_layer.featureCount(), 1)
117+
f = next(invalid_layer.getFeatures())
118+
self.assertEqual(f.attributes(), [
119+
1, 'segments 0 and 2 of line 0 intersect at 1, 1\nGeometry has 1 errors.'])
120+
121+
# GEOS method
122+
parameters['METHOD'] = 2
123+
ok, results = execute(
124+
alg, parameters, context=context, feedback=feedback)
125+
self.assertTrue(ok)
126+
invalid_layer = QgsProcessingUtils.mapLayerFromString(
127+
results['INVALID_OUTPUT'], context)
128+
self.assertEqual(invalid_layer.fields().names()[-1], '_errors')
129+
self.assertEqual(invalid_layer.featureCount(), 1)
130+
f = next(invalid_layer.getFeatures())
131+
self.assertEqual(f.attributes(), [1, 'Self-intersection'])
132+
133+
134+
if __name__ == '__main__':
135+
unittest.main()

0 commit comments

Comments
 (0)
Please sign in to comment.