Skip to content

Commit

Permalink
Port single sided buffer to new API
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 20, 2017
1 parent 4a935c1 commit 1cac3bb
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 122 deletions.
5 changes: 3 additions & 2 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Expand Up @@ -96,6 +96,7 @@
from .ShortestPathPointToLayer import ShortestPathPointToLayer
from .ShortestPathPointToPoint import ShortestPathPointToPoint
from .SimplifyGeometries import SimplifyGeometries
from .SingleSidedBuffer import SingleSidedBuffer
from .Slope import Slope
from .Smooth import Smooth
from .SnapGeometries import SnapGeometriesToLayer
Expand Down Expand Up @@ -157,7 +158,6 @@
# from .RectanglesOvalsDiamondsVariable import RectanglesOvalsDiamondsVariable
# from .RectanglesOvalsDiamondsFixed import RectanglesOvalsDiamondsFixed
# from .MergeLines import MergeLines
# from .SingleSidedBuffer import SingleSidedBuffer
# from .PointsAlongGeometry import PointsAlongGeometry
# from .Relief import Relief
# from .IdwInterpolation import IdwInterpolation
Expand Down Expand Up @@ -218,7 +218,7 @@ def getAlgs(self):
# RectanglesOvalsDiamondsVariable(),
# RectanglesOvalsDiamondsFixed(), MergeLines(),
#
# SingleSidedBuffer(), PointsAlongGeometry(),
# PointsAlongGeometry(),
# Relief(),
# IdwInterpolation(), TinInterpolation(),
# ExtendLines(), ExtractSpecificNodes(),
Expand Down Expand Up @@ -286,6 +286,7 @@ def getAlgs(self):
ShortestPathPointToLayer(),
ShortestPathPointToPoint(),
SimplifyGeometries(),
SingleSidedBuffer(),
Slope(),
Smooth(),
SnapGeometriesToLayer(),
Expand Down
124 changes: 57 additions & 67 deletions python/plugins/processing/algs/qgis/SingleSidedBuffer.py
Expand Up @@ -25,27 +25,17 @@

__revision__ = '$Format:%H$'

import os

from qgis.core import (QgsApplication,
QgsGeometry,
QgsFeatureSink,
from qgis.core import (QgsGeometry,
QgsWkbTypes,
QgsProcessingUtils)

from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterVector, ParameterSelection, ParameterNumber
from processing.core.outputs import OutputVector
from processing.tools import dataobjects

pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
QgsProcessing,
QgsProcessingParameterNumber,
QgsProcessingParameterEnum,
QgsProcessingException)

from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm

class SingleSidedBuffer(QgisAlgorithm):

INPUT_LAYER = 'INPUT_LAYER'
OUTPUT_LAYER = 'OUTPUT_LAYER'
class SingleSidedBuffer(QgisFeatureBasedAlgorithm):
DISTANCE = 'DISTANCE'
SIDE = 'SIDE'
SEGMENTS = 'SEGMENTS'
Expand All @@ -57,71 +47,71 @@ def group(self):

def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(ParameterVector(self.INPUT_LAYER,
self.tr('Input layer'), [dataobjects.TYPE_VECTOR_LINE]))
self.addParameter(ParameterNumber(self.DISTANCE,
self.tr('Distance'), default=10.0))
self.distance = None
self.segments = None
self.join_style = None
self.side = None
self.miter_limit = None
self.sides = [self.tr('Left'),
'Right']
self.addParameter(ParameterSelection(
self.join_styles = [self.tr('Round'),
'Mitre',
'Bevel']

def initParameters(self, config=None):
self.addParameter(QgsProcessingParameterNumber(self.DISTANCE,
self.tr('Distance'), defaultValue=10.0))
self.addParameter(QgsProcessingParameterEnum(
self.SIDE,
self.tr('Side'),
self.sides))
options=self.sides))

self.addParameter(ParameterNumber(self.SEGMENTS,
self.tr('Segments'), 1, default=8))
self.addParameter(QgsProcessingParameterNumber(self.SEGMENTS,
self.tr('Segments'), QgsProcessingParameterNumber.Integer,
minValue=1, defaultValue=8))

self.join_styles = [self.tr('Round'),
'Mitre',
'Bevel']
self.addParameter(ParameterSelection(
self.addParameter(QgsProcessingParameterEnum(
self.JOIN_STYLE,
self.tr('Join style'),
self.join_styles))
self.addParameter(ParameterNumber(self.MITRE_LIMIT,
self.tr('Mitre limit'), 1, default=2))

self.addOutput(OutputVector(self.OUTPUT_LAYER, self.tr('Single sided buffers')))
options=self.join_styles))
self.addParameter(QgsProcessingParameterNumber(self.MITRE_LIMIT,
self.tr('Mitre limit'), minValue=1, defaultValue=2))

def name(self):
return 'singlesidedbuffer'

def displayName(self):
return self.tr('Single sided buffer')

def processAlgorithm(self, parameters, context, feedback):
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)
def outputName(self):
return self.tr('Buffers')

writer = self.getOutputFromName(
self.OUTPUT_LAYER).getVectorWriter(layer.fields(), QgsWkbTypes.Polygon, layer.crs(), context)

