QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsalgorithmsmooth.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmsmooth.cpp
3 ---------------------
4 begin : April 2017
5 copyright : (C) 2017 by Nyall Dawson
6 email : nyall dot dawson 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 "qgsalgorithmsmooth.h"
19
21
22QString QgsSmoothAlgorithm::name() const
23{
24 return QStringLiteral( "smoothgeometry" );
25}
26
27QString QgsSmoothAlgorithm::displayName() const
28{
29 return QObject::tr( "Smooth" );
30}
31
32QStringList QgsSmoothAlgorithm::tags() const
33{
34 return QObject::tr( "smooth,curve,generalize,round,bend,corners" ).split( ',' );
35}
36
37QString QgsSmoothAlgorithm::group() const
38{
39 return QObject::tr( "Vector geometry" );
40}
41
42QString QgsSmoothAlgorithm::groupId() const
43{
44 return QStringLiteral( "vectorgeometry" );
45}
46
47QString QgsSmoothAlgorithm::outputName() const
48{
49 return QObject::tr( "Smoothed" );
50}
51
52QString QgsSmoothAlgorithm::shortHelpString() const
53{
54 return QObject::tr( "This algorithm smooths the geometries in a line or polygon layer. It creates a new layer with the "
55 "same features as the ones in the input layer, but with geometries containing a higher number of vertices "
56 "and corners in the geometries smoothed out.\n\n"
57 "The iterations parameter dictates how many smoothing iterations will be applied to each "
58 "geometry. A higher number of iterations results in smoother geometries with the cost of "
59 "greater number of nodes in the geometries.\n\n"
60 "The offset parameter controls how \"tightly\" the smoothed geometries follow the original geometries. "
61 "Smaller values results in a tighter fit, and larger values will create a looser fit.\n\n"
62 "The maximum angle parameter can be used to prevent smoothing of "
63 "nodes with large angles. Any node where the angle of the segments to either "
64 "side is larger than this will not be smoothed. For example, setting the maximum "
65 "angle to 90 degrees or lower would preserve right angles in the geometry.\n\n"
66 "If input geometries contain Z or M values, these will also be smoothed and the output "
67 "geometry will retain the same dimensionality as the input geometry." );
68}
69
70QgsSmoothAlgorithm *QgsSmoothAlgorithm::createInstance() const
71{
72 return new QgsSmoothAlgorithm();
73}
74
75QList<int> QgsSmoothAlgorithm::inputLayerTypes() const
76{
77 return QList<int>() << static_cast< int >( Qgis::ProcessingSourceType::VectorLine ) << static_cast< int >( Qgis::ProcessingSourceType::VectorPolygon );
78}
79
80void QgsSmoothAlgorithm::initParameters( const QVariantMap & )
81{
82 std::unique_ptr< QgsProcessingParameterNumber > iterations = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "ITERATIONS" ),
83 QObject::tr( "Iterations" ), Qgis::ProcessingNumberParameterType::Integer,
84 1, false, 1, 10 );
85 iterations->setIsDynamic( true );
86 iterations->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "ITERATIONS" ), QObject::tr( "Iterations" ), QgsPropertyDefinition::IntegerPositiveGreaterZero ) );
87 iterations->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
88 addParameter( iterations.release() );
89
90 std::unique_ptr< QgsProcessingParameterNumber > offset = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "OFFSET" ),
91 QObject::tr( "Offset" ), Qgis::ProcessingNumberParameterType::Double,
92 0.25, false, 0.0, 0.5 );
93 offset->setIsDynamic( true );
94 offset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "OFFSET" ), QObject::tr( "Offset" ), QgsPropertyDefinition::Double0To1 ) );
95 offset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
96 addParameter( offset.release() );
97
98 std::unique_ptr< QgsProcessingParameterNumber > maxAngle = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MAX_ANGLE" ),
99 QObject::tr( "Maximum node angle to smooth" ), Qgis::ProcessingNumberParameterType::Double,
100 180.0, false, 0.0, 180.0 );
101 maxAngle->setIsDynamic( true );
102 maxAngle->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "MAX_ANGLE" ), QObject::tr( "Maximum node angle to smooth" ), QgsPropertyDefinition::Rotation ) );
103 maxAngle->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
104 addParameter( maxAngle.release() );
105}
106
107bool QgsSmoothAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
108{
109 mIterations = parameterAsInt( parameters, QStringLiteral( "ITERATIONS" ), context );
110 mDynamicIterations = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "ITERATIONS" ) );
111 if ( mDynamicIterations )
112 mIterationsProperty = parameters.value( QStringLiteral( "ITERATIONS" ) ).value< QgsProperty >();
113
114 mOffset = parameterAsDouble( parameters, QStringLiteral( "OFFSET" ), context );
115 mDynamicOffset = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "OFFSET" ) );
116 if ( mDynamicOffset )
117 mOffsetProperty = parameters.value( QStringLiteral( "OFFSET" ) ).value< QgsProperty >();
118
119 mMaxAngle = parameterAsDouble( parameters, QStringLiteral( "MAX_ANGLE" ), context );
120 mDynamicMaxAngle = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "MAX_ANGLE" ) );
121 if ( mDynamicMaxAngle )
122 mMaxAngleProperty = parameters.value( QStringLiteral( "MAX_ANGLE" ) ).value< QgsProperty >();
123
124 return true;
125}
126
127QgsFeatureList QgsSmoothAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
128{
129 QgsFeature f = feature;
130 if ( f.hasGeometry() )
131 {
132 int iterations = mIterations;
133 if ( mDynamicIterations )
134 iterations = mIterationsProperty.valueAsInt( context.expressionContext(), iterations );
135
136 double offset = mOffset;
137 if ( mDynamicOffset )
138 offset = mOffsetProperty.valueAsDouble( context.expressionContext(), offset );
139
140 double maxAngle = mMaxAngle;
141 if ( mDynamicMaxAngle )
142 maxAngle = mMaxAngleProperty.valueAsDouble( context.expressionContext(), maxAngle );
143
144 const QgsGeometry outputGeometry = f.geometry().smooth( iterations, offset, -1, maxAngle );
145 if ( outputGeometry.isNull() )
146 {
147 feedback->reportError( QObject::tr( "Error smoothing geometry %1" ).arg( feature.id() ) );
148 }
149 f.setGeometry( outputGeometry );
150 }
151 return QgsFeatureList() << f;
152}
153
154Qgis::ProcessingFeatureSourceFlags QgsSmoothAlgorithm::sourceFlags() const
155{
157}
158
160
161
@ VectorPolygon
Vector polygon layers.
@ VectorLine
Vector line layers.
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition: qgis.h:3011
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:167
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:162
Q_GADGET bool isNull
Definition: qgsgeometry.h:164
QgsGeometry smooth(unsigned int iterations=1, double offset=0.25, double minimumDistance=-1.0, double maxAngle=180.0) const
Smooths a geometry by rounding off corners using the Chaikin algorithm.
Contains information about the context in which a processing algorithm is executed.
QgsExpressionContext & expressionContext()
Returns the expression context.
Base class for providing feedback from a processing algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
static bool isDynamic(const QVariantMap &parameters, const QString &name)
Returns true if the parameter with matching name is a dynamic parameter, and must be evaluated once f...
Definition for a property.
Definition: qgsproperty.h:45
@ Double0To1
Double value between 0-1 (inclusive)
Definition: qgsproperty.h:57
@ IntegerPositiveGreaterZero
Non-zero positive integer values.
Definition: qgsproperty.h:54
@ Rotation
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:58
A store for object properties.
Definition: qgsproperty.h:228
double valueAsDouble(const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property and interprets it as a double.
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:917