QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsalgorithmgrid.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmgrid.cpp
3 ---------------------
4 begin : August 2019
5 copyright : (C) 2019 by Clemens Raffler
6 email : clemens dot raffler 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//Disclaimer:This feature was developed by: Michael Minn, 2010
19
20#include "qgsalgorithmgrid.h"
21#include "qgslinestring.h"
22#include "qgswkbtypes.h"
23#include "qgsvectorlayer.h"
24#include "qgspolygon.h"
25
27
28QString QgsGridAlgorithm::name() const
29{
30 return QStringLiteral( "creategrid" );
31}
32
33QString QgsGridAlgorithm::displayName() const
34{
35 return QObject::tr( "Create grid" );
36}
37
38QStringList QgsGridAlgorithm::tags() const
39{
40 return QObject::tr( "grid,lines,polygons,vector,create,fishnet,diamond,hexagon" ).split( ',' );
41}
42
43QString QgsGridAlgorithm::group() const
44{
45 return QObject::tr( "Vector creation" );
46}
47
48QString QgsGridAlgorithm::groupId() const
49{
50 return QStringLiteral( "vectorcreation" );
51}
52
53void QgsGridAlgorithm::initAlgorithm( const QVariantMap & )
54{
55 addParameter( new QgsProcessingParameterEnum( QStringLiteral( "TYPE" ), QObject::tr( "Grid type" ), QStringList() << QObject::tr( "Point" ) << QObject::tr( "Line" ) << QObject::tr( "Rectangle (Polygon)" ) << QObject::tr( "Diamond (Polygon)" ) << QObject::tr( "Hexagon (Polygon)" ), false, 0 ) );
56
57 addParameter( new QgsProcessingParameterExtent( QStringLiteral( "EXTENT" ), QObject::tr( "Grid extent" ) ) );
58
59 addParameter( new QgsProcessingParameterDistance( QStringLiteral( "HSPACING" ), QObject::tr( "Horizontal spacing" ), 1, QStringLiteral( "CRS" ), false, 0, 1000000000.0 ) );
60 addParameter( new QgsProcessingParameterDistance( QStringLiteral( "VSPACING" ), QObject::tr( "Vertical spacing" ), 1, QStringLiteral( "CRS" ), false, 0, 1000000000.0 ) );
61
62 addParameter( new QgsProcessingParameterDistance( QStringLiteral( "HOVERLAY" ), QObject::tr( "Horizontal overlay" ), 0, QStringLiteral( "CRS" ), false, 0, 1000000000.0 ) );
63 addParameter( new QgsProcessingParameterDistance( QStringLiteral( "VOVERLAY" ), QObject::tr( "Vertical overlay" ), 0, QStringLiteral( "CRS" ), false, 0, 1000000000.0 ) );
64
65 addParameter( new QgsProcessingParameterCrs( QStringLiteral( "CRS" ), QObject::tr( "Grid CRS" ), QStringLiteral( "ProjectCrs" ) ) );
66
67 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Grid" ), QgsProcessing::TypeVectorAnyGeometry ) );
68}
69
70QString QgsGridAlgorithm::shortHelpString() const
71{
72 return QObject::tr( "This algorithm creates a vector layer with a grid covering a given extent. "
73 "Elements in the grid can be points, lines or polygons. The size and/or "
74 "placement of each element in the grid is defined using a horizontal and "
75 "vertical spacing. The CRS of the output layer must be defined. The grid extent "
76 "and the spacing values must be expressed in the coordinates and units of "
77 "this CRS. The top-left point (minX, maxY) is used as the reference point. "
78 "That means that, at that point, an element is guaranteed to be placed. "
79 "Unless the width and height of the selected extent is a multiple of the "
80 "selected spacing, that is not true for the other points that define that extent."
81 );
82}
83
84QgsGridAlgorithm *QgsGridAlgorithm::createInstance() const
85{
86 return new QgsGridAlgorithm();
87}
88
89bool QgsGridAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
90{
91 mIdx = parameterAsEnum( parameters, QStringLiteral( "TYPE" ), context );
92 mHSpacing = parameterAsDouble( parameters, QStringLiteral( "HSPACING" ), context );
93 mVSpacing = parameterAsDouble( parameters, QStringLiteral( "VSPACING" ), context );
94 mHOverlay = parameterAsDouble( parameters, QStringLiteral( "HOVERLAY" ), context );
95 mVOverlay = parameterAsDouble( parameters, QStringLiteral( "VOVERLAY" ), context );
96 mCrs = parameterAsCrs( parameters, QStringLiteral( "CRS" ), context );
97 mGridExtent = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, mCrs );
98
99 return true;
100}
101
102QVariantMap QgsGridAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
103{
104 if ( mHSpacing <= 0 || mVSpacing <= 0 )
105 throw QgsProcessingException( QObject::tr( "Invalid grid spacing. horizontal: '%1', vertical: '%2'" ).arg( mHSpacing ).arg( mVSpacing ) );
106
107 if ( mGridExtent.width() < mHSpacing ) //check if grid extent is smaller than horizontal spacing
108 throw QgsProcessingException( QObject::tr( "Horizontal spacing is too large for the covered area." ) );
109
110 if ( mGridExtent.height() < mVSpacing ) //check if grid extent is smaller than vertical spacing
111 throw QgsProcessingException( QObject::tr( "Vertical spacing is too large for the covered area." ) );
112
113 if ( mHSpacing <= mHOverlay || mVSpacing <= mVOverlay )
114 throw QgsProcessingException( QObject::tr( "Invalid overlay: horizontal: '%1', vertical: '%2'" ).arg( mHOverlay ).arg( mVOverlay ) );
115
116 QgsFields fields = QgsFields();
117 fields.append( QgsField( QStringLiteral( "id" ), QVariant::LongLong ) );
118 fields.append( QgsField( QStringLiteral( "left" ), QVariant::Double ) );
119 fields.append( QgsField( QStringLiteral( "top" ), QVariant::Double ) );
120 fields.append( QgsField( QStringLiteral( "right" ), QVariant::Double ) );
121 fields.append( QgsField( QStringLiteral( "bottom" ), QVariant::Double ) );
122
124 switch ( mIdx )
125 {
126 case 0:
127 outputWkb = QgsWkbTypes::Point;
128 break;
129 case 1:
130 outputWkb = QgsWkbTypes::LineString;
131 break;
132 }
133
134 QString dest;
135 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, outputWkb, mCrs ) );
136 if ( !sink )
137 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
138
139 feedback->setProgress( 0 );
140
141 switch ( mIdx )
142 {
143 case 0: //point
144 createPointGrid( sink, feedback );
145 break;
146 case 1: //line
147 createLineGrid( sink, feedback );
148 break;
149 case 2: //rectangle
150 createRectangleGrid( sink, feedback );
151 break;
152 case 3: //diamond
153 createDiamondGrid( sink, feedback );
154 break;
155 case 4: //hexagon
156 createHexagonGrid( sink, feedback );
157 break;
158 }
159
160
161 QVariantMap outputs;
162 outputs.insert( QStringLiteral( "OUTPUT" ), dest );
163 return outputs;
164}
165
166void QgsGridAlgorithm::createPointGrid( std::unique_ptr< QgsFeatureSink > &sink, QgsProcessingFeedback *feedback )
167{
169
170 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( mHSpacing - mHOverlay ) ) );
171 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - mVOverlay ) ) );
172
173 long long id = 1;
174 long long cnt = 0;
175 const long long cellcnt = rows * cols;
176
177 int thisProgress = 0;
178 int lastProgress = 0;
179
180 for ( long long col = 0; col < cols; col++ )
181 {
182 const double x = mGridExtent.xMinimum() + ( col * mHSpacing - col * mHOverlay );
183
184 for ( long long row = 0; row < rows; row++ )
185 {
186 const double y = mGridExtent.yMaximum() - ( row * mVSpacing - row * mVOverlay );
187
188 f.setGeometry( QgsGeometry( new QgsPoint( x, y ) ) );
189 f.setAttributes( QgsAttributes() << id << x << y << x + mHSpacing << y + mVSpacing );
190 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
191 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
192
193 id++;
194 cnt++;
195
196 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
197 if ( thisProgress != lastProgress )
198 {
199 lastProgress = thisProgress;
200 feedback->setProgress( lastProgress );
201 }
202
203 if ( feedback && feedback->isCanceled() )
204 break;
205 }
206 if ( feedback && feedback->isCanceled() )
207 break;
208 }
209}
210
211void QgsGridAlgorithm::createLineGrid( std::unique_ptr< QgsFeatureSink > &sink, QgsProcessingFeedback *feedback )
212{
214
215 double hSpace[2];
216 if ( mHOverlay > 0 )
217 {
218 hSpace[0] = mHSpacing - mHOverlay;
219 hSpace[1] = mHOverlay;
220 }
221 else
222 {
223 hSpace[0] = mHSpacing;
224 hSpace[1] = mHSpacing;
225 }
226
227 double vSpace[2];
228 if ( mVOverlay > 0 )
229 {
230 vSpace[0] = mVSpacing - mVOverlay;
231 vSpace[1] = mVOverlay;
232 }
233 else
234 {
235 vSpace[0] = mVSpacing;
236 vSpace[1] = mVSpacing;
237 }
238
239 long long cnt = 0;
240 long long id = 1;
241
242 //latitude lines
243 double cntMax = mGridExtent.height() / mVSpacing;
244
245 int thisProgress = 0;
246 int lastProgress = 0;
247
248 double y = mGridExtent.yMaximum();
249
250 while ( y >= mGridExtent.yMinimum() )
251 {
252 if ( feedback && feedback->isCanceled() )
253 break;
254
255 const QgsPoint pt1 = QgsPoint( mGridExtent.xMinimum(), y );
256 const QgsPoint pt2 = QgsPoint( mGridExtent.xMaximum(), y );
257
258 f.setGeometry( QgsGeometry( new QgsLineString( pt1, pt2 ) ) );
259 f.setAttributes( QgsAttributes() << id << mGridExtent.xMinimum() << y << mGridExtent.xMaximum() << y );
260 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
261 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
262 y = y - vSpace[cnt % 2];
263
264 id++;
265 cnt++;
266
267 //use 50 as count multiplicator because only half of the features are processed at this point
268 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / cntMax ) * 50 );
269 if ( thisProgress != lastProgress )
270 {
271 lastProgress = thisProgress;
272 feedback->setProgress( lastProgress );
273 }
274
275 }
276 //set progress to 50 manually in case the division doesn't amount to 50.
277 feedback->setProgress( 50 );
278
279 //longitude lines
280 cnt = 0;
281
282 //latitude lines
283 cntMax = mGridExtent.width() / mHSpacing;
284
285 lastProgress = 50;
286
287 double x = mGridExtent.xMinimum();
288
289 while ( x <= mGridExtent.xMaximum() )
290 {
291 if ( feedback->isCanceled() )
292 break;
293
294 const QgsPoint pt1 = QgsPoint( x, mGridExtent.yMaximum() );
295 const QgsPoint pt2 = QgsPoint( x, mGridExtent.yMinimum() );
296 f.setGeometry( QgsGeometry( new QgsLineString( pt1, pt2 ) ) );
297 f.setAttributes( QgsAttributes() << id << x << mGridExtent.yMaximum() << x << mGridExtent.yMinimum() );
298 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
299 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
300 x = x + hSpace[cnt % 2];
301
302 id++;
303 cnt++;
304
305 thisProgress = static_cast<int>( static_cast<double>( 50 ) + ( static_cast<double>( cnt ) / cntMax ) * 100 );
306 if ( thisProgress != lastProgress )
307 {
308 lastProgress = thisProgress;
309 feedback->setProgress( lastProgress );
310 }
311 }
312 feedback->setProgress( 100 );
313}
314
315void QgsGridAlgorithm::createRectangleGrid( std::unique_ptr< QgsFeatureSink > &sink, QgsProcessingFeedback *feedback )
316{
318
319 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( mHSpacing - mHOverlay ) ) );
320 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - mVOverlay ) ) );
321
322 long long id = 1;
323 long long cnt = 0;
324 const long long cellcnt = rows * cols;
325
326 int thisProgress = 0;
327 int lastProgress = 0;
328 QVector< double > ringX( 5 );
329 QVector< double > ringY( 5 );
330
331 for ( long long col = 0; col < cols; col++ )
332 {
333 if ( feedback && feedback->isCanceled() )
334 break;
335
336 const double x1 = mGridExtent.xMinimum() + ( col * mHSpacing - col * mHOverlay );
337 const double x2 = x1 + mHSpacing;
338
339 for ( long long row = 0; row < rows; row++ )
340 {
341 const double y1 = mGridExtent.yMaximum() - ( row * mVSpacing - row * mVOverlay );
342 const double y2 = y1 - mVSpacing;
343
344 ringX = { x1, x2, x2, x1, x1 };
345 ringY = { y1, y1, y2, y2, y1 };
346 std::unique_ptr< QgsPolygon > poly = std::make_unique< QgsPolygon >();
347 poly->setExteriorRing( new QgsLineString( ringX, ringY ) );
348 f.setGeometry( std::move( poly ) );
349 f.setAttributes( QgsAttributes() << id << x1 << y1 << x2 << y2 );
350 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
351 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
352
353 id++;
354 cnt++;
355
356 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
357 if ( thisProgress != lastProgress )
358 {
359 lastProgress = thisProgress;
360 feedback->setProgress( lastProgress );
361 }
362
363 if ( feedback && feedback->isCanceled() )
364 break;
365 }
366 }
367}
368
369void QgsGridAlgorithm::createDiamondGrid( std::unique_ptr< QgsFeatureSink > &sink, QgsProcessingFeedback *feedback )
370{
372
373 const double halfHSpacing = mHSpacing / 2;
374 const double halfVSpacing = mVSpacing / 2;
375
376 const double halfHOverlay = mHOverlay / 2;
377 const double halfVOverlay = mVOverlay / 2;
378
379 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( halfHSpacing - halfHOverlay ) ) );
380 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - halfVOverlay ) ) );
381
382 long long id = 1;
383 long long cnt = 0;
384 const long long cellcnt = rows * cols;
385
386 int thisProgress = 0;
387 int lastProgress = 0;
388 QVector< double > ringX( 5 );
389 QVector< double > ringY( 5 );
390
391 for ( long long col = 0; col < cols; col++ )
392 {
393 if ( feedback && feedback->isCanceled() )
394 break;
395
396 const double x = mGridExtent.xMinimum() - ( col * halfHOverlay );
397 const double x1 = x + ( ( col + 0 ) * halfHSpacing );
398 const double x2 = x + ( ( col + 1 ) * halfHSpacing );
399 const double x3 = x + ( ( col + 2 ) * halfHSpacing );
400
401 for ( long long row = 0; row < rows; row++ )
402 {
403 const double y = mGridExtent.yMaximum() + ( row * halfVOverlay );
404
405 double y1;
406 double y2;
407 double y3;
408
409 if ( ( col % 2 ) == 0 )
410 {
411 y1 = y - ( ( ( row * 2 ) + 0 ) * halfVSpacing );
412 y2 = y - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
413 y3 = y - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
414 }
415 else
416 {
417 y1 = y - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
418 y2 = y - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
419 y3 = y - ( ( ( row * 2 ) + 3 ) * halfVSpacing );
420 }
421
422 ringX = { x1, x2, x3, x2, x1 };
423 ringY = { y2, y1, y2, y3, y2 };
424 std::unique_ptr< QgsPolygon > poly = std::make_unique< QgsPolygon >();
425 poly->setExteriorRing( new QgsLineString( ringX, ringY ) );
426 f.setGeometry( std::move( poly ) );
427 f.setAttributes( QgsAttributes() << id << x1 << y1 << x3 << y3 );
428 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
429 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
430
431 id++;
432 cnt++;
433
434 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
435 if ( thisProgress != lastProgress )
436 {
437 lastProgress = thisProgress;
438 feedback->setProgress( lastProgress );
439 }
440
441 if ( feedback && feedback->isCanceled() )
442 break;
443 }
444 }
445}
446
447void QgsGridAlgorithm::createHexagonGrid( std::unique_ptr<QgsFeatureSink> &sink, QgsProcessingFeedback *feedback )
448{
450
451 // To preserve symmetry, hspacing is fixed relative to vspacing
452 const double xVertexLo = 0.288675134594813 * mVSpacing;
453 const double xVertexHi = 0.577350269189626 * mVSpacing;
454
455 mHSpacing = xVertexLo + xVertexHi;
456
457 mHOverlay = mHSpacing - mHOverlay;
458
459 if ( mHOverlay < 0 )
460 {
461 throw QgsProcessingException( QObject::tr( "To preserve symmetry, hspacing is fixed relative to vspacing\n hspacing is fixed at: %1 and hoverlay is fixed at: %2 hoverlay cannot be negative. Increase hoverlay." ).arg( mHSpacing ).arg( mHOverlay ) );
462 }
463
464 const double halfVSpacing = mVSpacing / 2;
465
466 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( mHOverlay ) ) );
467 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - mVOverlay ) ) );
468
469 long long id = 1;
470 long long cnt = 0;
471 const long long cellcnt = rows * cols;
472
473 int thisProgress = 0;
474 int lastProgress = 0;
475
476 QVector< double > ringX( 7 );
477 QVector< double > ringY( 7 );
478 for ( long long col = 0; col < cols; col++ )
479 {
480 if ( feedback && feedback->isCanceled() )
481 break;
482
483 // (column + 1) and (row + 1) calculation is used to maintain
484 // topology between adjacent shapes and avoid overlaps/holes
485 // due to rounding errors
486
487 const double x1 = mGridExtent.xMinimum() + ( col * mHOverlay );
488 const double x2 = x1 + ( xVertexHi - xVertexLo );
489 const double x3 = mGridExtent.xMinimum() + ( col * mHOverlay ) + mHSpacing;
490 const double x4 = x3 + ( xVertexHi - xVertexLo );
491
492 for ( long long row = 0; row < rows; row++ )
493 {
494 double y1;
495 double y2;
496 double y3;
497
498 if ( ( col % 2 ) == 0 )
499 {
500 y1 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 0 ) * halfVSpacing );
501 y2 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
502 y3 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
503 }
504 else
505 {
506 y1 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
507 y2 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
508 y3 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 3 ) * halfVSpacing );
509 }
510
511 ringX = { x1, x2, x3, x4, x3, x2, x1 };
512 ringY = { y2, y1, y1, y2, y3, y3, y2 };
513 std::unique_ptr< QgsPolygon > poly = std::make_unique< QgsPolygon >();
514 poly->setExteriorRing( new QgsLineString( ringX, ringY ) );
515 f.setGeometry( std::move( poly ) );
516 f.setAttributes( QgsAttributes() << id << x1 << y1 << x4 << y3 );
517 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
518 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
519
520 id++;
521 cnt++;
522
523 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
524 if ( thisProgress != lastProgress )
525 {
526 lastProgress = thisProgress;
527 feedback->setProgress( lastProgress );
528 }
529
530 if ( feedback && feedback->isCanceled() )
531 break;
532 }
533 }
534}
535
A vector of attributes.
Definition: qgsattributes.h:59
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:160
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:170
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
Container of fields for a vector layer.
Definition: qgsfields.h:45
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:164
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:45
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
Base class for providing feedback from a processing algorithm.
A coordinate reference system parameter for processing algorithms.
A double numeric parameter for distance values.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
A rectangular map extent parameter for processing algorithms.
A feature sink output for processing algorithms.
@ TypeVectorAnyGeometry
Any vector layer with geometry.
Definition: qgsprocessing.h:48
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70