QGIS API Documentation 3.43.0-Master (e01d6d7c4c0)
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 ) );
63 addParameter( new QgsProcessingParameterDistance( QStringLiteral( "VOVERLAY" ), QObject::tr( "Vertical overlay" ), 0, QStringLiteral( "CRS" ), false ) );
64
65 addParameter( new QgsProcessingParameterCrs( QStringLiteral( "CRS" ), QObject::tr( "Grid CRS" ), QStringLiteral( "ProjectCrs" ) ) );
66
67 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Grid" ), Qgis::ProcessingSourceType::VectorAnyGeometry ) );
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}
83QString QgsGridAlgorithm::shortDescription() const
84{
85 return QObject::tr( "Creates a vector layer with a grid covering a given extent." );
86}
87
88QgsGridAlgorithm *QgsGridAlgorithm::createInstance() const
89{
90 return new QgsGridAlgorithm();
91}
92
93bool QgsGridAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
94{
95 mIdx = parameterAsEnum( parameters, QStringLiteral( "TYPE" ), context );
96 mHSpacing = parameterAsDouble( parameters, QStringLiteral( "HSPACING" ), context );
97 mVSpacing = parameterAsDouble( parameters, QStringLiteral( "VSPACING" ), context );
98 mHOverlay = parameterAsDouble( parameters, QStringLiteral( "HOVERLAY" ), context );
99 mVOverlay = parameterAsDouble( parameters, QStringLiteral( "VOVERLAY" ), context );
100 mCrs = parameterAsCrs( parameters, QStringLiteral( "CRS" ), context );
101 mGridExtent = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, mCrs );
102
103 return true;
104}
105
106QVariantMap QgsGridAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
107{
108 if ( mHSpacing <= 0 || mVSpacing <= 0 )
109 throw QgsProcessingException( QObject::tr( "Invalid grid spacing. horizontal: '%1', vertical: '%2'" ).arg( mHSpacing ).arg( mVSpacing ) );
110
111 if ( mGridExtent.width() < mHSpacing ) //check if grid extent is smaller than horizontal spacing
112 throw QgsProcessingException( QObject::tr( "Horizontal spacing is too large for the covered area." ) );
113
114 if ( mGridExtent.height() < mVSpacing ) //check if grid extent is smaller than vertical spacing
115 throw QgsProcessingException( QObject::tr( "Vertical spacing is too large for the covered area." ) );
116
117 // if ( mHSpacing <= mHOverlay || mVSpacing <= mVOverlay )
118 // throw QgsProcessingException( QObject::tr( "Invalid overlay: horizontal: '%1', vertical: '%2'" ).arg( mHOverlay ).arg( mVOverlay ) );
119
120 QgsFields fields = QgsFields();
121 fields.append( QgsField( QStringLiteral( "id" ), QMetaType::Type::LongLong ) );
122 fields.append( QgsField( QStringLiteral( "left" ), QMetaType::Type::Double ) );
123 fields.append( QgsField( QStringLiteral( "top" ), QMetaType::Type::Double ) );
124 fields.append( QgsField( QStringLiteral( "right" ), QMetaType::Type::Double ) );
125 fields.append( QgsField( QStringLiteral( "bottom" ), QMetaType::Type::Double ) );
126
127 switch ( mIdx )
128 {
129 case 0: //point
130 case 2: //rectangle
131 case 4: //hexagon
132 fields.append( QgsField( QStringLiteral( "row_index" ), QMetaType::Type::LongLong ) );
133 fields.append( QgsField( QStringLiteral( "col_index" ), QMetaType::Type::LongLong ) );
134 break;
135 default:
136 break;
137 }
138
139
141 switch ( mIdx )
142 {
143 case 0:
144 outputWkb = Qgis::WkbType::Point;
145 break;
146 case 1:
147 outputWkb = Qgis::WkbType::LineString;
148 break;
149 }
150
151 QString dest;
152 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, outputWkb, mCrs ) );
153 if ( !sink )
154 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
155
156 feedback->setProgress( 0 );
157
158 switch ( mIdx )
159 {
160 case 0: //point
161 createPointGrid( sink, feedback );
162 break;
163 case 1: //line
164 createLineGrid( sink, feedback );
165 break;
166 case 2: //rectangle
167 createRectangleGrid( sink, feedback );
168 break;
169 case 3: //diamond
170 createDiamondGrid( sink, feedback );
171 break;
172 case 4: //hexagon
173 createHexagonGrid( sink, feedback );
174 break;
175 }
176
177 sink->finalize();
178 QVariantMap outputs;
179 outputs.insert( QStringLiteral( "OUTPUT" ), dest );
180 return outputs;
181}
182
183void QgsGridAlgorithm::createPointGrid( std::unique_ptr<QgsFeatureSink> &sink, QgsProcessingFeedback *feedback )
184{
186
187 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( mHSpacing - mHOverlay ) ) );
188 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - mVOverlay ) ) );
189
190 long long id = 1;
191 long long cnt = 0;
192 const long long cellcnt = rows * cols;
193
194 int thisProgress = 0;
195 int lastProgress = 0;
196
197 for ( long long col = 0; col < cols; col++ )
198 {
199 const double x = mGridExtent.xMinimum() + ( col * mHSpacing - col * mHOverlay );
200
201 for ( long long row = 0; row < rows; row++ )
202 {
203 const double y = mGridExtent.yMaximum() - ( row * mVSpacing - row * mVOverlay );
204
205 f.setGeometry( QgsGeometry( new QgsPoint( x, y ) ) );
206 f.setAttributes( QgsAttributes() << id << x << y << x + mHSpacing << y + mVSpacing << row << col );
207 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
208 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
209
210 id++;
211 cnt++;
212
213 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
214 if ( thisProgress != lastProgress )
215 {
216 lastProgress = thisProgress;
217 feedback->setProgress( lastProgress );
218 }
219
220 if ( feedback && feedback->isCanceled() )
221 break;
222 }
223 if ( feedback && feedback->isCanceled() )
224 break;
225 }
226}
227
228void QgsGridAlgorithm::createLineGrid( std::unique_ptr<QgsFeatureSink> &sink, QgsProcessingFeedback *feedback )
229{
231
232 double hSpace[2];
233 if ( mHOverlay > 0 )
234 {
235 hSpace[0] = mHSpacing - mHOverlay;
236 hSpace[1] = mHOverlay;
237 }
238 else
239 {
240 hSpace[0] = mHSpacing;
241 hSpace[1] = mHSpacing;
242 }
243
244 double vSpace[2];
245 if ( mVOverlay > 0 )
246 {
247 vSpace[0] = mVSpacing - mVOverlay;
248 vSpace[1] = mVOverlay;
249 }
250 else
251 {
252 vSpace[0] = mVSpacing;
253 vSpace[1] = mVSpacing;
254 }
255
256 long long cnt = 0;
257 long long id = 1;
258
259 //latitude lines
260 double cntMax = mGridExtent.height() / mVSpacing;
261
262 int thisProgress = 0;
263 int lastProgress = 0;
264
265 double y = mGridExtent.yMaximum();
266
267 while ( y >= mGridExtent.yMinimum() )
268 {
269 if ( feedback && feedback->isCanceled() )
270 break;
271
272 const QgsPoint pt1 = QgsPoint( mGridExtent.xMinimum(), y );
273 const QgsPoint pt2 = QgsPoint( mGridExtent.xMaximum(), y );
274
275 f.setGeometry( QgsGeometry( new QgsLineString( pt1, pt2 ) ) );
276 f.setAttributes( QgsAttributes() << id << mGridExtent.xMinimum() << y << mGridExtent.xMaximum() << y );
277 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
278 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
279 y = y - vSpace[cnt % 2];
280
281 id++;
282 cnt++;
283
284 //use 50 as count multiplicator because only half of the features are processed at this point
285 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / cntMax ) * 50 );
286 if ( thisProgress != lastProgress )
287 {
288 lastProgress = thisProgress;
289 feedback->setProgress( lastProgress );
290 }
291 }
292 //set progress to 50 manually in case the division doesn't amount to 50.
293 feedback->setProgress( 50 );
294
295 //longitude lines
296 cnt = 0;
297
298 //latitude lines
299 cntMax = mGridExtent.width() / mHSpacing;
300
301 lastProgress = 50;
302
303 double x = mGridExtent.xMinimum();
304
305 while ( x <= mGridExtent.xMaximum() )
306 {
307 if ( feedback->isCanceled() )
308 break;
309
310 const QgsPoint pt1 = QgsPoint( x, mGridExtent.yMaximum() );
311 const QgsPoint pt2 = QgsPoint( x, mGridExtent.yMinimum() );
312 f.setGeometry( QgsGeometry( new QgsLineString( pt1, pt2 ) ) );
313 f.setAttributes( QgsAttributes() << id << x << mGridExtent.yMaximum() << x << mGridExtent.yMinimum() );
314 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
315 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
316 x = x + hSpace[cnt % 2];
317
318 id++;
319 cnt++;
320
321 thisProgress = static_cast<int>( static_cast<double>( 50 ) + ( static_cast<double>( cnt ) / cntMax ) * 100 );
322 if ( thisProgress != lastProgress )
323 {
324 lastProgress = thisProgress;
325 feedback->setProgress( lastProgress );
326 }
327 }
328 feedback->setProgress( 100 );
329}
330
331void QgsGridAlgorithm::createRectangleGrid( std::unique_ptr<QgsFeatureSink> &sink, QgsProcessingFeedback *feedback )
332{
334
335 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( mHSpacing - mHOverlay ) ) );
336 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - mVOverlay ) ) );
337
338 long long id = 1;
339 long long cnt = 0;
340 const long long cellcnt = rows * cols;
341
342 int thisProgress = 0;
343 int lastProgress = 0;
344 QVector<double> ringX( 5 );
345 QVector<double> ringY( 5 );
346
347 for ( long long col = 0; col < cols; col++ )
348 {
349 if ( feedback && feedback->isCanceled() )
350 break;
351
352 const double x1 = mGridExtent.xMinimum() + ( col * mHSpacing - col * mHOverlay );
353 const double x2 = x1 + mHSpacing;
354
355 for ( long long row = 0; row < rows; row++ )
356 {
357 const double y1 = mGridExtent.yMaximum() - ( row * mVSpacing - row * mVOverlay );
358 const double y2 = y1 - mVSpacing;
359
360 ringX = { x1, x2, x2, x1, x1 };
361 ringY = { y1, y1, y2, y2, y1 };
362 auto poly = std::make_unique<QgsPolygon>();
363 poly->setExteriorRing( new QgsLineString( ringX, ringY ) );
364 f.setGeometry( std::move( poly ) );
365 f.setAttributes( QgsAttributes() << id << x1 << y1 << x2 << y2 << row << col );
366 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
367 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
368
369 id++;
370 cnt++;
371
372 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
373 if ( thisProgress != lastProgress )
374 {
375 lastProgress = thisProgress;
376 feedback->setProgress( lastProgress );
377 }
378
379 if ( feedback && feedback->isCanceled() )
380 break;
381 }
382 }
383}
384
385void QgsGridAlgorithm::createDiamondGrid( std::unique_ptr<QgsFeatureSink> &sink, QgsProcessingFeedback *feedback )
386{
388
389 const double halfHSpacing = mHSpacing / 2;
390 const double halfVSpacing = mVSpacing / 2;
391
392 const double halfHOverlay = mHOverlay / 2;
393 const double halfVOverlay = mVOverlay / 2;
394
395 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( halfHSpacing - halfHOverlay ) ) );
396 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - halfVOverlay ) ) );
397
398 long long id = 1;
399 long long cnt = 0;
400 const long long cellcnt = rows * cols;
401
402 int thisProgress = 0;
403 int lastProgress = 0;
404 QVector<double> ringX( 5 );
405 QVector<double> ringY( 5 );
406
407 for ( long long col = 0; col < cols; col++ )
408 {
409 if ( feedback && feedback->isCanceled() )
410 break;
411
412 const double x = mGridExtent.xMinimum() - ( col * halfHOverlay );
413 const double x1 = x + ( ( col + 0 ) * halfHSpacing );
414 const double x2 = x + ( ( col + 1 ) * halfHSpacing );
415 const double x3 = x + ( ( col + 2 ) * halfHSpacing );
416
417 for ( long long row = 0; row < rows; row++ )
418 {
419 const double y = mGridExtent.yMaximum() + ( row * halfVOverlay );
420
421 double y1;
422 double y2;
423 double y3;
424
425 if ( ( col % 2 ) == 0 )
426 {
427 y1 = y - ( ( ( row * 2 ) + 0 ) * halfVSpacing );
428 y2 = y - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
429 y3 = y - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
430 }
431 else
432 {
433 y1 = y - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
434 y2 = y - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
435 y3 = y - ( ( ( row * 2 ) + 3 ) * halfVSpacing );
436 }
437
438 ringX = { x1, x2, x3, x2, x1 };
439 ringY = { y2, y1, y2, y3, y2 };
440 auto poly = std::make_unique<QgsPolygon>();
441 poly->setExteriorRing( new QgsLineString( ringX, ringY ) );
442 f.setGeometry( std::move( poly ) );
443 f.setAttributes( QgsAttributes() << id << x1 << y1 << x3 << y3 );
444 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
445 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
446
447 id++;
448 cnt++;
449
450 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
451 if ( thisProgress != lastProgress )
452 {
453 lastProgress = thisProgress;
454 feedback->setProgress( lastProgress );
455 }
456
457 if ( feedback && feedback->isCanceled() )
458 break;
459 }
460 }
461}
462
463void QgsGridAlgorithm::createHexagonGrid( std::unique_ptr<QgsFeatureSink> &sink, QgsProcessingFeedback *feedback )
464{
466
467 // To preserve symmetry, hspacing is fixed relative to vspacing
468 const double xVertexLo = 0.288675134594813 * mVSpacing;
469 const double xVertexHi = 0.577350269189626 * mVSpacing;
470
471 mHSpacing = xVertexLo + xVertexHi;
472
473 mHOverlay = mHSpacing - mHOverlay;
474
475 if ( mHOverlay < 0 )
476 {
477 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 ) );
478 }
479
480 const double halfVSpacing = mVSpacing / 2;
481
482 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( mHOverlay ) ) );
483 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - mVOverlay ) ) );
484
485 long long id = 1;
486 long long cnt = 0;
487 const long long cellcnt = rows * cols;
488
489 int thisProgress = 0;
490 int lastProgress = 0;
491
492 QVector<double> ringX( 7 );
493 QVector<double> ringY( 7 );
494 for ( long long col = 0; col < cols; col++ )
495 {
496 if ( feedback && feedback->isCanceled() )
497 break;
498
499 // (column + 1) and (row + 1) calculation is used to maintain
500 // topology between adjacent shapes and avoid overlaps/holes
501 // due to rounding errors
502
503 const double x1 = mGridExtent.xMinimum() + ( col * mHOverlay );
504 const double x2 = x1 + ( xVertexHi - xVertexLo );
505 const double x3 = mGridExtent.xMinimum() + ( col * mHOverlay ) + mHSpacing;
506 const double x4 = x3 + ( xVertexHi - xVertexLo );
507
508 for ( long long row = 0; row < rows; row++ )
509 {
510 double y1;
511 double y2;
512 double y3;
513
514 if ( ( col % 2 ) == 0 )
515 {
516 y1 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 0 ) * halfVSpacing );
517 y2 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
518 y3 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
519 }
520 else
521 {
522 y1 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
523 y2 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
524 y3 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 3 ) * halfVSpacing );
525 }
526
527 ringX = { x1, x2, x3, x4, x3, x2, x1 };
528 ringY = { y2, y1, y1, y2, y3, y3, y2 };
529 auto poly = std::make_unique<QgsPolygon>();
530 poly->setExteriorRing( new QgsLineString( ringX, ringY ) );
531 f.setGeometry( std::move( poly ) );
532 f.setAttributes( QgsAttributes() << id << x1 << y1 << x4 << y3 << row << col );
533 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
534 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
535
536 id++;
537 cnt++;
538
539 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
540 if ( thisProgress != lastProgress )
541 {
542 lastProgress = thisProgress;
543 feedback->setProgress( lastProgress );
544 }
545
546 if ( feedback && feedback->isCanceled() )
547 break;
548 }
549 }
550}
551
@ VectorAnyGeometry
Any vector layer with geometry.
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:256
@ LineString
LineString.
@ Polygon
Polygon.
A vector of attributes.
@ 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:58
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:53
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:61
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:53
Container of fields for a vector layer.
Definition qgsfields.h:46
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Definition qgsfields.cpp:70
A geometry is the spatial representation of a feature.
Line string geometry type, with support for z-dimension and m-values.
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.
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.