Skip to content

Commit 5ae0e78

Browse files
committed
Check validity of input geometries in intersection algorithm, take 2
Fail if invalid geometries are found. And some easy performance wins. Just because. Fix #11986
1 parent 01e570c commit 5ae0e78

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

python/plugins/processing/algs/qgis/Intersection.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from processing.core.GeoAlgorithm import GeoAlgorithm
3535
from processing.core.ProcessingLog import ProcessingLog
3636
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
37-
from processing.core.parameters import ParameterVector
37+
from processing.core.parameters import ParameterVector, ParameterBoolean
3838
from processing.core.outputs import OutputVector
3939
from processing.tools import dataobjects, vector
4040

@@ -54,6 +54,7 @@ class Intersection(GeoAlgorithm):
5454

5555
INPUT = 'INPUT'
5656
INPUT2 = 'INPUT2'
57+
IGNORE_NULL = 'IGNORE_NULL'
5758
OUTPUT = 'OUTPUT'
5859

5960
def getIcon(self):
@@ -66,13 +67,17 @@ def defineCharacteristics(self):
6667
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
6768
self.addParameter(ParameterVector(self.INPUT2,
6869
self.tr('Intersect layer'), [ParameterVector.VECTOR_TYPE_ANY]))
70+
self.addParameter(ParameterBoolean(Intersection.IGNORE_NULL,
71+
self.tr('Ignore NULL geometries'),
72+
False, True))
6973
self.addOutput(OutputVector(self.OUTPUT, self.tr('Intersection')))
7074

7175
def processAlgorithm(self, progress):
7276
vlayerA = dataobjects.getObjectFromUri(
7377
self.getParameterValue(self.INPUT))
7478
vlayerB = dataobjects.getObjectFromUri(
7579
self.getParameterValue(self.INPUT2))
80+
ignoreNull = self.getParameterValue(Intersection.IGNORE_NULL)
7681

7782
geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(vlayerA.wkbType()))
7883
fields = vector.combineVectorFields(vlayerA, vlayerB)
@@ -84,13 +89,30 @@ def processAlgorithm(self, progress):
8489
total = 100.0 / len(selectionA)
8590
for current, inFeatA in enumerate(selectionA):
8691
progress.setPercentage(int(current * total))
87-
geom = QgsGeometry(inFeatA.geometry())
92+
geom = inFeatA.geometry()
93+
if not geom:
94+
if ignoreNull:
95+
continue
96+
else:
97+
raise GeoAlgorithmExecutionException(
98+
self.tr('Input layer A contains NULL geometries. Please check "Ignore NULL geometries" if you want to run this algorithm anyway.'))
99+
if not geom.isGeosValid():
100+
raise GeoAlgorithmExecutionException(
101+
self.tr('Input layer A contains invalid geometries (Feature {}). Unable to complete intersection algorithm.'.format(inFeatA.id())))
88102
atMapA = inFeatA.attributes()
89103
intersects = index.intersects(geom.boundingBox())
90-
for i in intersects:
91-
request = QgsFeatureRequest().setFilterFid(i)
92-
inFeatB = vlayerB.getFeatures(request).next()
104+
for inFeatB in vlayerB.getFeatures(QgsFeatureRequest().setFilterFids(intersects)):
93105
tmpGeom = QgsGeometry(inFeatB.geometry())
106+
if not geom:
107+
if ignoreNull:
108+
continue
109+
else:
110+
raise GeoAlgorithmExecutionException(
111+
self.tr('Input layer B contains NULL geometries. Please check "Ignore NULL geometries" if you want to run this algorithm anyway.'))
112+
if not geom.isGeosValid():
113+
raise GeoAlgorithmExecutionException(
114+
self.tr('Input layer B contains invalid geometries (Feature {}). Unable to complete intersection algorithm.'.format(inFeatB.id())))
115+
94116
if geom.intersects(tmpGeom):
95117
atMapB = inFeatB.attributes()
96118
int_geom = QgsGeometry(geom.intersection(tmpGeom))

python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ tests:
124124
INPUT2:
125125
name: polys.gml
126126
type: vector
127+
IGNORE_NULL: True
127128
results:
128129
OUTPUT:
129130
name: expected/intersection_collection_fallback.shp

0 commit comments

Comments
 (0)