Skip to content

Commit b7a4e20

Browse files
committed
[processing] add Rectangles, Ovals, Diamonds algorithm (fix #11575)
This is direct port of abandoned "Rectangles, Ovals and diamonds" plugin. There are two algorithms: one uses fixed values and second — variable values from attribute table. Test for fixed distance version included.
1 parent f3e0438 commit b7a4e20

6 files changed

+591
-2
lines changed

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@
144144
from .ReverseLineDirection import ReverseLineDirection
145145
from .SpatialIndex import SpatialIndex
146146
from .DefineProjection import DefineProjection
147+
from .RectanglesOvalsDiamondsVariable import RectanglesOvalsDiamondsVariable
148+
from .RectanglesOvalsDiamondsFixed import RectanglesOvalsDiamondsFixed
147149

148150
pluginPath = os.path.normpath(os.path.join(
149151
os.path.split(os.path.dirname(__file__))[0], os.pardir))
@@ -193,7 +195,9 @@ def __init__(self):
193195
SplitLinesWithLines(), CreateConstantRaster(),
194196
FieldsMapper(), SelectByAttributeSum(), Datasources2Vrt(),
195197
CheckValidity(), OrientedMinimumBoundingBox(), Smooth(),
196-
ReverseLineDirection(), SpatialIndex(), DefineProjection()
198+
ReverseLineDirection(), SpatialIndex(), DefineProjection(),
199+
RectanglesOvalsDiamondsVariable(),
200+
RectanglesOvalsDiamondsFixed()
197201
]
198202

