23 QString QgsRasterLayerUniqueValuesReportAlgorithm::name()
 const    25   return QStringLiteral( 
"rasterlayeruniquevaluesreport" );
    28 QString QgsRasterLayerUniqueValuesReportAlgorithm::displayName()
 const    30   return QObject::tr( 
"Raster layer unique values report" );
    33 QStringList QgsRasterLayerUniqueValuesReportAlgorithm::tags()
 const    35   return QObject::tr( 
"count,area,statistics" ).split( 
',' );
    38 QString QgsRasterLayerUniqueValuesReportAlgorithm::group()
 const    40   return QObject::tr( 
"Raster analysis" );
    43 QString QgsRasterLayerUniqueValuesReportAlgorithm::groupId()
 const    45   return QStringLiteral( 
"rasteranalysis" );
    48 void QgsRasterLayerUniqueValuesReportAlgorithm::initAlgorithm( 
const QVariantMap & )
    51                 QObject::tr( 
"Input layer" ) ) );
    53                 QObject::tr( 
"Band number" ), 1, QStringLiteral( 
"INPUT" ) ) );
    55                 QObject::tr( 
"Unique values report" ), QObject::tr( 
"HTML files (*.html)" ), QVariant(), 
true ) );
    64   addOutput( 
new QgsProcessingOutputNumber( QStringLiteral( 
"NODATA_PIXEL_COUNT" ), QObject::tr( 
"NODATA pixel count" ) ) );
    67 QString QgsRasterLayerUniqueValuesReportAlgorithm::shortHelpString()
 const    69   return QObject::tr( 
"This algorithm returns the count and area of each unique value in a given raster layer." );
    72 QgsRasterLayerUniqueValuesReportAlgorithm *QgsRasterLayerUniqueValuesReportAlgorithm::createInstance()
 const    74   return new QgsRasterLayerUniqueValuesReportAlgorithm();
    79   QgsRasterLayer *layer = parameterAsRasterLayer( parameters, QStringLiteral( 
"INPUT" ), context );
    80   int band = parameterAsInt( parameters, QStringLiteral( 
"BAND" ), context );
    85   mBand = parameterAsInt( parameters, QStringLiteral( 
"BAND" ), context );
    86   if ( mBand < 1 || mBand > layer->
bandCount() )
    87     throw QgsProcessingException( QObject::tr( 
"Invalid band number for BAND (%1): Valid values for input raster are 1 to %2" ).arg( mBand )
    92   mLayerWidth = layer->
width();
    93   mLayerHeight = layer->
height();
   105   QString outputFile = parameterAsFileOutput( parameters, QStringLiteral( 
"OUTPUT_HTML_FILE" ), context );
   110   std::unique_ptr< QgsFeatureSink > sink;
   111   if ( parameters.contains( QStringLiteral( 
"OUTPUT_TABLE" ) ) && parameters.value( QStringLiteral( 
"OUTPUT_TABLE" ) ).isValid() )
   114     outFields.
append( 
QgsField( QStringLiteral( 
"value" ), QVariant::Double, QString(), 20, 8 ) );
   115     outFields.
append( 
QgsField( QStringLiteral( 
"count" ), QVariant::Int, QString(), 20 ) );
   116     outFields.
append( 
QgsField( areaUnit.replace( QStringLiteral( 
"²" ), QStringLiteral( 
"2" ) ), QVariant::Double, QString(), 20, 8 ) );
   122   QHash< double, qgssize > uniqueValues;
   125   qgssize layerSize = 
static_cast< qgssize >( mLayerWidth ) * static_cast< qgssize >( mLayerHeight );
   128   int nbBlocksWidth = std::ceil( 1.0 * mLayerWidth / maxWidth );
   129   int nbBlocksHeight = std::ceil( 1.0 * mLayerHeight / maxHeight );
   130   int nbBlocks = nbBlocksWidth * nbBlocksHeight;
   139   std::unique_ptr< QgsRasterBlock > rasterBlock;
   140   while ( iter.readNextRasterPart( mBand, iterCols, iterRows, rasterBlock, iterLeft, iterTop ) )
   142     feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
   143     for ( 
int row = 0; row < iterRows; row++ )
   147       for ( 
int column = 0; column < iterCols; column++ )
   149         if ( mHasNoDataValue && rasterBlock->isNoData( row, column ) )
   155           double value = rasterBlock->value( row, column );
   156           uniqueValues[ value ]++;
   162   QMap< double, qgssize > sortedUniqueValues;
   163   for ( 
auto it = uniqueValues.constBegin(); it != uniqueValues.constEnd(); ++it )
   165     sortedUniqueValues.insert( it.key(), it.value() );
   169   outputs.insert( QStringLiteral( 
"EXTENT" ), mExtent.toString() );
   170   outputs.insert( QStringLiteral( 
"CRS_AUTHID" ), mCrs.authid() );
   171   outputs.insert( QStringLiteral( 
"WIDTH_IN_PIXELS" ), mLayerWidth );
   172   outputs.insert( QStringLiteral( 
"HEIGHT_IN_PIXELS" ), mLayerHeight );
   173   outputs.insert( QStringLiteral( 
"TOTAL_PIXEL_COUNT" ), layerSize );
   174   outputs.insert( QStringLiteral( 
"NODATA_PIXEL_COUNT" ), noDataCount );
   176   double pixelArea = mRasterUnitsPerPixelX * mRasterUnitsPerPixelY;
   178   if ( !outputFile.isEmpty() )
   180     QFile file( outputFile );
   181     if ( file.open( QIODevice::WriteOnly | QIODevice::Text ) )
   185       QTextStream out( &file );
   186       out << QStringLiteral( 
"<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/></head><body>\n" );
   187       out << QStringLiteral( 
"<p>%1: %2 (%3 %4)</p>\n" ).arg( QObject::tr( 
"Analyzed file" ), mSource, QObject::tr( 
"band" ) ).arg( mBand );
   188       out << QObject::tr( 
"<p>%1: %2</p>\n" ).arg( QObject::tr( 
"Extent" ), mExtent.toString() );
   189       out << QObject::tr( 
"<p>%1: %2 (%3)</p>\n" ).arg( QObject::tr( 
"Projection" ), mCrs.description(), mCrs.authid() );
   190       out << QObject::tr( 
"<p>%1: %2 (%3 %4)</p>\n" ).arg( QObject::tr( 
"Width in pixels" ) ).arg( mLayerWidth ).arg( QObject::tr( 
"units per pixel" ) ).arg( mRasterUnitsPerPixelX );
   191       out << QObject::tr( 
"<p>%1: %2 (%3 %4)</p>\n" ).arg( QObject::tr( 
"Height in pixels" ) ).arg( mLayerHeight ).arg( QObject::tr( 
"units per pixel" ) ).arg( mRasterUnitsPerPixelY );
   192       out << QObject::tr( 
"<p>%1: %2</p>\n" ).arg( QObject::tr( 
"Total pixel count" ) ).arg( layerSize );
   193       if ( mHasNoDataValue )
   194         out << QObject::tr( 
"<p>%1: %2</p>\n" ).arg( QObject::tr( 
"NODATA pixel count" ) ).arg( noDataCount );
   195       out << QStringLiteral( 
"<table><tr><td>%1</td><td>%2</td><td>%3 (%4)</td></tr>\n" ).arg( QObject::tr( 
"Value" ), QObject::tr( 
"Pixel count" ), QObject::tr( 
"Area" ), encodedAreaUnit );
   197       for ( 
auto it = sortedUniqueValues.constBegin(); it != sortedUniqueValues.constEnd(); ++it )
   199         double area = it.value() * pixelArea;
   200         out << QStringLiteral( 
"<tr><td>%1</td><td>%2</td><td>%3</td></tr>\n" ).arg( it.key() ).arg( it.value() ).arg( QString::number( area, 
'g', 16 ) );
   202       out << QStringLiteral( 
"</table>\n</body></html>" );
   203       outputs.insert( QStringLiteral( 
"OUTPUT_HTML_FILE" ), outputFile );
   209     for ( 
auto it = sortedUniqueValues.constBegin(); it != sortedUniqueValues.constEnd(); ++it )
   212       double area = it.value() * pixelArea;
   216     outputs.insert( QStringLiteral( 
"OUTPUT_TABLE" ), tableDest );
 int width() const
Returns the width of the (unclipped) raster. 
 
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
 
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. 
 
double rasterUnitsPerPixelY() const
Returns the number of raster units per each raster pixel in Y axis. 
 
Container of fields for a vector layer. 
 
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes. 
 
A numeric output for processing algorithms. 
 
A raster band parameter for Processing algorithms. 
 
int height() const
Returns the height of the (unclipped) raster. 
 
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
 
A feature sink output for processing algorithms. 
 
virtual QgsRectangle extent() const
Returns the extent of the layer. 
 
A string output for processing algorithms. 
 
QgsRasterDataProvider * dataProvider() override
Returns the layer's data provider. 
 
A raster layer parameter for processing algorithms. 
 
static Q_INVOKABLE QString toAbbreviatedString(QgsUnitTypes::DistanceUnit unit)
Returns a translated abbreviation representing a distance unit. 
 
static const int DEFAULT_MAXIMUM_TILE_HEIGHT
Default maximum tile height. 
 
Custom exception class for processing related exceptions. 
 
QgsCoordinateReferenceSystem crs() const
Returns the layer's spatial reference system. 
 
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Append a field. The field must have unique name, otherwise it is rejected (returns false) ...
 
Encapsulate a field in an attribute table or data source. 
 
A generic file based destination parameter, for specifying the destination path for a file (non-map l...
 
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value. 
 
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
 
static QString ampersandEncode(const QString &string)
Makes a raw string safe for inclusion as a HTML/XML string literal. 
 
bool isCanceled() const
Tells whether the operation has been canceled already. 
 
QString source() const
Returns the source for the layer. 
 
This class represents a coordinate reference system (CRS). 
 
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
 
Contains information about the context in which a processing algorithm is executed. 
 
static const int DEFAULT_MAXIMUM_TILE_WIDTH
Default maximum tile width. 
 
static Q_INVOKABLE QgsUnitTypes::AreaUnit distanceToAreaUnit(QgsUnitTypes::DistanceUnit distanceUnit)
Converts a distance unit to its corresponding area unit, e.g., meters to square meters. 
 
void startRasterRead(int bandNumber, int nCols, int nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.