QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
qgsalgorithmrandomraster.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmrandomraster.cpp
3 ---------------------
4 begin : May 2020
5 copyright : (C) 2020 by Clemens Raffler
6 email : clemens dot raffler at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19#include "qgsrasterfilewriter.h"
20#include "qgsstringutils.h"
21#include "random"
22#include "limits"
23
25
26//
27// QgsRandomRasterAlgorithmBase
28//
29QString QgsRandomRasterAlgorithmBase::group() const
30{
31 return QObject::tr( "Raster creation" );
32}
33
34QString QgsRandomRasterAlgorithmBase::groupId() const
35{
36 return QStringLiteral( "rastercreation" );
37}
38
39void QgsRandomRasterAlgorithmBase::initAlgorithm( const QVariantMap & )
40{
41 addParameter( new QgsProcessingParameterExtent( QStringLiteral( "EXTENT" ), QObject::tr( "Desired extent" ) ) );
42 addParameter( new QgsProcessingParameterCrs( QStringLiteral( "TARGET_CRS" ), QObject::tr( "Target CRS" ), QStringLiteral( "ProjectCrs" ) ) );
43 addParameter( new QgsProcessingParameterNumber( QStringLiteral( "PIXEL_SIZE" ), QObject::tr( "Pixel size" ),
44 QgsProcessingParameterNumber::Double, 1, false, 0.01 ) );
45
46 //add specific parameters
47 addAlgorithmParams();
48
49 addParameter( new QgsProcessingParameterRasterDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Output raster" ) ) );
50}
51
52bool QgsRandomRasterAlgorithmBase::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
53{
54 Q_UNUSED( feedback );
55 mCrs = parameterAsCrs( parameters, QStringLiteral( "TARGET_CRS" ), context );
56 mExtent = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, mCrs );
57 mPixelSize = parameterAsDouble( parameters, QStringLiteral( "PIXEL_SIZE" ), context );
58
59 return true;
60}
61
62QVariantMap QgsRandomRasterAlgorithmBase::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
63{
64 const int typeId = parameterAsInt( parameters, QStringLiteral( "OUTPUT_TYPE" ), context );
65 //prepare specific parameters
66 mRasterDataType = getRasterDataType( typeId );
67 prepareRandomParameters( parameters, context );
68
69 std::random_device rd {};
70 std::mt19937 mersenneTwister{rd()};
71
72 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral( "OUTPUT" ), context );
73 const QFileInfo fi( outputFile );
74 const QString outputFormat = QgsRasterFileWriter::driverForExtension( fi.suffix() );
75
76 const int rows = std::max( std::ceil( mExtent.height() / mPixelSize ), 1.0 );
77 const int cols = std::max( std::ceil( mExtent.width() / mPixelSize ), 1.0 );
78
79 //build new raster extent based on number of columns and cellsize
80 //this prevents output cellsize being calculated too small
81 const QgsRectangle rasterExtent = QgsRectangle( mExtent.xMinimum(), mExtent.yMaximum() - ( rows * mPixelSize ), mExtent.xMinimum() + ( cols * mPixelSize ), mExtent.yMaximum() );
82
83 std::unique_ptr< QgsRasterFileWriter > writer = std::make_unique< QgsRasterFileWriter >( outputFile );
84 writer->setOutputProviderKey( QStringLiteral( "gdal" ) );
85 writer->setOutputFormat( outputFormat );
86 std::unique_ptr<QgsRasterDataProvider > provider( writer->createOneBandRaster( mRasterDataType, cols, rows, rasterExtent, mCrs ) );
87 if ( !provider )
88 throw QgsProcessingException( QObject::tr( "Could not create raster output: %1" ).arg( outputFile ) );
89 if ( !provider->isValid() )
90 throw QgsProcessingException( QObject::tr( "Could not create raster output %1: %2" ).arg( outputFile, provider->error().message( QgsErrorMessage::Text ) ) );
91
92 const double step = rows > 0 ? 100.0 / rows : 1;
93
94 for ( int row = 0; row < rows ; row++ )
95 {
96 if ( feedback->isCanceled() )
97 {
98 break;
99 }
100 //prepare raw data depending on raster data type
101 QgsRasterBlock block( mRasterDataType, cols, 1 );
102 switch ( mRasterDataType )
103 {
105 {
106 std::vector<quint8> byteRow( cols );
107 for ( int col = 0; col < cols; col++ )
108 {
109 byteRow[col] = static_cast<quint8>( generateRandomLongValue( mersenneTwister ) );
110 }
111 block.setData( QByteArray( reinterpret_cast<const char *>( byteRow.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Byte ) * cols ) );
112 break;
113 }
115 {
116 std::vector<qint8> int8Row( cols );
117 for ( int col = 0; col < cols; col++ )
118 {
119 int8Row[col] = static_cast<qint8>( generateRandomLongValue( mersenneTwister ) );
120 }
121 block.setData( QByteArray( reinterpret_cast<const char *>( int8Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Int8 ) * cols ) );
122 break;
123 }
125 {
126 std::vector<qint16> int16Row( cols );
127 for ( int col = 0; col < cols; col++ )
128 {
129 int16Row[col] = static_cast<qint16>( generateRandomLongValue( mersenneTwister ) );
130 }
131 block.setData( QByteArray( reinterpret_cast<const char *>( int16Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Int16 ) * cols ) );
132 break;
133 }
135 {
136 std::vector<quint16> uInt16Row( cols );
137 for ( int col = 0; col < cols; col++ )
138 {
139 uInt16Row[col] = static_cast<quint16>( generateRandomLongValue( mersenneTwister ) );
140 }
141 block.setData( QByteArray( reinterpret_cast<const char *>( uInt16Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::UInt16 ) * cols ) );
142 break;
143 }
145 {
146 std::vector<qint32> int32Row( cols );
147 for ( int col = 0; col < cols; col++ )
148 {
149 int32Row[col] = generateRandomLongValue( mersenneTwister );
150 }
151 block.setData( QByteArray( reinterpret_cast<const char *>( int32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Int32 ) * cols ) );
152 break;
153 }
155 {
156 std::vector<quint32> uInt32Row( cols );
157 for ( int col = 0; col < cols; col++ )
158 {
159 uInt32Row[col] = static_cast<quint32>( generateRandomLongValue( mersenneTwister ) );
160 }
161 block.setData( QByteArray( reinterpret_cast<const char *>( uInt32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::UInt32 ) * cols ) );
162 break;
163 }
165 {
166 std::vector<float> float32Row( cols );
167 for ( int col = 0; col < cols; col++ )
168 {
169 float32Row[col] = static_cast<float>( generateRandomDoubleValue( mersenneTwister ) );
170 }
171 block.setData( QByteArray( reinterpret_cast<const char *>( float32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Float32 ) * cols ) );
172 break;
173 }
175 {
176 std::vector<double> float64Row( cols );
177 for ( int col = 0; col < cols; col++ )
178 {
179 float64Row[col] = generateRandomDoubleValue( mersenneTwister );
180 }
181 block.setData( QByteArray( reinterpret_cast<const char *>( float64Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Float64 ) * cols ) );
182 break;
183 }
184 default:
185 break;
186 }
187 provider->writeBlock( &block, 1, 0, row );
188 feedback->setProgress( row * step );
189 }
190
191 QVariantMap outputs;
192 outputs.insert( QStringLiteral( "OUTPUT" ), outputFile );
193 return outputs;
194}
195
196//
197//QgsRandomUniformRasterAlgorithm
198//
199QString QgsRandomUniformRasterAlgorithm::name() const
200{
201 return QStringLiteral( "createrandomuniformrasterlayer" );
202}
203
204QString QgsRandomUniformRasterAlgorithm::displayName() const
205{
206 return QObject::tr( "Create random raster layer (uniform distribution)" );
207}
208
209QStringList QgsRandomUniformRasterAlgorithm::tags() const
210{
211 return QObject::tr( "raster,create,random" ).split( ',' );
212}
213
214QString QgsRandomUniformRasterAlgorithm::shortHelpString() const
215{
216 return QObject::tr( "Generates a raster layer for given extent and cell size "
217 "filled with random values.\n"
218 "By default, the values will range between the minimum and "
219 "maximum value of the specified output raster type. This can "
220 "be overridden by using the advanced parameters for lower and "
221 "upper bound value. If the bounds have the same value or both "
222 "are zero (default) the algorithm will create random values in "
223 "the full value range of the chosen raster data type. "
224 "Choosing bounds outside the acceptable range of the output "
225 "raster type will abort the algorithm." );
226}
227
228QgsRandomUniformRasterAlgorithm *QgsRandomUniformRasterAlgorithm::createInstance() const
229{
230 return new QgsRandomUniformRasterAlgorithm();
231}
232
233void QgsRandomUniformRasterAlgorithm::addAlgorithmParams()
234{
235 QStringList rasterDataTypes = QStringList();
236 rasterDataTypes << QStringLiteral( "Byte" )
237 << QStringLiteral( "Integer16" )
238 << QStringLiteral( "Unsigned Integer16" )
239 << QStringLiteral( "Integer32" )
240 << QStringLiteral( "Unsigned Integer32" )
241 << QStringLiteral( "Float32" )
242 << QStringLiteral( "Float64" );
243
244 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 5, false );
245 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
246 addParameter( rasterTypeParameter.release() );
247
248 std::unique_ptr< QgsProcessingParameterNumber > lowerBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "LOWER_BOUND" ), QStringLiteral( "Lower bound for random number range" ), QgsProcessingParameterNumber::Double, QVariant(), true );
249 lowerBoundParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
250 addParameter( lowerBoundParameter.release() );
251
252 std::unique_ptr< QgsProcessingParameterNumber > upperBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "UPPER_BOUND" ), QStringLiteral( "Upper bound for random number range" ), QgsProcessingParameterNumber::Double, QVariant(), true );
253 upperBoundParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
254 addParameter( upperBoundParameter.release() );
255}
256
257Qgis::DataType QgsRandomUniformRasterAlgorithm::getRasterDataType( int typeId )
258{
259 switch ( typeId )
260 {
261 case 0:
263 case 1:
265 case 2:
267 case 3:
269 case 4:
271 case 5:
273 case 6:
275 default:
277 }
278}
279
280bool QgsRandomUniformRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
281{
282 mRandomUpperBound = parameterAsDouble( parameters, QStringLiteral( "UPPER_BOUND" ), context );
283 mRandomLowerBound = parameterAsDouble( parameters, QStringLiteral( "LOWER_BOUND" ), context );
284
285 if ( mRandomLowerBound > mRandomUpperBound )
286 throw QgsProcessingException( QObject::tr( "The chosen lower bound for random number range is greater than the upper bound. The lower bound value must be smaller than the upper bound value." ) );
287
288 const int typeId = parameterAsInt( parameters, QStringLiteral( "OUTPUT_TYPE" ), context );
289 const Qgis::DataType rasterDataType = getRasterDataType( typeId );
290
291 switch ( rasterDataType )
292 {
294 if ( mRandomLowerBound < std::numeric_limits<quint8>::min() || mRandomUpperBound > std::numeric_limits<quint8>::max() )
295 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept positive values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<quint8>::min() ).arg( std::numeric_limits<quint8>::max() ).arg( QLatin1String( "Byte" ) ) );
296 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
297 {
298 //if parameters unset (=both are 0 or equal) --> use the whole value range
299 mRandomUpperBound = std::numeric_limits<quint8>::max();
300 mRandomLowerBound = std::numeric_limits<quint8>::min();
301 }
302 break;
304 if ( mRandomLowerBound < std::numeric_limits<qint8>::min() || mRandomUpperBound > std::numeric_limits<qint8>::max() )
305 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept positive values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<qint8>::min() ).arg( std::numeric_limits<qint8>::max() ).arg( QLatin1String( "Int8" ) ) );
306 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
307 {
308 //if parameters unset (=both are 0 or equal) --> use the whole value range
309 mRandomUpperBound = std::numeric_limits<qint8>::max();
310 mRandomLowerBound = std::numeric_limits<qint8>::min();
311 }
312 break;
314 if ( mRandomLowerBound < std::numeric_limits<qint16>::min() || mRandomUpperBound > std::numeric_limits<qint16>::max() )
315 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<qint16>::min() ).arg( std::numeric_limits<qint16>::max() ).arg( QLatin1String( "Integer16" ) ) );
316 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
317 {
318 mRandomUpperBound = std::numeric_limits<qint16>::max();
319 mRandomLowerBound = std::numeric_limits<qint16>::min();
320 }
321 break;
323 if ( mRandomLowerBound < std::numeric_limits<quint16>::min() || mRandomUpperBound > std::numeric_limits<quint16>::max() )
324 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept positive values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<quint16>::min() ).arg( std::numeric_limits<quint16>::max() ).arg( QLatin1String( "Unsigned Integer16" ) ) );
325 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
326 {
327 mRandomUpperBound = std::numeric_limits<quint16>::max();
328 mRandomLowerBound = std::numeric_limits<quint16>::min();
329 }
330 break;
332 if ( mRandomLowerBound < std::numeric_limits<qint32>::min() || mRandomUpperBound > std::numeric_limits<qint32>::max() )
333 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<qint32>::min() ).arg( std::numeric_limits<qint32>::max() ).arg( QLatin1String( "Integer32" ) ) );
334 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
335 {
336 mRandomUpperBound = std::numeric_limits<qint32>::max();
337 mRandomLowerBound = std::numeric_limits<qint32>::min();
338 }
339 break;
341 if ( mRandomLowerBound < std::numeric_limits<quint32>::min() || mRandomUpperBound > std::numeric_limits<quint32>::max() )
342 throw QgsProcessingException( QObject::tr( "Raster datasets of type %3 only accept positive values between %1 and %2. Please choose other bounds for random values." ).arg( std::numeric_limits<quint32>::min() ).arg( std::numeric_limits<quint32>::max() ).arg( QLatin1String( "Unsigned Integer32" ) ) );
343 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
344 {
345 mRandomUpperBound = std::numeric_limits<quint32>::max();
346 mRandomLowerBound = std::numeric_limits<quint32>::min();
347 }
348 break;
350 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
351 {
352 mRandomUpperBound = std::numeric_limits<float>::max();
353 mRandomLowerBound = std::numeric_limits<float>::min();
354 }
355 break;
357 if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
358 {
359 mRandomUpperBound = std::numeric_limits<double>::max();
360 mRandomLowerBound = std::numeric_limits<double>::min();
361 }
362 break;
370 break;
371 }
372
373 mRandomUniformIntDistribution = std::uniform_int_distribution<long>( mRandomLowerBound, mRandomUpperBound );
374 mRandomUniformDoubleDistribution = std::uniform_real_distribution<double>( mRandomLowerBound, mRandomUpperBound );
375
376 return true;
377}
378
379long QgsRandomUniformRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
380{
381 return mRandomUniformIntDistribution( mersenneTwister );
382}
383
384double QgsRandomUniformRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
385{
386 return mRandomUniformDoubleDistribution( mersenneTwister );
387}
388
389//
390// QgsRandomBinomialRasterAlgorithm
391//
392QString QgsRandomBinomialRasterAlgorithm::name() const
393{
394 return QStringLiteral( "createrandombinomialrasterlayer" );
395}
396
397QString QgsRandomBinomialRasterAlgorithm::displayName() const
398{
399 return QObject::tr( "Create random raster layer (binomial distribution)" );
400}
401
402QStringList QgsRandomBinomialRasterAlgorithm::tags() const
403{
404 return QObject::tr( "raster,create,binomial,random" ).split( ',' );
405}
406
407QString QgsRandomBinomialRasterAlgorithm::shortHelpString() const
408{
409 return QObject::tr( "Generates a raster layer for given extent and cell size "
410 "filled with binomially distributed random values.\n"
411 "By default, the values will be chosen given an N of 10 and a probability of 0.5. "
412 "This can be overridden by using the advanced parameter for N and probability. "
413 "The raster data type is set to Integer types (Integer16 by default). "
414 "The binomial distribution random values are defined as positive integer numbers. "
415 "A floating point raster will represent a cast of integer values "
416 "to floating point." );
417}
418
419QgsRandomBinomialRasterAlgorithm *QgsRandomBinomialRasterAlgorithm::createInstance() const
420{
421 return new QgsRandomBinomialRasterAlgorithm();
422}
423
424
425void QgsRandomBinomialRasterAlgorithm::addAlgorithmParams( )
426{
427 QStringList rasterDataTypes = QStringList();
428 rasterDataTypes << QStringLiteral( "Integer16" )
429 << QStringLiteral( "Unsigned Integer16" )
430 << QStringLiteral( "Integer32" )
431 << QStringLiteral( "Unsigned Integer32" )
432 << QStringLiteral( "Float32" )
433 << QStringLiteral( "Float64" );
434
435 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
436 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
437 addParameter( rasterTypeParameter.release() );
438
439 std::unique_ptr< QgsProcessingParameterNumber > nParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "N" ), QStringLiteral( "N" ), QgsProcessingParameterNumber::Integer, 10, true, 0 );
441 addParameter( nParameter.release() );
442
443 std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), QgsProcessingParameterNumber::Double, 0.5, true, 0 );
444 probabilityParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
445 addParameter( probabilityParameter.release() );
446}
447
448Qgis::DataType QgsRandomBinomialRasterAlgorithm::getRasterDataType( int typeId )
449{
450 switch ( typeId )
451 {
452 case 0:
454 case 1:
456 case 2:
458 case 3:
460 case 4:
462 case 5:
464 default:
466 }
467}
468
469bool QgsRandomBinomialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
470{
471 const int n = parameterAsInt( parameters, QStringLiteral( "N" ), context );
472 const double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
473 mRandombinomialDistribution = std::binomial_distribution<long>( n, probability );
474 return true;
475}
476
477long QgsRandomBinomialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
478{
479 return mRandombinomialDistribution( mersenneTwister );
480}
481
482double QgsRandomBinomialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
483{
484 return static_cast<double>( mRandombinomialDistribution( mersenneTwister ) );
485}
486
487//
488// QgsRandomExponentialRasterAlgorithm
489//
490QString QgsRandomExponentialRasterAlgorithm::name() const
491{
492 return QStringLiteral( "createrandomexponentialrasterlayer" );
493}
494
495QString QgsRandomExponentialRasterAlgorithm::displayName() const
496{
497 return QObject::tr( "Create random raster layer (exponential distribution)" );
498}
499
500QStringList QgsRandomExponentialRasterAlgorithm::tags() const
501{
502 return QObject::tr( "raster,create,random,exponential" ).split( ',' );
503}
504
505QString QgsRandomExponentialRasterAlgorithm::shortHelpString() const
506{
507 return QObject::tr( "Generates a raster layer for given extent and cell size "
508 "filled with exponentially distributed random values.\n"
509 "By default, the values will be chosen given a lambda of 1.0. "
510 "This can be overridden by using the advanced parameter for lambda. "
511 "The raster data type is set to Float32 by default as "
512 "the exponential distribution random values are floating point numbers." );
513}
514
515QgsRandomExponentialRasterAlgorithm *QgsRandomExponentialRasterAlgorithm::createInstance() const
516{
517 return new QgsRandomExponentialRasterAlgorithm();
518}
519
520
521void QgsRandomExponentialRasterAlgorithm::addAlgorithmParams()
522{
523 QStringList rasterDataTypes = QStringList();
524 rasterDataTypes << QStringLiteral( "Float32" )
525 << QStringLiteral( "Float64" );
526
527 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
528 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
529 addParameter( rasterTypeParameter.release() );
530
531 std::unique_ptr< QgsProcessingParameterNumber > lambdaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "LAMBDA" ), QStringLiteral( "Lambda" ), QgsProcessingParameterNumber::Double, 1.0, true, 0.000001 );
532 lambdaParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
533 addParameter( lambdaParameter.release() );
534}
535
536Qgis::DataType QgsRandomExponentialRasterAlgorithm::getRasterDataType( int typeId )
537{
538 switch ( typeId )
539 {
540 case 0:
542 case 1:
544 default:
546 }
547}
548
549bool QgsRandomExponentialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
550{
551 const double lambda = parameterAsDouble( parameters, QStringLiteral( "LAMBDA" ), context );
552 mRandomExponentialDistribution = std::exponential_distribution<double>( lambda );
553 return true;
554}
555
556long QgsRandomExponentialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
557{
558 return static_cast<long>( mRandomExponentialDistribution( mersenneTwister ) );
559}
560
561double QgsRandomExponentialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
562{
563 return mRandomExponentialDistribution( mersenneTwister );
564}
565
566//
567// QgsRandomGammaRasterAlgorithm
568//
569QString QgsRandomGammaRasterAlgorithm::name() const
570{
571 return QStringLiteral( "createrandomgammarasterlayer" );
572}
573
574QString QgsRandomGammaRasterAlgorithm::displayName() const
575{
576 return QObject::tr( "Create random raster layer (gamma distribution)" );
577}
578
579QStringList QgsRandomGammaRasterAlgorithm::tags() const
580{
581 return QObject::tr( "raster,create,random,gamma" ).split( ',' );
582}
583
584QString QgsRandomGammaRasterAlgorithm::shortHelpString() const
585{
586 return QObject::tr( "Generates a raster layer for given extent and cell size "
587 "filled with gamma distributed random values.\n"
588 "By default, the values will be chosen given an alpha and beta value of 1.0. "
589 "This can be overridden by using the advanced parameter for alpha and beta. "
590 "The raster data type is set to Float32 by default as "
591 "the gamma distribution random values are floating point numbers." );
592}
593
594QgsRandomGammaRasterAlgorithm *QgsRandomGammaRasterAlgorithm::createInstance() const
595{
596 return new QgsRandomGammaRasterAlgorithm();
597}
598
599
600void QgsRandomGammaRasterAlgorithm::addAlgorithmParams()
601{
602 QStringList rasterDataTypes = QStringList();
603 rasterDataTypes << QStringLiteral( "Float32" )
604 << QStringLiteral( "Float64" );
605
606 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
607 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
608 addParameter( rasterTypeParameter.release() );
609
610 std::unique_ptr< QgsProcessingParameterNumber > alphaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "ALPHA" ), QStringLiteral( "Alpha" ), QgsProcessingParameterNumber::Double, 1.0, true, 0.000001 );
611 alphaParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
612 addParameter( alphaParameter.release() );
613
614 std::unique_ptr< QgsProcessingParameterNumber > betaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "BETA" ), QStringLiteral( "Beta" ), QgsProcessingParameterNumber::Double, 1.0, true, 0.000001 );
615 betaParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
616 addParameter( betaParameter.release() );
617}
618
619Qgis::DataType QgsRandomGammaRasterAlgorithm::getRasterDataType( int typeId )
620{
621 switch ( typeId )
622 {
623 case 0:
625 case 1:
627 default:
629 }
630}
631
632bool QgsRandomGammaRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
633{
634 const double alpha = parameterAsDouble( parameters, QStringLiteral( "ALPHA" ), context );
635 const double beta = parameterAsDouble( parameters, QStringLiteral( "BETA" ), context );
636 mRandomGammaDistribution = std::gamma_distribution<double>( alpha, beta );
637 return true;
638}
639
640long QgsRandomGammaRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
641{
642 return static_cast<long>( mRandomGammaDistribution( mersenneTwister ) );
643}
644
645double QgsRandomGammaRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
646{
647 return mRandomGammaDistribution( mersenneTwister );
648}
649
650//
651// QgsRandomGeometricRasterAlgorithm
652//
653QString QgsRandomGeometricRasterAlgorithm::name() const
654{
655 return QStringLiteral( "createrandomgeometricrasterlayer" );
656}
657
658QString QgsRandomGeometricRasterAlgorithm::displayName() const
659{
660 return QObject::tr( "Create random raster layer (geometric distribution)" );
661}
662
663QStringList QgsRandomGeometricRasterAlgorithm::tags() const
664{
665 return QObject::tr( "raster,create,random,geometric" ).split( ',' );
666}
667
668QString QgsRandomGeometricRasterAlgorithm::shortHelpString() const
669{
670 return QObject::tr( "Generates a raster layer for given extent and cell size "
671 "filled with geometrically distributed random values.\n"
672 "By default, the values will be chosen given a probability of 0.5. "
673 "This can be overridden by using the advanced parameter for mean "
674 "value. The raster data type is set to Integer types (Integer16 by default). "
675 "The geometric distribution random values are defined as positive integer numbers. "
676 "A floating point raster will represent a cast of "
677 "integer values to floating point." );
678}
679
680QgsRandomGeometricRasterAlgorithm *QgsRandomGeometricRasterAlgorithm::createInstance() const
681{
682 return new QgsRandomGeometricRasterAlgorithm();
683}
684
685
686void QgsRandomGeometricRasterAlgorithm::addAlgorithmParams()
687{
688 QStringList rasterDataTypes = QStringList();
689 rasterDataTypes << QStringLiteral( "Integer16" )
690 << QStringLiteral( "Unsigned Integer16" )
691 << QStringLiteral( "Integer32" )
692 << QStringLiteral( "Unsigned Integer32" )
693 << QStringLiteral( "Float32" )
694 << QStringLiteral( "Float64" );
695
696 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
697 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
698 addParameter( rasterTypeParameter.release() );
699
700 std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), QgsProcessingParameterNumber::Double, 0.5, true, 0.00001 );
701 probabilityParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
702 addParameter( probabilityParameter.release() );
703}
704
705Qgis::DataType QgsRandomGeometricRasterAlgorithm::getRasterDataType( int typeId )
706{
707 switch ( typeId )
708 {
709 case 0:
711 case 1:
713 case 2:
715 case 3:
717 case 4:
719 case 5:
721 default:
723 }
724}
725
726bool QgsRandomGeometricRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
727{
728 const double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
729 mRandomGeometricDistribution = std::geometric_distribution<long>( probability );
730 return true;
731}
732
733long QgsRandomGeometricRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
734{
735 return mRandomGeometricDistribution( mersenneTwister );
736}
737
738double QgsRandomGeometricRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
739{
740 return static_cast<double>( mRandomGeometricDistribution( mersenneTwister ) );
741}
742
743//
744// QgsRandomNegativeBinomialRasterAlgorithm
745//
746QString QgsRandomNegativeBinomialRasterAlgorithm::name() const
747{
748 return QStringLiteral( "createrandomnegativebinomialrasterlayer" );
749}
750
751QString QgsRandomNegativeBinomialRasterAlgorithm::displayName() const
752{
753 return QObject::tr( "Create random raster layer (negative binomial distribution)" );
754}
755
756QStringList QgsRandomNegativeBinomialRasterAlgorithm::tags() const
757{
758 return QObject::tr( "raster,create,random,negative,binomial,negative-binomial" ).split( ',' );
759}
760
761QString QgsRandomNegativeBinomialRasterAlgorithm::shortHelpString() const
762{
763 return QObject::tr( "Generates a raster layer for given extent and cell size "
764 "filled with negative binomially distributed random values.\n"
765 "By default, the values will be chosen given a distribution parameter k of 10.0 "
766 "and a probability of 0.5. "
767 "This can be overridden by using the advanced parameters for k and probability. "
768 "The raster data type is set to Integer types (Integer 16 by default). "
769 "The negative binomial distribution random values are defined as positive integer numbers. "
770 "A floating point raster will represent a cast of "
771 "integer values to floating point." );
772}
773
774QgsRandomNegativeBinomialRasterAlgorithm *QgsRandomNegativeBinomialRasterAlgorithm::createInstance() const
775{
776 return new QgsRandomNegativeBinomialRasterAlgorithm();
777}
778
779
780void QgsRandomNegativeBinomialRasterAlgorithm::addAlgorithmParams( )
781{
782 QStringList rasterDataTypes = QStringList();
783 rasterDataTypes << QStringLiteral( "Integer16" )
784 << QStringLiteral( "Unsigned Integer16" )
785 << QStringLiteral( "Integer32" )
786 << QStringLiteral( "Unsigned Integer32" )
787 << QStringLiteral( "Float32" )
788 << QStringLiteral( "Float64" );
789
790 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
791 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
792 addParameter( rasterTypeParameter.release() );
793
794 std::unique_ptr< QgsProcessingParameterNumber > kParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "K_PARAMETER" ), QStringLiteral( "Distribution parameter k" ), QgsProcessingParameterNumber::Integer, 10, true, 0.00001 );
796 addParameter( kParameter.release() );
797
798 std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), QgsProcessingParameterNumber::Double, 0.5, true, 0.00001 );
799 probabilityParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
800 addParameter( probabilityParameter.release() );
801}
802
803Qgis::DataType QgsRandomNegativeBinomialRasterAlgorithm::getRasterDataType( int typeId )
804{
805 switch ( typeId )
806 {
807 case 0:
809 case 1:
811 case 2:
813 case 3:
815 case 4:
817 case 5:
819 default:
821 }
822}
823
824bool QgsRandomNegativeBinomialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
825{
826 const int k = parameterAsInt( parameters, QStringLiteral( "K_PARAMETER" ), context );
827 const double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
828 mRandomNegativeBinomialDistribution = std::negative_binomial_distribution<long>( k, probability );
829 return true;
830}
831
832long QgsRandomNegativeBinomialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
833{
834 return mRandomNegativeBinomialDistribution( mersenneTwister );
835}
836
837double QgsRandomNegativeBinomialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
838{
839 return static_cast<double>( mRandomNegativeBinomialDistribution( mersenneTwister ) );
840}
841
842//
843// QgsRandomNormalRasterAlgorithm
844//
845QString QgsRandomNormalRasterAlgorithm::name() const
846{
847 return QStringLiteral( "createrandomnormalrasterlayer" );
848}
849
850QString QgsRandomNormalRasterAlgorithm::displayName() const
851{
852 return QObject::tr( "Create random raster layer (normal distribution)" );
853}
854
855QStringList QgsRandomNormalRasterAlgorithm::tags() const
856{
857 return QObject::tr( "raster,create,normal,distribution,random" ).split( ',' );
858}
859
860QString QgsRandomNormalRasterAlgorithm::shortHelpString() const
861{
862 return QObject::tr( "Generates a raster layer for given extent and cell size "
863 "filled with normally distributed random values.\n"
864 "By default, the values will be chosen given a mean of 0.0 and "
865 "a standard deviation of 1.0. This can be overridden by "
866 "using the advanced parameters for mean and standard deviation "
867 "value. The raster data type is set to Float32 by default "
868 "as the normal distribution random values are floating point numbers." );
869}
870
871QgsRandomNormalRasterAlgorithm *QgsRandomNormalRasterAlgorithm::createInstance() const
872{
873 return new QgsRandomNormalRasterAlgorithm();
874}
875
876void QgsRandomNormalRasterAlgorithm::addAlgorithmParams()
877{
878 QStringList rasterDataTypes = QStringList();
879 rasterDataTypes << QStringLiteral( "Float32" )
880 << QStringLiteral( "Float64" );
881
882 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
883 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
884 addParameter( rasterTypeParameter.release() );
885
886 std::unique_ptr< QgsProcessingParameterNumber > meanParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MEAN" ), QStringLiteral( "Mean of normal distribution" ), QgsProcessingParameterNumber::Double, 0, true );
887 meanParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
888 addParameter( meanParameter.release() );
889
890 std::unique_ptr< QgsProcessingParameterNumber > stdevParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "STDDEV" ), QStringLiteral( "Standard deviation of normal distribution" ), QgsProcessingParameterNumber::Double, 1, true, 0 );
891 stdevParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
892 addParameter( stdevParameter.release() );
893}
894
895Qgis::DataType QgsRandomNormalRasterAlgorithm::getRasterDataType( int typeId )
896{
897 switch ( typeId )
898 {
899 case 0:
901 case 1:
903 default:
905 }
906}
907
908bool QgsRandomNormalRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
909{
910 const double mean = parameterAsDouble( parameters, QStringLiteral( "MEAN" ), context );
911 const double stddev = parameterAsDouble( parameters, QStringLiteral( "STDDEV" ), context );
912 mRandomNormalDistribution = std::normal_distribution<double>( mean, stddev );
913 return true;
914}
915
916long QgsRandomNormalRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
917{
918 return static_cast<long>( mRandomNormalDistribution( mersenneTwister ) );
919}
920
921double QgsRandomNormalRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
922{
923 return mRandomNormalDistribution( mersenneTwister );
924}
925
926//
927// QgsRandomPoissonRasterAlgorithm
928//
929QString QgsRandomPoissonRasterAlgorithm::name() const
930{
931 return QStringLiteral( "createrandompoissonrasterlayer" );
932}
933
934QString QgsRandomPoissonRasterAlgorithm::displayName() const
935{
936 return QObject::tr( "Create random raster layer (poisson distribution)" );
937}
938
939QStringList QgsRandomPoissonRasterAlgorithm::tags() const
940{
941 return QObject::tr( "raster,create,random,poisson" ).split( ',' );
942}
943
944QString QgsRandomPoissonRasterAlgorithm::shortHelpString() const
945{
946 return QObject::tr( "Generates a raster layer for given extent and cell size "
947 "filled with poisson distributed random values.\n"
948 "By default, the values will be chosen given a mean of 1.0. "
949 "This can be overridden by using the advanced parameter for mean "
950 "value. The raster data type is set to Integer types (Integer16 by default). "
951 "The poisson distribution random values are positive integer numbers. "
952 "A floating point raster will represent a cast of integer values to floating point." );
953}
954
955QgsRandomPoissonRasterAlgorithm *QgsRandomPoissonRasterAlgorithm::createInstance() const
956{
957 return new QgsRandomPoissonRasterAlgorithm();
958}
959
960
961void QgsRandomPoissonRasterAlgorithm::addAlgorithmParams()
962{
963 QStringList rasterDataTypes = QStringList();
964 rasterDataTypes << QStringLiteral( "Integer16" )
965 << QStringLiteral( "Unsigned Integer16" )
966 << QStringLiteral( "Integer32" )
967 << QStringLiteral( "Unsigned Integer32" )
968 << QStringLiteral( "Float32" )
969 << QStringLiteral( "Float64" );
970
971 std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
972 rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
973 addParameter( rasterTypeParameter.release() );
974
975 std::unique_ptr< QgsProcessingParameterNumber > upperBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MEAN" ), QStringLiteral( "Mean" ), QgsProcessingParameterNumber::Double, 1.0, true, 0 );
976 upperBoundParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
977 addParameter( upperBoundParameter.release() );
978}
979
980Qgis::DataType QgsRandomPoissonRasterAlgorithm::getRasterDataType( int typeId )
981{
982 switch ( typeId )
983 {
984 case 0:
986 case 1:
988 case 2:
990 case 3:
992 case 4:
994 case 5:
996 default:
998 }
999}
1000
1001bool QgsRandomPoissonRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
1002{
1003 const double mean = parameterAsDouble( parameters, QStringLiteral( "MEAN" ), context );
1004 mRandomPoissonDistribution = std::poisson_distribution<long>( mean );
1005 return true;
1006}
1007
1008long QgsRandomPoissonRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
1009{
1010 return mRandomPoissonDistribution( mersenneTwister );
1011}
1012
1013double QgsRandomPoissonRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
1014{
1015 return static_cast<double>( mRandomPoissonDistribution( mersenneTwister ) );
1016}
1017
DataType
Raster data types.
Definition: qgis.h:242
@ CInt32
Complex Int32.
@ Float32
Thirty two bit floating point (float)
@ CFloat64
Complex Float64.
@ Int16
Sixteen bit signed integer (qint16)
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ Int8
Eight bit signed integer (qint8) (added in QGIS 3.30)
@ UInt16
Sixteen bit unsigned integer (quint16)
@ Byte
Eight bit unsigned integer (quint8)
@ UnknownDataType
Unknown or unspecified type.
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
@ Int32
Thirty two bit signed integer (qint32)
@ Float64
Sixty four bit floating point (double)
@ CFloat32
Complex Float32.
@ CInt16
Complex Int16.
@ UInt32
Thirty two bit unsigned integer (quint32)
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
Base class for providing feedback from a processing algorithm.
A coordinate reference system parameter for processing algorithms.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
A rectangular map extent parameter for processing algorithms.
A numeric parameter for processing algorithms.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
Raster data container.
static int typeSize(Qgis::DataType dataType) SIP_HOLDGIL
Returns the size in bytes for the specified dataType.
static QString driverForExtension(const QString &extension)
Returns the GDAL driver name for a specified file extension.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:3509