Skip to content

Commit 076fdc9

Browse files
committedAug 18, 2017
Port rectangles, ovals, diamonds to new API
1 parent 4820216 commit 076fdc9

File tree

4 files changed

+300
-206
lines changed

4 files changed

+300
-206
lines changed
 

‎python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@
119119
from .RandomSelectionWithinSubsets import RandomSelectionWithinSubsets
120120
from .Rasterize import RasterizeAlgorithm
121121
from .RasterLayerStatistics import RasterLayerStatistics
122+
from .RectanglesOvalsDiamondsFixed import RectanglesOvalsDiamondsFixed
123+
from .RectanglesOvalsDiamondsVariable import RectanglesOvalsDiamondsVariable
122124
from .RegularPoints import RegularPoints
123125
from .Relief import Relief
124126
from .ReverseLineDirection import ReverseLineDirection
@@ -166,8 +168,6 @@
166168
# from .FieldPyculator import FieldsPyculator
167169
# from .SelectByAttributeSum import SelectByAttributeSum
168170
# from .DefineProjection import DefineProjection
169-
# from .RectanglesOvalsDiamondsVariable import RectanglesOvalsDiamondsVariable
170-
# from .RectanglesOvalsDiamondsFixed import RectanglesOvalsDiamondsFixed
171171
# from .IdwInterpolation import IdwInterpolation
172172
# from .TinInterpolation import TinInterpolation
173173
# from .RasterCalculator import RasterCalculator
@@ -194,8 +194,6 @@ def getAlgs(self):
194194
# FieldsPyculator(),
195195
# FieldsMapper(), SelectByAttributeSum()
196196
# DefineProjection(),
197-
# RectanglesOvalsDiamondsVariable(),
198-
# RectanglesOvalsDiamondsFixed(),
199197
# IdwInterpolation(), TinInterpolation(),
200198
# RasterCalculator(),
201199
# ExecuteSQL(), FindProjection(),
@@ -279,6 +277,8 @@ def getAlgs(self):
279277
RandomSelectionWithinSubsets(),
280278
RasterizeAlgorithm(),
281279
RasterLayerStatistics(),
280+
RectanglesOvalsDiamondsFixed(),
281+
RectanglesOvalsDiamondsVariable(),
282282
RegularPoints(),
283283
Relief(),
284284
ReverseLineDirection(),

‎python/plugins/processing/algs/qgis/RectanglesOvalsDiamondsFixed.py

Lines changed: 100 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,29 @@
2828

2929
import math
3030

31-
from qgis.core import (QgsApplication,
31+
from qgis.core import (QgsProcessingParameterFeatureSource,
32+
QgsProcessingParameterEnum,
33+
QgsProcessingParameterNumber,
34+
QgsProcessingParameterFeatureSink,
3235
QgsFeature,
3336
QgsFeatureSink,
3437
QgsGeometry,
3538
QgsPointXY,
3639
QgsWkbTypes,
37-
QgsProcessingUtils)
40+
QgsProcessing)
3841

3942
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
40-
from processing.core.parameters import ParameterVector
41-
from processing.core.parameters import ParameterSelection
42-
from processing.core.parameters import ParameterNumber
43-
from processing.core.outputs import OutputVector
44-
from processing.tools import dataobjects
4543

4644

4745
class RectanglesOvalsDiamondsFixed(QgisAlgorithm):
4846

49-
INPUT_LAYER = 'INPUT_LAYER'
47+
INPUT = 'INPUT'
5048
SHAPE = 'SHAPE'
5149
WIDTH = 'WIDTH'
5250
HEIGHT = 'HEIGHT'
5351
ROTATION = 'ROTATION'
5452
SEGMENTS = 'SEGMENTS'
55-
OUTPUT_LAYER = 'OUTPUT_LAYER'
53+
OUTPUT = 'OUTPUT'
5654

