QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsalgorithmvectorize.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmvectorize.cpp
3 ---------------------
4 begin : June, 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
19#include "qgis.h"
20#include "qgsprocessing.h"
21
23
24QString QgsVectorizeAlgorithmBase::group() const
25{
26 return QObject::tr( "Vector creation" );
27}
28
29QString QgsVectorizeAlgorithmBase::groupId() const
30{
31 return QStringLiteral( "vectorcreation" );
32}
33
34void QgsVectorizeAlgorithmBase::initAlgorithm( const QVariantMap & )
35{
36 addParameter( new QgsProcessingParameterRasterLayer( QStringLiteral( "INPUT_RASTER" ),
37 QObject::tr( "Raster layer" ) ) );
38 addParameter( new QgsProcessingParameterBand( QStringLiteral( "RASTER_BAND" ),
39 QObject::tr( "Band number" ), 1, QStringLiteral( "INPUT_RASTER" ) ) );
40 addParameter( new QgsProcessingParameterString( QStringLiteral( "FIELD_NAME" ),
41 QObject::tr( "Field name" ), QStringLiteral( "VALUE" ) ) );
42
43 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), outputName(), outputType() ) );
44}
45
46bool QgsVectorizeAlgorithmBase::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
47{
48 QgsRasterLayer *layer = parameterAsRasterLayer( parameters, QStringLiteral( "INPUT_RASTER" ), context );
49
50 if ( !layer )
51 throw QgsProcessingException( invalidRasterError( parameters, QStringLiteral( "INPUT_RASTER" ) ) );
52
53 mBand = parameterAsInt( parameters, QStringLiteral( "RASTER_BAND" ), context );
54 if ( mBand < 1 || mBand > layer->bandCount() )
55 throw QgsProcessingException( QObject::tr( "Invalid band number for RASTER_BAND (%1): Valid values for input raster are 1 to %2" ).arg( mBand )
56 .arg( layer->bandCount() ) );
57
58 mInterface.reset( layer->dataProvider()->clone() );
59 mExtent = layer->extent();
60 mCrs = layer->crs();
61 mRasterUnitsPerPixelX = std::abs( layer->rasterUnitsPerPixelX() );
62 mRasterUnitsPerPixelY = std::abs( layer->rasterUnitsPerPixelY() );
63 mNbCellsXProvider = mInterface->xSize();
64 mNbCellsYProvider = mInterface->ySize();
65 return true;
66}
67
68QVariantMap QgsVectorizeAlgorithmBase::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
69{
70 const QString fieldName = parameterAsString( parameters, QStringLiteral( "FIELD_NAME" ), context );
71 QgsFields fields;
72 fields.append( QgsField( fieldName, QVariant::Double, QString(), 20, 8 ) );
73
74 QString dest;
75 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, sinkType(), mCrs ) );
76 if ( !sink )
77 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
78
79
82
83 QgsRasterIterator iter( mInterface.get() );
84 iter.startRasterRead( mBand, mNbCellsXProvider, mNbCellsYProvider, mExtent );
85
86 const int nbBlocksWidth = static_cast< int >( std::ceil( 1.0 * mNbCellsXProvider / maxWidth ) );
87 const int nbBlocksHeight = static_cast< int >( std::ceil( 1.0 * mNbCellsYProvider / maxHeight ) );
88 const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
89
90 int iterLeft = 0;
91 int iterTop = 0;
92 int iterCols = 0;
93 int iterRows = 0;
94 std::unique_ptr< QgsRasterBlock > rasterBlock;
95 QgsRectangle blockExtent;
96 bool isNoData = false;
97 while ( iter.readNextRasterPart( mBand, iterCols, iterRows, rasterBlock, iterLeft, iterTop, &blockExtent ) )
98 {
99 if ( feedback )
100 feedback->setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
101 if ( feedback && feedback->isCanceled() )
102 break;
103
104 double currentY = blockExtent.yMaximum() - 0.5 * mRasterUnitsPerPixelY;
105
106 for ( int row = 0; row < iterRows; row++ )
107 {
108 if ( feedback && feedback->isCanceled() )
109 break;
110
111 double currentX = blockExtent.xMinimum() + 0.5 * mRasterUnitsPerPixelX;
112
113 for ( int column = 0; column < iterCols; column++ )
114 {
115 const double value = rasterBlock->valueAndNoData( row, column, isNoData );
116 if ( !isNoData )
117 {
118 const QgsGeometry pixelRectGeometry = createGeometryForPixel( currentX, currentY, mRasterUnitsPerPixelX, mRasterUnitsPerPixelY );
119
120 QgsFeature f;
121 f.setGeometry( pixelRectGeometry );
122 f.setAttributes( QgsAttributes() << value );
123 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
124 throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
125 }
126 currentX += mRasterUnitsPerPixelX;
127 }
128 currentY -= mRasterUnitsPerPixelY;
129 }
130 }
131
132 QVariantMap outputs;
133 outputs.insert( QStringLiteral( "OUTPUT" ), dest );
134 return outputs;
135}
136
137//
138// QgsRasterPixelsToPolygonsAlgorithm
139//
140
141QString QgsRasterPixelsToPolygonsAlgorithm::name() const
142{
143 return QStringLiteral( "pixelstopolygons" );
144}
145
146QString QgsRasterPixelsToPolygonsAlgorithm::displayName() const
147{
148 return QObject::tr( "Raster pixels to polygons" );
149}
150
151QStringList QgsRasterPixelsToPolygonsAlgorithm::tags() const
152{
153 return QObject::tr( "vectorize,polygonize,raster,convert,pixels" ).split( ',' );
154}
155
156QString QgsRasterPixelsToPolygonsAlgorithm::shortHelpString() const
157{
158 return QObject::tr( "This algorithm converts a raster layer to a vector layer, by creating polygon features "
159 "for each individual pixel's extent in the raster layer.\n\n"
160 "Any nodata pixels are skipped in the output." );
161}
162
163QString QgsRasterPixelsToPolygonsAlgorithm::shortDescription() const
164{
165 return QObject::tr( "Creates a vector layer of polygons corresponding to each pixel in a raster layer." );
166}
167
168QgsRasterPixelsToPolygonsAlgorithm *QgsRasterPixelsToPolygonsAlgorithm::createInstance() const
169{
170 return new QgsRasterPixelsToPolygonsAlgorithm();
171}
172
173QString QgsRasterPixelsToPolygonsAlgorithm::outputName() const
174{
175 return QObject::tr( "Vector polygons" );
176}
177
178QgsProcessing::SourceType QgsRasterPixelsToPolygonsAlgorithm::outputType() const
179{
181}
182
183QgsWkbTypes::Type QgsRasterPixelsToPolygonsAlgorithm::sinkType() const
184{
186}
187
188QgsGeometry QgsRasterPixelsToPolygonsAlgorithm::createGeometryForPixel( double centerX, double centerY, double pixelWidthX, double pixelWidthY ) const
189{
190 const double hCellSizeX = pixelWidthX / 2.0;
191 const double hCellSizeY = pixelWidthY / 2.0;
192 return QgsGeometry::fromRect( QgsRectangle( centerX - hCellSizeX, centerY - hCellSizeY, centerX + hCellSizeX, centerY + hCellSizeY ) );
193}
194
195
196//
197// QgsRasterPixelsToPointsAlgorithm
198//
199
200QString QgsRasterPixelsToPointsAlgorithm::name() const
201{
202 return QStringLiteral( "pixelstopoints" );
203}
204
205QString QgsRasterPixelsToPointsAlgorithm::displayName() const
206{
207 return QObject::tr( "Raster pixels to points" );
208}
209
210QStringList QgsRasterPixelsToPointsAlgorithm::tags() const
211{
212 return QObject::tr( "vectorize,polygonize,raster,convert,pixels,centers" ).split( ',' );
213}
214
215QString QgsRasterPixelsToPointsAlgorithm::shortHelpString() const
216{
217 return QObject::tr( "This algorithm converts a raster layer to a vector layer, by creating point features "
218 "for each individual pixel's center in the raster layer.\n\n"
219 "Any nodata pixels are skipped in the output." );
220}
221
222QString QgsRasterPixelsToPointsAlgorithm::shortDescription() const
223{
224 return QObject::tr( "Creates a vector layer of points corresponding to each pixel in a raster layer." );
225}
226
227QgsRasterPixelsToPointsAlgorithm *QgsRasterPixelsToPointsAlgorithm::createInstance() const
228{
229 return new QgsRasterPixelsToPointsAlgorithm();
230}
231
232QString QgsRasterPixelsToPointsAlgorithm::outputName() const
233{
234 return QObject::tr( "Vector points" );
235}
236
237QgsProcessing::SourceType QgsRasterPixelsToPointsAlgorithm::outputType() const
238{
240}
241
242QgsWkbTypes::Type QgsRasterPixelsToPointsAlgorithm::sinkType() const
243{
244 return QgsWkbTypes::Point;
245}
246
247QgsGeometry QgsRasterPixelsToPointsAlgorithm::createGeometryForPixel( double centerX, double centerY, double, double ) const
248{
249 return QgsGeometry( new QgsPoint( centerX, centerY ) );
250}
251
253
254
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
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
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 raster band parameter for Processing algorithms.
A feature sink output for processing algorithms.
A raster layer parameter for processing algorithms.
A string parameter for processing algorithms.
SourceType
Data source types enum.
Definition: qgsprocessing.h:46
@ TypeVectorPolygon
Vector polygon layers.
Definition: qgsprocessing.h:51
@ TypeVectorPoint
Vector point layers.
Definition: qgsprocessing.h:49
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
Iterator for sequentially processing raster cells.
static const int DEFAULT_MAXIMUM_TILE_WIDTH
Default maximum tile width.
static const int DEFAULT_MAXIMUM_TILE_HEIGHT
Default maximum tile height.
Represents a raster layer.
int bandCount() const
Returns the number of bands in this layer.
double rasterUnitsPerPixelX() const
Returns the number of raster units per each raster pixel in X axis.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
double rasterUnitsPerPixelY() const
Returns the number of raster units per each raster pixel in Y axis.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70