Skip to content

Commit c752919

Browse files
committedJan 15, 2020
[processing][needs-docs] port Rectangle,ovals,diamonds algorithm to C++
and make width, height and rotation parameters dynamic. Old Python implementations marked as deprecated to maintain API compatibility.
1 parent cf36172 commit c752919

File tree

6 files changed

+298
-0
lines changed

6 files changed

+298
-0
lines changed
 

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
QgsProcessingParameterFeatureSink,
3030
QgsProcessingParameterDistance,
3131
QgsProcessingException,
32+
QgsProcessingAlgorithm,
3233
QgsFeature,
3334
QgsFeatureSink,
3435
QgsGeometry,
@@ -58,6 +59,9 @@ def groupId(self):
5859
def __init__(self):
5960
super().__init__()
6061

62+
def flags(self):
63+
return super().flags() | QgsProcessingAlgorithm.FlagDeprecated
64+
6165
def initAlgorithm(self, config=None):
6266
self.shapes = [self.tr('Rectangles'), self.tr('Diamonds'), self.tr('Ovals')]
6367

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
QgsPointXY,
3333
QgsProcessing,
3434
QgsProcessingException,
35+
QgsProcessingAlgorithm,
3536
QgsProcessingParameterField,
3637
QgsProcessingParameterFeatureSource,
3738
QgsProcessingParameterEnum,
@@ -60,6 +61,9 @@ def groupId(self):
6061
def __init__(self):
6162
super().__init__()
6263

64+
def flags(self):
65+
return super().flags() | QgsProcessingAlgorithm.FlagDeprecated
66+
6367
def initAlgorithm(self, config=None):
6468
self.shapes = [self.tr('Rectangles'), self.tr('Diamonds'), self.tr('Ovals')]
6569