199203
if hasMatplotlib:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
***************************************************************************
5+
RectanglesOvalsDiamondsFixed.py
6+
---------------------
7+
Date : April 2016
8+
Copyright : (C) 2016 by Alexander Bruy
9+
Email : alexander dot bruy at gmail dot com
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************
18+
"""
19+
20+
__author__ = 'Alexander Bruy'
21+
__date__ = 'August 2012'
22+
__copyright__ = '(C) 2012, Victor Olaya'
23+
24+
# This will get replaced with a git SHA1 when you do a git archive323
25+
26+
__revision__ = '$Format:%H$'
27+
28+
import os
29+
import math
30+
31+
from PyQt.QtGui import QIcon
32+
33+
from qgis.core import QGis, QgsFeature, QgsGeometry, QgsPoint
34+
35+
from processing.core.GeoAlgorithm import GeoAlgorithm
36+
from processing.core.ProcessingLog import ProcessingLog
37+
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
38+
from processing.core.parameters import ParameterVector
39+
from processing.core.parameters import ParameterSelection
40+
from processing.core.parameters import ParameterNumber
41+
from processing.core.outputs import OutputVector
42+
from processing.tools import dataobjects, vector
43+
44+
45+
class RectanglesOvalsDiamondsFixed(GeoAlgorithm):
46+
47+
INPUT_LAYER = 'INPUT_LAYER'
48+
SHAPE = 'SHAPE'
49+
WIDTH = 'WIDTH'
50+
HEIGHT = 'HEIGHT'
51+
ROTATION = 'ROTATION'
52+
SEGMENTS = 'SEGMENTS'
53+
OUTPUT_LAYER = 'OUTPUT_LAYER'
54+
55+
def defineCharacteristics(self):
56+
self.name, self.i18n_name = self.trAlgorithm('Rectangles, ovals, diamonds (fixed)')
57+
self.group, self.i18n_group = self.trAlgorithm('Vector geometry tools')
58+
59+
self.shapes = [self.tr('Rectangles'), self.tr('Diamonds'), self.tr('Ovals')]
60+
61+
self.addParameter(ParameterVector(self.INPUT_LAYER,
62+
self.tr('Input layer'),
63+
[ParameterVector.VECTOR_TYPE_POINT]))
64+
self.addParameter(ParameterSelection(self.SHAPE,
65+
self.tr('Buffer shape'), self.shapes))
66+
self.addParameter(ParameterNumber(self.WIDTH, self.tr('Width'),
67+
0.0000001, 999999999.0, 1.0))
68+
self.addParameter(ParameterNumber(self.HEIGHT, self.tr('Height'),
69+
0.0000001, 999999999.0, 1.0))
70+
self.addParameter(ParameterNumber(self.ROTATION, self.tr('Rotation'),
71+
0.0, 360.0, optional=True))
72+
self.addParameter(ParameterNumber(self.SEGMENTS,
73+
self.tr('Number of segments'),
74+
1,
75+
999999999,
76+
36))
77+
78+
self.addOutput(OutputVector(self.OUTPUT_LAYER,
79+
self.tr('Output')))
80+
81+
def processAlgorithm(self, progress):
82+
layer = dataobjects.getObjectFromUri(
83+
self.getParameterValue(self.INPUT_LAYER))
84+
shape = self.getParameterValue(self.SHAPE)
85+
width = self.getParameterValue(self.WIDTH)
86+
height = self.getParameterValue(self.HEIGHT)
87+
rotation = self.getParameterValue(self.ROTATION)
88+
segments = self.getParameterValue(self.SEGMENTS)
89+
90+
writer = self.getOutputFromName(
91+
self.OUTPUT_LAYER).getVectorWriter(
92+
layer.pendingFields().toList(),
93+
QGis.WKBPolygon,
94+
layer.crs())
95+
96+
outFeat = QgsFeature()
97+
98+
features = vector.features(layer)
99+
total = 100.0 / len(features)
100+
101+
if shape == 0:
102+
self.rectangles(writer, features, width, height, rotation)
103+
elif shape == 1:
104+
self.diamonds(writer, features, width, height, rotation)
105+
else:
106+
self.ovals(writer, features, width, height, rotation, segments)
107+
108+
del writer
109+
110+
def rectangles(self, writer, features, width, height, rotation):
111+
ft = QgsFeature()
112+
113+
xOffset = width / 2.0
114+
yOffset = height / 2.0
115+
116+
if rotation is not None:
117+
phi = rotation * math.pi / 180
118+
for current, feat in enumerate(features):
119+
point = feat.constGeometry().asPoint()
120+
x = point.x()
121+
y = point.y()
122+
points = [(-xOffset, -yOffset), (-xOffset, yOffset), (xOffset, yOffset), (xOffset, -yOffset)]
123+
polygon = [[QgsPoint(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x,
124+
-i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points]]
125+
126+
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
127+
ft.setAttributes(feat.attributes())
128+
writer.addFeature(ft)
129+
else:
130+
for current, feat in enumerate(features):
131+
point = feat.constGeometry().asPoint()
132+
x = point.x()
133+
y = point.y()
134+
points = [(-xOffset, -yOffset), (-xOffset, yOffset), (xOffset, yOffset), (xOffset, -yOffset)]
135+
polygon = [[QgsPoint(i[0] + x, i[1] + y) for i in points]]
136+
137+
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
138+
ft.setAttributes(feat.attributes())
139+
writer.addFeature(ft)
140+
141+
def diamonds(self, writer, features, width, height, rotation):
142+
ft = QgsFeature()
143+
144+
xOffset = width / 2.0
145+
yOffset = height / 2.0
146+
147+
if rotation is not None:
148+
phi = rotation * math.pi / 180
149+
for current, feat in enumerate(features):
150+
point = feat.constGeometry().asPoint()
151+
x = point.x()
152+
y = point.y()
153+
points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)]
154+
polygon = [[QgsPoint(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x,
155+
-i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points]]
156+
157+
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
158+
ft.setAttributes(feat.attributes())
159+
writer.addFeature(ft)
160+
else:
161+
for current, feat in enumerate(features):
162+
point = feat.constGeometry().asPoint()
163+
x = point.x()
164+
y = point.y()
165+
points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)]
166+
polygon = [[QgsPoint(i[0] + x, i[1] + y) for i in points]]
167+
168+
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
169+
ft.setAttributes(feat.attributes())
170+
writer.addFeature(ft)
171+
172+
def ovals(self, writer, features, width, height, rotation, segments):
173+
ft = QgsFeature()
174+
175+
xOffset = width / 2.0
176+
yOffset = height / 2.0
177+
178+
if rotation is not None:
179+
phi = rotation * math.pi / 180
180+
for current, feat in enumerate(features):
181+
point = feat.constGeometry().asPoint()
182+
x = point.x()
183+
y = point.y()
184+
points = []
185+
for t in [(2 * math.pi) / segments * i for i in xrange(segments)]:
186+
points.append((xOffset * math.cos(t), yOffset * math.sin(t)))
187+
polygon = [[QgsPoint(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x,
188+
-i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points]]
189+
190+
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
191+
ft.setAttributes(feat.attributes())
192+
writer.addFeature(ft)
193+
else:
194+
for current, feat in enumerate(features):
195+
point = feat.constGeometry().asPoint()
196+
x = point.x()
197+
y = point.y()
198+
points = []
199+
for t in [(2 * math.pi) / segments * i for i in xrange(segments)]:
200+
points.append((xOffset * math.cos(t), yOffset * math.sin(t)))
201+
polygon = [[QgsPoint(i[0] + x, i[1] + y) for i in points]]
202+
203+
ft.setGeometry(QgsGeometry.fromPolygon(polygon))
204+
ft.setAttributes(feat.attributes())
205+
writer.addFeature(ft)

0 commit comments

Comments
 (0)