5755
def group(self):
5856
return self.tr('Vector geometry tools')
@@ -63,26 +61,26 @@ def __init__(self):
6361
def initAlgorithm(self, config=None):
6462
self.shapes = [self.tr('Rectangles'), self.tr('Diamonds'), self.tr('Ovals')]
6563

66-
self.addParameter(ParameterVector(self.INPUT_LAYER,
67-
self.tr('Input layer'),
68-
[dataobjects.TYPE_VECTOR_POINT]))
69-
self.addParameter(ParameterSelection(self.SHAPE,
70-
self.tr('Buffer shape'), self.shapes))
71-
self.addParameter(ParameterNumber(self.WIDTH, self.tr('Width'),
72-
0.0000001, 999999999.0, 1.0))
73-
self.addParameter(ParameterNumber(self.HEIGHT, self.tr('Height'),
74-
0.0000001, 999999999.0, 1.0))
75-
self.addParameter(ParameterNumber(self.ROTATION, self.tr('Rotation'),
76-
0.0, 360.0, optional=True))
77-
self.addParameter(ParameterNumber(self.SEGMENTS,
78-
self.tr('Number of segments'),
79-
1,
80-
999999999,
81-
36))
82-
83-
self.addOutput(OutputVector(self.OUTPUT_LAYER,
84-
self.tr('Output'),
85-
datatype=[dataobjects.TYPE_VECTOR_POLYGON]))
64+
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
65+
self.tr('Input layer'),
66+
[QgsProcessing.TypeVectorPoint]))
67+
self.addParameter(QgsProcessingParameterEnum(self.SHAPE,
68+
self.tr('Buffer shape'), options=self.shapes))
69+
self.addParameter(QgsProcessingParameterNumber(self.WIDTH, self.tr('Width'), type=QgsProcessingParameterNumber.Double,
70+
minValue=0.0000001, maxValue=999999999.0, defaultValue=1.0))
71+
self.addParameter(QgsProcessingParameterNumber(self.HEIGHT, self.tr('Height'), type=QgsProcessingParameterNumber.Double,
72+
minValue=0.0000001, maxValue=999999999.0, defaultValue=1.0))
73+
self.addParameter(QgsProcessingParameterNumber(self.ROTATION, self.tr('Rotation'), type=QgsProcessingParameterNumber.Double,
74+
minValue=0.0, maxValue=360.0, optional=True))
75+
self.addParameter(QgsProcessingParameterNumber(self.SEGMENTS,
76+
self.tr('Number of segments'),
77+
minValue=1,
78+
maxValue=999999999,
79+
defaultValue=36))
80+
81+
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
82+
self.tr('Output'),
83+
type=QgsProcessing.TypeVectorPolygon))
8684

8785
def name(self):
8886
return 'rectanglesovalsdiamondsfixed'
@@ -91,36 +89,44 @@ def displayName(self):
9189
return self.tr('Rectangles, ovals, diamonds (fixed)')
9290

9391
def processAlgorithm(self, parameters, context, feedback):
94-
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)
95-
shape = self.getParameterValue(self.SHAPE)
96-
width = self.getParameterValue(self.WIDTH)
97-
height = self.getParameterValue(self.HEIGHT)
98-
rotation = self.getParameterValue(self.ROTATION)
99-
segments = self.getParameterValue(self.SEGMENTS)
92+
source = self.parameterAsSource(parameters, self.INPUT, context)
93+
shape = self.parameterAsEnum(parameters, self.SHAPE, context)
94+
width = self.parameterAsDouble(parameters, self.WIDTH, context)
95+
height = self.parameterAsDouble(parameters, self.HEIGHT, context)
96+
rotation = self.parameterAsDouble(parameters, self.ROTATION, context)
97+
segments = self.parameterAsInt(parameters, self.SEGMENTS, context)
10098

101-
writer = self.getOutputFromName(
102-
self.OUTPUT_LAYER).getVectorWriter(layer.fields(), QgsWkbTypes.Polygon, layer.crs(), context)
103-
104-
features = QgsProcessingUtils.getFeatures(layer, context)
99+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
100+
source.fields(), QgsWkbTypes.Polygon, source.sourceCrs())
105101

