Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsalgorithmtaperedbuffer.cpp
3 : : ---------------------
4 : : begin : March 2018
5 : : copyright : (C) 2018 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 "qgsalgorithmtaperedbuffer.h"
19 : :
20 : : ///@cond PRIVATE
21 : :
22 : 0 : QString QgsTaperedBufferAlgorithm::name() const
23 : : {
24 : 0 : return QStringLiteral( "taperedbuffer" );
25 : : }
26 : :
27 : 0 : QString QgsTaperedBufferAlgorithm::displayName() const
28 : : {
29 : 0 : return QObject::tr( "Tapered buffers" );
30 : : }
31 : :
32 : 0 : QStringList QgsTaperedBufferAlgorithm::tags() const
33 : : {
34 : 0 : return QObject::tr( "variable,distance,length,line,buffer" ).split( ',' );
35 : 0 : }
36 : :
37 : 0 : QString QgsTaperedBufferAlgorithm::group() const
38 : : {
39 : 0 : return QObject::tr( "Vector geometry" );
40 : : }
41 : :
42 : 0 : QString QgsTaperedBufferAlgorithm::groupId() const
43 : : {
44 : 0 : return QStringLiteral( "vectorgeometry" );
45 : : }
46 : :
47 : 0 : QString QgsTaperedBufferAlgorithm::outputName() const
48 : : {
49 : 0 : return QObject::tr( "Buffered" );
50 : : }
51 : :
52 : 0 : QgsProcessing::SourceType QgsTaperedBufferAlgorithm::outputLayerType() const
53 : : {
54 : 0 : return QgsProcessing::TypeVectorPolygon;
55 : : }
56 : :
57 : 0 : QgsWkbTypes::Type QgsTaperedBufferAlgorithm::outputWkbType( QgsWkbTypes::Type ) const
58 : : {
59 : 0 : return QgsWkbTypes::MultiPolygon;
60 : : }
61 : :
62 : 0 : bool QgsTaperedBufferAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * )
63 : : {
64 : 0 : mStartWidth = parameterAsDouble( parameters, QStringLiteral( "START_WIDTH" ), context );
65 : 0 : mDynamicStartWidth = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "START_WIDTH" ) );
66 : 0 : if ( mDynamicStartWidth )
67 : 0 : mStartWidthProperty = parameters.value( QStringLiteral( "START_WIDTH" ) ).value< QgsProperty >();
68 : :
69 : 0 : mEndWidth = parameterAsDouble( parameters, QStringLiteral( "END_WIDTH" ), context );
70 : 0 : mDynamicEndWidth = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "END_WIDTH" ) );
71 : 0 : if ( mDynamicEndWidth )
72 : 0 : mEndWidthProperty = parameters.value( QStringLiteral( "END_WIDTH" ) ).value< QgsProperty >();
73 : :
74 : 0 : mSegments = parameterAsInt( parameters, QStringLiteral( "Segments" ), context );
75 : 0 : mDynamicSegments = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "Segments" ) );
76 : 0 : if ( mDynamicSegments )
77 : 0 : mSegmentsProperty = parameters.value( QStringLiteral( "Segments" ) ).value< QgsProperty >();
78 : :
79 : 0 : return true;
80 : 0 : }
81 : :
82 : 0 : QString QgsTaperedBufferAlgorithm::shortHelpString() const
83 : : {
84 : 0 : return QObject::tr( "This algorithm creates tapered buffers along line geometries, using a specified start and "
85 : : "end buffer diameter corresponding to the buffer diameter at the start and end of the linestrings." );
86 : : }
87 : :
88 : 0 : QList<int> QgsTaperedBufferAlgorithm::inputLayerTypes() const
89 : : {
90 : 0 : return QList<int>() << QgsProcessing::TypeVectorLine;
91 : 0 : }
92 : :
93 : 0 : QgsTaperedBufferAlgorithm *QgsTaperedBufferAlgorithm::createInstance() const
94 : : {
95 : 0 : return new QgsTaperedBufferAlgorithm();
96 : 0 : }
97 : :
98 : 0 : void QgsTaperedBufferAlgorithm::initParameters( const QVariantMap & )
99 : : {
100 : 0 : std::unique_ptr< QgsProcessingParameterNumber > startWidth = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "START_WIDTH" ),
101 : 0 : QObject::tr( "Start width" ), QgsProcessingParameterNumber::Double,
102 : 0 : 0.0, false, 0.0 );
103 : 0 : startWidth->setIsDynamic( true );
104 : 0 : startWidth->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "START_WIDTH" ), QObject::tr( "Start width" ), QgsPropertyDefinition::DoublePositive ) );
105 : 0 : startWidth->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
106 : 0 : addParameter( startWidth.release() );
107 : :
108 : 0 : std::unique_ptr< QgsProcessingParameterNumber > endWidth = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "END_WIDTH" ),
109 : 0 : QObject::tr( "End width" ), QgsProcessingParameterNumber::Double,
110 : 0 : 1, false, 0.0 );
111 : 0 : endWidth->setIsDynamic( true );
112 : 0 : endWidth->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "END_WIDTH" ), QObject::tr( "End width" ), QgsPropertyDefinition::DoublePositive ) );
113 : 0 : endWidth->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
114 : 0 : addParameter( endWidth.release() );
115 : :
116 : 0 : std::unique_ptr< QgsProcessingParameterNumber > segments = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "SEGMENTS" ),
117 : 0 : QObject::tr( "Segments" ), QgsProcessingParameterNumber::Integer,
118 : 0 : 16, false, 1 );
119 : 0 : segments->setIsDynamic( true );
120 : 0 : segments->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "SEGMENTS" ), QObject::tr( "Segments" ), QgsPropertyDefinition::IntegerPositiveGreaterZero ) );
121 : 0 : segments->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
122 : 0 : addParameter( segments.release() );
123 : 0 : }
124 : :
125 : 0 : QgsFeatureList QgsTaperedBufferAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
126 : : {
127 : 0 : if ( !feature.hasGeometry() )
128 : 0 : return QgsFeatureList() << feature;
129 : :
130 : 0 : QgsFeature f = feature;
131 : 0 : int segments = mSegments;
132 : 0 : if ( mDynamicSegments )
133 : 0 : segments = mSegmentsProperty.valueAsInt( context.expressionContext(), segments );
134 : :
135 : 0 : double startWidth = mStartWidth;
136 : 0 : if ( mDynamicStartWidth )
137 : 0 : startWidth = mStartWidthProperty.valueAsDouble( context.expressionContext(), startWidth );
138 : :
139 : 0 : double endWidth = mEndWidth;
140 : 0 : if ( mDynamicEndWidth )
141 : 0 : endWidth = mEndWidthProperty.valueAsDouble( context.expressionContext(), endWidth );
142 : :
143 : 0 : QgsGeometry outputGeometry = feature.geometry().taperedBuffer( startWidth, endWidth, segments );
144 : 0 : if ( outputGeometry.isNull() )
145 : : {
146 : 0 : feedback->reportError( QObject::tr( "Error buffering geometry %1: %2" ).arg( feature.id() ).arg( outputGeometry.lastError() ) );
147 : 0 : }
148 : 0 : f.setGeometry( outputGeometry );
149 : :
150 : 0 : return QgsFeatureList() << f;
151 : 0 : }
152 : :
153 : :
154 : :
155 : :
156 : 0 : QString QgsVariableWidthBufferByMAlgorithm::name() const
157 : : {
158 : 0 : return QStringLiteral( "bufferbym" );
159 : : }
160 : :
161 : 0 : QString QgsVariableWidthBufferByMAlgorithm::displayName() const
162 : : {
163 : 0 : return QObject::tr( "Variable width buffer (by M value)" );
164 : : }
165 : :
166 : 0 : QStringList QgsVariableWidthBufferByMAlgorithm::tags() const
167 : : {
168 : 0 : return QObject::tr( "variable,distance,length,line,buffer" ).split( ',' );
169 : 0 : }
170 : :
171 : 0 : QString QgsVariableWidthBufferByMAlgorithm::group() const
172 : : {
173 : 0 : return QObject::tr( "Vector geometry" );
174 : : }
175 : :
176 : 0 : QString QgsVariableWidthBufferByMAlgorithm::groupId() const
177 : : {
178 : 0 : return QStringLiteral( "vectorgeometry" );
179 : : }
180 : :
181 : 0 : QString QgsVariableWidthBufferByMAlgorithm::outputName() const
182 : : {
183 : 0 : return QObject::tr( "Buffered" );
184 : : }
185 : :
186 : 0 : QgsProcessing::SourceType QgsVariableWidthBufferByMAlgorithm::outputLayerType() const
187 : : {
188 : 0 : return QgsProcessing::TypeVectorPolygon;
189 : : }
190 : :
191 : 0 : QgsWkbTypes::Type QgsVariableWidthBufferByMAlgorithm::outputWkbType( QgsWkbTypes::Type ) const
192 : : {
193 : 0 : return QgsWkbTypes::MultiPolygon;
194 : : }
195 : :
196 : 0 : bool QgsVariableWidthBufferByMAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * )
197 : : {
198 : 0 : mSegments = parameterAsInt( parameters, QStringLiteral( "Segments" ), context );
199 : 0 : mDynamicSegments = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "Segments" ) );
200 : 0 : if ( mDynamicSegments )
201 : 0 : mSegmentsProperty = parameters.value( QStringLiteral( "Segments" ) ).value< QgsProperty >();
202 : :
203 : 0 : return true;
204 : 0 : }
205 : :
206 : 0 : QString QgsVariableWidthBufferByMAlgorithm::shortHelpString() const
207 : : {
208 : 0 : return QObject::tr( "This algorithm creates variable width buffers along lines, using the M value of the line geometries "
209 : : "as the diameter of the buffer at each vertex." );
210 : : }
211 : :
212 : 0 : QList<int> QgsVariableWidthBufferByMAlgorithm::inputLayerTypes() const
213 : : {
214 : 0 : return QList<int>() << QgsProcessing::TypeVectorLine;
215 : 0 : }
216 : :
217 : 0 : QgsVariableWidthBufferByMAlgorithm *QgsVariableWidthBufferByMAlgorithm::createInstance() const
218 : : {
219 : 0 : return new QgsVariableWidthBufferByMAlgorithm();
220 : 0 : }
221 : :
222 : 0 : void QgsVariableWidthBufferByMAlgorithm::initParameters( const QVariantMap & )
223 : : {
224 : 0 : std::unique_ptr< QgsProcessingParameterNumber > segments = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "SEGMENTS" ),
225 : 0 : QObject::tr( "Segments" ), QgsProcessingParameterNumber::Integer,
226 : 0 : 16, false, 1 );
227 : 0 : segments->setIsDynamic( true );
228 : 0 : segments->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "SEGMENTS" ), QObject::tr( "Segments" ), QgsPropertyDefinition::IntegerPositiveGreaterZero ) );
229 : 0 : segments->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
230 : 0 : addParameter( segments.release() );
231 : 0 : }
232 : :
233 : 0 : QgsFeatureList QgsVariableWidthBufferByMAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
234 : : {
235 : 0 : if ( !feature.hasGeometry() )
236 : 0 : return QgsFeatureList() << feature;
237 : :
238 : 0 : QgsFeature f = feature;
239 : 0 : int segments = mSegments;
240 : 0 : if ( mDynamicSegments )
241 : 0 : segments = mSegmentsProperty.valueAsInt( context.expressionContext(), segments );
242 : :
243 : 0 : QgsGeometry outputGeometry = feature.geometry().variableWidthBufferByM( segments );
244 : 0 : if ( outputGeometry.isNull() )
245 : : {
246 : 0 : feedback->reportError( QObject::tr( "Error buffering geometry %1: %2" ).arg( feature.id() ).arg( outputGeometry.lastError() ) );
247 : 0 : }
248 : 0 : f.setGeometry( outputGeometry );
249 : :
250 : 0 : return QgsFeatureList() << f;
251 : 0 : }
252 : : ///@endcond
253 : :
254 : :
|