207 lines
9.3 KiB
Python
Raw Normal View History

2012-10-04 19:33:47 +02:00
# -*- coding: utf-8 -*-
"""
***************************************************************************
Union.py
---------------------
Date : August 2012
Copyright : (C) 2012 by Victor Olaya
Email : volayaf at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
2012-10-04 19:33:47 +02:00
# This will get replaced with a git SHA1 when you do a git archive
2012-10-04 19:33:47 +02:00
__revision__ = '$Format:%H$'
from qgis.core import QgsFeatureRequest, QgsFeature, QgsGeometry
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
2012-09-15 18:25:25 +03:00
class Union(GeoAlgorithm):
2012-09-15 18:25:25 +03:00
INPUT = 'INPUT'
INPUT2 = 'INPUT2'
OUTPUT = 'OUTPUT'
2012-09-15 18:25:25 +03:00
def processAlgorithm(self, progress):
vlayerA = dataobjects.getObjectFromUri(self.getParameterValue(Union.INPUT))
vlayerB = dataobjects.getObjectFromUri(self.getParameterValue(Union.INPUT2))
2012-09-15 18:25:25 +03:00
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = vlayerA.dataProvider()
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())
2012-09-15 18:25:25 +03:00
inFeatA = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
indexA = vector.spatialindex(vlayerB)
indexB = vector.spatialindex(vlayerA)
2012-09-15 18:25:25 +03:00
count = 0
nElement = 0
featuresA = vector.features(vlayerA)
nFeat = len(featuresA)
for inFeatA in featuresA:
progress.setPercentage(nElement / float(nFeat) * 50)
nElement += 1
lstIntersectingB = []
geom = QgsGeometry(inFeatA.geometry())
atMapA = inFeatA.attributes()
intersects = indexA.intersects(geom.boundingBox())
if len(intersects) < 1:
try:
outFeat.setGeometry(geom)
outFeat.setAttributes(atMapA)
writer.addFeature(outFeat)
except:
# This really shouldn't happen, as we haven't
# edited the input geom at all
raise GeoAlgorithmExecutionException(
2015-01-15 20:41:15 +02:00
self.tr('Feature exception while computing union'))
else:
for id in intersects:
count += 1
request = QgsFeatureRequest().setFilterFid(id)
inFeatB = vlayerB.getFeatures(request).next()
atMapB = inFeatB.attributes()
tmpGeom = QgsGeometry(inFeatB.geometry())
if geom.intersects(tmpGeom):
int_geom = geom.intersection(tmpGeom)
lstIntersectingB.append(tmpGeom)
if int_geom is None:
# There was a problem creating the intersection
raise GeoAlgorithmExecutionException(
2015-01-15 20:41:15 +02:00
self.tr('Geometry exception while computing '
'intersection'))
else:
int_geom = QgsGeometry(int_geom)
if int_geom.wkbType() == 0:
# Intersection produced different geomety types
temp_list = int_geom.asGeometryCollection()
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(
2015-01-15 20:41:15 +02:00
self.tr('Feature exception while computing union'))
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:
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(
2015-01-15 20:41:15 +02:00
self.tr('Feature exception while computing union'))
2012-09-15 18:25:25 +03:00
2013-02-07 01:09:39 +01:00
length = len(vproviderA.fields())
2012-09-15 18:25:25 +03:00
featuresA = vector.features(vlayerB)
nFeat = len(featuresA)
for inFeatA in featuresA:
progress.setPercentage(nElement / float(nFeat) * 100)
add = False
geom = QgsGeometry(inFeatA.geometry())
diff_geom = QgsGeometry(geom)
atMap = [None] * length
2013-02-07 01:09:39 +01:00
atMap.extend(inFeatA.attributes())
intersects = indexB.intersects(geom.boundingBox())
if len(intersects) < 1:
try:
2013-05-06 23:07:42 +02:00
outFeat.setGeometry(geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except Exception as err:
raise GeoAlgorithmExecutionException(
2015-01-15 20:41:15 +02:00
self.tr('Feature exception while computing union'))
else:
for id in intersects:
request = QgsFeatureRequest().setFilterFid(id)
2013-03-26 14:15:12 +01:00
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:
# 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(
2015-01-15 20:41:15 +02:00
self.tr('Geometry exception while computing intersection'))
2012-09-15 18:25:25 +03:00
if add:
try:
outFeat.setGeometry(diff_geom)
2013-05-06 23:07:42 +02:00
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except Exception as err:
2013-02-07 01:09:39 +01:00
raise err
FEATURE_EXCEPT = False
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'))
2012-09-15 18:25:25 +03:00
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Union')
self.group, self.i18n_group = self.trAlgorithm('Vector overlay tools')
2015-01-15 20:41:15 +02:00
self.addParameter(ParameterVector(Union.INPUT,
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY]))
2015-01-15 20:41:15 +02:00
self.addParameter(ParameterVector(Union.INPUT2,
self.tr('Input layer 2'), [ParameterVector.VECTOR_TYPE_ANY]))
2015-01-15 20:41:15 +02:00
self.addOutput(OutputVector(Union.OUTPUT, self.tr('Union')))