mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[processing] fixes for vector geoprocessing algorithms
This commit is contained in:
parent
4c2c905c32
commit
d4e400a425
@ -26,12 +26,18 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
from qgis.core import QGis, QgsFeature, QgsGeometry, QgsFeatureRequest, QgsWKBTypes
|
||||
|
||||
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.outputs import OutputVector
|
||||
from processing.tools import dataobjects, vector
|
||||
|
||||
GEOM_25D = [QGis.WKBPoint25D, QGis.WKBLineString25D, QGis.WKBPolygon25D,
|
||||
QGis.WKBMultiPoint25D, QGis.WKBMultiLineString25D,
|
||||
QGis.WKBMultiPolygon25D]
|
||||
|
||||
|
||||
class Clip(GeoAlgorithm):
|
||||
|
||||
@ -54,6 +60,11 @@ class Clip(GeoAlgorithm):
|
||||
layerB = dataobjects.getObjectFromUri(
|
||||
self.getParameterValue(Clip.OVERLAY))
|
||||
|
||||
geomType = layerA.dataProvider().geometryType()
|
||||
if geomType in GEOM_25D:
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Input layer has unsupported geometry type {}').format(geomType))
|
||||
|
||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
|
||||
layerA.pendingFields(),
|
||||
layerA.dataProvider().geometryType(),
|
||||
@ -88,39 +99,37 @@ class Clip(GeoAlgorithm):
|
||||
outFeat.setGeometry(QgsGeometry(tmpGeom))
|
||||
first = False
|
||||
else:
|
||||
try:
|
||||
cur_geom = QgsGeometry(outFeat.geometry())
|
||||
new_geom = QgsGeometry(
|
||||
cur_geom.combine(tmpGeom))
|
||||
outFeat.setGeometry(QgsGeometry(new_geom))
|
||||
except:
|
||||
cur_geom = QgsGeometry(outFeat.geometry())
|
||||
new_geom = QgsGeometry(cur_geom.combine(tmpGeom))
|
||||
if new_geom.isGeosEmpty() or not new_geom.isGeosValid():
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
|
||||
self.tr('GEOS geoprocessing error: One or '
|
||||
'more input features have invalid '
|
||||
'geometry.'))
|
||||
break
|
||||
|
||||
outFeat.setGeometry(QgsGeometry(new_geom))
|
||||
if found:
|
||||
try:
|
||||
cur_geom = QgsGeometry(outFeat.geometry())
|
||||
new_geom = QgsGeometry(geom.intersection(cur_geom))
|
||||
if new_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(new_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
|
||||
int_com = QgsGeometry(geom.combine(cur_geom))
|
||||
int_sym = QgsGeometry(geom.symDifference(cur_geom))
|
||||
new_geom = QgsGeometry(int_com.difference(int_sym))
|
||||
try:
|
||||
outFeat.setGeometry(new_geom)
|
||||
outFeat.setAttributes(attrs)
|
||||
writer.addFeature(outFeat)
|
||||
except:
|
||||
cur_geom = QgsGeometry(outFeat.geometry())
|
||||
new_geom = QgsGeometry(geom.intersection(cur_geom))
|
||||
if new_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(new_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
|
||||
int_com = QgsGeometry(geom.combine(cur_geom))
|
||||
int_sym = QgsGeometry(geom.symDifference(cur_geom))
|
||||
new_geom = QgsGeometry(int_com.difference(int_sym))
|
||||
if new_geom.isGeosEmpty() or not new_geom.isGeosValid():
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
|
||||
self.tr('Feature geometry error: One or more '
|
||||
'output features ignored due to '
|
||||
'invalid geometry.'))
|
||||
self.tr('GEOS geoprocessing error: One or more '
|
||||
'input features have invalid geometry.'))
|
||||
continue
|
||||
try:
|
||||
outFeat.setGeometry(new_geom)
|
||||
outFeat.setAttributes(attrs)
|
||||
writer.addFeature(outFeat)
|
||||
except:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
|
||||
self.tr('GEOS geoprocessing error: One or more '
|
||||
'input features have invalid geometry.'))
|
||||
self.tr('Feature geometry error: One or more '
|
||||
'output features ignored due to '
|
||||
'invalid geometry.'))
|
||||
continue
|
||||
|
||||
current += 1
|
||||
|
@ -25,13 +25,18 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
from qgis.core import QgsFeatureRequest, QgsFeature, QgsGeometry
|
||||
from qgis.core import QGis, QgsFeatureRequest, QgsFeature, QgsGeometry
|
||||
from processing.core.ProcessingLog import ProcessingLog
|
||||
from processing.core.GeoAlgorithm import GeoAlgorithm
|
||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||
from processing.core.parameters import ParameterVector
|
||||
from processing.core.outputs import OutputVector
|
||||
from processing.tools import dataobjects, vector
|
||||
|
||||
GEOM_25D = [QGis.WKBPoint25D, QGis.WKBLineString25D, QGis.WKBPolygon25D,
|
||||
QGis.WKBMultiPoint25D, QGis.WKBMultiLineString25D,
|
||||
QGis.WKBMultiPolygon25D]
|
||||
|
||||
|
||||
class Difference(GeoAlgorithm):
|
||||
|
||||
@ -59,13 +64,14 @@ class Difference(GeoAlgorithm):
|
||||
layerB = dataobjects.getObjectFromUri(
|
||||
self.getParameterValue(Difference.OVERLAY))
|
||||
|
||||
GEOS_EXCEPT = True
|
||||
|
||||
FEATURE_EXCEPT = True
|
||||
geomType = layerA.dataProvider().geometryType()
|
||||
if geomType in GEOM_25D:
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Input layer has unsupported geometry type {}').format(geomType))
|
||||
|
||||
writer = self.getOutputFromName(
|
||||
Difference.OUTPUT).getVectorWriter(layerA.pendingFields(),
|
||||
layerA.dataProvider().geometryType(),
|
||||
geomType,
|
||||
layerA.dataProvider().crs())
|
||||
|
||||
inFeatA = QgsFeature()
|
||||
@ -89,17 +95,15 @@ class Difference(GeoAlgorithm):
|
||||
request = QgsFeatureRequest().setFilterFid(i)
|
||||
inFeatB = layerB.getFeatures(request).next()
|
||||
tmpGeom = QgsGeometry(inFeatB.geometry())
|
||||
try:
|
||||
if diff_geom.intersects(tmpGeom):
|
||||
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
|
||||
if diff_geom.isGeosEmpty():
|
||||
GEOS_EXCEPT = False
|
||||
if diff_geom.intersects(tmpGeom):
|
||||
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
|
||||
if diff_geom.isGeosEmpty() or not diff_geom.isGeosValid():
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
|
||||
self.tr('GEOS geoprocessing error: One or '
|
||||
'more input features have invalid '
|
||||
'geometry.'))
|
||||
add = False
|
||||
break
|
||||
except:
|
||||
GEOS_EXCEPT = False
|
||||
add = False
|
||||
break
|
||||
|
||||
if add:
|
||||
try:
|
||||
@ -107,17 +111,11 @@ class Difference(GeoAlgorithm):
|
||||
outFeat.setAttributes(attrs)
|
||||
writer.addFeature(outFeat)
|
||||
except:
|
||||
FEATURE_EXCEPT = False
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
continue
|
||||
|
||||
current += 1
|
||||
progress.setPercentage(int(current * total))
|
||||
|
||||
del writer
|
||||
|
||||
if not GEOS_EXCEPT:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
|
||||
self.tr('Geometry exception while computing difference'))
|
||||
if not FEATURE_EXCEPT:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
|
||||
self.tr('Feature exception while computing difference'))
|
||||
|
@ -26,8 +26,10 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
from qgis.core import QGis, QgsFeatureRequest, QgsFeature, QgsGeometry, QgsWKBTypes
|
||||
|
||||
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.outputs import OutputVector
|
||||
from processing.tools import dataobjects, vector
|
||||
@ -41,6 +43,10 @@ for key, value in wkbTypeGroups.items():
|
||||
for const in value:
|
||||
wkbTypeGroups[const] = key
|
||||
|
||||
GEOM_25D = [QGis.WKBPoint25D, QGis.WKBLineString25D, QGis.WKBPolygon25D,
|
||||
QGis.WKBMultiPoint25D, QGis.WKBMultiLineString25D,
|
||||
QGis.WKBMultiPolygon25D]
|
||||
|
||||
|
||||
class Intersection(GeoAlgorithm):
|
||||
|
||||
@ -48,6 +54,15 @@ class Intersection(GeoAlgorithm):
|
||||
INPUT2 = 'INPUT2'
|
||||
OUTPUT = 'OUTPUT'
|
||||
|
||||
def defineCharacteristics(self):
|
||||
self.name, self.i18n_name = self.trAlgorithm('Intersection')
|
||||
self.group, self.i18n_group = self.trAlgorithm('Vector overlay tools')
|
||||
self.addParameter(ParameterVector(self.INPUT,
|
||||
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
|
||||
self.addParameter(ParameterVector(self.INPUT2,
|
||||
self.tr('Intersect layer'), [ParameterVector.VECTOR_TYPE_ANY]))
|
||||
self.addOutput(OutputVector(self.OUTPUT, self.tr('Intersection')))
|
||||
|
||||
def processAlgorithm(self, progress):
|
||||
vlayerA = dataobjects.getObjectFromUri(
|
||||
self.getParameterValue(self.INPUT))
|
||||
@ -55,9 +70,14 @@ class Intersection(GeoAlgorithm):
|
||||
self.getParameterValue(self.INPUT2))
|
||||
vproviderA = vlayerA.dataProvider()
|
||||
|
||||
geomType = vproviderA.geometryType()
|
||||
if geomType in GEOM_25D:
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Input layer has unsupported geometry type {}').format(geomType))
|
||||
|
||||
fields = vector.combineVectorFields(vlayerA, vlayerB)
|
||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields,
|
||||
vproviderA.geometryType(), vproviderA.crs())
|
||||
geomType, vproviderA.crs())
|
||||
inFeatA = QgsFeature()
|
||||
inFeatB = QgsFeature()
|
||||
outFeat = QgsFeature()
|
||||
@ -75,36 +95,30 @@ class Intersection(GeoAlgorithm):
|
||||
request = QgsFeatureRequest().setFilterFid(i)
|
||||
inFeatB = vlayerB.getFeatures(request).next()
|
||||
tmpGeom = QgsGeometry(inFeatB.geometry())
|
||||
try:
|
||||
if geom.intersects(tmpGeom):
|
||||
atMapB = inFeatB.attributes()
|
||||
int_geom = QgsGeometry(geom.intersection(tmpGeom))
|
||||
if int_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
|
||||
int_com = geom.combine(tmpGeom)
|
||||
int_sym = geom.symDifference(tmpGeom)
|
||||
int_geom = QgsGeometry(int_com.difference(int_sym))
|
||||
try:
|
||||
if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[int_geom.wkbType()]]:
|
||||
outFeat.setGeometry(int_geom)
|
||||
attrs = []
|
||||
attrs.extend(atMapA)
|
||||
attrs.extend(atMapB)
|
||||
outFeat.setAttributes(attrs)
|
||||
writer.addFeature(outFeat)
|
||||
except:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
continue
|
||||
except:
|
||||
break
|
||||
if geom.intersects(tmpGeom):
|
||||
atMapB = inFeatB.attributes()
|
||||
int_geom = QgsGeometry(geom.intersection(tmpGeom))
|
||||
if int_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
|
||||
int_com = geom.combine(tmpGeom)
|
||||
int_sym = geom.symDifference(tmpGeom)
|
||||
int_geom = QgsGeometry(int_com.difference(int_sym))
|
||||
if int_geom.isGeosEmpty() or not int_geom.isGeosValid():
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
|
||||
self.tr('GEOS geoprocessing error: One or '
|
||||
'more input features have invalid '
|
||||
'geometry.'))
|
||||
break
|
||||
try:
|
||||
if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[int_geom.wkbType()]]:
|
||||
outFeat.setGeometry(int_geom)
|
||||
attrs = []
|
||||
attrs.extend(atMapA)
|
||||
attrs.extend(atMapB)
|
||||
outFeat.setAttributes(attrs)
|
||||
writer.addFeature(outFeat)
|
||||
except:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
continue
|
||||
|
||||
del writer
|
||||
|
||||
def defineCharacteristics(self):
|
||||
self.name, self.i18n_name = self.trAlgorithm('Intersection')
|
||||
self.group, self.i18n_group = self.trAlgorithm('Vector overlay tools')
|
||||
self.addParameter(ParameterVector(self.INPUT,
|
||||
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
|
||||
self.addParameter(ParameterVector(self.INPUT2,
|
||||
self.tr('Intersect layer'), [ParameterVector.VECTOR_TYPE_ANY]))
|
||||
self.addOutput(OutputVector(self.OUTPUT, self.tr('Intersection')))
|
||||
|
@ -25,13 +25,18 @@ __copyright__ = '(C) 2014, Alexander Bruy'
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
from qgis.core import QgsFeature, QgsGeometry, QgsFeatureRequest, NULL
|
||||
from qgis.core import QGis, QgsFeature, QgsGeometry, QgsFeatureRequest, NULL
|
||||
from processing.core.ProcessingLog import ProcessingLog
|
||||
from processing.core.GeoAlgorithm import GeoAlgorithm
|
||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||
from processing.core.parameters import ParameterVector
|
||||
from processing.core.outputs import OutputVector
|
||||
from processing.tools import dataobjects, vector
|
||||
|
||||
GEOM_25D = [QGis.WKBPoint25D, QGis.WKBLineString25D, QGis.WKBPolygon25D,
|
||||
QGis.WKBMultiPoint25D, QGis.WKBMultiLineString25D,
|
||||
QGis.WKBMultiPolygon25D]
|
||||
|
||||
|
||||
class SymmetricalDifference(GeoAlgorithm):
|
||||
|
||||
@ -58,12 +63,14 @@ class SymmetricalDifference(GeoAlgorithm):
|
||||
providerA = layerA.dataProvider()
|
||||
providerB = layerB.dataProvider()
|
||||
|
||||
GEOS_EXCEPT = True
|
||||
FEATURE_EXCEPT = True
|
||||
geomType = providerA.geometryType()
|
||||
if geomType in GEOM_25D:
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Input layer has unsupported geometry type {}').format(geomType))
|
||||
|
||||
fields = vector.combineVectorFields(layerA, layerB)
|
||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
|
||||
fields, providerA.geometryType(), providerA.crs())
|
||||
fields, geomType, providerA.crs())
|
||||
|
||||
featB = QgsFeature()
|
||||
outFeat = QgsFeature()
|
||||
@ -86,20 +93,24 @@ class SymmetricalDifference(GeoAlgorithm):
|
||||
for i in intersects:
|
||||
providerB.getFeatures(QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
|
||||
tmpGeom = QgsGeometry(featB.geometry())
|
||||
try:
|
||||
if diffGeom.intersects(tmpGeom):
|
||||
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
|
||||
except:
|
||||
add = False
|
||||
GEOS_EXCEPT = False
|
||||
break
|
||||
if diffGeom.intersects(tmpGeom):
|
||||
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
|
||||
if not diffGeom.isGeosValid():
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
|
||||
self.tr('GEOS geoprocessing error: One or '
|
||||
'more input features have invalid '
|
||||
'geometry.'))
|
||||
add = False
|
||||
break
|
||||
|
||||
if add:
|
||||
try:
|
||||
outFeat.setGeometry(diffGeom)
|
||||
outFeat.setAttributes(attrs)
|
||||
writer.addFeature(outFeat)
|
||||
except:
|
||||
FEATURE_EXCEPT = False
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
continue
|
||||
|
||||
count += 1
|
||||
@ -117,30 +128,27 @@ class SymmetricalDifference(GeoAlgorithm):
|
||||
for i in intersects:
|
||||
providerA.getFeatures(QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
|
||||
tmpGeom = QgsGeometry(featB.geometry())
|
||||
try:
|
||||
if diffGeom.intersects(tmpGeom):
|
||||
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
|
||||
except:
|
||||
add = False
|
||||
GEOS_EXCEPT = False
|
||||
break
|
||||
if diffGeom.intersects(tmpGeom):
|
||||
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
|
||||
if not diffGeom.isGeosValid():
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
|
||||
self.tr('GEOS geoprocessing error: One or '
|
||||
'more input features have invalid '
|
||||
'geometry.'))
|
||||
add = False
|
||||
break
|
||||
|
||||
if add:
|
||||
try:
|
||||
outFeat.setGeometry(diffGeom)
|
||||
outFeat.setAttributes(attrs)
|
||||
writer.addFeature(outFeat)
|
||||
except:
|
||||
FEATURE_EXCEPT = False
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
continue
|
||||
|
||||
count += 1
|
||||
progress.setPercentage(int(count * total))
|
||||
|
||||
del writer
|
||||
|
||||
if not GEOS_EXCEPT:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
|
||||
self.tr('Geometry exception while computing symmetrical difference'))
|
||||
if not FEATURE_EXCEPT:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
|
||||
self.tr('Feature exception while computing symmetrical difference'))
|
||||
|
@ -33,6 +33,19 @@ from processing.core.parameters import ParameterVector
|
||||
from processing.core.outputs import OutputVector
|
||||
from processing.tools import dataobjects, vector
|
||||
|
||||
wkbTypeGroups = {
|
||||
'Point': (QGis.WKBPoint, QGis.WKBMultiPoint, QGis.WKBPoint25D, QGis.WKBMultiPoint25D,),
|
||||
'LineString': (QGis.WKBLineString, QGis.WKBMultiLineString, QGis.WKBLineString25D, QGis.WKBMultiLineString25D,),
|
||||
'Polygon': (QGis.WKBPolygon, QGis.WKBMultiPolygon, QGis.WKBPolygon25D, QGis.WKBMultiPolygon25D,),
|
||||
}
|
||||
for key, value in wkbTypeGroups.items():
|
||||
for const in value:
|
||||
wkbTypeGroups[const] = key
|
||||
|
||||
GEOM_25D = [QGis.WKBPoint25D, QGis.WKBLineString25D, QGis.WKBPolygon25D,
|
||||
QGis.WKBMultiPoint25D, QGis.WKBMultiLineString25D,
|
||||
QGis.WKBMultiPolygon25D]
|
||||
|
||||
|
||||
class Union(GeoAlgorithm):
|
||||
|
||||
@ -40,18 +53,29 @@ class Union(GeoAlgorithm):
|
||||
INPUT2 = 'INPUT2'
|
||||
OUTPUT = 'OUTPUT'
|
||||
|
||||
def defineCharacteristics(self):
|
||||
self.name, self.i18n_name = self.trAlgorithm('Union')
|
||||
self.group, self.i18n_group = self.trAlgorithm('Vector overlay tools')
|
||||
self.addParameter(ParameterVector(Union.INPUT,
|
||||
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
|
||||
self.addParameter(ParameterVector(Union.INPUT2,
|
||||
self.tr('Input layer 2'), [ParameterVector.VECTOR_TYPE_ANY]))
|
||||
self.addOutput(OutputVector(Union.OUTPUT, self.tr('Union')))
|
||||
|
||||
def processAlgorithm(self, progress):
|
||||
vlayerA = dataobjects.getObjectFromUri(self.getParameterValue(Union.INPUT))
|
||||
vlayerB = dataobjects.getObjectFromUri(self.getParameterValue(Union.INPUT2))
|
||||
GEOS_EXCEPT = True
|
||||
FEATURE_EXCEPT = True
|
||||
|
||||
vproviderA = vlayerA.dataProvider()
|
||||
|
||||
geomType = vproviderA.geometryType()
|
||||
if geomType in GEOM_25D:
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Input layer has unsupported geometry type {}').format(geomType))
|
||||
|
||||
fields = vector.combineVectorFields(vlayerA, vlayerB)
|
||||
names = [field.name() for field in fields]
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, unicode(names))
|
||||
writer = self.getOutputFromName(Union.OUTPUT).getVectorWriter(fields,
|
||||
vproviderA.geometryType(), vproviderA.crs())
|
||||
geomType, vproviderA.crs())
|
||||
inFeatA = QgsFeature()
|
||||
inFeatB = QgsFeature()
|
||||
outFeat = QgsFeature()
|
||||
@ -77,8 +101,8 @@ class Union(GeoAlgorithm):
|
||||
except:
|
||||
# This really shouldn't happen, as we haven't
|
||||
# edited the input geom at all
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Feature exception while computing union'))
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
else:
|
||||
for id in intersects:
|
||||
count += 1
|
||||
@ -93,9 +117,9 @@ class Union(GeoAlgorithm):
|
||||
|
||||
if int_geom is None:
|
||||
# There was a problem creating the intersection
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Geometry exception while computing '
|
||||
'intersection'))
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.'))
|
||||
int_geom = QgsGeometry()
|
||||
else:
|
||||
int_geom = QgsGeometry(int_geom)
|
||||
|
||||
@ -105,38 +129,52 @@ class Union(GeoAlgorithm):
|
||||
for i in temp_list:
|
||||
if i.type() == geom.type():
|
||||
int_geom = QgsGeometry(i)
|
||||
try:
|
||||
outFeat.setGeometry(int_geom)
|
||||
attrs = []
|
||||
attrs.extend(atMapA)
|
||||
attrs.extend(atMapB)
|
||||
outFeat.setAttributes(attrs)
|
||||
writer.addFeature(outFeat)
|
||||
except Exception as err:
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Feature exception while computing union'))
|
||||
try:
|
||||
outFeat.setGeometry(int_geom)
|
||||
outFeat.setAttributes(atMapA + atMapB)
|
||||
writer.addFeature(outFeat)
|
||||
except:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
else:
|
||||
# Geometry list: prevents writing error
|
||||
# in geometries of different types
|
||||
# produced by the intersection
|
||||
# fix #3549
|
||||
if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[int_geom.wkbType()]]:
|
||||
try:
|
||||
outFeat.setGeometry(int_geom)
|
||||
outFeat.setAttributes(atMapA + atMapB)
|
||||
writer.addFeature(outFeat)
|
||||
except:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
|
||||
# the remaining bit of inFeatA's geometry
|
||||
# if there is nothing left, this will just silently fail and we're good
|
||||
diff_geom = QgsGeometry(geom)
|
||||
if len(lstIntersectingB) != 0:
|
||||
intB = QgsGeometry.unaryUnion(lstIntersectingB)
|
||||
diff_geom = diff_geom.difference(intB)
|
||||
if diff_geom.isGeosEmpty() or not diff_geom.isGeosValid():
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
|
||||
self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.'))
|
||||
|
||||
if diff_geom.wkbType() == 0 or QgsWKBTypes.flatType(diff_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
|
||||
temp_list = diff_geom.asGeometryCollection()
|
||||
for i in temp_list:
|
||||
if i.type() == geom.type():
|
||||
diff_geom = QgsGeometry(i)
|
||||
try:
|
||||
# the remaining bit of inFeatA's geometry
|
||||
# if there is nothing left, this will just silently fail and we're good
|
||||
diff_geom = QgsGeometry(geom)
|
||||
if len(lstIntersectingB) != 0:
|
||||
intB = QgsGeometry.unaryUnion(lstIntersectingB)
|
||||
diff_geom = diff_geom.difference(intB)
|
||||
|
||||
if diff_geom.wkbType() == 0 or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
|
||||
temp_list = diff_geom.asGeometryCollection()
|
||||
for i in temp_list:
|
||||
if i.type() == geom.type():
|
||||
diff_geom = QgsGeometry(i)
|
||||
outFeat.setGeometry(diff_geom)
|
||||
outFeat.setAttributes(atMapA)
|
||||
writer.addFeature(outFeat)
|
||||
except Exception as err:
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Feature exception while computing union'))
|
||||
except:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
|
||||
length = len(vproviderA.fields())
|
||||
atMapA = [None] * length
|
||||
|
||||
featuresA = vector.features(vlayerB)
|
||||
nFeat = len(featuresA)
|
||||
@ -154,53 +192,41 @@ class Union(GeoAlgorithm):
|
||||
outFeat.setGeometry(geom)
|
||||
outFeat.setAttributes(atMap)
|
||||
writer.addFeature(outFeat)
|
||||
except Exception as err:
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Feature exception while computing union'))
|
||||
except:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
else:
|
||||
for id in intersects:
|
||||
request = QgsFeatureRequest().setFilterFid(id)
|
||||
inFeatB = vlayerA.getFeatures(request).next()
|
||||
atMapB = inFeatB.attributes()
|
||||
tmpGeom = QgsGeometry(inFeatB.geometry())
|
||||
try:
|
||||
if diff_geom.intersects(tmpGeom):
|
||||
add = True
|
||||
diff_geom = QgsGeometry(
|
||||
diff_geom.difference(tmpGeom))
|
||||
else:
|
||||
|
||||
if diff_geom.intersects(tmpGeom):
|
||||
add = True
|
||||
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
|
||||
if diff_geom.isGeosEmpty() or not diff_geom.isGeosValid():
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
|
||||
self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.'))
|
||||
else:
|
||||
try:
|
||||
# Ihis only happends if the bounding box
|
||||
# intersects, but the geometry doesn't
|
||||
outFeat.setGeometry(diff_geom)
|
||||
outFeat.setAttributes(atMap)
|
||||
writer.addFeature(outFeat)
|
||||
except Exception as err:
|
||||
raise GeoAlgorithmExecutionException(
|
||||
self.tr('Geometry exception while computing intersection'))
|
||||
except:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
|
||||
if add:
|
||||
try:
|
||||
outFeat.setGeometry(diff_geom)
|
||||
outFeat.setAttributes(atMap)
|
||||
writer.addFeature(outFeat)
|
||||
except Exception as err:
|
||||
raise err
|
||||
FEATURE_EXCEPT = False
|
||||
except:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
nElement += 1
|
||||
|
||||
del writer
|
||||
if not GEOS_EXCEPT:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
|
||||
self.tr('Geometry exception while computing intersection'))
|
||||
if not FEATURE_EXCEPT:
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
|
||||
self.tr('Feature exception while computing intersection'))
|
||||
|
||||
def defineCharacteristics(self):
|
||||
self.name, self.i18n_name = self.trAlgorithm('Union')
|
||||
self.group, self.i18n_group = self.trAlgorithm('Vector overlay tools')
|
||||
self.addParameter(ParameterVector(Union.INPUT,
|
||||
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
|
||||
self.addParameter(ParameterVector(Union.INPUT2,
|
||||
self.tr('Input layer 2'), [ParameterVector.VECTOR_TYPE_ANY]))
|
||||
self.addOutput(OutputVector(Union.OUTPUT, self.tr('Union')))
|
||||
|
Loading…
x
Reference in New Issue
Block a user