diff --git a/python/plugins/sextante/algs/ftools/Difference.py b/python/plugins/sextante/algs/ftools/Difference.py index 15ce119330d7..532da9f26ea1 100644 --- a/python/plugins/sextante/algs/ftools/Difference.py +++ b/python/plugins/sextante/algs/ftools/Difference.py @@ -22,22 +22,24 @@ # This will get replaced with a git SHA1 when you do a git archive __revision__ = '$Format:%H$' - from PyQt4.QtCore import * -from PyQt4.QtGui import * + from qgis.core import * -from sextante.parameters.ParameterVector import ParameterVector + from sextante.core.QGisLayers import QGisLayers -from sextante.outputs.OutputVector import OutputVector -from sextante.algs.ftools import FToolsUtils as utils from sextante.core.SextanteLog import SextanteLog from sextante.core.GeoAlgorithm import GeoAlgorithm +from sextante.parameters.ParameterVector import ParameterVector + +from sextante.outputs.OutputVector import OutputVector + +from sextante.algs.ftools import FToolsUtils as utils class Difference(GeoAlgorithm): INPUT = "INPUT" - INPUT2 = "INPUT2" + OVERLAY = "OVERLAY" OUTPUT = "OUTPUT" #=========================================================================== @@ -45,67 +47,68 @@ class Difference(GeoAlgorithm): # return QtGui.QIcon(os.path.dirname(__file__) + "/icons/difference.png") #=========================================================================== + def defineCharacteristics(self): + self.name = "Difference" + self.group = "Vector overlay tools" + self.addParameter(ParameterVector(Difference.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY)) + self.addParameter(ParameterVector(Difference.OVERLAY, "Difference layer", ParameterVector.VECTOR_TYPE_ANY)) + self.addOutput(OutputVector(Difference.OUTPUT, "Difference")) + def processAlgorithm(self, progress): - vlayerA = QGisLayers.getObjectFromUri(self.getParameterValue(Difference.INPUT)) - vlayerB = QGisLayers.getObjectFromUri(self.getParameterValue(Difference.INPUT2)) + layerA = QGisLayers.getObjectFromUri(self.getParameterValue(Difference.INPUT)) + layerB = QGisLayers.getObjectFromUri(self.getParameterValue(Difference.OVERLAY)) + GEOS_EXCEPT = True + FEATURE_EXCEPT = True - vproviderA = vlayerA.dataProvider() - vproviderB = vlayerB.dataProvider() - fields = vproviderA.fields() - # check for crs compatibility - crsA = vproviderA.crs() - crsB = vproviderB.crs() - if not crsA.isValid() or not crsB.isValid(): - SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Difference. Invalid CRS. Results might be unexpected") - else: - if crsA != crsB: - SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Difference. Non-matching CRSs. Results might be unexpected") - writer = self.getOutputFromName(Difference.OUTPUT).getVectorWriter(fields, vproviderA.geometryType(), vproviderA.crs() ) + + writer = self.getOutputFromName(Difference.OUTPUT).getVectorWriter(layerA.pendingFields(), + layerA.dataProvider().geometryType(), layerA.dataProvider().crs()) + inFeatA = QgsFeature() inFeatB = QgsFeature() outFeat = QgsFeature() - index = utils.createSpatialIndex(vlayerB) - nElement = 0 - selectionA = QGisLayers.features(vlayerA) - nFeat = len(selectionA) + + index = utils.createSpatialIndex(layerB) + + selectionA = QGisLayers.features(layerA) + + current = 0 + total = 100.0 / float(len(selectionA)) + for inFeatA in selectionA: - nElement += 1 - progress.setPercentage(nElement/float(nFeat) * 100) add = True - geom = QgsGeometry( inFeatA.geometry() ) - diff_geom = QgsGeometry( geom ) - atMap = inFeatA.attributes() - intersects = index.intersects( geom.boundingBox() ) - for id in intersects: - vlayerB.featureAtId( int( id ), inFeatB , True) - tmpGeom = QgsGeometry( inFeatB.geometry() ) + geom = QgsGeometry(inFeatA.geometry()) + diff_geom = QgsGeometry(geom) + attrs = inFeatA.attributes() + intersections = index.intersects(geom.boundingBox()) + for i in intersections: + 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.intersects(tmpGeom): + diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) except: GEOS_EXCEPT = False add = False break + if add: try: - outFeat.setGeometry( diff_geom ) - outFeat.setAttributes( atMap ) - writer.addFeature( outFeat ) + outFeat.setGeometry(diff_geom) + outFeat.setAttributes(attrs) + writer.addFeature(outFeat) except: FEATURE_EXCEPT = False continue + current += 1 + progress.setPercentage(int(current * total)) del writer + if not GEOS_EXCEPT: SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Geometry exception while computing difference") if not FEATURE_EXCEPT: SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Feature exception while computing difference") - - def defineCharacteristics(self): - self.name = "Difference" - self.group = "Vector overlay tools" - self.addParameter(ParameterVector(Difference.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY)) - self.addParameter(ParameterVector(Difference.INPUT2, "Difference layer", ParameterVector.VECTOR_TYPE_ANY)) - self.addOutput(OutputVector(Difference.OUTPUT, "Difference"))