26QString QgsCellStatisticsAlgorithmBase::group()
const
28 return QObject::tr(
"Raster analysis" );
31QString QgsCellStatisticsAlgorithmBase::groupId()
const
33 return QStringLiteral(
"rasteranalysis" );
36void QgsCellStatisticsAlgorithmBase::initAlgorithm(
const QVariantMap & )
41 addSpecificAlgorithmParams();
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,
false );
49 addParameter( output_nodata_parameter.release() );
52 QObject::tr(
"Output layer" ) ) );
63 QgsRasterLayer *referenceLayer = parameterAsRasterLayer( parameters, QStringLiteral(
"REFERENCE_LAYER" ), context );
64 if ( !referenceLayer )
67 mIgnoreNoData = parameterAsBool( parameters, QStringLiteral(
"IGNORE_NODATA" ), context );
68 mNoDataValue = parameterAsDouble( parameters, QStringLiteral(
"OUTPUT_NODATA_VALUE" ), context );
69 mCrs = referenceLayer->
crs();
72 mLayerWidth = referenceLayer->
width();
73 mLayerHeight = referenceLayer->
height();
74 mExtent = referenceLayer->
extent();
76 const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral(
"INPUT" ), context );
77 QList< QgsRasterLayer * > rasterLayers;
78 rasterLayers.reserve( layers.count() );
87 QgsRasterAnalysisUtils::RasterLogicInput input;
91 input.interface = input.sourceDataProvider.get();
93 if ( layer->
crs() != mCrs )
95 input.projector = std::make_unique< QgsRasterProjector >();
96 input.projector->setInput( input.sourceDataProvider.get() );
98 input.interface = input.projector.get();
100 mInputs.emplace_back( std::move( input ) );
107 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
109 for (
int band : i.bands )
112 if (
static_cast<int>( mDataType ) <
static_cast<int>( inputDataType ) )
113 mDataType = inputDataType;
117 prepareSpecificAlgorithmParameters( parameters, context, feedback );
125 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral(
"OUTPUT" ), context );
126 QFileInfo fi( outputFile );
129 std::unique_ptr< QgsRasterFileWriter > writer = std::make_unique< QgsRasterFileWriter >( outputFile );
130 writer->setOutputProviderKey( QStringLiteral(
"gdal" ) );
131 writer->setOutputFormat( outputFormat );
132 mOutputRasterDataProvider.reset( writer->createOneBandRaster( mDataType, mLayerWidth, mLayerHeight, mExtent, mCrs ) );
133 if ( !mOutputRasterDataProvider )
135 if ( !mOutputRasterDataProvider->isValid() )
138 mOutputRasterDataProvider->setNoDataValue( 1, mNoDataValue );
142 processRasterStack( feedback );
144 mOutputRasterDataProvider.reset();
147 outputs.insert( QStringLiteral(
"EXTENT" ), mExtent.toString() );
148 outputs.insert( QStringLiteral(
"CRS_AUTHID" ), mCrs.authid() );
149 outputs.insert( QStringLiteral(
"WIDTH_IN_PIXELS" ), mLayerWidth );
150 outputs.insert( QStringLiteral(
"HEIGHT_IN_PIXELS" ), mLayerHeight );
151 outputs.insert( QStringLiteral(
"TOTAL_PIXEL_COUNT" ), layerSize );
152 outputs.insert( QStringLiteral(
"OUTPUT" ), outputFile );
161QString QgsCellStatisticsAlgorithm::displayName()
const
163 return QObject::tr(
"Cell statistics" );
166QString QgsCellStatisticsAlgorithm::name()
const
168 return QStringLiteral(
"cellstatistics" );
171QStringList QgsCellStatisticsAlgorithm::tags()
const
173 return QObject::tr(
"cell,pixel,statistic,count,mean,sum,majority,minority,variance,variety,range,median,minimum,maximum" ).split(
',' );
176QString QgsCellStatisticsAlgorithm::shortHelpString()
const
178 return QObject::tr(
"The Cell statistics algorithm computes a value for each cell of the "
179 "output raster. At each cell location, "
180 "the output value is defined as a function of all overlaid cell values of the "
182 "The output raster's extent and resolution is defined by a reference "
183 "raster. The following functions can be applied on the input "
184 "raster cells per output raster cell location:\n"
190 " <li>Standard deviation</li>"
194 " <li>Minority (least frequent value)</li>"
195 " <li>Majority (most frequent value)</li>"
196 " <li>Range (max-min)</li>"
197 " <li>Variety (count of unique values)</li>"
199 "Input raster layers that do not match the cell size of the reference raster layer will be "
200 "resampled using nearest neighbor resampling. The output raster data type will be set to "
201 "the most complex data type present in the input datasets except when using the functions "
202 "Mean, Standard deviation and Variance (data type is always Float32/Float64 depending on input float type) or Count and Variety (data type is always Int32).\n"
203 "<i>Calculation details - general:</i> NoData values in any of the input layers will result in a NoData cell output if the Ignore NoData parameter is not set.\n"
204 "<i>Calculation details - Count:</i> Count will always result in the number of cells without NoData values at the current cell location.\n"
205 "<i>Calculation details - Median:</i> If the number of input layers is even, the median will be calculated as the "
206 "arithmetic mean of the two middle values of the ordered cell input values. In this case the output data type is Float32.\n"
207 "<i>Calculation details - Minority/Majority:</i> If no unique minority or majority could be found, the result is NoData, except all "
208 "input cell values are equal." );
211QgsCellStatisticsAlgorithm *QgsCellStatisticsAlgorithm::createInstance()
const
213 return new QgsCellStatisticsAlgorithm();
216void QgsCellStatisticsAlgorithm::addSpecificAlgorithmParams()
218 QStringList statistics = QStringList();
219 statistics << QObject::tr(
"Sum" )
220 << QObject::tr(
"Count" )
221 << QObject::tr(
"Mean" )
222 << QObject::tr(
"Median" )
223 << QObject::tr(
"Standard deviation" )
224 << QObject::tr(
"Variance" )
225 << QObject::tr(
"Minimum" )
226 << QObject::tr(
"Maximum" )
227 << QObject::tr(
"Minority" )
228 << QObject::tr(
"Majority" )
229 << QObject::tr(
"Range" )
230 << QObject::tr(
"Variety" );
232 addParameter(
new QgsProcessingParameterEnum( QStringLiteral(
"STATISTIC" ), QObject::tr(
"Statistic" ), statistics,
false, 0,
false ) );
239 mMethod =
static_cast<QgsRasterAnalysisUtils::CellValueStatisticMethods
>( parameterAsEnum( parameters, QStringLiteral(
"STATISTIC" ), context ) );
243 mMethod == QgsRasterAnalysisUtils::Mean ||
244 mMethod == QgsRasterAnalysisUtils::StandardDeviation ||
245 mMethod == QgsRasterAnalysisUtils::Variance ||
246 ( mMethod == QgsRasterAnalysisUtils::Median && ( mInputs.size() % 2 == 0 ) )
249 if (
static_cast<int>( mDataType ) < 6 )
252 else if ( mMethod == QgsRasterAnalysisUtils::Count || mMethod == QgsRasterAnalysisUtils::Variety )
254 if (
static_cast<int>( mDataType ) > 5 )
264 int nbBlocksWidth =
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
265 int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
266 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
267 mOutputRasterDataProvider->setEditable(
true );
269 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
276 std::unique_ptr< QgsRasterBlock > outputBlock;
277 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
279 std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
280 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
284 for (
int band : i.bands )
288 std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
289 inputBlocks.emplace_back( std::move( b ) );
293 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
294 for (
int row = 0; row < iterRows; row++ )
299 for (
int col = 0; col < iterCols; col++ )
302 bool noDataInStack =
false;
303 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
304 int cellValueStackSize = cellValues.size();
306 if ( noDataInStack && !mIgnoreNoData )
310 if ( mMethod == QgsRasterAnalysisUtils::Count )
311 outputBlock->setValue( row, col, cellValueStackSize );
314 outputBlock->setValue( row, col, mNoDataValue );
317 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
321 case QgsRasterAnalysisUtils::Sum:
322 result = std::accumulate( cellValues.begin(), cellValues.end(), 0.0 );
324 case QgsRasterAnalysisUtils::Count:
325 result = cellValueStackSize;
327 case QgsRasterAnalysisUtils::Mean:
328 result = QgsRasterAnalysisUtils::meanFromCellValues( cellValues, cellValueStackSize );
330 case QgsRasterAnalysisUtils::Median:
331 result = QgsRasterAnalysisUtils::medianFromCellValues( cellValues, cellValueStackSize );
333 case QgsRasterAnalysisUtils::StandardDeviation:
334 result = QgsRasterAnalysisUtils::stddevFromCellValues( cellValues, cellValueStackSize );
336 case QgsRasterAnalysisUtils::Variance:
337 result = QgsRasterAnalysisUtils::varianceFromCellValues( cellValues, cellValueStackSize );
339 case QgsRasterAnalysisUtils::Minimum:
340 result = QgsRasterAnalysisUtils::minimumFromCellValues( cellValues );
342 case QgsRasterAnalysisUtils::Maximum:
343 result = QgsRasterAnalysisUtils::maximumFromCellValues( cellValues );
345 case QgsRasterAnalysisUtils::Minority:
346 result = QgsRasterAnalysisUtils::minorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
348 case QgsRasterAnalysisUtils::Majority:
349 result = QgsRasterAnalysisUtils::majorityFromCellValues( cellValues, mNoDataValue, cellValueStackSize );
351 case QgsRasterAnalysisUtils::Range:
352 result = QgsRasterAnalysisUtils::rangeFromCellValues( cellValues );
354 case QgsRasterAnalysisUtils::Variety:
355 result = QgsRasterAnalysisUtils::varietyFromCellValues( cellValues );
358 outputBlock->setValue( row, col, result );
363 outputBlock->setValue( row, col, mNoDataValue );
367 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
369 mOutputRasterDataProvider->setEditable(
false );
375QString QgsCellStatisticsPercentileAlgorithm::displayName()
const
377 return QObject::tr(
"Cell stack percentile" );
380QString QgsCellStatisticsPercentileAlgorithm::name()
const
382 return QStringLiteral(
"cellstackpercentile" );
385QStringList QgsCellStatisticsPercentileAlgorithm::tags()
const
387 return QObject::tr(
"cell,pixel,statistic,percentile,quantile,quartile" ).split(
',' );
390QString QgsCellStatisticsPercentileAlgorithm::shortHelpString()
const
392 return QObject::tr(
"The Cell stack percentile algorithm returns the cell-wise percentile value of a stack of rasters "
393 "and writes the results to an output raster. The percentile to return is determined by the percentile input value (ranges between 0 and 1). "
394 "At each cell location, the specified percentile is obtained using the respective value from "
395 "the stack of all overlaid and sorted cell values of the input rasters.\n\n"
396 "There are three methods for percentile calculation:"
398 " <li>Nearest rank</li>"
399 " <li>Inclusive linear interpolation (PERCENTILE.INC)</li>"
400 " <li>Exclusive linear interpolation (PERCENTILE.EXC)</li>"
402 "While the output value can stay the same for the nearest rank method (obtains the value that is nearest to the "
403 "specified percentile), the linear interpolation method return unique values for different percentiles. Both interpolation "
404 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
405 "The output raster's extent and resolution is defined by a reference "
406 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
407 "resampled using nearest neighbor resampling. NoData values in any of the input layers will result in a NoData cell output if the Ignore NoData parameter is not set. "
408 "The output raster data type will be set to the most complex data type present in the input datasets. " );
411QgsCellStatisticsPercentileAlgorithm *QgsCellStatisticsPercentileAlgorithm::createInstance()
const
413 return new QgsCellStatisticsPercentileAlgorithm();
416void QgsCellStatisticsPercentileAlgorithm::addSpecificAlgorithmParams()
418 addParameter(
new QgsProcessingParameterEnum( QStringLiteral(
"METHOD" ), QObject::tr(
"Method" ), QStringList() << QObject::tr(
"Nearest rank" ) << QObject::tr(
"Inclusive linear interpolation (PERCENTILE.INC)" ) << QObject::tr(
"Exclusive linear interpolation (PERCENTILE.EXC)" ),
false, 0,
false ) );
425 mMethod =
static_cast< QgsRasterAnalysisUtils::CellValuePercentileMethods
>( parameterAsEnum( parameters, QStringLiteral(
"METHOD" ), context ) );
426 mPercentile = parameterAsDouble( parameters, QStringLiteral(
"PERCENTILE" ), context );
430 if ( mMethod != QgsRasterAnalysisUtils::CellValuePercentileMethods::NearestRankPercentile &&
static_cast< int >( mDataType ) < 6 )
441 int nbBlocksWidth =
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
442 int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
443 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
444 mOutputRasterDataProvider->setEditable(
true );
446 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
453 std::unique_ptr< QgsRasterBlock > outputBlock;
454 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
456 std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
457 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
461 for (
int band : i.bands )
465 std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
466 inputBlocks.emplace_back( std::move( b ) );
470 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
471 for (
int row = 0; row < iterRows; row++ )
476 for (
int col = 0; col < iterCols; col++ )
479 bool noDataInStack =
false;
480 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
481 int cellValueStackSize = cellValues.size();
483 if ( noDataInStack && !mIgnoreNoData )
485 outputBlock->setValue( row, col, mNoDataValue );
487 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
491 case QgsRasterAnalysisUtils::NearestRankPercentile:
492 result = QgsRasterAnalysisUtils::nearestRankPercentile( cellValues, cellValueStackSize, mPercentile );
494 case QgsRasterAnalysisUtils::InterpolatedPercentileInc:
495 result = QgsRasterAnalysisUtils::interpolatedPercentileInc( cellValues, cellValueStackSize, mPercentile );
497 case QgsRasterAnalysisUtils::InterpolatedPercentileExc:
498 result = QgsRasterAnalysisUtils::interpolatedPercentileExc( cellValues, cellValueStackSize, mPercentile, mNoDataValue );
501 outputBlock->setValue( row, col, result );
506 outputBlock->setValue( row, col, mNoDataValue );
510 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
512 mOutputRasterDataProvider->setEditable(
false );
518QString QgsCellStatisticsPercentRankFromValueAlgorithm::displayName()
const
520 return QObject::tr(
"Cell stack percent rank from value" );
523QString QgsCellStatisticsPercentRankFromValueAlgorithm::name()
const
525 return QStringLiteral(
"cellstackpercentrankfromvalue" );
528QStringList QgsCellStatisticsPercentRankFromValueAlgorithm::tags()
const
530 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value" ).split(
',' );
533QString QgsCellStatisticsPercentRankFromValueAlgorithm::shortHelpString()
const
535 return QObject::tr(
"The Cell stack percentrank from value algorithm calculates the cell-wise percentrank value of a stack of rasters based on a single input value "
536 "and writes them to an output raster.\n\n"
537 "At each cell location, the specified value is ranked among the respective values in the stack of all overlaid and sorted cell values from the input rasters. "
538 "For values outside of the stack value distribution, the algorithm returns NoData because the value cannot be ranked among the cell values.\n\n"
539 "There are two methods for percentile calculation:"
541 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
542 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
544 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
545 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
546 "The output raster's extent and resolution is defined by a reference "
547 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
548 "resampled using nearest neighbor resampling. NoData values in any of the input layers will result in a NoData cell output if the Ignore NoData parameter is not set. "
549 "The output raster data type will always be Float32." );
552QgsCellStatisticsPercentRankFromValueAlgorithm *QgsCellStatisticsPercentRankFromValueAlgorithm::createInstance()
const
554 return new QgsCellStatisticsPercentRankFromValueAlgorithm();
557void QgsCellStatisticsPercentRankFromValueAlgorithm::addSpecificAlgorithmParams()
559 addParameter(
new QgsProcessingParameterEnum( QStringLiteral(
"METHOD" ), QObject::tr(
"Method" ), QStringList() << QObject::tr(
"Inclusive linear interpolation (PERCENTRANK.INC)" ) << QObject::tr(
"Exclusive linear interpolation (PERCENTRANK.EXC)" ),
false, 0,
false ) );
566 mMethod =
static_cast< QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, QStringLiteral(
"METHOD" ), context ) );
567 mValue = parameterAsDouble( parameters, QStringLiteral(
"VALUE" ), context );
574void QgsCellStatisticsPercentRankFromValueAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
579 int nbBlocksWidth =
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
580 int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
581 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
582 mOutputRasterDataProvider->setEditable(
true );
584 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
591 std::unique_ptr< QgsRasterBlock > outputBlock;
592 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
594 std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
595 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
599 for (
int band : i.bands )
603 std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
604 inputBlocks.emplace_back( std::move( b ) );
608 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
609 for (
int row = 0; row < iterRows; row++ )
614 for (
int col = 0; col < iterCols; col++ )
617 bool noDataInStack =
false;
618 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
619 int cellValueStackSize = cellValues.size();
621 if ( noDataInStack && !mIgnoreNoData )
623 outputBlock->setValue( row, col, mNoDataValue );
625 else if ( !noDataInStack || ( mIgnoreNoData && cellValueStackSize > 0 ) )
629 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
630 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, mValue, mNoDataValue );
632 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
633 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, mValue, mNoDataValue );
636 outputBlock->setValue( row, col, result );
641 outputBlock->setValue( row, col, mNoDataValue );
645 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
647 mOutputRasterDataProvider->setEditable(
false );
654QString QgsCellStatisticsPercentRankFromRasterAlgorithm::displayName()
const
656 return QObject::tr(
"Cell stack percentrank from raster layer" );
659QString QgsCellStatisticsPercentRankFromRasterAlgorithm::name()
const
661 return QStringLiteral(
"cellstackpercentrankfromrasterlayer" );
664QStringList QgsCellStatisticsPercentRankFromRasterAlgorithm::tags()
const
666 return QObject::tr(
"cell,pixel,statistic,percentrank,rank,percent,value,raster" ).split(
',' );
669QString QgsCellStatisticsPercentRankFromRasterAlgorithm::shortHelpString()
const
671 return QObject::tr(
"The Cell stack percentrank from raster layer algorithm calculates the cell-wise percentrank value of a stack of rasters based on an input value raster "
672 "and writes them to an output raster.\n\n"
673 "At each cell location, the current value of the value raster is used ranked among the respective values in the stack of all overlaid and sorted cell values of the input rasters. "
674 "For values outside of the the stack value distribution, the algorithm returns NoData because the value cannot be ranked among the cell values.\n\n"
675 "There are two methods for percentile calculation:"
677 " <li>Inclusive linearly interpolated percent rank (PERCENTRANK.INC)</li>"
678 " <li>Exclusive linearly interpolated percent rank (PERCENTRANK.EXC)</li>"
680 "The linear interpolation method return the unique percent rank for different values. Both interpolation "
681 "methods follow their counterpart methods implemented by LibreOffice or Microsoft Excel. \n\n"
682 "The output raster's extent and resolution is defined by a reference "
683 "raster. If the input raster layers that do not match the cell size of the reference raster layer will be "
684 "resampled using nearest neighbor resampling. NoData values in any of the input layers will result in a NoData cell output if the Ignore NoData parameter is not set. "
685 "The output raster data type will always be Float32." );
688QgsCellStatisticsPercentRankFromRasterAlgorithm *QgsCellStatisticsPercentRankFromRasterAlgorithm::createInstance()
const
690 return new QgsCellStatisticsPercentRankFromRasterAlgorithm();
693void QgsCellStatisticsPercentRankFromRasterAlgorithm::addSpecificAlgorithmParams()
696 addParameter(
new QgsProcessingParameterBand( QStringLiteral(
"VALUE_RASTER_BAND" ), QObject::tr(
"Value raster band" ), 1, QStringLiteral(
"VALUE_LAYER" ) ) );
697 addParameter(
new QgsProcessingParameterEnum( QStringLiteral(
"METHOD" ), QObject::tr(
"Method" ), QStringList() << QObject::tr(
"Inclusive linear interpolation (PERCENTRANK.INC)" ) << QObject::tr(
"Exclusive linear interpolation (PERCENTRANK.EXC)" ),
false, 0,
false ) );
703 mMethod =
static_cast< QgsRasterAnalysisUtils::CellValuePercentRankMethods
>( parameterAsEnum( parameters, QStringLiteral(
"METHOD" ), context ) );
705 QgsRasterLayer *inputValueRaster = parameterAsRasterLayer( parameters, QStringLiteral(
"INPUT_VALUE_RASTER" ), context );
706 if ( !inputValueRaster )
711 mValueRasterBand = parameterAsInt( parameters, QStringLiteral(
"VALUE_RASTER_BAND" ), context );
718void QgsCellStatisticsPercentRankFromRasterAlgorithm::processRasterStack(
QgsProcessingFeedback *feedback )
722 int nbBlocksWidth =
static_cast< int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
723 int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
724 int nbBlocks = nbBlocksWidth * nbBlocksHeight;
725 mOutputRasterDataProvider->setEditable(
true );
727 outputIter.startRasterRead( 1, mLayerWidth, mLayerHeight, mExtent );
734 std::unique_ptr< QgsRasterBlock > outputBlock;
735 while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) )
737 std::unique_ptr< QgsRasterBlock > valueBlock( mValueRasterInterface->block( mValueRasterBand, blockExtent, iterCols, iterRows ) );
739 std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks;
740 for (
const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) )
744 for (
int band : i.bands )
748 std::unique_ptr< QgsRasterBlock > b( i.interface->block( band, blockExtent, iterCols, iterRows ) );
749 inputBlocks.emplace_back( std::move( b ) );
753 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
754 for (
int row = 0; row < iterRows; row++ )
759 for (
int col = 0; col < iterCols; col++ )
761 bool percentRankValueIsNoData =
false;
762 double percentRankValue = valueBlock->valueAndNoData( row, col, percentRankValueIsNoData );
765 bool noDataInStack =
false;
766 std::vector<double> cellValues = QgsRasterAnalysisUtils::getCellValuesFromBlockStack( inputBlocks, row, col, noDataInStack );
767 int cellValueStackSize = cellValues.size();
769 if ( noDataInStack && !mIgnoreNoData && !percentRankValueIsNoData )
771 outputBlock->setValue( row, col, mNoDataValue );
773 else if ( !noDataInStack || ( !percentRankValueIsNoData && mIgnoreNoData && cellValueStackSize > 0 ) )
777 case QgsRasterAnalysisUtils::InterpolatedPercentRankInc:
778 result = QgsRasterAnalysisUtils::interpolatedPercentRankInc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
780 case QgsRasterAnalysisUtils::InterpolatedPercentRankExc:
781 result = QgsRasterAnalysisUtils::interpolatedPercentRankExc( cellValues, cellValueStackSize, percentRankValue, mNoDataValue );
784 outputBlock->setValue( row, col, result );
789 outputBlock->setValue( row, col, mNoDataValue );
793 mOutputRasterDataProvider->writeBlock( outputBlock.get(), 1, iterLeft, iterTop );
795 mOutputRasterDataProvider->setEditable(
false );
DataType
Raster data types.
@ Float32
Thirty two bit floating point (float)
@ Byte
Eight bit unsigned integer (quint8)
@ 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.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
A parameter for processing algorithms which accepts multiple map layers.
A numeric parameter for processing algorithms.
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...