From fa7d689f3e18ce6c8d99cf7fe4d94bc202cfa580 Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Wed, 3 Oct 2012 19:18:28 +0300 Subject: [PATCH] review buffer tools --- python/plugins/sextante/ftools/Buffer.py | 240 +++++++++--------- .../sextante/ftools/FixedDistanceBuffer.py | 56 ++-- .../sextante/ftools/VariableDistanceBuffer.py | 58 +++-- 3 files changed, 188 insertions(+), 166 deletions(-) diff --git a/python/plugins/sextante/ftools/Buffer.py b/python/plugins/sextante/ftools/Buffer.py index f16a67a5089d..cabbdca42568 100644 --- a/python/plugins/sextante/ftools/Buffer.py +++ b/python/plugins/sextante/ftools/Buffer.py @@ -1,144 +1,154 @@ from PyQt4.QtCore import * -from PyQt4.QtGui import * + from qgis.core import * -from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException + from sextante.core.SextanteLog import SextanteLog -def buffering(progress, writer, distance, field, useSelection, useField, layer, dissolve, segments ): +def buffering(progress, writer, distance, field, useSelection, useField, layer, dissolve, segments): GEOS_EXCEPT = True FEATURE_EXCEPT = True - vproviderA = layer.dataProvider() - allAttrs = vproviderA.attributeIndexes() - vproviderA.select( allAttrs ) - fields = vproviderA.fields() + + layer.select(layer.pendingAllAttributesList()) + if useField: - field = vproviderA.fieldNameIndex(field) + field = layer.fieldNameIndex(field) + outFeat = QgsFeature() inFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() - nElement = 0 + + current = 0 + # there is selection in input layer if useSelection: - nFeat = layer.selectedFeatureCount() - selectionA = layer.selectedFeatures() - # with dissolve - if dissolve: - first = True - for inFeat in selectionA: - atMap = inFeat.attributeMap() - if useField: - value = atMap[ field ].doDouble()[ 0 ] - else: - value = distance - inGeom = QgsGeometry( inFeat.geometry() ) - try: - outGeom = inGeom.buffer( float( value ), segments) - if first: - tempGeom = QgsGeometry( outGeom ) - first = False - else: - try: - tempGeom = tempGeom.combine( outGeom ) - except: - GEOS_EXCEPT = False - continue - except: - GEOS_EXCEPT = False - continue - nElement += 1 - progress.setPercentage(int(nElement/nFeat * 100)) - try: - outFeat.setGeometry( tempGeom ) - writer.addFeature( outFeat ) - except: - FEATURE_EXCEPT = False - # without dissolve - else: - for inFeat in selectionA: - atMap = inFeat.attributeMap() - if useField: - value = atMap[ field ].toDouble()[ 0 ] - else: - value = distance - inGeom = QgsGeometry( inFeat.geometry() ) - try: - outGeom = inGeom.buffer( float( value ), segments ) + total = 100.0 / float(layer.selectedFeatureCount()) + selection = layer.selectedFeatures() + + # with dissolve + if dissolve: + first = True + for inFeat in selection: + atMap = inFeat.attributeMap() + if useField: + value = atMap[field].doDouble()[0] + else: + value = distance + + inGeom = QgsGeometry(inFeat.geometry()) + try: + outGeom = inGeom.buffer(float(value), segments) + if first: + tempGeom = QgsGeometry(outGeom) + first = False + else: + try: + tempGeom = tempGeom.combine( outGeom ) + except: + GEOS_EXCEPT = False + continue + except: + GEOS_EXCEPT = False + continue + + current += 1 + progress.setPercentage(int(current * total)) try: - outFeat.setGeometry( outGeom ) - outFeat.setAttributeMap( atMap ) - writer.addFeature( outFeat ) + outFeat.setGeometry(tempGeom) + writer.addFeature(outFeat) except: - FEATURE_EXCEPT = False - continue - except: - GEOS_EXCEPT = False - continue - nElement += 1 - progress.setPercentage(int(nElement/nFeat * 100)) + FEATURE_EXCEPT = False + # without dissolve + else: + for inFeat in selection: + atMap = inFeat.attributeMap() + if useField: + value = atMap[field].toDouble()[0] + else: + value = distance + + inGeom = QgsGeometry(inFeat.geometry()) + try: + outGeom = inGeom.buffer(float(value), segments) + try: + outFeat.setGeometry(outGeom) + outFeat.setAttributeMap(atMap) + writer.addFeature(outFeat) + except: + FEATURE_EXCEPT = False + continue + except: + GEOS_EXCEPT = False + continue + + current += 1 + progress.setPercentage(int(current * total)) # there is no selection in input layer else: - nFeat = vproviderA.featureCount() + total = 100.0 / float(layer.featureCount()) + # with dissolve if dissolve: - first = True - while vproviderA.nextFeature( inFeat ): - atMap = inFeat.attributeMap() - if useField: - value = atMap[ field ].toDouble()[ 0 ] - else: - value = distance - inGeom = QgsGeometry( inFeat.geometry() ) - try: - outGeom = inGeom.buffer( float( value ), segments) - if first: - tempGeom = QgsGeometry( outGeom ) - first = False - else: + first = True + while layer.nextFeature(inFeat): + atMap = inFeat.attributeMap() + if useField: + value = atMap[field].toDouble()[0] + else: + value = distance + + inGeom = QgsGeometry(inFeat.geometry()) try: - tempGeom = tempGeom.combine( outGeom ) + outGeom = inGeom.buffer(float(value), segments) + if first: + tempGeom = QgsGeometry(outGeom) + first = False + else: + try: + tempGeom = tempGeom.combine(outGeom) + except: + GEOS_EXCEPT = False + continue except: - GEOS_EXCEPT = False - continue + GEOS_EXCEPT = False + continue + + current += 1 + progress.setPercentage(int(current * total)) + try: + outFeat.setGeometry(tempGeom) + writer.addFeature(outFeat) except: - GEOS_EXCEPT = False - continue - nElement += 1 - progress.setPercentage(int(nElement/nFeat * 100)) - try: - outFeat.setGeometry( tempGeom ) - writer.addFeature( outFeat ) - except: - FEATURE_EXCEPT = False + FEATURE_EXCEPT = False # without dissolve else: - vproviderA.rewind() - while vproviderA.nextFeature( inFeat ): - atMap = inFeat.attributeMap() - if useField: - value = atMap[ field ].toDouble()[ 0 ] - else: - value = distance - inGeom = QgsGeometry( inFeat.geometry() ) - try: - outGeom = inGeom.buffer( float( value ),segments ) - try: - outFeat.setGeometry( outGeom ) - outFeat.setAttributeMap( atMap ) - writer.addFeature( outFeat ) - except: - FEATURE_EXCEPT = False - continue - except: - GEOS_EXCEPT = False - continue - nElement += 1 - progress.setPercentage(int(nElement/nFeat * 100)) + while layer.nextFeature(inFeat): + atMap = inFeat.attributeMap() + if useField: + value = atMap[field].toDouble()[0] + else: + value = distance + + inGeom = QgsGeometry(inFeat.geometry()) + try: + outGeom = inGeom.buffer(float(value), segments) + try: + outFeat.setGeometry(outGeom) + outFeat.setAttributeMap(atMap) + writer.addFeature(outFeat) + except: + FEATURE_EXCEPT = False + continue + except: + GEOS_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 buffer") if not FEATURE_EXCEPT: SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Feature exception while computing buffer") - - - diff --git a/python/plugins/sextante/ftools/FixedDistanceBuffer.py b/python/plugins/sextante/ftools/FixedDistanceBuffer.py index 8ecca4257240..1a6d98358ddc 100644 --- a/python/plugins/sextante/ftools/FixedDistanceBuffer.py +++ b/python/plugins/sextante/ftools/FixedDistanceBuffer.py @@ -1,14 +1,19 @@ -from sextante.core.GeoAlgorithm import GeoAlgorithm import os.path + from PyQt4 import QtGui from PyQt4.QtCore import * -from PyQt4.QtGui import * + from qgis.core import * -from sextante.parameters.ParameterVector import ParameterVector + +from sextante.core.GeoAlgorithm import GeoAlgorithm from sextante.core.QGisLayers import QGisLayers -from sextante.outputs.OutputVector import OutputVector + +from sextante.parameters.ParameterVector import ParameterVector from sextante.parameters.ParameterBoolean import ParameterBoolean from sextante.parameters.ParameterNumber import ParameterNumber + +from sextante.outputs.OutputVector import OutputVector + from sextante.ftools import Buffer as buff class FixedDistanceBuffer(GeoAlgorithm): @@ -24,27 +29,28 @@ class FixedDistanceBuffer(GeoAlgorithm): def getIcon(self): return QtGui.QIcon(os.path.dirname(__file__) + "/icons/buffer.png") - def processAlgorithm(self, progress): - vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(FixedDistanceBuffer.INPUT)) - vprovider = vlayer.dataProvider() - allAttrs = vprovider.attributeIndexes() - vprovider.select(allAttrs) - writer = self.getOutputFromName(FixedDistanceBuffer.OUTPUT).getVectorWriter(vprovider.fields(), QGis.WKBPolygon, vprovider.crs() ) - useSelection = self.getParameterValue(FixedDistanceBuffer.USE_SELECTED) - distance = self.getParameterValue(FixedDistanceBuffer.DISTANCE) - dissolve = self.getParameterValue(FixedDistanceBuffer.DISSOLVE) - segments = int(self.getParameterValue(FixedDistanceBuffer.SEGMENTS)) - layer = QGisLayers.getObjectFromUri(self.getParameterValue(FixedDistanceBuffer.INPUT)) - buff.buffering(progress, writer, distance, None, useSelection, False, layer, dissolve, segments) - def defineCharacteristics(self): self.name = "Fixed distance buffer" self.group = "Geoprocessing tools" - self.addParameter(ParameterVector(FixedDistanceBuffer.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY)) - self.addParameter(ParameterBoolean(FixedDistanceBuffer.USE_SELECTED, "Use selected features", False)) - self.addParameter(ParameterNumber(FixedDistanceBuffer.DISTANCE, "Distance", 0, default=10 )) - self.addParameter(ParameterNumber(FixedDistanceBuffer.SEGMENTS, "Segments", 1, default=10 )) - self.addParameter(ParameterBoolean(FixedDistanceBuffer.DISSOLVE, "Dissolve result", True)) - self.addOutput(OutputVector(FixedDistanceBuffer.OUTPUT, "Buffer")) - - #========================================================= + + self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY)) + self.addParameter(ParameterBoolean(self.USE_SELECTED, "Use selected features", False)) + self.addParameter(ParameterNumber(self.DISTANCE, "Distance", 0.0, default=10.0)) + self.addParameter(ParameterNumber(self.SEGMENTS, "Segments", 1, default=5)) + self.addParameter(ParameterBoolean(self.DISSOLVE, "Dissolve result", False)) + + self.addOutput(OutputVector(self.OUTPUT, "Buffer")) + + def processAlgorithm(self, progress): + layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT)) + useSelection = self.getParameterValue(self.USE_SELECTED) + distance = self.getParameterValue(self.DISTANCE) + dissolve = self.getParameterValue(self.DISSOLVE) + segments = int(self.getParameterValue(self.SEGMENTS)) + + provider = layer.dataProvider() + writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.pendingFields(), + QGis.WKBPolygon, provider.crs()) + + buff.buffering(progress, writer, distance, None, useSelection, False, + layer, dissolve, segments) diff --git a/python/plugins/sextante/ftools/VariableDistanceBuffer.py b/python/plugins/sextante/ftools/VariableDistanceBuffer.py index 3e20b925dc8a..a0c9af25e28e 100644 --- a/python/plugins/sextante/ftools/VariableDistanceBuffer.py +++ b/python/plugins/sextante/ftools/VariableDistanceBuffer.py @@ -1,17 +1,22 @@ -from sextante.core.GeoAlgorithm import GeoAlgorithm import os.path + from PyQt4 import QtGui from PyQt4.QtCore import * -from PyQt4.QtGui import * + from qgis.core import * -from sextante.parameters.ParameterVector import ParameterVector + +from sextante.core.GeoAlgorithm import GeoAlgorithm from sextante.core.QGisLayers import QGisLayers -from sextante.outputs.OutputVector import OutputVector + +from sextante.parameters.ParameterVector import ParameterVector from sextante.parameters.ParameterBoolean import ParameterBoolean from sextante.parameters.ParameterNumber import ParameterNumber -from sextante.ftools import Buffer as buff from sextante.parameters.ParameterTableField import ParameterTableField +from sextante.outputs.OutputVector import OutputVector + +from sextante.ftools import Buffer as buff + class VariableDistanceBuffer(GeoAlgorithm): INPUT = "INPUT" @@ -24,27 +29,28 @@ class VariableDistanceBuffer(GeoAlgorithm): def getIcon(self): return QtGui.QIcon(os.path.dirname(__file__) + "/icons/buffer.png") - def processAlgorithm(self, progress): - vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(VariableDistanceBuffer.INPUT)) - vprovider = vlayer.dataProvider() - allAttrs = vprovider.attributeIndexes() - vprovider.select(allAttrs) - writer = self.getOutputFromName(VariableDistanceBuffer.OUTPUT).getVectorWriter(vprovider.fields(), QGis.WKBPolygon, vprovider.crs() ) - useSelection = self.getParameterValue(VariableDistanceBuffer.USE_SELECTED) - dissolve = self.getParameterValue(VariableDistanceBuffer.DISSOLVE) - field = self.getParameterValue(VariableDistanceBuffer.FIELD) - segments = int(self.getParameterValue(VariableDistanceBuffer.SEGMENTS)) - layer = QGisLayers.getObjectFromUri(self.getParameterValue(VariableDistanceBuffer.INPUT)) - buff.buffering(progress, writer, 0, field, useSelection, True, layer, dissolve, segments) - def defineCharacteristics(self): self.name = "Variable distance buffer" self.group = "Geoprocessing tools" - self.addParameter(ParameterVector(VariableDistanceBuffer.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY)) - self.addParameter(ParameterBoolean(VariableDistanceBuffer.USE_SELECTED, "Use selected features", False)) - self.addParameter(ParameterTableField(VariableDistanceBuffer.FIELD, "Distance field",VariableDistanceBuffer.INPUT )) - self.addParameter(ParameterNumber(VariableDistanceBuffer.SEGMENTS, "Segments", 1, default=10 )) - self.addParameter(ParameterBoolean(VariableDistanceBuffer.DISSOLVE, "Dissolve result", True)) - self.addOutput(OutputVector(VariableDistanceBuffer.OUTPUT, "Buffer")) - - #========================================================= + + self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY)) + self.addParameter(ParameterBoolean(self.USE_SELECTED, "Use selected features", False)) + self.addParameter(ParameterTableField(self.FIELD, "Distance field",self.INPUT )) + self.addParameter(ParameterNumber(self.SEGMENTS, "Segments", 1, default=5)) + self.addParameter(ParameterBoolean(self.DISSOLVE, "Dissolve result", False)) + + self.addOutput(OutputVector(self.OUTPUT, "Buffer")) + + def processAlgorithm(self, progress): + layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT)) + useSelection = self.getParameterValue(self.USE_SELECTED) + dissolve = self.getParameterValue(self.DISSOLVE) + field = self.getParameterValue(self.FIELD) + segments = int(self.getParameterValue(self.SEGMENTS)) + + provider = layer.dataProvider() + writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.pendingFields(), + QGis.WKBPolygon, provider.crs()) + + buff.buffering(progress, writer, 0, field, useSelection, True, + layer, dissolve, segments)