‎src/analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ SET(QGIS_ANALYSIS_SRCS
115115
processing/qgsalgorithmrastersurfacevolume.cpp
116116
processing/qgsalgorithmrasterzonalstats.cpp
117117
processing/qgsalgorithmreclassifybylayer.cpp
118+
processing/qgsalgorithmrectanglesovalsdiamonds.cpp
118119
processing/qgsalgorithmremoveduplicatesbyattribute.cpp
119120
processing/qgsalgorithmremoveduplicatevertices.cpp
120121
processing/qgsalgorithmremoveholes.cpp
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/***************************************************************************
2+
qgsalgorithmrectanglesovalsdiamonds.cpp
3+
---------------------
4+
begin : January 2020
5+
copyright : (C) 2020 by Alexander Bruy
6+
email : alexander dot bruy at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgsalgorithmrectanglesovalsdiamonds.h"
19+
#include "qgsapplication.h"
20+
21+
///@cond PRIVATE
22+
23+
QString QgsRectanglesOvalsDiamondsAlgorithm::name() const
24+
{
25+
return QStringLiteral( "rectanglesovalsdiamonds" );
26+
}
27+
28+
QString QgsRectanglesOvalsDiamondsAlgorithm::displayName() const
29+
{
30+
return QObject::tr( "Rectangles, ovals, diamonds" );
31+
}
32+
33+
QStringList QgsRectanglesOvalsDiamondsAlgorithm::tags() const
34+
{
35+
return QObject::tr( "buffer,grow,fixed,variable,distance,rectangle,oval,diamond,point" ).split( ',' );
36+
}
37+
38+
QString QgsRectanglesOvalsDiamondsAlgorithm::group() const
39+
{
40+
return QObject::tr( "Vector geometry" );
41+
}
42+
43+
QString QgsRectanglesOvalsDiamondsAlgorithm::groupId() const
44+
{
45+
return QStringLiteral( "vectorgeometry" );
46+
}
47+
48+
QString QgsRectanglesOvalsDiamondsAlgorithm::shortHelpString() const
49+
{
50+
return QObject::tr( "Creates a rectangle, oval or diamond-shaped polygons from the input point layer using "
51+
"specified width, height and (optional) rotation values." );
52+
}
53+
54+
QString QgsRectanglesOvalsDiamondsAlgorithm::outputName() const
55+
{
56+
return QObject::tr( "Polygon" );
57+
}
58+
59+
QList<int> QgsRectanglesOvalsDiamondsAlgorithm::inputLayerTypes() const
60+
{
61+
return QList<int>() << QgsProcessing::TypeVectorPoint;
62+
}
63+
64+
QgsProcessing::SourceType QgsRectanglesOvalsDiamondsAlgorithm::outputLayerType() const
65+
{
66+
return QgsProcessing::TypeVectorPolygon;
67+
}
68+
69+
QgsWkbTypes::Type QgsRectanglesOvalsDiamondsAlgorithm::outputWkbType( QgsWkbTypes::Type inputWkbType ) const
70+
{
71+
QgsWkbTypes::Type outputWkbType = QgsWkbTypes::Polygon;
72+
if ( QgsWkbTypes::hasM( inputWkbType ) )
73+
{
74+
outputWkbType = QgsWkbTypes::addM( outputWkbType );
75+
}
76+
if ( QgsWkbTypes::hasZ( inputWkbType ) )
77+
{
78+
outputWkbType = QgsWkbTypes::addZ( outputWkbType );
79+
}
80+
81+
return outputWkbType;
82+
}
83+
84+
QgsRectanglesOvalsDiamondsAlgorithm *QgsRectanglesOvalsDiamondsAlgorithm::createInstance() const
85+
{
86+
return new QgsRectanglesOvalsDiamondsAlgorithm();
87+
}
88+
89+
void QgsRectanglesOvalsDiamondsAlgorithm::initParameters( const QVariantMap & )
90+
{
91+
addParameter( new QgsProcessingParameterEnum( QStringLiteral( "SHAPE" ), QObject::tr( "Shape" ), QStringList() << QObject::tr( "Rectangle" ) << QObject::tr( "Diamond" ) << QObject::tr( "Oval" ), false, 0 ) );
92+
93+
auto widthParam = qgis::make_unique < QgsProcessingParameterDistance >( QStringLiteral( "WIDTH" ), QObject::tr( "Width" ), 1.0, QStringLiteral( "INPUT" ), false, 0.0 );
94+
widthParam->setIsDynamic( true );
95+
widthParam->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Width" ), QObject::tr( "Width" ), QgsPropertyDefinition::Double ) );
96+
widthParam->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
97+
addParameter( widthParam.release() );
98+
99+
auto heightParam = qgis::make_unique < QgsProcessingParameterDistance >( QStringLiteral( "HEIGHT" ), QObject::tr( "Height" ), 1.0, QStringLiteral( "INPUT" ), false, 0.0 );
100+
heightParam->setIsDynamic( true );
101+
heightParam->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Height" ), QObject::tr( "Height" ), QgsPropertyDefinition::Double ) );
102+
heightParam->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
103+
addParameter( heightParam.release() );
104+
105+
auto rotationParam = qgis::make_unique < QgsProcessingParameterNumber >( QStringLiteral( "ROTATION" ), QObject::tr( "Rotation" ), QgsProcessingParameterNumber::Double, 0.0, true, 0.0, 360.0 );
106+
rotationParam->setIsDynamic( true );
107+
rotationParam->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Rotation" ), QObject::tr( "Rotation" ), QgsPropertyDefinition::Double ) );
108+
rotationParam->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
109+
addParameter( rotationParam.release() );
110+
111+
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "SEGMENTS" ), QObject::tr( "Segments" ), QgsProcessingParameterNumber::Integer, 5, false, 1 ) );
112+
}
113+
114+
bool QgsRectanglesOvalsDiamondsAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
115+
{
116+
mShape = parameterAsEnum( parameters, QStringLiteral( "SHAPE" ), context );
117+
118+
mWidth = parameterAsDouble( parameters, QStringLiteral( "WIDTH" ), context );
119+
mDynamicWidth = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "WIDTH" ) );
120+
if ( mDynamicWidth )
121+
mWidthProperty = parameters.value( QStringLiteral( "WIDTH" ) ).value< QgsProperty >();
122+
123+
mHeight = parameterAsDouble( parameters, QStringLiteral( "HEIGHT" ), context );
124+
mDynamicHeight = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "HEIGHT" ) );
125+
if ( mDynamicHeight )
126+
mHeightProperty = parameters.value( QStringLiteral( "HEIGHT" ) ).value< QgsProperty >();
127+
128+
mRotation = parameterAsDouble( parameters, QStringLiteral( "ROTATION" ), context );
129+
mDynamicRotation = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "ROTATION" ) );
130+
if ( mDynamicRotation )
131+
mRotationProperty = parameters.value( QStringLiteral( "ROTATION" ) ).value< QgsProperty >();
132+
133+
mSegments = parameterAsDouble( parameters, QStringLiteral( "SEGMENTS" ), context );
134+
135+
return true;
136+
}
137+
138+
QgsFeatureList QgsRectanglesOvalsDiamondsAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
139+
{
140+
QgsFeature outFeature = feature;
141+
if ( outFeature.hasGeometry() )
142+
{
143+
double width = mWidth;
144+
if ( mDynamicWidth )
145+
width = mWidthProperty.valueAsDouble( context.expressionContext(), width );
146+
147+
double height = mHeight;
148+
if ( mDynamicHeight )
149+
height = mHeightProperty.valueAsDouble( context.expressionContext(), height );
150+
151+
double rotation = mRotation;
152+
if ( mDynamicRotation )
153+
rotation = mRotationProperty.valueAsDouble( context.expressionContext(), rotation );
154+
155+
if ( width == 0 || height == 0 )
156+
{
157+
throw QgsProcessingException( QObject::tr( "Width and height should be greater than 0." ) );
158+
}
159+
160+
double phi = rotation * M_PI / 180;
161+
double xOffset = width / 2.0;
162+
double yOffset = height / 2.0;
163+
QgsPointXY point = outFeature.geometry().asPoint();
164+
double x = point.x();
165+
double y = point.y();
166+
167+
QgsPolylineXY ring;
168+
switch ( mShape )
169+
{
170+
case 0:
171+
// rectangle
172+
ring << QgsPointXY( -xOffset, -yOffset )
173+
<< QgsPointXY( -xOffset, yOffset )
174+
<< QgsPointXY( xOffset, yOffset )
175+
<< QgsPointXY( xOffset, -yOffset );
176+
break;
177+
case 1:
178+
// diamond
179+
ring << QgsPointXY( 0.0, -yOffset )
180+
<< QgsPointXY( -xOffset, 0.0 )
181+
<< QgsPointXY( 0.0, yOffset )
182+
<< QgsPointXY( xOffset, 0.0 );
183+
break;
184+
case 2:
185+
// oval
186+
for ( int i = 0; i < mSegments; i ++ )
187+
{
188+
double t = ( 2 * M_PI ) / mSegments * i;
189+
ring << QgsPointXY( xOffset * cos( t ), yOffset * sin( t ) );
190+
}
191+
break;
192+
}
193+
194+
for ( int i = 0; i < ring.size(); ++i )
195+
{
196+
QgsPointXY p = ring[ i ];
197+
double px = p.x();
198+
double py = p.y();
199+
ring[ i ] = QgsPointXY( px * cos( phi ) + py * sin( phi ) + x,
200+
-px * sin( phi ) + py * cos( phi ) + y );
201+
}
202+
203+
outFeature.setGeometry( QgsGeometry::fromPolygonXY( QgsPolygonXY() << ring ) );
204+
}
205+
206+
return QgsFeatureList() << outFeature;
207+
}
208+
209+
///@endcond
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/***************************************************************************
2+
qgsalgorithmrectanglesovalsdiamonds.h
3+
----------------------
4+
begin : January 2020
5+
copyright : (C) 2020 by Alexander Bruy
6+
email : alexander dot bruy at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSALGORITHMRECTANGLESOVALSDIAMONDS_H
19+
#define QGSALGORITHMRECTANGLESOVALSDIAMONDS_H
20+
21+
#define SIP_NO_FILE
22+
23+
#include "qgis_sip.h"
24+
#include "qgsprocessingalgorithm.h"
25+
#include "qgsapplication.h"
26+
27+
///@cond PRIVATE
28+
29+
/**
30+
* Native rectangles, ovals, diamonds algorithm.
31+
*/
32+
class QgsRectanglesOvalsDiamondsAlgorithm : public QgsProcessingFeatureBasedAlgorithm
33+
{
34+
35+
public:
36+
37+
QgsRectanglesOvalsDiamondsAlgorithm() = default;
38+
QString name() const override;
39+
QString displayName() const override;
40+
QStringList tags() const override;
41+
QString group() const override;
42+
QString groupId() const override;
43+
QString shortHelpString() const override;
44+
QList<int> inputLayerTypes() const override;
45+
void initParameters( const QVariantMap &configuration = QVariantMap() ) override;
46+
QgsRectanglesOvalsDiamondsAlgorithm *createInstance() const override SIP_FACTORY;
47+
48+
protected:
49+
50+
QString outputName() const override;
51+
QgsProcessing::SourceType outputLayerType() const override;
52+
QgsWkbTypes::Type outputWkbType( QgsWkbTypes::Type inputWkbType ) const override;
53+
54+
bool prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
55+
QgsFeatureList processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
56+
57+
private:
58+
int mShape = 0;
59+
int mSegments = 0;
60+
61+
double mWidth = 0.0;
62+
bool mDynamicWidth = false;
63+
QgsProperty mWidthProperty;
64+
65+
double mHeight = 0.0;
66+
bool mDynamicHeight = false;
67+
QgsProperty mHeightProperty;
68+
69+
double mRotation = 0.0;
70+
bool mDynamicRotation = false;
71+
QgsProperty mRotationProperty;
72+
};
73+
74+
///@endcond PRIVATE
75+
76+
#endif // QGSALGORITHMRECTANGLESOVALSDIAMONDS_H
77+
78+

‎src/analysis/processing/qgsnativealgorithms.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
#include "qgsalgorithmrastersurfacevolume.h"
110110
#include "qgsalgorithmrasterzonalstats.h"
111111
#include "qgsalgorithmreclassifybylayer.h"
112+
#include "qgsalgorithmrectanglesovalsdiamonds.h"
112113
#include "qgsalgorithmremoveduplicatesbyattribute.h"
113114
#include "qgsalgorithmremoveduplicatevertices.h"
114115
#include "qgsalgorithmremoveholes.h"
@@ -306,6 +307,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
306307
addAlgorithm( new QgsAlgorithmRemoveDuplicateVertices() );
307308
addAlgorithm( new QgsReclassifyByLayerAlgorithm() );
308309
addAlgorithm( new QgsReclassifyByTableAlgorithm() );
310+
addAlgorithm( new QgsRectanglesOvalsDiamondsAlgorithm() );
309311
addAlgorithm( new QgsRemoveDuplicatesByAttributeAlgorithm() );
310312
addAlgorithm( new QgsRemoveHolesAlgorithm() );
311313
addAlgorithm( new QgsRemoveNullGeometryAlgorithm() );

0 commit comments

Comments
 (0)
Please sign in to comment.