QGIS API Documentation 3.41.0-Master (3440c17df1d)
Loading...
Searching...
No Matches
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}
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" ), QMetaType::Type::LongLong ) );
118 fields.append( QgsField( QStringLiteral( "left" ), QMetaType::Type::Double ) );
119 fields.append( QgsField( QStringLiteral( "top" ), QMetaType::Type::Double ) );
120 fields.append( QgsField( QStringLiteral( "right" ), QMetaType::Type::Double ) );
121 fields.append( QgsField( QStringLiteral( "bottom" ), QMetaType::Type::Double ) );
122
123 switch ( mIdx )
124 {
125 case 0: //point
126 case 2: //rectangle
127 case 4: //hexagon
128 fields.append( QgsField( QStringLiteral( "row_index" ), QMetaType::Type::LongLong ) );
129 fields.append( QgsField( QStringLiteral( "col_index" ), QMetaType::Type::LongLong ) );
130 break;
131 default:
132 break;
133 }
134
135
137 switch ( mIdx )
138 {
139 case 0:
140 outputWkb = Qgis::WkbType::Point;
141 break;
142 case 1:
143 outputWkb = Qgis::WkbType::LineString;
144 break;
145 }
146
147 QString dest;
148 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, outputWkb, mCrs ) );
149 if ( !sink )
150 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
151
152 feedback->setProgress( 0 );
153
154 switch ( mIdx )
155 {
156 case 0: //point
157 createPointGrid( sink, feedback );
158 break;
159 case 1: //line
160 createLineGrid( sink, feedback );
161 break;
162 case 2: //rectangle
163 createRectangleGrid( sink, feedback );
164 break;
165 case 3: //diamond
166 createDiamondGrid( sink, feedback );
167 break;
168 case 4: //hexagon
169 createHexagonGrid( sink, feedback );
170 break;
171 }
172
173 sink->finalize();
174 QVariantMap outputs;
175 outputs.insert( QStringLiteral( "OUTPUT" ), dest );
176 return outputs;
177}
178
179void QgsGridAlgorithm::createPointGrid( std::unique_ptr< QgsFeatureSink > &sink, QgsProcessingFeedback *feedback )
180{
182
183 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( mHSpacing - mHOverlay ) ) );
184 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - mVOverlay ) ) );
185
186 long long id = 1;
187 long long cnt = 0;
188 const long long cellcnt = rows * cols;
189
190 int thisProgress = 0;
191 int lastProgress = 0;
192
193 for ( long long col = 0; col < cols; col++ )
194 {
195 const double x = mGridExtent.xMinimum() + ( col * mHSpacing - col * mHOverlay );
196
197 for ( long long row = 0; row < rows; row++ )
198 {
199 const double y = mGridExtent.yMaximum() - ( row * mVSpacing - row * mVOverlay );
200
201 f.setGeometry( QgsGeometry( new QgsPoint( x, y ) ) );
202 f.setAttributes( QgsAttributes() << id << x << y << x + mHSpacing << y + mVSpacing << row << col );
203 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
204 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
205
206 id++;
207 cnt++;
208
209 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
210 if ( thisProgress != lastProgress )
211 {
212 lastProgress = thisProgress;
213 feedback->setProgress( lastProgress );
214 }
215
216 if ( feedback && feedback->isCanceled() )
217 break;
218 }
219 if ( feedback && feedback->isCanceled() )
220 break;
221 }
222}
223
224void QgsGridAlgorithm::createLineGrid( std::unique_ptr< QgsFeatureSink > &sink, QgsProcessingFeedback *feedback )
225{
227
228 double hSpace[2];
229 if ( mHOverlay > 0 )
230 {
231 hSpace[0] = mHSpacing - mHOverlay;
232 hSpace[1] = mHOverlay;
233 }
234 else
235 {
236 hSpace[0] = mHSpacing;
237 hSpace[1] = mHSpacing;
238 }
239
240 double vSpace[2];
241 if ( mVOverlay > 0 )
242 {
243 vSpace[0] = mVSpacing - mVOverlay;
244 vSpace[1] = mVOverlay;
245 }
246 else
247 {
248 vSpace[0] = mVSpacing;
249 vSpace[1] = mVSpacing;
250 }
251
252 long long cnt = 0;
253 long long id = 1;
254
255 //latitude lines
256 double cntMax = mGridExtent.height() / mVSpacing;
257
258 int thisProgress = 0;
259 int lastProgress = 0;
260
261 double y = mGridExtent.yMaximum();
262
263 while ( y >= mGridExtent.yMinimum() )
264 {
265 if ( feedback && feedback->isCanceled() )
266 break;
267
268 const QgsPoint pt1 = QgsPoint( mGridExtent.xMinimum(), y );
269 const QgsPoint pt2 = QgsPoint( mGridExtent.xMaximum(), y );
270
271 f.setGeometry( QgsGeometry( new QgsLineString( pt1, pt2 ) ) );
272 f.setAttributes( QgsAttributes() << id << mGridExtent.xMinimum() << y << mGridExtent.xMaximum() << y );
273 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
274 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
275 y = y - vSpace[cnt % 2];
276
277 id++;
278 cnt++;
279
280 //use 50 as count multiplicator because only half of the features are processed at this point
281 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / cntMax ) * 50 );
282 if ( thisProgress != lastProgress )
283 {
284 lastProgress = thisProgress;
285 feedback->setProgress( lastProgress );
286 }
287
288 }
289 //set progress to 50 manually in case the division doesn't amount to 50.
290 feedback->setProgress( 50 );
291
292 //longitude lines
293 cnt = 0;
294
295 //latitude lines
296 cntMax = mGridExtent.width() / mHSpacing;
297
298 lastProgress = 50;
299
300 double x = mGridExtent.xMinimum();
301
302 while ( x <= mGridExtent.xMaximum() )
303 {
304 if ( feedback->isCanceled() )
305 break;
306
307 const QgsPoint pt1 = QgsPoint( x, mGridExtent.yMaximum() );
308 const QgsPoint pt2 = QgsPoint( x, mGridExtent.yMinimum() );
309 f.setGeometry( QgsGeometry( new QgsLineString( pt1, pt2 ) ) );
310 f.setAttributes( QgsAttributes() << id << x << mGridExtent.yMaximum() << x << mGridExtent.yMinimum() );
311 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
312 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
313 x = x + hSpace[cnt % 2];
314
315 id++;
316 cnt++;
317
318 thisProgress = static_cast<int>( static_cast<double>( 50 ) + ( static_cast<double>( cnt ) / cntMax ) * 100 );
319 if ( thisProgress != lastProgress )
320 {
321 lastProgress = thisProgress;
322 feedback->setProgress( lastProgress );
323 }
324 }
325 feedback->setProgress( 100 );
326}
327
328void QgsGridAlgorithm::createRectangleGrid( std::unique_ptr< QgsFeatureSink > &sink, QgsProcessingFeedback *feedback )
329{
331
332 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( mHSpacing - mHOverlay ) ) );
333 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - mVOverlay ) ) );
334
335 long long id = 1;
336 long long cnt = 0;
337 const long long cellcnt = rows * cols;
338
339 int thisProgress = 0;
340 int lastProgress = 0;
341 QVector< double > ringX( 5 );
342 QVector< double > ringY( 5 );
343
344 for ( long long col = 0; col < cols; col++ )
345 {
346 if ( feedback && feedback->isCanceled() )
347 break;
348
349 const double x1 = mGridExtent.xMinimum() + ( col * mHSpacing - col * mHOverlay );
350 const double x2 = x1 + mHSpacing;
351
352 for ( long long row = 0; row < rows; row++ )
353 {
354 const double y1 = mGridExtent.yMaximum() - ( row * mVSpacing - row * mVOverlay );
355 const double y2 = y1 - mVSpacing;
356
357 ringX = { x1, x2, x2, x1, x1 };
358 ringY = { y1, y1, y2, y2, y1 };
359 std::unique_ptr< QgsPolygon > poly = std::make_unique< QgsPolygon >();
360 poly->setExteriorRing( new QgsLineString( ringX, ringY ) );
361 f.setGeometry( std::move( poly ) );
362 f.setAttributes( QgsAttributes() << id << x1 << y1 << x2 << y2 << row << col );
363 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
364 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
365
366 id++;
367 cnt++;
368
369 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
370 if ( thisProgress != lastProgress )
371 {
372 lastProgress = thisProgress;
373 feedback->setProgress( lastProgress );
374 }
375
376 if ( feedback && feedback->isCanceled() )
377 break;
378 }
379 }
380}
381
382void QgsGridAlgorithm::createDiamondGrid( std::unique_ptr< QgsFeatureSink > &sink, QgsProcessingFeedback *feedback )
383{
385
386 const double halfHSpacing = mHSpacing / 2;
387 const double halfVSpacing = mVSpacing / 2;
388
389 const double halfHOverlay = mHOverlay / 2;
390 const double halfVOverlay = mVOverlay / 2;
391
392 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( halfHSpacing - halfHOverlay ) ) );
393 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - halfVOverlay ) ) );
394
395 long long id = 1;
396 long long cnt = 0;
397 const long long cellcnt = rows * cols;
398
399 int thisProgress = 0;
400 int lastProgress = 0;
401 QVector< double > ringX( 5 );
402 QVector< double > ringY( 5 );
403
404 for ( long long col = 0; col < cols; col++ )
405 {
406 if ( feedback && feedback->isCanceled() )
407 break;
408
409 const double x = mGridExtent.xMinimum() - ( col * halfHOverlay );
410 const double x1 = x + ( ( col + 0 ) * halfHSpacing );
411 const double x2 = x + ( ( col + 1 ) * halfHSpacing );
412 const double x3 = x + ( ( col + 2 ) * halfHSpacing );
413
414 for ( long long row = 0; row < rows; row++ )
415 {
416 const double y = mGridExtent.yMaximum() + ( row * halfVOverlay );
417
418 double y1;
419 double y2;
420 double y3;
421
422 if ( ( col % 2 ) == 0 )
423 {
424 y1 = y - ( ( ( row * 2 ) + 0 ) * halfVSpacing );
425 y2 = y - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
426 y3 = y - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
427 }
428 else
429 {
430 y1 = y - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
431 y2 = y - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
432 y3 = y - ( ( ( row * 2 ) + 3 ) * halfVSpacing );
433 }
434
435 ringX = { x1, x2, x3, x2, x1 };
436 ringY = { y2, y1, y2, y3, y2 };
437 std::unique_ptr< QgsPolygon > poly = std::make_unique< QgsPolygon >();
438 poly->setExteriorRing( new QgsLineString( ringX, ringY ) );
439 f.setGeometry( std::move( poly ) );
440 f.setAttributes( QgsAttributes() << id << x1 << y1 << x3 << y3 );
441 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
442 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
443
444 id++;
445 cnt++;
446
447 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
448 if ( thisProgress != lastProgress )
449 {
450 lastProgress = thisProgress;
451 feedback->setProgress( lastProgress );
452 }
453
454 if ( feedback && feedback->isCanceled() )
455 break;
456 }
457 }
458}
459
460void QgsGridAlgorithm::createHexagonGrid( std::unique_ptr<QgsFeatureSink> &sink, QgsProcessingFeedback *feedback )
461{
463
464 // To preserve symmetry, hspacing is fixed relative to vspacing
465 const double xVertexLo = 0.288675134594813 * mVSpacing;
466 const double xVertexHi = 0.577350269189626 * mVSpacing;
467
468 mHSpacing = xVertexLo + xVertexHi;
469
470 mHOverlay = mHSpacing - mHOverlay;
471
472 if ( mHOverlay < 0 )
473 {
474 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 ) );
475 }
476
477 const double halfVSpacing = mVSpacing / 2;
478
479 const long long cols = static_cast<long long>( std::ceil( mGridExtent.width() / ( mHOverlay ) ) );
480 const long long rows = static_cast<long long>( std::ceil( mGridExtent.height() / ( mVSpacing - mVOverlay ) ) );
481
482 long long id = 1;
483 long long cnt = 0;
484 const long long cellcnt = rows * cols;
485
486 int thisProgress = 0;
487 int lastProgress = 0;
488
489 QVector< double > ringX( 7 );
490 QVector< double > ringY( 7 );
491 for ( long long col = 0; col < cols; col++ )
492 {
493 if ( feedback && feedback->isCanceled() )
494 break;
495
496 // (column + 1) and (row + 1) calculation is used to maintain
497 // topology between adjacent shapes and avoid overlaps/holes
498 // due to rounding errors
499
500 const double x1 = mGridExtent.xMinimum() + ( col * mHOverlay );
501 const double x2 = x1 + ( xVertexHi - xVertexLo );
502 const double x3 = mGridExtent.xMinimum() + ( col * mHOverlay ) + mHSpacing;
503 const double x4 = x3 + ( xVertexHi - xVertexLo );
504
505 for ( long long row = 0; row < rows; row++ )
506 {
507 double y1;
508 double y2;
509 double y3;
510
511 if ( ( col % 2 ) == 0 )
512 {
513 y1 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 0 ) * halfVSpacing );
514 y2 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
515 y3 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
516 }
517 else
518 {
519 y1 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 1 ) * halfVSpacing );
520 y2 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 2 ) * halfVSpacing );
521 y3 = mGridExtent.yMaximum() + ( row * mVOverlay ) - ( ( ( row * 2 ) + 3 ) * halfVSpacing );
522 }
523
524 ringX = { x1, x2, x3, x4, x3, x2, x1 };
525 ringY = { y2, y1, y1, y2, y3, y3, y2 };
526 std::unique_ptr< QgsPolygon > poly = std::make_unique< QgsPolygon >();
527 poly->setExteriorRing( new QgsLineString( ringX, ringY ) );
528 f.setGeometry( std::move( poly ) );
529 f.setAttributes( QgsAttributes() << id << x1 << y1 << x4 << y3 << row << col );
530 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
531 throw QgsProcessingException( writeFeatureError( sink.get(), QVariantMap(), QStringLiteral( "OUTPUT" ) ) );
532
533 id++;
534 cnt++;
535
536 thisProgress = static_cast<int>( ( static_cast<double>( cnt ) / static_cast<double>( cellcnt ) ) * 100 );
537 if ( thisProgress != lastProgress )
538 {
539 lastProgress = thisProgress;
540 feedback->setProgress( lastProgress );
541 }
542
543 if ( feedback && feedback->isCanceled() )
544 break;
545 }
546 }
547}
548
@ 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.