Skip to content

Commit

Permalink
Check validity of input geometries in intersection algorithm, take 2
Browse files Browse the repository at this point in the history
Fail if invalid geometries are found.
And some easy performance wins. Just because.

Fix qgis#11986
  • Loading branch information
m-kuhn committed Oct 20, 2016
1 parent 01e570c commit 5ae0e78
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
32 changes: 27 additions & 5 deletions python/plugins/processing/algs/qgis/Intersection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

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

INPUT = 'INPUT'
INPUT2 = 'INPUT2'
IGNORE_NULL = 'IGNORE_NULL'
OUTPUT = 'OUTPUT'

def getIcon(self):
Expand All @@ -66,13 +67,17 @@ 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):
vlayerA = dataobjects.getObjectFromUri(
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)
Expand All @@ -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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ tests:
INPUT2:
name: polys.gml
type: vector
IGNORE_NULL: True
results:
OUTPUT:
name: expected/intersection_collection_fallback.shp
Expand Down

0 comments on commit 5ae0e78

Please sign in to comment.