Port Variable distance buffer to new API

Improvements:
- add cap style/join style/ miter limit setting from fixed distance buffer
This commit is contained in:
Nyall Dawson 2017-07-28 14:10:48 +10:00
parent 5763381cbd
commit e8290928dd
4 changed files with 102 additions and 60 deletions

View File

@ -44,8 +44,11 @@ def buffering(feedback, context, sink, distance, field, useField, source, dissol
# With dissolve
if dissolve:
attributes_to_fetch = []
if useField:
attributes_to_fetch.append(field)
features = source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]))
features = source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(attributes_to_fetch))
buffered_geometries = []
for inFeat in features:
if feedback.isCanceled():

View File

@ -128,12 +128,12 @@ from .Translate import Translate
from .TruncateTable import TruncateTable
from .Union import Union
from .UniqueValues import UniqueValues
from .VariableDistanceBuffer import VariableDistanceBuffer
from .VectorSplit import VectorSplit
from .VoronoiPolygons import VoronoiPolygons
from .ZonalStatistics import ZonalStatistics
# from .ExtractByLocation import ExtractByLocation
# from .VariableDistanceBuffer import VariableDistanceBuffer
# from .RandomSelection import RandomSelection
# from .RandomSelectionWithinSubsets import RandomSelectionWithinSubsets
# from .SelectByLocation import SelectByLocation
@ -185,7 +185,6 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
def getAlgs(self):
# algs = [
# VariableDistanceBuffer(),
# RandomSelection(), RandomSelectionWithinSubsets(),
# SelectByLocation(),
# ExtractByLocation(),
@ -300,6 +299,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
TruncateTable(),
Union(),
UniqueValues(),
VariableDistanceBuffer(),
VectorSplit(),
VoronoiPolygons(),
ZonalStatistics()

View File

@ -30,17 +30,16 @@ import os
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsWkbTypes,
QgsFeatureSink,
QgsProcessingUtils)
QgsProcessing,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingParameterNumber,
QgsProcessingParameterBoolean,
QgsProcessingParameterEnum,
QgsProcessingParameterFeatureSink)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterTableField
from processing.core.outputs import OutputVector
from . import Buffer as buff
from processing.tools import dataobjects
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
@ -52,6 +51,9 @@ class VariableDistanceBuffer(QgisAlgorithm):
FIELD = 'FIELD'
SEGMENTS = 'SEGMENTS'
DISSOLVE = 'DISSOLVE'
END_CAP_STYLE = 'END_CAP_STYLE'
JOIN_STYLE = 'JOIN_STYLE'
MITRE_LIMIT = 'MITRE_LIMIT'
def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'buffer.png'))
@ -63,16 +65,35 @@ class VariableDistanceBuffer(QgisAlgorithm):
super().__init__()
def initAlgorithm(self, config=None):
self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer')))
self.addParameter(ParameterTableField(self.FIELD,
self.tr('Distance field'), self.INPUT))
self.addParameter(ParameterNumber(self.SEGMENTS,
self.tr('Segments'), 1, default=5))
self.addParameter(ParameterBoolean(self.DISSOLVE,
self.tr('Dissolve result'), False))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer')))
self.addOutput(OutputVector(self.OUTPUT, self.tr('Buffer'), datatype=[dataobjects.TYPE_VECTOR_POLYGON]))
self.addParameter(QgsProcessingParameterField(self.FIELD,
self.tr('Distance field'), parentLayerParameterName=self.INPUT))
self.addParameter(QgsProcessingParameterNumber(self.SEGMENTS,
self.tr('Segments'), type=QgsProcessingParameterNumber.Integer,
minValue=1, defaultValue=5))
self.addParameter(QgsProcessingParameterBoolean(self.DISSOLVE,
self.tr('Dissolve result'), defaultValue=False))
self.end_cap_styles = [self.tr('Round'),
'Flat',
'Square']
self.addParameter(QgsProcessingParameterEnum(
self.END_CAP_STYLE,
self.tr('End cap style'),
options=self.end_cap_styles, defaultValue=0))
self.join_styles = [self.tr('Round'),
'Mitre',
'Bevel']
self.addParameter(QgsProcessingParameterEnum(
self.JOIN_STYLE,
self.tr('Join style'),
options=self.join_styles, defaultValue=0))
self.addParameter(QgsProcessingParameterNumber(self.MITRE_LIMIT,
self.tr('Mitre limit'), minValue=0, defaultValue=2))
self.addParameter(
QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Buffer'), QgsProcessing.TypeVectorPolygon))
def name(self):
return 'variabledistancebuffer'
@ -81,12 +102,20 @@ class VariableDistanceBuffer(QgisAlgorithm):
return self.tr('Variable distance buffer')
def processAlgorithm(self, parameters, context, feedback):
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
dissolve = self.getParameterValue(self.DISSOLVE)
field = self.getParameterValue(self.FIELD)
segments = int(self.getParameterValue(self.SEGMENTS))
source = self.parameterAsSource(parameters, self.INPUT, context)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), QgsWkbTypes.Polygon,
layer.crs(), context)
dissolve = self.parameterAsBool(parameters, self.DISSOLVE, context)
segments = self.parameterAsInt(parameters, self.SEGMENTS, context)
end_cap_style = self.parameterAsEnum(parameters, self.END_CAP_STYLE, context) + 1
join_style = self.parameterAsEnum(parameters, self.JOIN_STYLE, context) + 1
miter_limit = self.parameterAsDouble(parameters, self.MITRE_LIMIT, context)
buff.buffering(feedback, context, writer, 0, field, True, layer, dissolve, segments)
field = self.parameterAsString(parameters, self.FIELD, context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), QgsWkbTypes.Polygon, source.sourceCrs())
buff.buffering(feedback, context, sink, 0, field, True, source, dissolve, segments, end_cap_style,
join_style, miter_limit)
return {self.OUTPUT: dest_id}

