Skip to content

Commit d4e400a

Browse files
committedJan 29, 2016
[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')))

‎python/plugins/processing/algs/qgis/SymmetricalDifference.py

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

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

28-
from qgis.core import QgsFeature, QgsGeometry, QgsFeatureRequest, NULL
28+
from qgis.core import QGis, QgsFeature, QgsGeometry, QgsFeatureRequest, NULL
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 SymmetricalDifference(GeoAlgorithm):
3742

@@ -58,12 +63,14 @@ def processAlgorithm(self, progress):
5863
providerA = layerA.dataProvider()
5964
providerB = layerB.dataProvider()
6065

61-
GEOS_EXCEPT = True
62-
FEATURE_EXCEPT = True
66+
geomType = providerA.geometryType()
67+
if geomType in GEOM_25D:
68+
raise GeoAlgorithmExecutionException(
69+
self.tr('Input layer has unsupported geometry type {}').format(geomType))
6370

6471
fields = vector.combineVectorFields(layerA, layerB)
6572
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
66-
fields, providerA.geometryType(), providerA.crs())
73+
fields, geomType, providerA.crs())
6774

6875
featB = QgsFeature()
6976
outFeat = QgsFeature()
@@ -86,20 +93,24 @@ def processAlgorithm(self, progress):
8693
for i in intersects:
8794
providerB.getFeatures(QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
8895
tmpGeom = QgsGeometry(featB.geometry())
89-
try:
90-
if diffGeom.intersects(tmpGeom):
91-
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
92-
except:
93-
add = False
94-
GEOS_EXCEPT = False
95-
break
96+
if diffGeom.intersects(tmpGeom):
97+
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
98+
if not diffGeom.isGeosValid():
99+
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
100+
self.tr('GEOS geoprocessing error: One or '
101+
'more input features have invalid '
102+
'geometry.'))
103+
add = False
104+
break
105+
96106
if add:
97107
try:
98108
outFeat.setGeometry(diffGeom)
99109
outFeat.setAttributes(attrs)
100110
writer.addFeature(outFeat)
101111
except:
102-
FEATURE_EXCEPT = False
112+
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
113+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
103114
continue
104115

105116
count += 1
@@ -117,30 +128,27 @@ def processAlgorithm(self, progress):
117128
for i in intersects:
118129
providerA.getFeatures(QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
119130
tmpGeom = QgsGeometry(featB.geometry())
120-
try:
121-
if diffGeom.intersects(tmpGeom):
122-
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
123-
except:
124-
add = False
125-
GEOS_EXCEPT = False
126-
break
131+
if diffGeom.intersects(tmpGeom):
132+
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
133+
if not diffGeom.isGeosValid():
134+
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
135+
self.tr('GEOS geoprocessing error: One or '
136+
'more input features have invalid '
137+
'geometry.'))
138+
add = False
139+
break
140+
127141
if add:
128142
try:
129143
outFeat.setGeometry(diffGeom)
130144
outFeat.setAttributes(attrs)
131145
writer.addFeature(outFeat)
132146
except:
133-
FEATURE_EXCEPT = False
147+
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
148+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
134149
continue
135150

136151
count += 1
137152
progress.setPercentage(int(count * total))
138153

139154
del writer
140-
141-
if not GEOS_EXCEPT:
142-
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
143-
self.tr('Geometry exception while computing symmetrical difference'))
144-
if not FEATURE_EXCEPT:
145-
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
146-
self.tr('Feature exception while computing symmetrical difference'))

‎python/plugins/processing/algs/qgis/Union.py

Lines changed: 92 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,49 @@
3333
from processing.core.outputs import OutputVector
3434
from processing.tools import dataobjects, vector
3535

36+
wkbTypeGroups = {
37+
'Point': (QGis.WKBPoint, QGis.WKBMultiPoint, QGis.WKBPoint25D, QGis.WKBMultiPoint25D,),
38+
'LineString': (QGis.WKBLineString, QGis.WKBMultiLineString, QGis.WKBLineString25D, QGis.WKBMultiLineString25D,),
39+
'Polygon': (QGis.WKBPolygon, QGis.WKBMultiPolygon, QGis.WKBPolygon25D, QGis.WKBMultiPolygon25D,),
40+
}
41+
for key, value in wkbTypeGroups.items():
42+
for const in value:
43+
wkbTypeGroups[const] = key
44+
45+
GEOM_25D = [QGis.WKBPoint25D, QGis.WKBLineString25D, QGis.WKBPolygon25D,
46+
QGis.WKBMultiPoint25D, QGis.WKBMultiLineString25D,
47+
QGis.WKBMultiPolygon25D]
48+
3649

