25using namespace Qt::StringLiterals;
29QString QgsRasterCellIndexAlgorithm::name()
const
31 return u
"rastercellindex"_s;
34QString QgsRasterCellIndexAlgorithm::displayName()
const
36 return QObject::tr(
"Raster grid cell index" );
39QStringList QgsRasterCellIndexAlgorithm::tags()
const
41 return QObject::tr(
"grid,cell,index,sort,rank,order,ascending,descending" ).split(
',' );
44QString QgsRasterCellIndexAlgorithm::group()
const
46 return QObject::tr(
"Raster analysis" );
49QString QgsRasterCellIndexAlgorithm::groupId()
const
51 return u
"rasteranalysis"_s;
54QString QgsRasterCellIndexAlgorithm::shortHelpString()
const
57 "This algorithm ranks valid non-NoData raster grid cells according to their value, "
58 "outputting a new grid where each cell contains its 0-based sorted index (rank).\n\n"
59 "NoData cells in the input layer are preserved as NoData in the output layer.\n\n"
60 "This algorithm is a port of the SAGA 'Grid Cell Index' tool."
64QString QgsRasterCellIndexAlgorithm::shortDescription()
const
66 return QObject::tr(
"Creates an index raster according to the cell values in either ascending or descending order." );
69void QgsRasterCellIndexAlgorithm::initAlgorithm(
const QVariantMap & )
75 const QStringList orders = { QObject::tr(
"Ascending" ), QObject::tr(
"Descending" ) };
76 auto orderParam = std::make_unique<QgsProcessingParameterEnum>( u
"ORDER"_s, QObject::tr(
"Sort order" ), orders,
false, 0 );
77 orderParam->setHelp( QObject::tr(
"Sort order: Ascending (assigns 0 to the lowest value) or Descending (assigns 0 to the highest value)." ) );
78 addParameter( orderParam.release() );
81 outputNodataParam->setHelp( QObject::tr(
"The NODATA value to use in the output raster." ) );
83 addParameter( outputNodataParam.release() );
85 auto creationOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATION_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
86 creationOptsParam->setHelp( QObject::tr(
"The raster creation options for the output raster. These options control things like colorimetry, compression, etc." ) );
87 creationOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
89 addParameter( creationOptsParam.release() );
91 auto outputParam = std::make_unique<QgsProcessingParameterRasterDestination>( u
"OUTPUT"_s, QObject::tr(
"Output layer" ) );
92 addParameter( outputParam.release() );
95QgsRasterCellIndexAlgorithm *QgsRasterCellIndexAlgorithm::createInstance()
const
97 return new QgsRasterCellIndexAlgorithm();
102 QgsRasterLayer *layer = parameterAsRasterLayer( parameters, u
"INPUT"_s, context );
106 mBand = parameterAsInt( parameters, u
"BAND"_s, context );
107 if ( mBand < 1 || mBand > layer->
bandCount() )
108 throw QgsProcessingException( QObject::tr(
"Invalid band number for BAND (%1): Valid values for input raster are 1 to %2" ).arg( mBand ).arg( layer->
bandCount() ) );
111 mLayerWidth = layer->
width();
112 mLayerHeight = layer->
height();
113 mExtent = layer->
extent();
121 QGS_MARK_ALGORITHM_SOURCE
123 const Qt::SortOrder sortOrder = ( parameterAsInt( parameters, u
"ORDER"_s, context ) == 0 ) ? Qt::AscendingOrder : Qt::DescendingOrder;
125 const QString creationOptions = parameterAsString( parameters, u
"CREATION_OPTIONS"_s, context ).trimmed();
126 const int outputNodata = parameterAsInt( parameters, u
"NODATA"_s, context );
128 const QString outputFile = parameterAsOutputLayer( parameters, u
"OUTPUT"_s, context );
129 const QString outputFormat = parameterAsOutputRasterFormat( parameters, u
"OUTPUT"_s, context );
131 std::unique_ptr<QgsRasterBlock> inputBlock( mInterface->block( 1, mExtent, mLayerWidth, mLayerHeight ) );
136 const qgssize count = sortedIndex.sortedCount();
138 const qgssize totalCells =
static_cast<qgssize>( mLayerWidth ) * mLayerHeight;
139 auto outputBlock = std::make_unique< QgsRasterBlock >(
Qgis::DataType::Int32, mLayerWidth, mLayerHeight );
140 outputBlock->setNoDataValue( outputNodata );
142 int32_t *outputData =
reinterpret_cast<int32_t *
>( outputBlock->bits() );
143 std::fill_n( outputData, totalCells,
static_cast<int32_t
>( outputNodata ) );
145 for (
qgssize rank = 0; rank < count; ++rank )
150 feedback->
setProgress( 100.0 *
static_cast<double>( rank ) / count );
152 const qgssize outputBlockIndex = sortedIndex.sortedIndex( rank, sortOrder );
153 outputData[outputBlockIndex] =
static_cast<int32_t
>( rank );
156 auto outputWriter = std::make_unique<QgsRasterFileWriter>( outputFile );
157 outputWriter->setOutputProviderKey( u
"gdal"_s );
158 if ( !creationOptions.isEmpty() )
160 outputWriter->setCreationOptions( creationOptions.split(
'|' ) );
162 outputWriter->setOutputFormat( outputFormat );
164 std::unique_ptr<QgsRasterDataProvider> destProvider( outputWriter->createOneBandRaster(
Qgis::DataType::Int32, mLayerWidth, mLayerHeight, mExtent, mCrs ) );
167 if ( !destProvider->isValid() )
170 destProvider->setNoDataValue( 1, outputNodata );
171 destProvider->setEditable(
true );
172 if ( !destProvider->writeBlock( outputBlock.get(), 1 ) )
174 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( destProvider->error().summary() ) );
176 destProvider->setEditable(
false );
179 outputs.insert( u
"OUTPUT"_s, outputFile );
@ Int32
Thirty two bit signed integer (qint32).
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
bool isCanceled() const
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
virtual Q_INVOKABLE QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
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 raster band parameter for Processing algorithms.
A raster layer parameter for processing algorithms.
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
Represents a raster layer.
int height() const
Returns the height of the (unclipped) raster.
int bandCount() const
Returns the number of bands in this layer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
int width() const
Returns the width of the (unclipped) raster.
Creates a flat index over a QgsRasterBlock, sorted by cell values.
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...