View File

@ -370,6 +370,11 @@ tests:
compare:
geometry:
precision: 7
fields:
fid: skip
name: skip
intval: skip
floatval: skip
# - algorithm: qgis:rectanglesovalsdiamondsfixed
# name: Create fixed distance rectange buffers around points
@ -2092,39 +2097,44 @@ tests:
geometry:
precision: 7
# - algorithm: qgis:variabledistancebuffer
# name: variable buffer on points
# params:
# DISSOLVE: false
# FIELD: buffer
# INPUT:
# name: custom/variable_buffer.gml
# type: vector
# SEGMENTS: 5
# results:
# OUTPUT:
# name: expected/variable_buffer_points.gml
# type: vector
# compare:
# geometry:
# precision: 5
#
# - algorithm: qgis:variabledistancebuffer
# name: variable buffer on points with dissolve option
# params:
# DISSOLVE: true
# FIELD: buffer
# INPUT:
# name: custom/variable_buffer.gml
# type: vector
# SEGMENTS: 5
# results:
# OUTPUT:
# name: expected/variable_buffer_points_dissolved.gml
# type: vector
# compare:
# geometry:
# precision: 5
- algorithm: qgis:variabledistancebuffer
name: variable buffer on points
params:
DISSOLVE: false
FIELD: buffer
INPUT:
name: custom/variable_buffer.gml
type: vector
SEGMENTS: 5
results:
OUTPUT:
name: expected/variable_buffer_points.gml
type: vector
compare:
geometry:
precision: 5
- algorithm: qgis:variabledistancebuffer
name: variable buffer on points with dissolve option
params:
DISSOLVE: true
FIELD: buffer
INPUT:
name: custom/variable_buffer.gml
type: vector
SEGMENTS: 5
results:
OUTPUT:
name: expected/variable_buffer_points_dissolved.gml
type: vector
compare:
geometry:
precision: 5
fields:
id: skip
id2: skip
fid: skip
- algorithm: qgis:adduniquevalueindexfield
name: add unique field based on another field