106102
if shape == 0:
107-
self.rectangles(writer, features, width, height, rotation)
103+
self.rectangles(sink, source, width, height, rotation, feedback)
108104
elif shape == 1:
109-
self.diamonds(writer, features, width, height, rotation)
105+
self.diamonds(sink, source, width, height, rotation, feedback)
110106
else:
111-
self.ovals(writer, features, width, height, rotation, segments)
107+
self.ovals(sink, source, width, height, rotation, segments, feedback)
108+
109+
return {self.OUTPUT: dest_id}
112110

113-
del writer
111+
def rectangles(self, sink, source, width, height, rotation, feedback):
114112

115-
def rectangles(self, writer, features, width, height, rotation):
113+
features = source.getFeatures()
116114
ft = QgsFeature()
117115

118116
xOffset = width / 2.0
119117
yOffset = height / 2.0
120118

119+
total = 100.0 / source.featureCount() if source.featureCount() else 0
120+
121121
if rotation is not None:
122122
phi = rotation * math.pi / 180
123123
for current, feat in enumerate(features):
124+
if feedback.isCanceled():
125+
break
126+
127+
if not feat.hasGeometry():
128+
continue
129+
124130
point = feat.geometry().asPoint()
125131
x = point.x()
126132
y = point.y()
@@ -130,9 +136,17 @@ def rectangles(self, writer, features, width, height, rotation):
130136

131137
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
132138
ft.setAttributes(feat.attributes())
133-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
139+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
140+
141+
feedback.setProgress(int(current * total))
134142
else:
135143
for current, feat in enumerate(features):
144+
if feedback.isCanceled():
145+
break
146+
147+
if not feat.hasGeometry():
148+
continue
149+
136150
point = feat.geometry().asPoint()
137151
x = point.x()
138152
y = point.y()
@@ -141,17 +155,27 @@ def rectangles(self, writer, features, width, height, rotation):
141155

142156
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
143157
ft.setAttributes(feat.attributes())
144-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
158+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
159+
160+
feedback.setProgress(int(current * total))
145161

146-
def diamonds(self, writer, features, width, height, rotation):
162+
def diamonds(self, sink, source, width, height, rotation, feedback):
163+
features = source.getFeatures()
147164
ft = QgsFeature()
148165

149166
xOffset = width / 2.0
150167
yOffset = height / 2.0
151168

169+
total = 100.0 / source.featureCount() if source.featureCount() else 0
152170
if rotation is not None:
153171
phi = rotation * math.pi / 180
154172
for current, feat in enumerate(features):
173+
if feedback.isCanceled():
174+
break
175+
176+
if not feat.hasGeometry():
177+
continue
178+
155179
point = feat.geometry().asPoint()
156180
x = point.x()
157181
y = point.y()
@@ -161,9 +185,16 @@ def diamonds(self, writer, features, width, height, rotation):
161185

162186
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
163187
ft.setAttributes(feat.attributes())
164-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
188+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
189+
feedback.setProgress(int(current * total))
165190
else:
166191
for current, feat in enumerate(features):
192+
if feedback.isCanceled():
193+
break
194+
195+
if not feat.hasGeometry():
196+
continue
197+
167198
point = feat.geometry().asPoint()
168199
x = point.x()
169200
y = point.y()
@@ -172,17 +203,26 @@ def diamonds(self, writer, features, width, height, rotation):
172203

173204
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
174205
ft.setAttributes(feat.attributes())
175-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
206+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
207+
feedback.setProgress(int(current * total))
176208

177-
def ovals(self, writer, features, width, height, rotation, segments):
209+
def ovals(self, sink, source, width, height, rotation, segments, feedback):
210+
features = source.getFeatures()
178211
ft = QgsFeature()
179212

180213
xOffset = width / 2.0
181214
yOffset = height / 2.0
182215