3750
class Union(GeoAlgorithm):
3851

3952
INPUT = 'INPUT'
4053
INPUT2 = 'INPUT2'
4154
OUTPUT = 'OUTPUT'
4255

56+
def defineCharacteristics(self):
57+
self.name, self.i18n_name = self.trAlgorithm('Union')
58+
self.group, self.i18n_group = self.trAlgorithm('Vector overlay tools')
59+
self.addParameter(ParameterVector(Union.INPUT,
60+
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
61+
self.addParameter(ParameterVector(Union.INPUT2,
62+
self.tr('Input layer 2'), [ParameterVector.VECTOR_TYPE_ANY]))
63+
self.addOutput(OutputVector(Union.OUTPUT, self.tr('Union')))
64+
4365
def processAlgorithm(self, progress):
4466
vlayerA = dataobjects.getObjectFromUri(self.getParameterValue(Union.INPUT))
4567
vlayerB = dataobjects.getObjectFromUri(self.getParameterValue(Union.INPUT2))
46-
GEOS_EXCEPT = True
47-
FEATURE_EXCEPT = True
68+
4869
vproviderA = vlayerA.dataProvider()
4970

71+
geomType = vproviderA.geometryType()
72+
if geomType in GEOM_25D:
73+
raise GeoAlgorithmExecutionException(
74+
self.tr('Input layer has unsupported geometry type {}').format(geomType))
75+
5076
fields = vector.combineVectorFields(vlayerA, vlayerB)
51-
names = [field.name() for field in fields]
52-
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, unicode(names))
5377
writer = self.getOutputFromName(Union.OUTPUT).getVectorWriter(fields,
54-
vproviderA.geometryType(), vproviderA.crs())
78+
geomType, vproviderA.crs())
5579
inFeatA = QgsFeature()
5680
inFeatB = QgsFeature()
5781
outFeat = QgsFeature()
@@ -77,8 +101,8 @@ def processAlgorithm(self, progress):
77101
except:
78102
# This really shouldn't happen, as we haven't
79103
# edited the input geom at all
80-
raise GeoAlgorithmExecutionException(
81-
self.tr('Feature exception while computing union'))
104+
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
105+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
82106
else:
83107
for id in intersects:
84108
count += 1
@@ -93,9 +117,9 @@ def processAlgorithm(self, progress):
93117

94118
if int_geom is None:
95119
# There was a problem creating the intersection
96-
raise GeoAlgorithmExecutionException(
97-
self.tr('Geometry exception while computing '
98-
'intersection'))
120+
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
121+
self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.'))
122+
int_geom = QgsGeometry()
99123
else:
100124
int_geom = QgsGeometry(int_geom)
101125