distance = self.getParameterValue(self.DISTANCE)
segments = int(self.getParameterValue(self.SEGMENTS))
join_style = self.getParameterValue(self.JOIN_STYLE) + 1
if self.getParameterValue(self.SIDE) == 0:
side = QgsGeometry.SideLeft
else:
side = QgsGeometry.SideRight
miter_limit = self.getParameterValue(self.MITRE_LIMIT)
def outputType(self):
return QgsProcessing.TypeVectorPolygon

features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
def outputWkbType(self, input_wkb_type):
return QgsWkbTypes.Polygon

for current, input_feature in enumerate(features):
output_feature = input_feature
input_geometry = input_feature.geometry()
if input_geometry:
output_geometry = input_geometry.singleSidedBuffer(distance, segments,
side, join_style, miter_limit)
if not output_geometry:
raise GeoAlgorithmExecutionException(
self.tr('Error calculating single sided buffer'))

output_feature.setGeometry(output_geometry)

writer.addFeature(output_feature, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total))

del writer
def prepareAlgorithm(self, parameters, context, feedback):
self.distance = self.parameterAsDouble(parameters, self.DISTANCE, context)
self.segments = self.parameterAsInt(parameters, self.SEGMENTS, context)
self.join_style = self.parameterAsEnum(parameters, self.JOIN_STYLE, context) + 1
if self.parameterAsEnum(parameters, self.SIDE, context) == 0:
self.side = QgsGeometry.SideLeft
else:
self.side = QgsGeometry.SideRight
self.miter_limit = self.parameterAsDouble(parameters, self.MITRE_LIMIT, context)
return True

def processFeature(self, feature, feedback):
input_geometry = feature.geometry()
if input_geometry:
output_geometry = input_geometry.singleSidedBuffer(self.distance, self.segments,
self.side, self.join_style, self.miter_limit)
if not output_geometry:
raise QgsProcessingException(
self.tr('Error calculating single sided buffer'))

feature.setGeometry(output_geometry)

return feature
106 changes: 53 additions & 53 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Expand Up @@ -913,59 +913,59 @@ tests:
name: expected/lines_translated.gml
type: vector

# - algorithm: qgis:singlesidedbuffer
# name: Single sided buffer lines (left, round)
# params:
# DISTANCE: 1.0
# INPUT_LAYER:
# name: lines.gml
# type: vector
# JOIN_STYLE: '0'
# MITRE_LIMIT: 2
# SEGMENTS: 8
# SIDE: '0'
# results:
# OUTPUT_LAYER:
# name: expected/single_sided_buffer_line.gml
# type: vector
# compare:
# geometry:
# precision: 7
#
# - algorithm: qgis:singlesidedbuffer
# name: Single sided buffer lines (Right, mitre)
# params:
# DISTANCE: 1.0
# INPUT_LAYER:
# name: lines.gml
# type: vector
# JOIN_STYLE: '1'
# MITRE_LIMIT: 2
# SEGMENTS: 8
# SIDE: '1'
# results:
# OUTPUT_LAYER:
# name: expected/single_sided_buffer_line_mitre.gml
# type: vector
# compare:
# geometry:
# precision: 7
#
# - algorithm: qgis:singlesidedbuffer
# name: Single sided buffer multiline (bevel)
# params:
# DISTANCE: 1.0
# INPUT_LAYER:
# name: multilines.gml
# type: vector
# JOIN_STYLE: '2'
# MITRE_LIMIT: 2
# SEGMENTS: 8
# SIDE: '0'
# results:
# OUTPUT_LAYER:
# name: expected/single_sided_buffer_multiline_bevel.gml
# type: vector
- algorithm: qgis:singlesidedbuffer
name: Single sided buffer lines (left, round)
params:
DISTANCE: 1.0
INPUT:
name: lines.gml
type: vector
JOIN_STYLE: '0'
MITRE_LIMIT: 2
SEGMENTS: 8
SIDE: '0'
results:
OUTPUT:
name: expected/single_sided_buffer_line.gml
type: vector
compare:
geometry:
precision: 7

- algorithm: qgis:singlesidedbuffer
name: Single sided buffer lines (Right, mitre)
params:
DISTANCE: 1.0
INPUT:
name: lines.gml
type: vector
JOIN_STYLE: '1'
MITRE_LIMIT: 2
SEGMENTS: 8
SIDE: '1'
results:
OUTPUT:
name: expected/single_sided_buffer_line_mitre.gml
type: vector
compare:
geometry:
precision: 7

- algorithm: qgis:singlesidedbuffer
name: Single sided buffer multiline (bevel)
params:
DISTANCE: 1.0
INPUT:
name: multilines.gml
type: vector
JOIN_STYLE: '2'
MITRE_LIMIT: 2
SEGMENTS: 8
SIDE: '0'
results:
OUTPUT:
name: expected/single_sided_buffer_multiline_bevel.gml
type: vector

- algorithm: qgis:extractnodes
name: Test (qgis:extractnodes)
Expand Down

0 comments on commit 1cac3bb

Please sign in to comment.