29QString QgsRasterFrequencyByComparisonOperatorBase::group()
const
31 return QObject::tr(
"Raster analysis" );
34QString QgsRasterFrequencyByComparisonOperatorBase::groupId()
const
36 return QStringLiteral(
"rasteranalysis" );
39void QgsRasterFrequencyByComparisonOperatorBase::initAlgorithm(
const QVariantMap & )
42 addParameter(
new QgsProcessingParameterBand( QStringLiteral(
"INPUT_VALUE_RASTER_BAND" ), QObject::tr(
"Value raster band" ), 1, QStringLiteral(
"INPUT_VALUE_RASTER" ) ) );
46 auto output_nodata_parameter = std::make_unique<QgsProcessingParameterNumber>( QStringLiteral(
"OUTPUT_NODATA_VALUE" ), QObject::tr(
"Output NoData value" ),
Qgis::ProcessingNumberParameterType::Double, -9999,
true );
48 addParameter( output_nodata_parameter.release() );
52 auto createOptsParam = std::make_unique<QgsProcessingParameterString>( QStringLiteral(
"CREATE_OPTIONS" ), QObject::tr(
"Creation options" ), QVariant(),
false,
true );
53 createOptsParam->setMetadata( QVariantMap( { { QStringLiteral(
"widget_wrapper" ), QVariantMap( { { QStringLiteral(
"widget_type" ), QStringLiteral(
"rasteroptions" ) } } ) } } ) );
55 addParameter( createOptsParam.release() );
57 auto creationOptsParam = std::make_unique<QgsProcessingParameterString>( QStringLiteral(
"CREATION_OPTIONS" ), QObject::tr(
"Creation options" ), QVariant(),
false,
true );
58 creationOptsParam->setMetadata( QVariantMap( { { QStringLiteral(
"widget_wrapper" ), QVariantMap( { { QStringLiteral(
"widget_type" ), QStringLiteral(
"rasteroptions" ) } } ) } } ) );
60 addParameter( creationOptsParam.release() );
63 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"OCCURRENCE_COUNT" ), QObject::tr(
"Count of value occurrences" ) ) );
64 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"FOUND_LOCATIONS_COUNT" ), QObject::tr(
"Count of cells with equal value occurrences" ) ) );
65 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"MEAN_FREQUENCY_PER_LOCATION" ), QObject::tr(
"Mean frequency at valid cell locations" ) ) );
75 QgsRasterLayer *inputValueRaster = parameterAsRasterLayer( parameters, QStringLiteral(
"INPUT_VALUE_RASTER" ), context );
76 if ( !inputValueRaster )
79 mInputValueRasterBand = parameterAsInt( parameters, QStringLiteral(
"INPUT_VALUE_RASTER_BAND" ), context );
80 mIgnoreNoData = parameterAsBool( parameters, QStringLiteral(
"IGNORE_NODATA" ), context );
83 mNoDataValue = parameterAsDouble( parameters, QStringLiteral(
"OUTPUT_NODATA_VALUE" ), context );
84 mCrs = inputValueRaster->
crs();
87 mLayerWidth = inputValueRaster->
width();
88 mLayerHeight = inputValueRaster->
height();
89 mExtent = inputValueRaster->
extent();
91 const QList<QgsMapLayer *> layers = parameterAsLayerList( parameters, QStringLiteral(
"INPUT_RASTERS" ), context );
92 QList<QgsRasterLayer *> rasterLayers;
93 rasterLayers.reserve( layers.count() );
102 QgsRasterAnalysisUtils::RasterLogicInput input;
106 input.interface = input.sourceDataProvider.get();
108 if ( layer->
crs() != mCrs )
110 input.projector = std::make_unique<QgsRasterProjector>();
111 input.projector->setInput( input.sourceDataProvider.get() );
113 input.interface = input.projector.get();
115 mInputs.emplace_back( std::move( input ) );
124 QString creationOptions = parameterAsString( parameters, QStringLiteral(
"CREATION_OPTIONS" ), context ).trimmed();
126 const QString optionsString = parameterAsString( parameters, QStringLiteral(
"CREATE_OPTIONS" ), context );
127 if ( !optionsString.isEmpty() )
128 creationOptions = optionsString;
130 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral(
"OUTPUT" ), context );
131 const QFileInfo fi( outputFile );
134 auto writer = std::make_unique<QgsRasterFileWriter>( outputFile );
135 writer->setOutputProviderKey( QStringLiteral(
"gdal" ) );
136 if ( !creationOptions.isEmpty() )
138 writer->setCreationOptions( creationOptions.split(
'|' ) );
140 writer->setOutputFormat( outputFormat );
141 std::unique_ptr<QgsRasterDataProvider> provider( writer->createOneBandRaster(
Qgis::DataType::Int32, mLayerWidth, mLayerHeight, mExtent, mCrs ) );
144 if ( !provider->isValid() )
147 provider->setNoDataValue( 1, mNoDataValue );
148 const qgssize layerSize =
static_cast<qgssize>( mLayerWidth ) *
static_cast<qgssize>( mLayerHeight );
152 const int nbBlocksWidth =
static_cast<int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
153 const int nbBlocksHeight =
static_cast<int>( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
154 const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
155 provider->setEditable(
true );
158 iter.startRasterRead( mInputValueRasterBand, mLayerWidth, mLayerHeight, mExtent );
165 unsigned long long occurrenceCount = 0;
166 unsigned long long noDataLocationsCount = 0;
167 std::unique_ptr<QgsRasterBlock> inputBlock;
168 while ( iter.readNextRasterPart( 1, iterCols, iterRows, inputBlock, iterLeft, iterTop, &blockExtent ) )
170 std::vector<std::unique_ptr<QgsRasterBlock>> inputBlocks;
171 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : mInputs )
175 for (
const int band : i.bands )
179 std::unique_ptr<QgsRasterBlock> b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
180 inputBlocks.emplace_back( std::move( b ) );
185 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
186 for (
int row = 0; row < iterRows; row++ )
191 for (
int col = 0; col < iterCols; col++ )
193 bool valueRasterCellIsNoData =
false;
194 const double value = inputBlock->valueAndNoData( row, col, valueRasterCellIsNoData );
196 if ( valueRasterCellIsNoData && !mIgnoreNoData )
200 outputBlock->setValue( row, col, mNoDataValue );
201 noDataLocationsCount++;
205 bool noDataInStack =
false;
206 const std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
208 if ( noDataInStack && !mIgnoreNoData )
210 outputBlock->setValue( row, col, mNoDataValue );
211 noDataLocationsCount++;
215 const int frequency = applyComparisonOperator( value, cellValues );
216 outputBlock->setValue( row, col, frequency );
217 occurrenceCount += frequency;
222 if ( !provider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop ) )
224 throw QgsProcessingException( QObject::tr(
"Could not write raster block: %1" ).arg( provider->error().summary() ) );
227 provider->setEditable(
false );
229 const unsigned long long foundLocationsCount = layerSize - noDataLocationsCount;
230 const double meanEqualCountPerValidLocation =
static_cast<double>( occurrenceCount ) /
static_cast<double>( foundLocationsCount * mInputs.size() );
233 outputs.insert( QStringLiteral(
"OCCURRENCE_COUNT" ), occurrenceCount );
234 outputs.insert( QStringLiteral(
"FOUND_LOCATIONS_COUNT" ), foundLocationsCount );
235 outputs.insert( QStringLiteral(
"MEAN_FREQUENCY_PER_LOCATION" ), meanEqualCountPerValidLocation );
236 outputs.insert( QStringLiteral(
"EXTENT" ), mExtent.toString() );
237 outputs.insert( QStringLiteral(
"CRS_AUTHID" ), mCrs.authid() );
238 outputs.insert( QStringLiteral(
"WIDTH_IN_PIXELS" ), mLayerWidth );
239 outputs.insert( QStringLiteral(
"HEIGHT_IN_PIXELS" ), mLayerHeight );
240 outputs.insert( QStringLiteral(
"TOTAL_PIXEL_COUNT" ), layerSize );
241 outputs.insert( QStringLiteral(
"OUTPUT" ), outputFile );
250QString QgsRasterFrequencyByEqualOperatorAlgorithm::displayName()
const
252 return QObject::tr(
"Equal to frequency" );
255QString QgsRasterFrequencyByEqualOperatorAlgorithm::name()
const
257 return QStringLiteral(
"equaltofrequency" );
260QStringList QgsRasterFrequencyByEqualOperatorAlgorithm::tags()
const
262 return QObject::tr(
"cell,equal,frequency,pixel,stack" ).split(
',' );
265QString QgsRasterFrequencyByEqualOperatorAlgorithm::shortHelpString()
const
267 return QObject::tr(
"The Equal to frequency algorithm evaluates on a cell-by-cell basis the frequency "
268 "(number of times) the values of an input stack of rasters are equal "
269 "to the value of a value raster. \n "
270 "If multiband rasters are used in the data raster stack, the algorithm will always "
271 "perform the analysis on the first band of the rasters - use GDAL to use other bands in the analysis. "
272 "The input value layer serves as reference layer for the sample layers. "
273 "Any NoData cells in the value raster or the data layer stack will result in a NoData cell "
274 "in the output raster if the ignore NoData parameter is not checked. "
275 "The output NoData value can be set manually. The output rasters extent and resolution "
276 "is defined by the input raster layer and is always of int32 type." );
279QgsRasterFrequencyByEqualOperatorAlgorithm *QgsRasterFrequencyByEqualOperatorAlgorithm::createInstance()
const
281 return new QgsRasterFrequencyByEqualOperatorAlgorithm();
284int QgsRasterFrequencyByEqualOperatorAlgorithm::applyComparisonOperator(
double searchValue, std::vector<double> cellValueStack )
286 return static_cast<int>( std::count( cellValueStack.begin(), cellValueStack.end(), searchValue ) );
293QString QgsRasterFrequencyByGreaterThanOperatorAlgorithm::displayName()
const
295 return QObject::tr(
"Greater than frequency" );
298QString QgsRasterFrequencyByGreaterThanOperatorAlgorithm::name()
const
300 return QStringLiteral(
"greaterthanfrequency" );
303QStringList QgsRasterFrequencyByGreaterThanOperatorAlgorithm::tags()
const
305 return QObject::tr(
"cell,greater,frequency,pixel,stack" ).split(
',' );
308QString QgsRasterFrequencyByGreaterThanOperatorAlgorithm::shortHelpString()
const
310 return QObject::tr(
"The Greater than frequency algorithm evaluates on a cell-by-cell basis the frequency "
311 "(number of times) the values of an input stack of rasters are greater than "
312 "the value of a value raster. \n "
313 "If multiband rasters are used in the data raster stack, the algorithm will always "
314 "perform the analysis on the first band of the rasters - use GDAL to use other bands in the analysis. "
315 "The input value layer serves as reference layer for the sample layers. "
316 "Any NoData cells in the value raster or the data layer stack will result in a NoData cell "
317 "in the output raster if the ignore NoData parameter is not checked. "
318 "The output NoData value can be set manually. The output rasters extent and resolution "
319 "is defined by the input raster layer and is always of int32 type." );
322QgsRasterFrequencyByGreaterThanOperatorAlgorithm *QgsRasterFrequencyByGreaterThanOperatorAlgorithm::createInstance()
const
324 return new QgsRasterFrequencyByGreaterThanOperatorAlgorithm();
327int QgsRasterFrequencyByGreaterThanOperatorAlgorithm::applyComparisonOperator(
double searchValue, std::vector<double> cellValueStack )
329 return static_cast<int>( std::count_if( cellValueStack.begin(), cellValueStack.end(), [&](
double const &stackValue ) { return stackValue > searchValue; } ) );
336QString QgsRasterFrequencyByLessThanOperatorAlgorithm::displayName()
const
338 return QObject::tr(
"Less than frequency" );
341QString QgsRasterFrequencyByLessThanOperatorAlgorithm::name()
const
343 return QStringLiteral(
"lessthanfrequency" );
346QStringList QgsRasterFrequencyByLessThanOperatorAlgorithm::tags()
const
348 return QObject::tr(
"cell,less,lower,frequency,pixel,stack" ).split(
',' );
351QString QgsRasterFrequencyByLessThanOperatorAlgorithm::shortHelpString()
const
353 return QObject::tr(
"The Less than frequency algorithm evaluates on a cell-by-cell basis the frequency "
354 "(number of times) the values of an input stack of rasters are less than "
355 "the value of a value raster. \n "
356 "If multiband rasters are used in the data raster stack, the algorithm will always "
357 "perform the analysis on the first band of the rasters - use GDAL to use other bands in the analysis. "
358 "The input value layer serves as reference layer for the sample layers. "
359 "Any NoData cells in the value raster or the data layer stack will result in a NoData cell "
360 "in the output raster if the ignore NoData parameter is not checked. "
361 "The output NoData value can be set manually. The output rasters extent and resolution "
362 "is defined by the input raster layer and is always of int32 type." );
365QgsRasterFrequencyByLessThanOperatorAlgorithm *QgsRasterFrequencyByLessThanOperatorAlgorithm::createInstance()
const
367 return new QgsRasterFrequencyByLessThanOperatorAlgorithm();
370int QgsRasterFrequencyByLessThanOperatorAlgorithm::applyComparisonOperator(
double searchValue, std::vector<double> cellValueStack )
372 return static_cast<int>( std::count_if( cellValueStack.begin(), cellValueStack.end(), [&](
double const &stackValue ) { return stackValue < searchValue; } ) );
@ Int32
Thirty two bit signed integer (qint32)
@ Hidden
Parameter is hidden and should not be shown to users.
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
@ Double
Double/float values.
bool isCanceled() const
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.
A parameter for processing algorithms which accepts multiple map layers.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
A raster layer parameter for processing algorithms.
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value.
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...