@@ -105,38 +129,52 @@ def processAlgorithm(self, progress):
105129
for i in temp_list:
106130
if i.type() == geom.type():
107131
int_geom = QgsGeometry(i)
108-
try:
109-
outFeat.setGeometry(int_geom)
110-
attrs = []
111-
attrs.extend(atMapA)
112-
attrs.extend(atMapB)
113-
outFeat.setAttributes(attrs)
114-
writer.addFeature(outFeat)
115-
except Exception as err:
116-
raise GeoAlgorithmExecutionException(
117-
self.tr('Feature exception while computing union'))
118-
132+
try:
133+
outFeat.setGeometry(int_geom)
134+
outFeat.setAttributes(atMapA + atMapB)
135+
writer.addFeature(outFeat)
136+
except:
137+
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
138+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
139+
else:
140+
# Geometry list: prevents writing error
141+
# in geometries of different types
142+
# produced by the intersection
143+
# fix #3549
144+
if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[int_geom.wkbType()]]:
145+
try:
146+
outFeat.setGeometry(int_geom)
147+
outFeat.setAttributes(atMapA + atMapB)
148+
writer.addFeature(outFeat)
149+
except:
150+
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
151+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
152+
153+
# the remaining bit of inFeatA's geometry
154+
# if there is nothing left, this will just silently fail and we're good
155+
diff_geom = QgsGeometry(geom)
156+
if len(lstIntersectingB) != 0:
157+
intB = QgsGeometry.unaryUnion(lstIntersectingB)
158+
diff_geom = diff_geom.difference(intB)
159+
if diff_geom.isGeosEmpty() or not diff_geom.isGeosValid():
160+
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
161+
self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.'))
162+
163+
if diff_geom.wkbType() == 0 or QgsWKBTypes.flatType(diff_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
164+
temp_list = diff_geom.asGeometryCollection()
165+
for i in temp_list:
166+
if i.type() == geom.type():
167+
diff_geom = QgsGeometry(i)
119168
try:
120-
# the remaining bit of inFeatA's geometry
121-
# if there is nothing left, this will just silently fail and we're good
122-
diff_geom = QgsGeometry(geom)
123-
if len(lstIntersectingB) != 0:
124-
intB = QgsGeometry.unaryUnion(lstIntersectingB)
125-
diff_geom = diff_geom.difference(intB)
126-
127-
if diff_geom.wkbType() == 0 or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
128-
temp_list = diff_geom.asGeometryCollection()
129-
for i in temp_list:
130-
if i.type() == geom.type():
131-
diff_geom = QgsGeometry(i)
132169
outFeat.setGeometry(diff_geom)
133170
outFeat.setAttributes(atMapA)
134171
writer.addFeature(outFeat)
135-
except Exception as err:
136-
raise GeoAlgorithmExecutionException(
137-
self.tr('Feature exception while computing union'))
172+
except:
173+
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
174+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
138175

139176
length = len(vproviderA.fields())
177+
atMapA = [None] * length
140178

141179
featuresA = vector.features(vlayerB)
142180
nFeat = len(featuresA)
@@ -154,53 +192,41 @@ def processAlgorithm(self, progress):
154192
outFeat.setGeometry(geom)
155193
outFeat.setAttributes(atMap)
156194
writer.addFeature(outFeat)
157-
except Exception as err:
158-
raise GeoAlgorithmExecutionException(
159-
self.tr('Feature exception while computing union'))
195+
except:
196+
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
197+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
160198
else:
161199
for id in intersects:
162200
request = QgsFeatureRequest().setFilterFid(id)
163201
inFeatB = vlayerA.getFeatures(request).next()
164202
atMapB = inFeatB.attributes()
165203
tmpGeom = QgsGeometry(inFeatB.geometry())
166-
try:
167-
if diff_geom.intersects(tmpGeom):
168-
add = True
169-
diff_geom = QgsGeometry(
170-
diff_geom.difference(tmpGeom))
171-
else:
204+
205+
if diff_geom.intersects(tmpGeom):
206+
add = True
207+
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
208+
if diff_geom.isGeosEmpty() or not diff_geom.isGeosValid():
209+
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
210+
self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.'))
211+
else:
212+
try:
172213
# Ihis only happends if the bounding box
173214
# intersects, but the geometry doesn't
174215
outFeat.setGeometry(diff_geom)
175216
outFeat.setAttributes(atMap)
176217
writer.addFeature(outFeat)
177-
except Exception as err:
178-
raise GeoAlgorithmExecutionException(
179-
self.tr('Geometry exception while computing intersection'))
218+
except:
219+
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
220+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
180221

181222
if add:
182223
try:
183224
outFeat.setGeometry(diff_geom)
184225
outFeat.setAttributes(atMap)
185226
writer.addFeature(outFeat)
186-
except Exception as err:
187-
raise err
188-
FEATURE_EXCEPT = False
227+
except:
228+
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
229+
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
189230
nElement += 1
190231

191232
del writer
192-
if not GEOS_EXCEPT:
193-
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
194-
self.tr('Geometry exception while computing intersection'))
195-
if not FEATURE_EXCEPT:
196-
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
197-
self.tr('Feature exception while computing intersection'))
198-
199-
def defineCharacteristics(self):
200-
self.name, self.i18n_name = self.trAlgorithm('Union')
201-
self.group, self.i18n_group = self.trAlgorithm('Vector overlay tools')
202-
self.addParameter(ParameterVector(Union.INPUT,
203-
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
204-
self.addParameter(ParameterVector(Union.INPUT2,
205-
self.tr('Input layer 2'), [ParameterVector.VECTOR_TYPE_ANY]))
206-
self.addOutput(OutputVector(Union.OUTPUT, self.tr('Union')))

1 commit comments

Comments
 (1)

rldhont commented on Jun 10, 2016

@rldhont
Contributor

Hi @alexbruy , Why did you restrict these process ?
Is it linked to GEOS version ?
We tests with 25D data and clip it's working.
http://hub.qgis.org/issues/14929

Please sign in to comment.