Skip to content

Commit d4e400a

Browse files
committed
[processing] fixes for vector geoprocessing algorithms
1 parent 4c2c905 commit d4e400a

File tree

5 files changed

+225
-170
lines changed

5 files changed

+225
-170
lines changed

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

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,18 @@
2626
__revision__ = '$Format:%H$'
2727

2828
from qgis.core import QGis, QgsFeature, QgsGeometry, QgsFeatureRequest, QgsWKBTypes
29+
2930
from processing.core.GeoAlgorithm import GeoAlgorithm
3031
from processing.core.ProcessingLog import ProcessingLog
32+
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
3133
from processing.core.parameters import ParameterVector
3234
from processing.core.outputs import OutputVector
3335
from processing.tools import dataobjects, vector
3436

37+
GEOM_25D = [QGis.WKBPoint25D, QGis.WKBLineString25D, QGis.WKBPolygon25D,
38+
QGis.WKBMultiPoint25D, QGis.WKBMultiLineString25D,
39+
QGis.WKBMultiPolygon25D]
40+
3541

3642
class Clip(GeoAlgorithm):
3743

@@ -54,6 +60,11 @@ def processAlgorithm(self, progress):
5460
layerB = dataobjects.getObjectFromUri(
5561
self.getParameterValue(Clip.OVERLAY))
5662

63+
geomType = layerA.dataProvider().geometryType()
64+
if geomType in GEOM_25D:
65+
raise GeoAlgorithmExecutionException(
66+
self.tr('Input layer has unsupported geometry type {}').format(geomType))
67+
5768
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
5869
layerA.pendingFields(),
5970
layerA.dataProvider().geometryType(),
@@ -88,39 +99,37 @@ def processAlgorithm(self, progress):
8899
outFeat.setGeometry(QgsGeometry(tmpGeom))
89100
first = False
90101
else:
91-
try:
92-
cur_geom = QgsGeometry(outFeat.geometry())
93-
new_geom = QgsGeometry(
94-
cur_geom.combine(tmpGeom))
95-
outFeat.setGeometry(QgsGeometry(new_geom))
96-
except:
102+
cur_geom = QgsGeometry(outFeat.geometry())
103+
new_geom = QgsGeometry(cur_geom.combine(tmpGeom))
104+
if new_geom.isGeosEmpty() or not new_geom.isGeosValid():
97105
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
98106
self.tr('GEOS geoprocessing error: One or '
99107
'more input features have invalid '
100108
'geometry.'))
101109
break
110+
111+
outFeat.setGeometry(QgsGeometry(new_geom))
102112
if found:
103-
try:
104-
cur_geom = QgsGeometry(outFeat.geometry())
105-
new_geom = QgsGeometry(geom.intersection(cur_geom))
106-
if new_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(new_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
107-
int_com = QgsGeometry(geom.combine(cur_geom))
108-
int_sym = QgsGeometry(geom.symDifference(cur_geom))
109-
new_geom = QgsGeometry(int_com.difference(int_sym))
110-
try:
111-
outFeat.setGeometry(new_geom)
112-
outFeat.setAttributes(attrs)
113-
writer.addFeature(outFeat)
114-
except:
113+
cur_geom = QgsGeometry(outFeat.geometry())
114+
new_geom = QgsGeometry(geom.intersection(cur_geom))
115+
if new_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(new_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
116+
int_com = QgsGeometry(geom.combine(cur_geom))
117+
int_sym = QgsGeometry(geom.symDifference(cur_geom))
118+
new_geom = QgsGeometry(int_com.difference(int_sym))
119+
if new_geom.isGeosEmpty() or not new_geom.isGeosValid():
115120
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
116-
self.tr('Feature geometry error: One or more '
117-
'output features ignored due to '
118-
'invalid geometry.'))
121+
self.tr('GEOS geoprocessing error: One or more '
122+
'input features have invalid geometry.'))
119123
continue
124+
try:
125+
outFeat.setGeometry(new_geom)
126+
outFeat.setAttributes(attrs)
127+
writer.addFeature(outFeat)
120128
except:
121129
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
122-
self.tr('GEOS geoprocessing error: One or more '
123-
'input features have invalid geometry.'))
130+
self.tr('Feature geometry error: One or more '
131+
'output features ignored due to '
132+
'invalid geometry.'))
124133
continue
125134

