QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 
18 #include "qgsalgorithmvectorize.h"
19 #include "qgis.h"
20 #include "qgsprocessing.h"
21 
23 
24 QString QgsVectorizeAlgorithmBase::group() const
25 {
26  return QObject::tr( "Vector creation" );
27 }
28 
29 QString QgsVectorizeAlgorithmBase::groupId() const
30 {
31  return QStringLiteral( "vectorcreation" );
32 }
33 
34 void 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 
46 bool 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 
68 QVariantMap 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  int nbBlocksWidth = static_cast< int >( std::ceil( 1.0 * mNbCellsXProvider / maxWidth ) );
87  int nbBlocksHeight = static_cast< int >( std::ceil( 1.0 * mNbCellsYProvider / maxHeight ) );
88  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  QgsGeometry pixelRectGeometry = createGeometryForPixel( currentX, currentY, mRasterUnitsPerPixelX, mRasterUnitsPerPixelY );
119 
120  QgsFeature f;
121  f.setGeometry( pixelRectGeometry );
122  f.setAttributes( QgsAttributes() << value );
123  sink->addFeature( f, QgsFeatureSink::FastInsert );
124  }
125  currentX += mRasterUnitsPerPixelX;
126  }
127  currentY -= mRasterUnitsPerPixelY;
128  }
129  }
130 
131  QVariantMap outputs;
132  outputs.insert( QStringLiteral( "OUTPUT" ), dest );
133  return outputs;
134 }
135 
136 //
137 // QgsRasterPixelsToPolygonsAlgorithm
138 //
139 
140 QString QgsRasterPixelsToPolygonsAlgorithm::name() const
141 {
142  return QStringLiteral( "pixelstopolygons" );
143 }
144 
145 QString QgsRasterPixelsToPolygonsAlgorithm::displayName() const
146 {
147  return QObject::tr( "Raster pixels to polygons" );
148 }
149 
150 QStringList QgsRasterPixelsToPolygonsAlgorithm::tags() const
151 {
152  return QObject::tr( "vectorize,polygonize,raster,convert,pixels" ).split( ',' );
153 }
154 
155 QString QgsRasterPixelsToPolygonsAlgorithm::shortHelpString() const
156 {
157  return QObject::tr( "This algorithm converts a raster layer to a vector layer, by creating polygon features "
158  "for each individual pixel's extent in the raster layer.\n\n"
159  "Any nodata pixels are skipped in the output." );
160 }
161 
162 QString QgsRasterPixelsToPolygonsAlgorithm::shortDescription() const
163 {
164  return QObject::tr( "Creates a vector layer of polygons corresponding to each pixel in a raster layer." );
165 }
166 
167 QgsRasterPixelsToPolygonsAlgorithm *QgsRasterPixelsToPolygonsAlgorithm::createInstance() const
168 {
169  return new QgsRasterPixelsToPolygonsAlgorithm();
170 }
171 
172 QString QgsRasterPixelsToPolygonsAlgorithm::outputName() const
173 {
174  return QObject::tr( "Vector polygons" );
175 }
176 
177 QgsProcessing::SourceType QgsRasterPixelsToPolygonsAlgorithm::outputType() const
178 {
180 }
181 
182 QgsWkbTypes::Type QgsRasterPixelsToPolygonsAlgorithm::sinkType() const
183 {
184  return QgsWkbTypes::Polygon;
185 }
186 
187 QgsGeometry QgsRasterPixelsToPolygonsAlgorithm::createGeometryForPixel( double centerX, double centerY, double pixelWidthX, double pixelWidthY ) const
188 {
189  const double hCellSizeX = pixelWidthX / 2.0;
190  const double hCellSizeY = pixelWidthY / 2.0;
191  return QgsGeometry::fromRect( QgsRectangle( centerX - hCellSizeX, centerY - hCellSizeY, centerX + hCellSizeX, centerY + hCellSizeY ) );
192 }
193 
194 
195 //
196 // QgsRasterPixelsToPointsAlgorithm
197 //
198 
199 QString QgsRasterPixelsToPointsAlgorithm::name() const
200 {
201  return QStringLiteral( "pixelstopoints" );
202 }
203 
204 QString QgsRasterPixelsToPointsAlgorithm::displayName() const
205 {
206  return QObject::tr( "Raster pixels to points" );
207 }
208 
209 QStringList QgsRasterPixelsToPointsAlgorithm::tags() const
210 {
211  return QObject::tr( "vectorize,polygonize,raster,convert,pixels,centers" ).split( ',' );
212 }
213 
214 QString QgsRasterPixelsToPointsAlgorithm::shortHelpString() const
215 {
216  return QObject::tr( "This algorithm converts a raster layer to a vector layer, by creating point features "
217  "for each individual pixel's center in the raster layer.\n\n"
218  "Any nodata pixels are skipped in the output." );
219 }
220 
221 QString QgsRasterPixelsToPointsAlgorithm::shortDescription() const
222 {
223  return QObject::tr( "Creates a vector layer of points corresponding to each pixel in a raster layer." );
224 }
225 
226 QgsRasterPixelsToPointsAlgorithm *QgsRasterPixelsToPointsAlgorithm::createInstance() const
227 {
228  return new QgsRasterPixelsToPointsAlgorithm();
229 }
230 
231 QString QgsRasterPixelsToPointsAlgorithm::outputName() const
232 {
233  return QObject::tr( "Vector points" );
234 }
235 
236 QgsProcessing::SourceType QgsRasterPixelsToPointsAlgorithm::outputType() const
237 {
239 }
240 
241 QgsWkbTypes::Type QgsRasterPixelsToPointsAlgorithm::sinkType() const
242 {
243  return QgsWkbTypes::Point;
244 }
245 
246 QgsGeometry QgsRasterPixelsToPointsAlgorithm::createGeometryForPixel( double centerX, double centerY, double, double ) const
247 {
248  return QgsGeometry( new QgsPoint( centerX, centerY ) );
249 }
250 
252 
253 
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
A rectangle specified with double values.
Definition: qgsrectangle.h:41
Base class for providing feedback from a processing algorithm.
Iterator for sequentially processing raster cells.
int bandCount() const
Returns the number of bands in this layer.
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
double rasterUnitsPerPixelX() const
Returns the number of raster units per each raster pixel in X axis.
QgsRasterInterface * clone() const override=0
Clone itself, create deep copy.
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
double rasterUnitsPerPixelY() const
Returns the number of raster units per each raster pixel in Y axis.
Container of fields for a vector layer.
Definition: qgsfields.h:42
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:111
void setAttributes(const QgsAttributes &attrs)
Sets the feature&#39;s attributes.
Definition: qgsfeature.cpp:127
A raster band parameter for Processing algorithms.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
A feature sink output for processing algorithms.
virtual QgsRectangle extent() const
Returns the extent of the layer.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
QgsRasterDataProvider * dataProvider() override
Returns the layer&#39;s data provider, it may be nullptr.
A raster layer parameter for processing algorithms.
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
static const int DEFAULT_MAXIMUM_TILE_HEIGHT
Default maximum tile height.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:82
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
Vector polygon layers.
Definition: qgsprocessing.h:50
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:48
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
Vector point layers.
Definition: qgsprocessing.h:48
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
SourceType
Data source types enum.
Definition: qgsprocessing.h:44
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
A vector of attributes.
Definition: qgsattributes.h:57
Contains information about the context in which a processing algorithm is executed.
static const int DEFAULT_MAXIMUM_TILE_WIDTH
Default maximum tile width.
A string parameter for processing algorithms.
void startRasterRead(int bandNumber, int nCols, int nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:85