28
28
29
29
import math
30
30
31
- from qgis .core import (QgsApplication ,
31
+ from qgis .core import (QgsProcessingParameterFeatureSource ,
32
+ QgsProcessingParameterEnum ,
33
+ QgsProcessingParameterNumber ,
34
+ QgsProcessingParameterFeatureSink ,
32
35
QgsFeature ,
33
36
QgsFeatureSink ,
34
37
QgsGeometry ,
35
38
QgsPointXY ,
36
39
QgsWkbTypes ,
37
- QgsProcessingUtils )
40
+ QgsProcessing )
38
41
39
42
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
45
43
46
44
47
45
class RectanglesOvalsDiamondsFixed (QgisAlgorithm ):
48
46
49
- INPUT_LAYER = 'INPUT_LAYER '
47
+ INPUT = 'INPUT '
50
48
SHAPE = 'SHAPE'
51
49
WIDTH = 'WIDTH'
52
50
HEIGHT = 'HEIGHT'
53
51
ROTATION = 'ROTATION'
54
52
SEGMENTS = 'SEGMENTS'
55
- OUTPUT_LAYER = 'OUTPUT_LAYER '
53
+ OUTPUT = 'OUTPUT '
56
54
57
55
def group (self ):
58
56
return self .tr ('Vector geometry tools' )
@@ -63,26 +61,26 @@ def __init__(self):
63
61
def initAlgorithm (self , config = None ):
64
62
self .shapes = [self .tr ('Rectangles' ), self .tr ('Diamonds' ), self .tr ('Ovals' )]
65
63
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 ))
86
84
87
85
def name (self ):
88
86
return 'rectanglesovalsdiamondsfixed'
@@ -91,36 +89,44 @@ def displayName(self):
91
89
return self .tr ('Rectangles, ovals, diamonds (fixed)' )
92
90
93
91
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 )
100
98
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 ())
105
101
106
102
if shape == 0 :
107
- self .rectangles (writer , features , width , height , rotation )
103
+ self .rectangles (sink , source , width , height , rotation , feedback )
108
104
elif shape == 1 :
109
- self .diamonds (writer , features , width , height , rotation )
105
+ self .diamonds (sink , source , width , height , rotation , feedback )
110
106
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 }
112
110
113
- del writer
111
+ def rectangles ( self , sink , source , width , height , rotation , feedback ):
114
112
115
- def rectangles ( self , writer , features , width , height , rotation ):
113
+ features = source . getFeatures ()
116
114
ft = QgsFeature ()
117
115
118
116
xOffset = width / 2.0
119
117
yOffset = height / 2.0
120
118
119
+ total = 100.0 / source .featureCount () if source .featureCount () else 0
120
+
121
121
if rotation is not None :
122
122
phi = rotation * math .pi / 180
123
123
for current , feat in enumerate (features ):
124
+ if feedback .isCanceled ():
125
+ break
126
+
127
+ if not feat .hasGeometry ():
128
+ continue
129
+
124
130
point = feat .geometry ().asPoint ()
125
131
x = point .x ()
126
132
y = point .y ()
@@ -130,9 +136,17 @@ def rectangles(self, writer, features, width, height, rotation):
130
136
131
137
ft .setGeometry (QgsGeometry .fromPolygon (polygon ))
132
138
ft .setAttributes (feat .attributes ())
133
- writer .addFeature (ft , QgsFeatureSink .FastInsert )
139
+ sink .addFeature (ft , QgsFeatureSink .FastInsert )
140
+
141
+ feedback .setProgress (int (current * total ))
134
142
else :
135
143
for current , feat in enumerate (features ):
144
+ if feedback .isCanceled ():
145
+ break
146
+
147
+ if not feat .hasGeometry ():
148
+ continue
149
+
136
150
point = feat .geometry ().asPoint ()
137
151
x = point .x ()
138
152
y = point .y ()
@@ -141,17 +155,27 @@ def rectangles(self, writer, features, width, height, rotation):
141
155
142
156
ft .setGeometry (QgsGeometry .fromPolygon (polygon ))
143
157
ft .setAttributes (feat .attributes ())
144
- writer .addFeature (ft , QgsFeatureSink .FastInsert )
158
+ sink .addFeature (ft , QgsFeatureSink .FastInsert )
159
+
160
+ feedback .setProgress (int (current * total ))
145
161
146
- def diamonds (self , writer , features , width , height , rotation ):
162
+ def diamonds (self , sink , source , width , height , rotation , feedback ):
163
+ features = source .getFeatures ()
147
164
ft = QgsFeature ()
148
165
149
166
xOffset = width / 2.0
150
167
yOffset = height / 2.0
151
168
169
+ total = 100.0 / source .featureCount () if source .featureCount () else 0
152
170
if rotation is not None :
153
171
phi = rotation * math .pi / 180
154
172
for current , feat in enumerate (features ):
173
+ if feedback .isCanceled ():
174
+ break
175
+
176
+ if not feat .hasGeometry ():
177
+ continue
178
+
155
179
point = feat .geometry ().asPoint ()
156
180
x = point .x ()
157
181
y = point .y ()
@@ -161,9 +185,16 @@ def diamonds(self, writer, features, width, height, rotation):
161
185
162
186
ft .setGeometry (QgsGeometry .fromPolygon (polygon ))
163
187
ft .setAttributes (feat .attributes ())
164
- writer .addFeature (ft , QgsFeatureSink .FastInsert )
188
+ sink .addFeature (ft , QgsFeatureSink .FastInsert )
189
+ feedback .setProgress (int (current * total ))
165
190
else :
166
191
for current , feat in enumerate (features ):
192
+ if feedback .isCanceled ():
193
+ break
194
+
195
+ if not feat .hasGeometry ():
196
+ continue
197
+
167
198
point = feat .geometry ().asPoint ()
168
199
x = point .x ()
169
200
y = point .y ()
@@ -172,17 +203,26 @@ def diamonds(self, writer, features, width, height, rotation):
172
203
173
204
ft .setGeometry (QgsGeometry .fromPolygon (polygon ))
174
205
ft .setAttributes (feat .attributes ())
175
- writer .addFeature (ft , QgsFeatureSink .FastInsert )
206
+ sink .addFeature (ft , QgsFeatureSink .FastInsert )
207
+ feedback .setProgress (int (current * total ))
176
208
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 ()
178
211
ft = QgsFeature ()
179
212
180
213
xOffset = width / 2.0
181
214
yOffset = height / 2.0
182
215
216
+ total = 100.0 / source .featureCount () if source .featureCount () else 0
183
217
if rotation is not None :
184
218
phi = rotation * math .pi / 180
185
219
for current , feat in enumerate (features ):
220
+ if feedback .isCanceled ():
221
+ break
222
+
223
+ if not feat .hasGeometry ():
224
+ continue
225
+
186
226
point = feat .geometry ().asPoint ()
187
227
x = point .x ()
188
228
y = point .y ()
@@ -194,9 +234,16 @@ def ovals(self, writer, features, width, height, rotation, segments):
194
234
195
235
ft .setGeometry (QgsGeometry .fromPolygon (polygon ))
196
236
ft .setAttributes (feat .attributes ())
197
- writer .addFeature (ft , QgsFeatureSink .FastInsert )
237
+ sink .addFeature (ft , QgsFeatureSink .FastInsert )
238
+ feedback .setProgress (int (current * total ))
198
239
else :
199
240
for current , feat in enumerate (features ):
241
+ if feedback .isCanceled ():
242
+ break
243
+
244
+ if not feat .hasGeometry ():
245
+ continue
246
+
200
247
point = feat .geometry ().asPoint ()
201
248
x = point .x ()
202
249
y = point .y ()
@@ -207,4 +254,5 @@ def ovals(self, writer, features, width, height, rotation, segments):
207
254
208
255
ft .setGeometry (QgsGeometry .fromPolygon (polygon ))
209
256
ft .setAttributes (feat .attributes ())
210
- writer .addFeature (ft , QgsFeatureSink .FastInsert )
257
+ sink .addFeature (ft , QgsFeatureSink .FastInsert )
258
+ feedback .setProgress (int (current * total ))
0 commit comments