29 QString QgsRasterFrequencyByComparisonOperatorBase::group()
const
31 return QObject::tr(
"Raster analysis" );
34 QString QgsRasterFrequencyByComparisonOperatorBase::groupId()
const
36 return QStringLiteral(
"rasteranalysis" );
39 void QgsRasterFrequencyByComparisonOperatorBase::initAlgorithm(
const QVariantMap & )
42 addParameter(
new QgsProcessingParameterBand( QStringLiteral(
"INPUT_VALUE_RASTER_BAND" ), QObject::tr(
"Value raster band" ), 1, QStringLiteral(
"INPUT_VALUE_RASTER" ) ) );
50 std::unique_ptr< QgsProcessingParameterNumber > output_nodata_parameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral(
"OUTPUT_NODATA_VALUE" ), QObject::tr(
"Output NoData value" ),
QgsProcessingParameterNumber::Double, -9999,
true );
52 addParameter( output_nodata_parameter.release() );
55 QObject::tr(
"Output layer" ) ) );
56 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"OCCURRENCE_COUNT" ), QObject::tr(
"Count of value occurrences" ) ) );
57 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"FOUND_LOCATIONS_COUNT" ), QObject::tr(
"Count of cells with equal value occurrences" ) ) );
58 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"MEAN_FREQUENCY_PER_LOCATION" ), QObject::tr(
"Mean frequency at valid cell locations" ) ) );
68 QgsRasterLayer *inputValueRaster = parameterAsRasterLayer( parameters, QStringLiteral(
"INPUT_VALUE_RASTER" ), context );
69 if ( !inputValueRaster )
72 mInputValueRasterBand = parameterAsInt( parameters, QStringLiteral(
"INPUT_VALUE_RASTER_BAND" ), context );
73 mIgnoreNoData = parameterAsBool( parameters, QStringLiteral(
"IGNORE_NODATA" ), context );
76 mNoDataValue = parameterAsDouble( parameters, QStringLiteral(
"OUTPUT_NODATA_VALUE" ), context );
77 mCrs = inputValueRaster->
crs();
80 mLayerWidth = inputValueRaster->
width();
81 mLayerHeight = inputValueRaster->
height();
82 mExtent = inputValueRaster->
extent();
84 const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral(
"INPUT_RASTERS" ), context );
85 QList< QgsRasterLayer * > rasterLayers;
86 rasterLayers.reserve( layers.count() );
95 QgsRasterAnalysisUtils::RasterLogicInput input;
99 input.interface = input.sourceDataProvider.get();
101 if ( layer->
crs() != mCrs )
103 input.projector = std::make_unique< QgsRasterProjector >();
104 input.projector->setInput( input.sourceDataProvider.get() );
106 input.interface = input.projector.get();
108 mInputs.emplace_back( std::move( input ) );
117 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral(
"OUTPUT" ), context );
118 QFileInfo fi( outputFile );
121 std::unique_ptr< QgsRasterFileWriter > writer = std::make_unique< QgsRasterFileWriter >( outputFile );
122 writer->setOutputProviderKey( QStringLiteral(
"gdal" ) );
123 writer->setOutputFormat( outputFormat );
124 std::unique_ptr<QgsRasterDataProvider > provider( writer->createOneBandRaster(
Qgis::DataType::Int32, mLayerWidth, mLayerHeight, mExtent, mCrs ) );
127 if ( !provider->isValid() )
130 provider->setNoDataValue( 1, mNoDataValue );
135 int nbBlocksWidth =
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
136 int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
137 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
138 provider->setEditable(
true );
141 iter.startRasterRead( mInputValueRasterBand, mLayerWidth, mLayerHeight, mExtent );
148 unsigned long long occurrenceCount = 0;
149 unsigned long long noDataLocationsCount = 0;
150 std::unique_ptr< QgsRasterBlock > inputBlock;
151 while ( iter.readNextRasterPart( 1, iterCols, iterRows, inputBlock, iterLeft, iterTop, &blockExtent ) )
153 std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
154 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : mInputs )
158 for (
int band : i.bands )
162 std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
163 inputBlocks.emplace_back( std::move( b ) );
167 std::unique_ptr< QgsRasterBlock > outputBlock = std::make_unique<QgsRasterBlock>(
Qgis::DataType::Int32, iterCols, iterRows );
168 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
169 for (
int row = 0; row < iterRows; row++ )
174 for (
int col = 0; col < iterCols; col++ )
176 bool valueRasterCellIsNoData =
false;
177 double value = inputBlock->valueAndNoData( row, col, valueRasterCellIsNoData );
179 if ( valueRasterCellIsNoData && !mIgnoreNoData )
183 outputBlock->setValue( row, col, mNoDataValue );
184 noDataLocationsCount++;
188 bool noDataInStack =
false;
189 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
191 if ( noDataInStack && !mIgnoreNoData )
193 outputBlock->setValue( row, col, mNoDataValue );
194 noDataLocationsCount++;
198 int frequency = applyComparisonOperator( value, cellValues );
199 outputBlock->setValue( row, col, frequency );
200 occurrenceCount += frequency;
205 provider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
207 provider->setEditable(
false );
209 unsigned long long foundLocationsCount = layerSize - noDataLocationsCount;
210 double meanEqualCountPerValidLocation =
static_cast<double>( occurrenceCount ) /
static_cast<double>( foundLocationsCount * mInputs.size() );
213 outputs.insert( QStringLiteral(
"OCCURRENCE_COUNT" ), occurrenceCount );
214 outputs.insert( QStringLiteral(
"FOUND_LOCATIONS_COUNT" ), foundLocationsCount );
215 outputs.insert( QStringLiteral(
"MEAN_FREQUENCY_PER_LOCATION" ), meanEqualCountPerValidLocation );
216 outputs.insert( QStringLiteral(
"EXTENT" ), mExtent.toString() );
217 outputs.insert( QStringLiteral(
"CRS_AUTHID" ), mCrs.authid() );
218 outputs.insert( QStringLiteral(
"WIDTH_IN_PIXELS" ), mLayerWidth );
219 outputs.insert( QStringLiteral(
"HEIGHT_IN_PIXELS" ), mLayerHeight );
220 outputs.insert( QStringLiteral(
"TOTAL_PIXEL_COUNT" ), layerSize );
221 outputs.insert( QStringLiteral(
"OUTPUT" ), outputFile );
230 QString QgsRasterFrequencyByEqualOperatorAlgorithm::displayName()
const
232 return QObject::tr(
"Equal to frequency" );
235 QString QgsRasterFrequencyByEqualOperatorAlgorithm::name()
const
237 return QStringLiteral(
"equaltofrequency" );
240 QStringList QgsRasterFrequencyByEqualOperatorAlgorithm::tags()
const
242 return QObject::tr(
"cell,equal,frequency,pixel,stack" ).split(
',' );
245 QString QgsRasterFrequencyByEqualOperatorAlgorithm::shortHelpString()
const
247 return QObject::tr(
"The Equal to frequency algorithm evaluates on a cell-by-cell basis the frequency "
248 "(number of times) the values of an input stack of rasters are equal "
249 "to the value of a value raster. \n "
250 "If multiband rasters are used in the data raster stack, the algorithm will always "
251 "perform the analysis on the first band of the rasters - use GDAL to use other bands in the analysis. "
252 "The input value layer serves as reference layer for the sample layers. "
253 "Any NoData cells in the value raster or the data layer stack will result in a NoData cell "
254 "in the output raster if the ignore NoData parameter is not checked. "
255 "The output NoData value can be set manually. The output rasters extent and resolution "
256 "is defined by the input raster layer and is always of int32 type." );
259 QgsRasterFrequencyByEqualOperatorAlgorithm *QgsRasterFrequencyByEqualOperatorAlgorithm::createInstance()
const
261 return new QgsRasterFrequencyByEqualOperatorAlgorithm();
264 int QgsRasterFrequencyByEqualOperatorAlgorithm::applyComparisonOperator(
double searchValue, std::vector<double> cellValueStack )
266 return static_cast<int>( std::count( cellValueStack.begin(), cellValueStack.end(), searchValue ) );
273 QString QgsRasterFrequencyByGreaterThanOperatorAlgorithm::displayName()
const
275 return QObject::tr(
"Greater than frequency" );
278 QString QgsRasterFrequencyByGreaterThanOperatorAlgorithm::name()
const
280 return QStringLiteral(
"greaterthanfrequency" );
283 QStringList QgsRasterFrequencyByGreaterThanOperatorAlgorithm::tags()
const
285 return QObject::tr(
"cell,greater,frequency,pixel,stack" ).split(
',' );
288 QString QgsRasterFrequencyByGreaterThanOperatorAlgorithm::shortHelpString()
const
290 return QObject::tr(
"The Greater than frequency algorithm evaluates on a cell-by-cell basis the frequency "
291 "(number of times) the values of an input stack of rasters are greater than "
292 "the value of a value raster. \n "
293 "If multiband rasters are used in the data raster stack, the algorithm will always "
294 "perform the analysis on the first band of the rasters - use GDAL to use other bands in the analysis. "
295 "The input value layer serves as reference layer for the sample layers. "
296 "Any NoData cells in the value raster or the data layer stack will result in a NoData cell "
297 "in the output raster if the ignore NoData parameter is not checked. "
298 "The output NoData value can be set manually. The output rasters extent and resolution "
299 "is defined by the input raster layer and is always of int32 type." );
302 QgsRasterFrequencyByGreaterThanOperatorAlgorithm *QgsRasterFrequencyByGreaterThanOperatorAlgorithm::createInstance()
const
304 return new QgsRasterFrequencyByGreaterThanOperatorAlgorithm();
307 int QgsRasterFrequencyByGreaterThanOperatorAlgorithm::applyComparisonOperator(
double searchValue, std::vector<double> cellValueStack )
309 return static_cast<int>( std::count_if( cellValueStack.begin(), cellValueStack.end(), [&](
double const & stackValue ) { return stackValue > searchValue; } ) );
316 QString QgsRasterFrequencyByLessThanOperatorAlgorithm::displayName()
const
318 return QObject::tr(
"Less than frequency" );
321 QString QgsRasterFrequencyByLessThanOperatorAlgorithm::name()
const
323 return QStringLiteral(
"lessthanfrequency" );
326 QStringList QgsRasterFrequencyByLessThanOperatorAlgorithm::tags()
const
328 return QObject::tr(
"cell,less,lower,frequency,pixel,stack" ).split(
',' );
331 QString QgsRasterFrequencyByLessThanOperatorAlgorithm::shortHelpString()
const
333 return QObject::tr(
"The Less than frequency algorithm evaluates on a cell-by-cell basis the frequency "
334 "(number of times) the values of an input stack of rasters are less than "
335 "the value of a value raster. \n "
336 "If multiband rasters are used in the data raster stack, the algorithm will always "
337 "perform the analysis on the first band of the rasters - use GDAL to use other bands in the analysis. "
338 "The input value layer serves as reference layer for the sample layers. "
339 "Any NoData cells in the value raster or the data layer stack will result in a NoData cell "
340 "in the output raster if the ignore NoData parameter is not checked. "
341 "The output NoData value can be set manually. The output rasters extent and resolution "
342 "is defined by the input raster layer and is always of int32 type." );
345 QgsRasterFrequencyByLessThanOperatorAlgorithm *QgsRasterFrequencyByLessThanOperatorAlgorithm::createInstance()
const
347 return new QgsRasterFrequencyByLessThanOperatorAlgorithm();
350 int QgsRasterFrequencyByLessThanOperatorAlgorithm::applyComparisonOperator(
double searchValue, std::vector<double> cellValueStack )
352 return static_cast<int>( std::count_if( cellValueStack.begin(), cellValueStack.end(), [&](
double const & stackValue ) { return stackValue < searchValue; } ) );
@ Int32
Thirty two bit signed integer (qint32)
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Base class for all map layer types.
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
A numeric output for processing algorithms.
A string output for processing algorithms.
A raster band parameter for Processing algorithms.
A boolean parameter for processing algorithms.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
A parameter for processing algorithms which accepts multiple map layers.
@ Double
Double/float values.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
A raster layer parameter for processing algorithms.
@ TypeRaster
Raster layers.
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value.
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
static QString driverForExtension(const QString &extension)
Returns the GDAL driver name for a specified file extension.
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 height() const
Returns the height of the (unclipped) raster.
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.
int width() const
Returns the width of the (unclipped) raster.
A rectangle specified with double 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...