QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsreclassifyutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsreclassifyutils.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 "qgsreclassifyutils.h"
19#include "qgsrasterinterface.h"
20#include "qgsrasteriterator.h"
21#include "qgsrasterblock.h"
24
25#include "qgis.h"
26
28
29void QgsReclassifyUtils::reportClasses( const QVector<QgsReclassifyUtils::RasterClass> &classes, QgsProcessingFeedback *feedback )
30{
31 int i = 1;
32 feedback->pushInfo( QObject::tr( "Using classes:" ) );
33 for ( const RasterClass &c : classes )
34 {
35 feedback->pushInfo( QStringLiteral( " %1) %2 %3 %4" ).arg( i )
36 .arg( c.asText() )
37 .arg( QChar( 0x2192 ) )
38 .arg( c.value ) );
39 i++;
40 }
41}
42
43void QgsReclassifyUtils::checkForOverlaps( const QVector<QgsReclassifyUtils::RasterClass> &classes, QgsProcessingFeedback *feedback )
44{
45 // test each class against each other class
46 for ( int i = 0; i < classes.count() - 1; i++ )
47 {
48 for ( int j = i + 1; j < classes.count(); j++ )
49 {
50 const QgsReclassifyUtils::RasterClass &class1 = classes.at( i );
51 const QgsReclassifyUtils::RasterClass &class2 = classes.at( j );
52 if ( class1.overlaps( class2 ) )
53 {
54 feedback->reportError( QObject::tr( "Warning: Class %1 (%2) overlaps with class %3 (%4)" ).arg( i + 1 )
55 .arg( class1.asText() )
56 .arg( j + 1 )
57 .arg( class2.asText() ) );
58 }
59 }
60 }
61}
62
63void QgsReclassifyUtils::reclassify( const QVector<QgsReclassifyUtils::RasterClass> &classes, QgsRasterInterface *sourceRaster, int band,
64 const QgsRectangle &extent, int sourceWidthPixels, int sourceHeightPixels,
65 QgsRasterDataProvider *destinationRaster, double destNoDataValue, bool useNoDataForMissingValues,
66 QgsProcessingFeedback *feedback )
67{
70
71 QgsRasterIterator iter( sourceRaster );
72 iter.startRasterRead( band, sourceWidthPixels, sourceHeightPixels, extent );
73
74 const int nbBlocksWidth = static_cast< int >( std::ceil( 1.0 * sourceWidthPixels / maxWidth ) );
75 const int nbBlocksHeight = static_cast< int >( std::ceil( 1.0 * sourceHeightPixels / maxHeight ) );
76 const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
77
78 int iterLeft = 0;
79 int iterTop = 0;
80 int iterCols = 0;
81 int iterRows = 0;
82 destinationRaster->setEditable( true );
83 std::unique_ptr< QgsRasterBlock > rasterBlock;
84 bool reclassed = false;
85 bool isNoData = false;
86 while ( iter.readNextRasterPart( band, iterCols, iterRows, rasterBlock, iterLeft, iterTop ) )
87 {
88 if ( feedback )
89 feedback->setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
90 if ( feedback && feedback->isCanceled() )
91 break;
92 std::unique_ptr< QgsRasterBlock > reclassifiedBlock = std::make_unique< QgsRasterBlock >( destinationRaster->dataType( 1 ), iterCols, iterRows );
93
94 for ( int row = 0; row < iterRows; row++ )
95 {
96 if ( feedback && feedback->isCanceled() )
97 break;
98 for ( int column = 0; column < iterCols; column++ )
99 {
100 const double value = rasterBlock->valueAndNoData( row, column, isNoData );
101 if ( isNoData )
102 reclassifiedBlock->setValue( row, column, destNoDataValue );
103 else
104 {
105 const double newValue = reclassifyValue( classes, value, reclassed );
106 if ( reclassed )
107 reclassifiedBlock->setValue( row, column, newValue );
108 else
109 reclassifiedBlock->setValue( row, column, useNoDataForMissingValues ? destNoDataValue : value );
110 }
111 }
112 }
113 destinationRaster->writeBlock( reclassifiedBlock.get(), 1, iterLeft, iterTop );
114 }
115 destinationRaster->setEditable( false );
116}
117
118
119
121
122
123
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
Base class for providing feedback from a processing algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
Base class for raster data providers.
bool writeBlock(QgsRasterBlock *block, int band, int xOffset=0, int yOffset=0)
Writes pixel data from a raster block into the provider data source.
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
virtual bool setEditable(bool enabled)
Turns on/off editing mode of the provider.
Base class for processing filters like renderers, reprojector, resampler etc.
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.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c