mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-07 00:02:15 -05:00
136 lines
4.8 KiB
Python
136 lines
4.8 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
"""QGIS Unit tests for Processing CheckValidity algorithm.
|
||
|
|
||
|
.. 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__ = 'Alessandro Pasotti'
|
||
|
__date__ = '2018-09'
|
||
|
__copyright__ = 'Copyright 2018, The QGIS Project'
|
||
|
# This will get replaced with a git SHA1 when you do a git archive
|
||
|
__revision__ = '$Format:%H$'
|
||
|
|
||
|
from qgis.PyQt.QtCore import QCoreApplication, QVariant
|
||
|
from qgis.core import (
|
||
|
QgsFeature,
|
||
|
QgsGeometry,
|
||
|
QgsApplication,
|
||
|
QgsMemoryProviderUtils,
|
||
|
QgsWkbTypes,
|
||
|
QgsField,
|
||
|
QgsFields,
|
||
|
QgsProcessingContext,
|
||
|
QgsProcessingFeedback,
|
||
|
QgsCoordinateReferenceSystem,
|
||
|
QgsProject,
|
||
|
QgsProcessingException,
|
||
|
QgsProcessingUtils,
|
||
|
QgsSettings
|
||
|
)
|
||
|
from processing.core.Processing import Processing
|
||
|
from processing.gui.AlgorithmExecutor import execute
|
||
|
from qgis.testing import start_app, unittest
|
||
|
from qgis.PyQt.QtTest import QSignalSpy
|
||
|
from qgis.analysis import QgsNativeAlgorithms
|
||
|
|
||
|
start_app()
|
||
|
|
||
|
|
||
|
class ConsoleFeedBack(QgsProcessingFeedback):
|
||
|
|
||
|
def reportError(self, error, fatalError=False):
|
||
|
print(error)
|
||
|
|
||
|
|
||
|
class TestQgsProcessingCheckValidity(unittest.TestCase):
|
||
|
|
||
|
@classmethod
|
||
|
def setUpClass(cls):
|
||
|
"""Run before all tests"""
|
||
|
QCoreApplication.setOrganizationName("QGIS_Test")
|
||
|
QCoreApplication.setOrganizationDomain(
|
||
|
"QGIS_TestPyQgsProcessingCheckValidity.com")
|
||
|
QCoreApplication.setApplicationName(
|
||
|
"QGIS_TestPyQgsProcessingCheckValidity")
|
||
|
QgsSettings().clear()
|
||
|
Processing.initialize()
|
||
|
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
|
||
|
cls.registry = QgsApplication.instance().processingRegistry()
|
||
|
|
||
|
def _make_layer(self, layer_wkb_name):
|
||
|
fields = QgsFields()
|
||
|
wkb_type = getattr(QgsWkbTypes, layer_wkb_name)
|
||
|
fields.append(QgsField('int_f', QVariant.Int))
|
||
|
layer = QgsMemoryProviderUtils.createMemoryLayer(
|
||
|
'%s_layer' % layer_wkb_name, fields, wkb_type, QgsCoordinateReferenceSystem(4326))
|
||
|
self.assertTrue(layer.isValid())
|
||
|
self.assertEqual(layer.wkbType(), wkb_type)
|
||
|
return layer
|
||
|
|
||
|
def test_check_validity(self):
|
||
|
"""Test that the output invalid contains the error reason"""
|
||
|
|
||
|
polygon_layer = self._make_layer('Polygon')
|
||
|
self.assertTrue(polygon_layer.startEditing())
|
||
|
f = QgsFeature(polygon_layer.fields())
|
||
|
f.setAttributes([1])
|
||
|
# Flake!
|
||
|
f.setGeometry(QgsGeometry.fromWkt(
|
||
|
'POLYGON ((0 0, 2 2, 0 2, 2 0, 0 0))'))
|
||
|
self.assertTrue(f.isValid())
|
||
|
f2 = QgsFeature(polygon_layer.fields())
|
||
|
f2.setAttributes([1])
|
||
|
f2.setGeometry(QgsGeometry.fromWkt(
|
||
|
'POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))'))
|
||
|
self.assertTrue(f2.isValid())
|
||
|
self.assertTrue(polygon_layer.addFeatures([f, f2]))
|
||
|
polygon_layer.commitChanges()
|
||
|
polygon_layer.rollBack()
|
||
|
self.assertEqual(polygon_layer.featureCount(), 2)
|
||
|
|
||
|
QgsProject.instance().addMapLayers([polygon_layer])
|
||
|
|
||
|
alg = self.registry.createAlgorithmById('qgis:checkvalidity')
|
||
|
|
||
|
context = QgsProcessingContext()
|
||
|
context.setProject(QgsProject.instance())
|
||
|
feedback = ConsoleFeedBack()
|
||
|
|
||
|
self.assertIsNotNone(alg)
|
||
|
parameters = {}
|
||
|
parameters['INPUT_LAYER'] = polygon_layer.id()
|
||
|
parameters['VALID_OUTPUT'] = 'memory:'
|
||
|
parameters['INVALID_OUTPUT'] = 'memory:'
|
||
|
parameters['ERROR_OUTPUT'] = 'memory:'
|
||
|
|
||
|
# QGIS method
|
||
|
parameters['METHOD'] = 1
|
||
|
ok, results = execute(
|
||
|
alg, parameters, context=context, feedback=feedback)
|
||
|
self.assertTrue(ok)
|
||
|
invalid_layer = QgsProcessingUtils.mapLayerFromString(
|
||
|
results['INVALID_OUTPUT'], context)
|
||
|
self.assertEqual(invalid_layer.fields().names()[-1], '_errors')
|
||
|
self.assertEqual(invalid_layer.featureCount(), 1)
|
||
|
f = next(invalid_layer.getFeatures())
|
||
|
self.assertEqual(f.attributes(), [
|
||
|
1, 'segments 0 and 2 of line 0 intersect at 1, 1\nGeometry has 1 errors.'])
|
||
|
|
||
|
# GEOS method
|
||
|
parameters['METHOD'] = 2
|
||
|
ok, results = execute(
|
||
|
alg, parameters, context=context, feedback=feedback)
|
||
|
self.assertTrue(ok)
|
||
|
invalid_layer = QgsProcessingUtils.mapLayerFromString(
|
||
|
results['INVALID_OUTPUT'], context)
|
||
|
self.assertEqual(invalid_layer.fields().names()[-1], '_errors')
|
||
|
self.assertEqual(invalid_layer.featureCount(), 1)
|
||
|
f = next(invalid_layer.getFeatures())
|
||
|
self.assertEqual(f.attributes(), [1, 'Self-intersection'])
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
unittest.main()
|