216+
total = 100.0 / source.featureCount() if source.featureCount() else 0
183217
if rotation is not None:
184218
phi = rotation * math.pi / 180
185219
for current, feat in enumerate(features):
220+
if feedback.isCanceled():
221+
break
222+
223+
if not feat.hasGeometry():
224+
continue
225+
186226
point = feat.geometry().asPoint()
187227
x = point.x()
188228
y = point.y()
@@ -194,9 +234,16 @@ def ovals(self, writer, features, width, height, rotation, segments):
194234

195235
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
196236
ft.setAttributes(feat.attributes())
197-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
237+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
238+
feedback.setProgress(int(current * total))
198239
else:
199240
for current, feat in enumerate(features):
241+
if feedback.isCanceled():
242+
break
243+
244+
if not feat.hasGeometry():
245+
continue
246+
200247
point = feat.geometry().asPoint()
201248
x = point.x()
202249
y = point.y()
@@ -207,4 +254,5 @@ def ovals(self, writer, features, width, height, rotation, segments):
207254

208255
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
209256
ft.setAttributes(feat.attributes())
210-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
257+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
258+
feedback.setProgress(int(current * total))

‎python/plugins/processing/algs/qgis/RectanglesOvalsDiamondsVariable.py

Lines changed: 134 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,30 @@
2828

2929
import math
3030

31-
from qgis.core import (QgsApplication,
32-
QgsWkbTypes,
31+
from qgis.core import (QgsWkbTypes,
3332
QgsFeature,
3433
QgsFeatureSink,
3534
QgsGeometry,
3635
QgsPointXY,
37-
QgsMessageLog,
38-
QgsProcessingUtils)
36+
QgsProcessing,
37+
QgsProcessingParameterField,
38+
QgsProcessingParameterFeatureSource,
39+
QgsProcessingParameterEnum,
40+
QgsProcessingParameterNumber,
41+
QgsProcessingParameterFeatureSink)
3942

4043
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
41-
from processing.core.parameters import ParameterVector
42-
from processing.core.parameters import ParameterSelection
43-
from processing.core.parameters import ParameterTableField
44-
from processing.core.parameters import ParameterNumber
45-
from processing.core.outputs import OutputVector
46-
from processing.tools import dataobjects
4744

4845

4946
class RectanglesOvalsDiamondsVariable(QgisAlgorithm):
5047

51-
INPUT_LAYER = 'INPUT_LAYER'
48+
INPUT = 'INPUT'
5249
SHAPE = 'SHAPE'
5350
WIDTH = 'WIDTH'
5451
HEIGHT = 'HEIGHT'
5552
ROTATION = 'ROTATION'
5653
SEGMENTS = 'SEGMENTS'
57-
OUTPUT_LAYER = 'OUTPUT_LAYER'
54+
OUTPUT = 'OUTPUT'
5855

5956
def group(self):
6057
return self.tr('Vector geometry tools')
@@ -65,33 +62,35 @@ def __init__(self):
6562
def initAlgorithm(self, config=None):
6663
self.shapes = [self.tr('Rectangles'), self.tr('Diamonds'), self.tr('Ovals')]
6764

