QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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 
22 QString QgsSmoothAlgorithm::name() const
23 {
24  return QStringLiteral( "smoothgeometry" );
25 }
26 
27 QString QgsSmoothAlgorithm::displayName() const
28 {
29  return QObject::tr( "Smooth" );
30 }
31 
32 QStringList QgsSmoothAlgorithm::tags() const
33 {
34  return QObject::tr( "smooth,curve,generalize,round,bend,corners" ).split( ',' );
35 }
36 
37 QString QgsSmoothAlgorithm::group() const
38 {
39  return QObject::tr( "Vector geometry" );
40 }
41 
42 QString QgsSmoothAlgorithm::groupId() const
43 {
44  return QStringLiteral( "vectorgeometry" );
45 }
46 
47 QString QgsSmoothAlgorithm::outputName() const
48 {
49  return QObject::tr( "Smoothed" );
50 }
51 
52 QgsProcessing::SourceType QgsSmoothAlgorithm::outputLayerType() const
53 {
55 }
56 
57 QString QgsSmoothAlgorithm::shortHelpString() const
58 {
59  return QObject::tr( "This algorithm smooths the geometries in a line or polygon layer. It creates a new layer with the "
60  "same features as the ones in the input layer, but with geometries containing a higher number of vertices "
61  "and corners in the geometries smoothed out.\n\n"
62  "The iterations parameter dictates how many smoothing iterations will be applied to each "
63  "geometry. A higher number of iterations results in smoother geometries with the cost of "
64  "greater number of nodes in the geometries.\n\n"
65  "The offset parameter controls how \"tightly\" the smoothed geometries follow the original geometries. "
66  "Smaller values results in a tighter fit, and larger values will create a looser fit.\n\n"
67  "The maximum angle parameter can be used to prevent smoothing of "
68  "nodes with large angles. Any node where the angle of the segments to either "
69  "side is larger than this will not be smoothed. For example, setting the maximum "
70  "angle to 90 degrees or lower would preserve right angles in the geometry.\n\n"
71  "If input geometries contain Z or M values, these will also be smoothed and the output "
72  "geometry will retain the same dimensionality as the input geometry." );
73 }
74 
75 QgsSmoothAlgorithm *QgsSmoothAlgorithm::createInstance() const
76 {
77  return new QgsSmoothAlgorithm();
78 }
79 
80 QList<int> QgsSmoothAlgorithm::inputLayerTypes() const
81 {
83 }
84 
85 void QgsSmoothAlgorithm::initParameters( const QVariantMap & )
86 {
87  std::unique_ptr< QgsProcessingParameterNumber > iterations = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "ITERATIONS" ),
88  QObject::tr( "Iterations" ), QgsProcessingParameterNumber::Integer,
89  1, false, 1, 10 );
90  iterations->setIsDynamic( true );
91  iterations->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "ITERATIONS" ), QObject::tr( "Iterations" ), QgsPropertyDefinition::IntegerPositiveGreaterZero ) );
92  iterations->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
93  addParameter( iterations.release() );
94 
95  std::unique_ptr< QgsProcessingParameterNumber > offset = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "OFFSET" ),
96  QObject::tr( "Offset" ), QgsProcessingParameterNumber::Double,
97  0.25, false, 0.0, 0.5 );
98  offset->setIsDynamic( true );
99  offset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "OFFSET" ), QObject::tr( "Offset" ), QgsPropertyDefinition::Double0To1 ) );
100  offset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
101  addParameter( offset.release() );
102 
103  std::unique_ptr< QgsProcessingParameterNumber > maxAngle = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MAX_ANGLE" ),
104  QObject::tr( "Maximum node angle to smooth" ), QgsProcessingParameterNumber::Double,
105  180.0, false, 0.0, 180.0 );
106  maxAngle->setIsDynamic( true );
107  maxAngle->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "MAX_ANGLE" ), QObject::tr( "Maximum node angle to smooth" ), QgsPropertyDefinition::Rotation ) );
108  maxAngle->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
109  addParameter( maxAngle.release() );
110 }
111 
112 bool QgsSmoothAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
113 {
114  mIterations = parameterAsInt( parameters, QStringLiteral( "ITERATIONS" ), context );
115  mDynamicIterations = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "ITERATIONS" ) );
116  if ( mDynamicIterations )
117  mIterationsProperty = parameters.value( QStringLiteral( "ITERATIONS" ) ).value< QgsProperty >();
118 
119  mOffset = parameterAsDouble( parameters, QStringLiteral( "OFFSET" ), context );
120  mDynamicOffset = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "OFFSET" ) );
121  if ( mDynamicOffset )
122  mOffsetProperty = parameters.value( QStringLiteral( "OFFSET" ) ).value< QgsProperty >();
123 
124  mMaxAngle = parameterAsDouble( parameters, QStringLiteral( "MAX_ANGLE" ), context );
125  mDynamicMaxAngle = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "MAX_ANGLE" ) );
126  if ( mDynamicMaxAngle )
127  mMaxAngleProperty = parameters.value( QStringLiteral( "MAX_ANGLE" ) ).value< QgsProperty >();
128 
129  return true;
130 }
131 
132 QgsFeatureList QgsSmoothAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
133 {
134  QgsFeature f = feature;
135  if ( f.hasGeometry() )
136  {
137  int iterations = mIterations;
138  if ( mDynamicIterations )
139  iterations = mIterationsProperty.valueAsInt( context.expressionContext(), iterations );
140 
141  double offset = mOffset;
142  if ( mDynamicOffset )
143  offset = mOffsetProperty.valueAsDouble( context.expressionContext(), offset );
144 
145  double maxAngle = mMaxAngle;
146  if ( mDynamicMaxAngle )
147  maxAngle = mMaxAngleProperty.valueAsDouble( context.expressionContext(), maxAngle );
148 
149  QgsGeometry outputGeometry = f.geometry().smooth( iterations, offset, -1, maxAngle );
150  if ( outputGeometry.isNull() )
151  {
152  feedback->reportError( QObject::tr( "Error smoothing geometry %1" ).arg( feature.id() ) );
153  }
154  f.setGeometry( outputGeometry );
155  }
156  return QgsFeatureList() << f;
157 }
158 
159 QgsProcessingFeatureSource::Flag QgsSmoothAlgorithm::sourceFlags() const
160 {
162 }
163 
165 
166 
QgsFeatureId id
Definition: qgsfeature.h:64
Base class for providing feedback from a processing algorithm.
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:571
Non-zero positive integer values.
Definition: qgsproperty.h:56
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:106
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:60
Vector polygon layers.
Definition: qgsprocessing.h:50
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.
A store for object properties.
Definition: qgsproperty.h:229
QgsExpressionContext & expressionContext()
Returns the expression context.
Definition for a property.
Definition: qgsproperty.h:46
Flag
Flags controlling how QgsProcessingFeatureSource fetches features.
Vector line layers.
Definition: qgsprocessing.h:49
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
SourceType
Data source types enum.
Definition: qgsprocessing.h:44
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.
QgsGeometry geometry
Definition: qgsfeature.h:67
Contains information about the context in which a processing algorithm is executed.
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...
Double value between 0-1 (inclusive)
Definition: qgsproperty.h:59