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" ) ) );
47 std::unique_ptr< QgsProcessingParameterNumber > output_nodata_parameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral(
"OUTPUT_NODATA_VALUE" ), QObject::tr(
"Output NoData value" ),
Qgis::ProcessingNumberParameterType::Double, -9999,
true );
49 addParameter( output_nodata_parameter.release() );
51 std::unique_ptr< QgsProcessingParameterString > createOptsParam = std::make_unique< QgsProcessingParameterString >( QStringLiteral(
"CREATE_OPTIONS" ), QObject::tr(
"Creation options" ), QVariant(),
false,
true );
52 createOptsParam->setMetadata( QVariantMap( {{QStringLiteral(
"widget_wrapper" ), QVariantMap( {{QStringLiteral(
"widget_type" ), QStringLiteral(
"rasteroptions" ) }} ) }} ) );
54 addParameter( createOptsParam.release() );
57 QObject::tr(
"Output layer" ) ) );
58 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"OCCURRENCE_COUNT" ), QObject::tr(
"Count of value occurrences" ) ) );
59 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"FOUND_LOCATIONS_COUNT" ), QObject::tr(
"Count of cells with equal value occurrences" ) ) );
60 addOutput(
new QgsProcessingOutputNumber( QStringLiteral(
"MEAN_FREQUENCY_PER_LOCATION" ), QObject::tr(
"Mean frequency at valid cell locations" ) ) );
70 QgsRasterLayer *inputValueRaster = parameterAsRasterLayer( parameters, QStringLiteral(
"INPUT_VALUE_RASTER" ), context );
71 if ( !inputValueRaster )
74 mInputValueRasterBand = parameterAsInt( parameters, QStringLiteral(
"INPUT_VALUE_RASTER_BAND" ), context );
75 mIgnoreNoData = parameterAsBool( parameters, QStringLiteral(
"IGNORE_NODATA" ), context );
78 mNoDataValue = parameterAsDouble( parameters, QStringLiteral(
"OUTPUT_NODATA_VALUE" ), context );
79 mCrs = inputValueRaster->
crs();
82 mLayerWidth = inputValueRaster->
width();
83 mLayerHeight = inputValueRaster->
height();
84 mExtent = inputValueRaster->
extent();
86 const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral(
"INPUT_RASTERS" ), context );
87 QList< QgsRasterLayer * > rasterLayers;
88 rasterLayers.reserve( layers.count() );
97 QgsRasterAnalysisUtils::RasterLogicInput input;
101 input.interface = input.sourceDataProvider.get();
103 if ( layer->
crs() != mCrs )
105 input.projector = std::make_unique< QgsRasterProjector >();
106 input.projector->setInput( input.sourceDataProvider.get() );
108 input.interface = input.projector.get();
110 mInputs.emplace_back( std::move( input ) );
119 const QString createOptions = parameterAsString( parameters, QStringLiteral(
"CREATE_OPTIONS" ), context ).trimmed();
120 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral(
"OUTPUT" ), context );
121 const QFileInfo fi( outputFile );
124 std::unique_ptr< QgsRasterFileWriter > writer = std::make_unique< QgsRasterFileWriter >( outputFile );
125 writer->setOutputProviderKey( QStringLiteral(
"gdal" ) );
126 if ( !createOptions.isEmpty() )
128 writer->setCreateOptions( createOptions.split(
'|' ) );
130 writer->setOutputFormat( outputFormat );
131 std::unique_ptr<QgsRasterDataProvider > provider( writer->createOneBandRaster(
Qgis::DataType::Int32, mLayerWidth, mLayerHeight, mExtent, mCrs ) );
134 if ( !provider->isValid() )
137 provider->setNoDataValue( 1, mNoDataValue );
138 const qgssize layerSize =
static_cast< qgssize >( mLayerWidth ) *
static_cast< qgssize >( mLayerHeight );
142 const int nbBlocksWidth =
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
143 const int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
144 const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
145 provider->setEditable(
true );
148 iter.startRasterRead( mInputValueRasterBand, mLayerWidth, mLayerHeight, mExtent );
155 unsigned long long occurrenceCount = 0;
156 unsigned long long noDataLocationsCount = 0;
157 std::unique_ptr< QgsRasterBlock > inputBlock;
158 while ( iter.readNextRasterPart( 1, iterCols, iterRows, inputBlock, iterLeft, iterTop, &blockExtent ) )
160 std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
161 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : mInputs )
165 for (
const int band : i.bands )
169 std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
170 inputBlocks.emplace_back( std::move( b ) );
174 std::unique_ptr< QgsRasterBlock > outputBlock = std::make_unique<QgsRasterBlock>(
Qgis::DataType::Int32, iterCols, iterRows );
175 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
176 for (
int row = 0; row < iterRows; row++ )
181 for (
int col = 0; col < iterCols; col++ )
183 bool valueRasterCellIsNoData =
false;
184 const double value = inputBlock->valueAndNoData( row, col, valueRasterCellIsNoData );
186 if ( valueRasterCellIsNoData && !mIgnoreNoData )
190 outputBlock->setValue( row, col, mNoDataValue );
191 noDataLocationsCount++;
195 bool noDataInStack =
false;
196 const std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
198 if ( noDataInStack && !mIgnoreNoData )
200 outputBlock->setValue( row, col, mNoDataValue );
201 noDataLocationsCount++;
205 const int frequency = applyComparisonOperator( value, cellValues );
206 outputBlock->setValue( row, col, frequency );
207 occurrenceCount += frequency;
212 provider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
214 provider->setEditable(
false );
216 const unsigned long long foundLocationsCount = layerSize - noDataLocationsCount;
217 const double meanEqualCountPerValidLocation =
static_cast<double>( occurrenceCount ) /
static_cast<double>( foundLocationsCount * mInputs.size() );
220 outputs.insert( QStringLiteral(
"OCCURRENCE_COUNT" ), occurrenceCount );
221 outputs.insert( QStringLiteral(
"FOUND_LOCATIONS_COUNT" ), foundLocationsCount );
222 outputs.insert( QStringLiteral(
"MEAN_FREQUENCY_PER_LOCATION" ), meanEqualCountPerValidLocation );
223 outputs.insert( QStringLiteral(
"EXTENT" ), mExtent.toString() );
224 outputs.insert( QStringLiteral(
"CRS_AUTHID" ), mCrs.authid() );
225 outputs.insert( QStringLiteral(
"WIDTH_IN_PIXELS" ), mLayerWidth );
226 outputs.insert( QStringLiteral(
"HEIGHT_IN_PIXELS" ), mLayerHeight );
227 outputs.insert( QStringLiteral(
"TOTAL_PIXEL_COUNT" ), layerSize );
228 outputs.insert( QStringLiteral(
"OUTPUT" ), outputFile );
237QString QgsRasterFrequencyByEqualOperatorAlgorithm::displayName()
const
239 return QObject::tr(
"Equal to frequency" );
242QString QgsRasterFrequencyByEqualOperatorAlgorithm::name()
const
244 return QStringLiteral(
"equaltofrequency" );
247QStringList QgsRasterFrequencyByEqualOperatorAlgorithm::tags()
const
249 return QObject::tr(
"cell,equal,frequency,pixel,stack" ).split(
',' );
252QString QgsRasterFrequencyByEqualOperatorAlgorithm::shortHelpString()
const
254 return QObject::tr(
"The Equal to frequency algorithm evaluates on a cell-by-cell basis the frequency "
255 "(number of times) the values of an input stack of rasters are equal "
256 "to the value of a value raster. \n "
257 "If multiband rasters are used in the data raster stack, the algorithm will always "
258 "perform the analysis on the first band of the rasters - use GDAL to use other bands in the analysis. "
259 "The input value layer serves as reference layer for the sample layers. "
260 "Any NoData cells in the value raster or the data layer stack will result in a NoData cell "
261 "in the output raster if the ignore NoData parameter is not checked. "
262 "The output NoData value can be set manually. The output rasters extent and resolution "
263 "is defined by the input raster layer and is always of int32 type." );
266QgsRasterFrequencyByEqualOperatorAlgorithm *QgsRasterFrequencyByEqualOperatorAlgorithm::createInstance()
const
268 return new QgsRasterFrequencyByEqualOperatorAlgorithm();
271int QgsRasterFrequencyByEqualOperatorAlgorithm::applyComparisonOperator(
double searchValue, std::vector<double> cellValueStack )
273 return static_cast<int>( std::count( cellValueStack.begin(), cellValueStack.end(), searchValue ) );
280QString QgsRasterFrequencyByGreaterThanOperatorAlgorithm::displayName()
const
282 return QObject::tr(
"Greater than frequency" );
285QString QgsRasterFrequencyByGreaterThanOperatorAlgorithm::name()
const
287 return QStringLiteral(
"greaterthanfrequency" );
290QStringList QgsRasterFrequencyByGreaterThanOperatorAlgorithm::tags()
const
292 return QObject::tr(
"cell,greater,frequency,pixel,stack" ).split(
',' );
295QString QgsRasterFrequencyByGreaterThanOperatorAlgorithm::shortHelpString()
const
297 return QObject::tr(
"The Greater than frequency algorithm evaluates on a cell-by-cell basis the frequency "
298 "(number of times) the values of an input stack of rasters are greater than "
299 "the value of a value raster. \n "
300 "If multiband rasters are used in the data raster stack, the algorithm will always "
301 "perform the analysis on the first band of the rasters - use GDAL to use other bands in the analysis. "
302 "The input value layer serves as reference layer for the sample layers. "
303 "Any NoData cells in the value raster or the data layer stack will result in a NoData cell "
304 "in the output raster if the ignore NoData parameter is not checked. "
305 "The output NoData value can be set manually. The output rasters extent and resolution "
306 "is defined by the input raster layer and is always of int32 type." );
309QgsRasterFrequencyByGreaterThanOperatorAlgorithm *QgsRasterFrequencyByGreaterThanOperatorAlgorithm::createInstance()
const
311 return new QgsRasterFrequencyByGreaterThanOperatorAlgorithm();
314int QgsRasterFrequencyByGreaterThanOperatorAlgorithm::applyComparisonOperator(
double searchValue, std::vector<double> cellValueStack )
316 return static_cast<int>( std::count_if( cellValueStack.begin(), cellValueStack.end(), [&](
double const & stackValue ) { return stackValue > searchValue; } ) );
323QString QgsRasterFrequencyByLessThanOperatorAlgorithm::displayName()
const
325 return QObject::tr(
"Less than frequency" );
328QString QgsRasterFrequencyByLessThanOperatorAlgorithm::name()
const
330 return QStringLiteral(
"lessthanfrequency" );
333QStringList QgsRasterFrequencyByLessThanOperatorAlgorithm::tags()
const
335 return QObject::tr(
"cell,less,lower,frequency,pixel,stack" ).split(
',' );
338QString QgsRasterFrequencyByLessThanOperatorAlgorithm::shortHelpString()
const
340 return QObject::tr(
"The Less than frequency algorithm evaluates on a cell-by-cell basis the frequency "
341 "(number of times) the values of an input stack of rasters are less than "
342 "the value of a value raster. \n "
343 "If multiband rasters are used in the data raster stack, the algorithm will always "
344 "perform the analysis on the first band of the rasters - use GDAL to use other bands in the analysis. "
345 "The input value layer serves as reference layer for the sample layers. "
346 "Any NoData cells in the value raster or the data layer stack will result in a NoData cell "
347 "in the output raster if the ignore NoData parameter is not checked. "
348 "The output NoData value can be set manually. The output rasters extent and resolution "
349 "is defined by the input raster layer and is always of int32 type." );
352QgsRasterFrequencyByLessThanOperatorAlgorithm *QgsRasterFrequencyByLessThanOperatorAlgorithm::createInstance()
const
354 return new QgsRasterFrequencyByLessThanOperatorAlgorithm();
357int QgsRasterFrequencyByLessThanOperatorAlgorithm::applyComparisonOperator(
double searchValue, std::vector<double> cellValueStack )
359 return static_cast<int>( std::count_if( cellValueStack.begin(), cellValueStack.end(), [&](
double const & stackValue ) { return stackValue < searchValue; } ) );
@ Int32
Thirty two bit signed integer (qint32)
@ 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...