diff --git a/python/plugins/processing/algs/qgis/Intersection.py b/python/plugins/processing/algs/qgis/Intersection.py index 2dafc82c432a..39ccc3f96044 100644 --- a/python/plugins/processing/algs/qgis/Intersection.py +++ b/python/plugins/processing/algs/qgis/Intersection.py @@ -34,7 +34,7 @@ from processing.core.GeoAlgorithm import GeoAlgorithm from processing.core.ProcessingLog import ProcessingLog from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException -from processing.core.parameters import ParameterVector +from processing.core.parameters import ParameterVector, ParameterBoolean from processing.core.outputs import OutputVector from processing.tools import dataobjects, vector @@ -54,6 +54,7 @@ class Intersection(GeoAlgorithm): INPUT = 'INPUT' INPUT2 = 'INPUT2' + IGNORE_NULL = 'IGNORE_NULL' OUTPUT = 'OUTPUT' def getIcon(self): @@ -66,6 +67,9 @@ def defineCharacteristics(self): self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY])) self.addParameter(ParameterVector(self.INPUT2, self.tr('Intersect layer'), [ParameterVector.VECTOR_TYPE_ANY])) + self.addParameter(ParameterBoolean(Intersection.IGNORE_NULL, + self.tr('Ignore NULL geometries'), + False, True)) self.addOutput(OutputVector(self.OUTPUT, self.tr('Intersection'))) def processAlgorithm(self, progress): @@ -73,6 +77,7 @@ def processAlgorithm(self, progress): self.getParameterValue(self.INPUT)) vlayerB = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT2)) + ignoreNull = self.getParameterValue(Intersection.IGNORE_NULL) geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(vlayerA.wkbType())) fields = vector.combineVectorFields(vlayerA, vlayerB) @@ -84,13 +89,30 @@ def processAlgorithm(self, progress): total = 100.0 / len(selectionA) for current, inFeatA in enumerate(selectionA): progress.setPercentage(int(current * total)) - geom = QgsGeometry(inFeatA.geometry()) + geom = inFeatA.geometry() + if not geom: + if ignoreNull: + continue + else: + raise GeoAlgorithmExecutionException( + self.tr('Input layer A contains NULL geometries. Please check "Ignore NULL geometries" if you want to run this algorithm anyway.')) + if not geom.isGeosValid(): + raise GeoAlgorithmExecutionException( + self.tr('Input layer A contains invalid geometries (Feature {}). Unable to complete intersection algorithm.'.format(inFeatA.id()))) atMapA = inFeatA.attributes() intersects = index.intersects(geom.boundingBox()) - for i in intersects: - request = QgsFeatureRequest().setFilterFid(i) - inFeatB = vlayerB.getFeatures(request).next() + for inFeatB in vlayerB.getFeatures(QgsFeatureRequest().setFilterFids(intersects)): tmpGeom = QgsGeometry(inFeatB.geometry()) + if not geom: + if ignoreNull: + continue + else: + raise GeoAlgorithmExecutionException( + self.tr('Input layer B contains NULL geometries. Please check "Ignore NULL geometries" if you want to run this algorithm anyway.')) + if not geom.isGeosValid(): + raise GeoAlgorithmExecutionException( + self.tr('Input layer B contains invalid geometries (Feature {}). Unable to complete intersection algorithm.'.format(inFeatB.id()))) + if geom.intersects(tmpGeom): atMapB = inFeatB.attributes() int_geom = QgsGeometry(geom.intersection(tmpGeom)) diff --git a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml index 4dd33503172f..07b594eee685 100644 --- a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml +++ b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml @@ -124,6 +124,7 @@ tests: INPUT2: name: polys.gml type: vector + IGNORE_NULL: True results: OUTPUT: name: expected/intersection_collection_fallback.shp