68-
self.addParameter(ParameterVector(self.INPUT_LAYER,
69-
self.tr('Input layer'),
70-
[dataobjects.TYPE_VECTOR_POINT]))
71-
self.addParameter(ParameterSelection(self.SHAPE,
72-
self.tr('Buffer shape'), self.shapes))
73-
self.addParameter(ParameterTableField(self.WIDTH,
74-
self.tr('Width field'),
75-
self.INPUT_LAYER,
76-
ParameterTableField.DATA_TYPE_NUMBER))
77-
self.addParameter(ParameterTableField(self.HEIGHT,
78-
self.tr('Height field'),
79-
self.INPUT_LAYER,
80-
ParameterTableField.DATA_TYPE_NUMBER))
81-
self.addParameter(ParameterTableField(self.ROTATION,
82-
self.tr('Rotation field'),
83-
self.INPUT_LAYER,
84-
ParameterTableField.DATA_TYPE_NUMBER,
85-
True))
86-
self.addParameter(ParameterNumber(self.SEGMENTS,
87-
self.tr('Number of segments'),
88-
1,
89-
999999999,
90-
36))
91-
92-
self.addOutput(OutputVector(self.OUTPUT_LAYER,
93-
self.tr('Output'),
94-
datatype=[dataobjects.TYPE_VECTOR_POLYGON]))
65+
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
66+
self.tr('Input layer'),
67+
[QgsProcessing.TypeVectorPoint]))
68+
69+
self.addParameter(QgsProcessingParameterEnum(self.SHAPE,
70+
self.tr('Buffer shape'), options=self.shapes))
71+
72+
self.addParameter(QgsProcessingParameterField(self.WIDTH,
73+
self.tr('Width field'),
74+
parentLayerParameterName=self.INPUT,
75+
type=QgsProcessingParameterField.Numeric))
76+
self.addParameter(QgsProcessingParameterField(self.HEIGHT,
77+
self.tr('Height field'),
78+
parentLayerParameterName=self.INPUT,
79+
type=QgsProcessingParameterField.Numeric))
80+
self.addParameter(QgsProcessingParameterField(self.ROTATION,
81+
self.tr('Rotation field'),
82+
parentLayerParameterName=self.INPUT,
83+
type=QgsProcessingParameterField.Numeric,
84+
optional=True))
85+
self.addParameter(QgsProcessingParameterNumber(self.SEGMENTS,
86+
self.tr('Number of segments'),
87+
minValue=1,
88+
maxValue=999999999,
89+
defaultValue=36))
90+
91+
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
92+
self.tr('Output'),
93+
type=QgsProcessing.TypeVectorPolygon))
9594

9695
def name(self):
9796
return 'rectanglesovalsdiamondsvariable'
@@ -100,40 +99,50 @@ def displayName(self):
10099
return self.tr('Rectangles, ovals, diamonds (variable)')
101100

102101
def processAlgorithm(self, parameters, context, feedback):
103-
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)
104-
shape = self.getParameterValue(self.SHAPE)
105-
width = self.getParameterValue(self.WIDTH)
106-
height = self.getParameterValue(self.HEIGHT)
107-
rotation = self.getParameterValue(self.ROTATION)
108-
segments = self.getParameterValue(self.SEGMENTS)
102+
source = self.parameterAsSource(parameters, self.INPUT, context)
103+
shape = self.parameterAsEnum(parameters, self.SHAPE, context)
109104

110-
writer = self.getOutputFromName(
111-
self.OUTPUT_LAYER).getVectorWriter(layer.fields(), QgsWkbTypes.Polygon, layer.crs(), context)
105+
width_field = self.parameterAsString(parameters, self.WIDTH, context)
106+
height_field = self.parameterAsString(parameters, self.HEIGHT, context)
107+
rotation_field = self.parameterAsString(parameters, self.ROTATION, context)
108+
segments = self.parameterAsInt(parameters, self.SEGMENTS, context)
112109

113-
features = QgsProcessingUtils.getFeatures(layer, context)
110+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
111+
source.fields(), QgsWkbTypes.Polygon, source.sourceCrs())
114112

113+
width = source.fields().lookupField(width_field)
114+
height = source.fields().lookupField(height_field)
115+
rotation = source.fields().lookupField(rotation_field)
115116
if shape == 0:
116-
self.rectangles(writer, features, width, height, rotation)
117+
self.rectangles(sink, source, width, height, rotation, feedback)
117118
elif shape == 1:
118-
self.diamonds(writer, features, width, height, rotation)
119+
self.diamonds(sink, source, width, height, rotation, feedback)
119120
else:
120-
self.ovals(writer, features, width, height, rotation, segments)
121+
self.ovals(sink, source, width, height, rotation, segments, feedback)
121122