126135
current += 1

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

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@
2525

2626
__revision__ = '$Format:%H$'
2727

28-
from qgis.core import QgsFeatureRequest, QgsFeature, QgsGeometry
28+
from qgis.core import QGis, QgsFeatureRequest, QgsFeature, QgsGeometry
2929
from processing.core.ProcessingLog import ProcessingLog
3030
from processing.core.GeoAlgorithm import GeoAlgorithm
31+
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
3132
from processing.core.parameters import ParameterVector
3233
from processing.core.outputs import OutputVector
3334
from processing.tools import dataobjects, vector
3435

36+
GEOM_25D = [QGis.WKBPoint25D, QGis.WKBLineString25D, QGis.WKBPolygon25D,
37+
QGis.WKBMultiPoint25D, QGis.WKBMultiLineString25D,
38+
QGis.WKBMultiPolygon25D]
39+
3540

3641
class Difference(GeoAlgorithm):
3742

@@ -59,13 +64,14 @@ def processAlgorithm(self, progress):
5964
layerB = dataobjects.getObjectFromUri(
6065
self.getParameterValue(Difference.OVERLAY))
6166

62-
GEOS_EXCEPT = True
63-
64-
FEATURE_EXCEPT = True
67+
geomType = layerA.dataProvider().geometryType()
68+
if geomType in GEOM_25D:
69+
raise GeoAlgorithmExecutionException(
70+
self.tr('Input layer has unsupported geometry type {}').format(geomType))
6571

6672
writer = self.getOutputFromName(
6773
Difference.OUTPUT).getVectorWriter(layerA.pendingFields(),
68-
layerA.dataProvider().geometryType(),
74+
geomType,
6975
layerA.dataProvider().crs())
7076

7177
inFeatA = QgsFeature()
@@ -89,35 +95,27 @@ def processAlgorithm(self, progress):
8995
request = QgsFeatureRequest().setFilterFid(i)
9096
inFeatB = layerB.getFeatures(request).next()
9197
tmpGeom = QgsGeometry(inFeatB.geometry())
92-
try:
93-
if diff_geom.intersects(tmpGeom):
94-
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
95-
if diff_geom.isGeosEmpty():
96-
GEOS_EXCEPT = False
98+
if diff_geom.intersects(tmpGeom):
99+
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
100+
if diff_geom.isGeosEmpty() or not diff_geom.isGeosValid():
101+
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
102+
self.tr('GEOS geoprocessing error: One or '
103+
'more input features have invalid '
104+
'geometry.'))
97105
add = False
98106
break
99-
except:
100-
GEOS_EXCEPT = False
101-
add = False
102-
break
103107

104108
if add:
105109
try:
106110
outFeat.setGeometry(diff_geom)
107111
outFeat.setAttributes(attrs)
108112
writer.addFeature(outFeat)
109113
except:
110-
FEATURE_EXCEPT = False
114+
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
115+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
111116
continue
112117

113118
current += 1
114119
progress.setPercentage(int(current * total))
115120

116121
del writer
117-
118-
if not GEOS_EXCEPT:
119-
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
120-
self.tr('Geometry exception while computing difference'))
121-
if not FEATURE_EXCEPT:
122-
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
123-
self.tr('Feature exception while computing difference'))

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

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
__revision__ = '$Format:%H$'
2727

2828
from qgis.core import QGis, QgsFeatureRequest, QgsFeature, QgsGeometry, QgsWKBTypes
29+
2930
from processing.core.GeoAlgorithm import GeoAlgorithm
3031
from processing.core.ProcessingLog import ProcessingLog
32+
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
3133
from processing.core.parameters import ParameterVector
3234
from processing.core.outputs import OutputVector
3335
from processing.tools import dataobjects, vector
@@ -41,23 +43,41 @@
4143
for const in value:
4244
wkbTypeGroups[const] = key
4345

46+
GEOM_25D = [QGis.WKBPoint25D, QGis.WKBLineString25D, QGis.WKBPolygon25D,
47+
QGis.WKBMultiPoint25D, QGis.WKBMultiLineString25D,
48+
QGis.WKBMultiPolygon25D]
49+
4450

4551
class Intersection(GeoAlgorithm):
4652