122-
del writer
123+
return {self.OUTPUT: dest_id}
123124

124-
def rectangles(self, writer, features, width, height, rotation):
125+
def rectangles(self, sink, source, width, height, rotation, feedback):
125126
ft = QgsFeature()
127+
features = source.getFeatures()
126128

127-
if rotation is not None:
129+
total = 100.0 / source.featureCount() if source.featureCount() else 0
130+
131+
if rotation >= 0:
128132
for current, feat in enumerate(features):
133+
if feedback.isCanceled():
134+
break
135+
136+
if not feat.hasGeometry():
137+
continue
138+
129139
w = feat[width]
130140
h = feat[height]
131141
angle = feat[rotation]
132142
if not w or not h or not angle:
133-
QgsMessageLog.logMessage(self.tr('Feature {} has empty '
134-
'width, height or angle. '
135-
'Skipping...'.format(feat.id())),
136-
self.tr('Processing'), QgsMessageLog.WARNING)
143+
feedback.pushInfo(self.tr('Feature {} has empty '
144+
'width, height or angle. '
145+
'Skipping...'.format(feat.id())))
137146
continue
138147

139148
xOffset = w / 2.0
@@ -149,16 +158,23 @@ def rectangles(self, writer, features, width, height, rotation):
149158

150159
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
151160
ft.setAttributes(feat.attributes())
152-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
161+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
162+
163+
feedback.setProgress(int(current * total))
153164
else:
154165
for current, feat in enumerate(features):
166+
if feedback.isCanceled():
167+
break
168+
169+
if not feat.hasGeometry():
170+
continue
171+
155172
w = feat[width]
156173
h = feat[height]
157174
if not w or not h:
158-
QgsMessageLog.logMessage(self.tr('Feature {} has empty '
159-
'width or height. '
160-
'Skipping...'.format(feat.id())),
161-
self.tr('Processing'), QgsMessageLog.WARNING)
175+
feedback.pushInfo(self.tr('Feature {} has empty '
176+
'width or height. '
177+
'Skipping...'.format(feat.id())))
162178
continue
163179

164180
xOffset = w / 2.0
@@ -172,21 +188,30 @@ def rectangles(self, writer, features, width, height, rotation):
172188

173189
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
174190
ft.setAttributes(feat.attributes())
175-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
191+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
192+
193+
feedback.setProgress(int(current * total))
176194

177-
def diamonds(self, writer, features, width, height, rotation):
195+
def diamonds(self, sink, source, width, height, rotation, feedback):
196+
features = source.getFeatures()
178197
ft = QgsFeature()
179198

180-
if rotation is not None:
199+
total = 100.0 / source.featureCount() if source.featureCount() else 0
200+
if rotation >= 0:
181201
for current, feat in enumerate(features):
202+
if feedback.isCanceled():
203+
break
204+
205+
if not feat.hasGeometry():
206+
continue
207+
182208
w = feat[width]
183209
h = feat[height]
184210
angle = feat[rotation]
185211
if not w or not h or not angle:
186-
QgsMessageLog.logMessage(self.tr('Feature {} has empty '
187-
'width, height or angle. '
188-
'Skipping...'.format(feat.id())),
189-
self.tr('Processing'), QgsMessageLog.WARNING)
212+
feedback.pushInfo(self.tr('Feature {} has empty '
213+
'width, height or angle. '
214+
'Skipping...'.format(feat.id())))
190215
continue
191216

192217
xOffset = w / 2.0
@@ -202,16 +227,22 @@ def diamonds(self, writer, features, width, height, rotation):
202227

203228
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
204229
ft.setAttributes(feat.attributes())
205-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
230+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
231+
feedback.setProgress(int(current * total))
206232
else:
207233
for current, feat in enumerate(features):
234+
if feedback.isCanceled():
235+
break
236+
237+
if not feat.hasGeometry():
238+
continue
239+
208240
w = feat[width]
209241
h = feat[height]
210242
if not w or not h:
211-
QgsMessageLog.logMessage(self.tr('Feature {} has empty '
212-
'width or height. '
213-
'Skipping...'.format(feat.id())),
214-
self.tr('Processing'), QgsMessageLog.WARNING)
243+
feedback.pushInfo(self.tr('Feature {} has empty '
244+
'width or height. '
245+
'Skipping...'.format(feat.id())))
215246
continue
216247