4753
INPUT = 'INPUT'
4854
INPUT2 = 'INPUT2'
4955
OUTPUT = 'OUTPUT'
5056

57+
def defineCharacteristics(self):
58+
self.name, self.i18n_name = self.trAlgorithm('Intersection')
59+
self.group, self.i18n_group = self.trAlgorithm('Vector overlay tools')
60+
self.addParameter(ParameterVector(self.INPUT,
61+
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
62+
self.addParameter(ParameterVector(self.INPUT2,
63+
self.tr('Intersect layer'), [ParameterVector.VECTOR_TYPE_ANY]))
64+
self.addOutput(OutputVector(self.OUTPUT, self.tr('Intersection')))
65+
5166
def processAlgorithm(self, progress):
5267
vlayerA = dataobjects.getObjectFromUri(
5368
self.getParameterValue(self.INPUT))
5469
vlayerB = dataobjects.getObjectFromUri(
5570
self.getParameterValue(self.INPUT2))
5671
vproviderA = vlayerA.dataProvider()
5772

73+
geomType = vproviderA.geometryType()
74+
if geomType in GEOM_25D:
75+
raise GeoAlgorithmExecutionException(
76+
self.tr('Input layer has unsupported geometry type {}').format(geomType))
77+
5878
fields = vector.combineVectorFields(vlayerA, vlayerB)
5979
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields,
60-
vproviderA.geometryType(), vproviderA.crs())
80+
geomType, vproviderA.crs())
6181
inFeatA = QgsFeature()
6282
inFeatB = QgsFeature()
6383
outFeat = QgsFeature()
@@ -75,36 +95,30 @@ def processAlgorithm(self, progress):
7595
request = QgsFeatureRequest().setFilterFid(i)
7696
inFeatB = vlayerB.getFeatures(request).next()
7797
tmpGeom = QgsGeometry(inFeatB.geometry())
78-
try:
79-
if geom.intersects(tmpGeom):
80-
atMapB = inFeatB.attributes()
81-
int_geom = QgsGeometry(geom.intersection(tmpGeom))
82-
if int_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
83-
int_com = geom.combine(tmpGeom)
84-
int_sym = geom.symDifference(tmpGeom)
85-
int_geom = QgsGeometry(int_com.difference(int_sym))
86-
try:
87-
if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[int_geom.wkbType()]]:
88-
outFeat.setGeometry(int_geom)
89-
attrs = []
90-
attrs.extend(atMapA)
91-
attrs.extend(atMapB)
92-
outFeat.setAttributes(attrs)
93-
writer.addFeature(outFeat)
94-
except:
95-
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
96-
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
97-
continue
98-
except:
99-
break
98+
if geom.intersects(tmpGeom):
99+
atMapB = inFeatB.attributes()
100+
int_geom = QgsGeometry(geom.intersection(tmpGeom))
101+
if int_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
102+
int_com = geom.combine(tmpGeom)
103+
int_sym = geom.symDifference(tmpGeom)
104+
int_geom = QgsGeometry(int_com.difference(int_sym))
105+
if int_geom.isGeosEmpty() or not int_geom.isGeosValid():
106+
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
107+
self.tr('GEOS geoprocessing error: One or '
108+
'more input features have invalid '
109+
'geometry.'))
110+
break
111+
try:
112+
if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[int_geom.wkbType()]]:
113+
outFeat.setGeometry(int_geom)
114+
attrs = []
115+
attrs.extend(atMapA)
116+
attrs.extend(atMapB)
117+
outFeat.setAttributes(attrs)
118+
writer.addFeature(outFeat)
119+
except:
120+
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
121+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
122+
continue
100123

101124
del writer
102-
103-
def defineCharacteristics(self):
104-
self.name, self.i18n_name = self.trAlgorithm('Intersection')
105-
self.group, self.i18n_group = self.trAlgorithm('Vector overlay tools')
106-
self.addParameter(ParameterVector(self.INPUT,
107-
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
108-
self.addParameter(ParameterVector(self.INPUT2,
109-
self.tr('Intersect layer'), [ParameterVector.VECTOR_TYPE_ANY]))
110-
self.addOutput(OutputVector(self.OUTPUT, self.tr('Intersection')))

0 commit comments

Comments
 (0)