217248
xOffset = w / 2.0
@@ -225,21 +256,29 @@ def diamonds(self, writer, features, width, height, rotation):
225256

226257
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
227258
ft.setAttributes(feat.attributes())
228-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
259+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
260+
feedback.setProgress(int(current * total))
229261

230-
def ovals(self, writer, features, width, height, rotation, segments):
262+
def ovals(self, sink, source, width, height, rotation, segments, feedback):
263+
features = source.getFeatures()
231264
ft = QgsFeature()
232265

233-
if rotation is not None:
266+
total = 100.0 / source.featureCount() if source.featureCount() else 0
267+
if rotation >= 0:
234268
for current, feat in enumerate(features):
269+
if feedback.isCanceled():
270+
break
271+
272+
if not feat.hasGeometry():
273+
continue
274+
235275
w = feat[width]
236276
h = feat[height]
237277
angle = feat[rotation]
238278
if not w or not h or not angle:
239-
QgsMessageLog.logMessage(self.tr('Feature {} has empty '
240-
'width, height or angle. '
241-
'Skipping...'.format(feat.id())),
242-
self.tr('Processing'), QgsMessageLog.WARNING)
279+
feedback.pushInfo(self.tr('Feature {} has empty '
280+
'width, height or angle. '
281+
'Skipping...'.format(feat.id())))
243282
continue
244283

245284
xOffset = w / 2.0
@@ -257,16 +296,22 @@ def ovals(self, writer, features, width, height, rotation, segments):
257296

258297
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
259298
ft.setAttributes(feat.attributes())
260-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
299+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
300+
feedback.setProgress(int(current * total))
261301
else:
262302
for current, feat in enumerate(features):
303+
if feedback.isCanceled():
304+
break
305+
306+
if not feat.hasGeometry():
307+
continue
308+
263309
w = feat[width]
264310
h = feat[height]
265311
if not w or not h:
266-
QgsMessageLog.logMessage(self.tr('Feature {} has empty '
267-
'width or height. '
268-
'Skipping...'.format(feat.id())),
269-
self.tr('Processing'), QgsMessageLog.WARNING)
312+
feedback.pushInfo(self.tr('Feature {} has empty '
313+
'width or height. '
314+
'Skipping...'.format(feat.id())))
270315
continue
271316

272317
xOffset = w / 2.0
@@ -282,4 +327,5 @@ def ovals(self, writer, features, width, height, rotation, segments):
282327

283328
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
284329
ft.setAttributes(feat.attributes())
285-
writer.addFeature(ft, QgsFeatureSink.FastInsert)
330+
sink.addFeature(ft, QgsFeatureSink.FastInsert)
331+
feedback.setProgress(int(current * total))

‎python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -569,24 +569,24 @@ tests:
569569
intval: skip
570570
floatval: skip
571571

572-
# - algorithm: qgis:rectanglesovalsdiamondsfixed
573-
# name: Create fixed distance rectange buffers around points
574-
# params:
575-
# HEIGHT: 0.25
576-
# INPUT_LAYER:
577-
# name: points.gml
578-
# type: vector
579-
# ROTATION: 45
580-
# SEGMENTS: 36
581-
# SHAPE: 0
582-
# WIDTH: 0.5
583-
# results:
584-
# OUTPUT_LAYER:
585-
# name: expected/rectanglesovalsdiamondsfixed.gml
586-
# type: vector
587-
# compare:
588-
# geometry:
589-
# precision: 7
572+
- algorithm: qgis:rectanglesovalsdiamondsfixed
573+
name: Create fixed distance rectange buffers around points
574+
params:
575+
HEIGHT: 0.25
576+
INPUT:
577+
name: points.gml
578+
type: vector
579+
ROTATION: 45
580+
SEGMENTS: 36
581+
SHAPE: 0
582+
WIDTH: 0.5
583+
results:
584+
OUTPUT:
585+
name: expected/rectanglesovalsdiamondsfixed.gml
586+
type: vector
587+
compare:
588+
geometry:
589+
precision: 7
590590

591591
- algorithm: qgis:mergelines
592592
name: Merge lines algorithm
@@ -2898,50 +2898,50 @@ tests:
28982898
geometry:
28992899
precision: 5
29002900

2901-
# - algorithm: qgis:rectanglesovalsdiamondsvariable
2902-
# name: Rectangular buffer shape
2903-
# params:
2904-
# HEIGHT: id
2905-
# INPUT_LAYER:
2906-
# name: custom/points_weighted.gml
2907-
# type: vector
2908-
# SEGMENTS: 36
2909-
# SHAPE: '0'
2910-
# WIDTH: id
2911-
# results:
2912-
# OUTPUT_LAYER:
2913-
# name: expected/buffer_rect.gml
2914-
# type: vector
2915-
#
2916-
# - algorithm: qgis:rectanglesovalsdiamondsvariable
2917-
# name: Diamond buffer shape
2918-
# params:
2919-
# HEIGHT: id
2920-
# INPUT_LAYER:
2921-
# name: custom/points_weighted.gml
2922-
# type: vector
2923-
# SEGMENTS: 36
2924-
# SHAPE: '1'
2925-
# WIDTH: id
2926-
# results:
2927-
# OUTPUT_LAYER:
2928-
# name: expected/buffer_diamond.gml
2929-
# type: vector
2930-
#
2931-
# - algorithm: qgis:rectanglesovalsdiamondsvariable
2932-
# name: Oval buffer shape
2933-
# params:
2934-
# HEIGHT: id
2935-
# INPUT_LAYER:
2936-
# name: custom/points_weighted.gml
2937-
# type: vector
2938-
# SEGMENTS: 36
2939-
# SHAPE: '2'
2940-
# WIDTH: id
2941-
# results:
2942-
# OUTPUT_LAYER:
2943-
# name: expected/buffer_ovals.gml
2944-
# type: vector
2901+
- algorithm: qgis:rectanglesovalsdiamondsvariable
2902+
name: Rectangular buffer shape
2903+
params:
2904+
HEIGHT: id
2905+
INPUT:
2906+
name: custom/points_weighted.gml
2907+
type: vector
2908+
SEGMENTS: 36
2909+
SHAPE: '0'
2910+
WIDTH: id
2911+
results:
2912+
OUTPUT:
2913+
name: expected/buffer_rect.gml
2914+
type: vector
2915+
2916+
- algorithm: qgis:rectanglesovalsdiamondsvariable
2917+
name: Diamond buffer shape
2918+
params:
2919+
HEIGHT: id
2920+
INPUT:
2921+
name: custom/points_weighted.gml
2922+
type: vector
2923+
SEGMENTS: 36
2924+
SHAPE: '1'
2925+
WIDTH: id
2926+
results:
2927+
OUTPUT:
2928+
name: expected/buffer_diamond.gml
2929+
type: vector
2930+
2931+
- algorithm: qgis:rectanglesovalsdiamondsvariable
2932+
name: Oval buffer shape
2933+
params:
2934+
HEIGHT: id
2935+
INPUT:
2936+
name: custom/points_weighted.gml
2937+
type: vector
2938+
SEGMENTS: 36
2939+
SHAPE: '2'
2940+
WIDTH: id
2941+
results:
2942+
OUTPUT:
2943+
name: expected/buffer_ovals.gml
2944+
type: vector
29452945

29462946
- algorithm: qgis:creategridlines
29472947
name: Lines grid 0.1 degree spacing

0 commit comments

Comments
 (0)
Please sign in to comment.