QGIS API Documentation  3.20.0-Odense (decaadbb31)
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 //
29 QString QgsRandomRasterAlgorithmBase::group() const
30 {
31  return QObject::tr( "Raster creation" );
32 }
33 
34 QString QgsRandomRasterAlgorithmBase::groupId() const
35 {
36  return QStringLiteral( "rastercreation" );
37 }
38 
39 void 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 
52 bool 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 
62 QVariantMap QgsRandomRasterAlgorithmBase::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
63 {
64  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  QFileInfo fi( outputFile );
74  const QString outputFormat = QgsRasterFileWriter::driverForExtension( fi.suffix() );
75 
76  int rows = std::max( std::ceil( mExtent.height() / mPixelSize ), 1.0 );
77  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  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  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<qint16> int16Row( cols );
117  for ( int col = 0; col < cols; col++ )
118  {
119  int16Row[col] = static_cast<qint16>( generateRandomLongValue( mersenneTwister ) );
120  }
121  block.setData( QByteArray( reinterpret_cast<const char *>( int16Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Int16 ) * cols ) );
122  break;
123  }
125  {
126  std::vector<quint16> uInt16Row( cols );
127  for ( int col = 0; col < cols; col++ )
128  {
129  uInt16Row[col] = static_cast<quint16>( generateRandomLongValue( mersenneTwister ) );
130  }
131  block.setData( QByteArray( reinterpret_cast<const char *>( uInt16Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::UInt16 ) * cols ) );
132  break;
133  }
135  {
136  std::vector<qint32> int32Row( cols );
137  for ( int col = 0; col < cols; col++ )
138  {
139  int32Row[col] = generateRandomLongValue( mersenneTwister );
140  }
141  block.setData( QByteArray( reinterpret_cast<const char *>( int32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Int32 ) * cols ) );
142  break;
143  }
145  {
146  std::vector<quint32> uInt32Row( cols );
147  for ( int col = 0; col < cols; col++ )
148  {
149  uInt32Row[col] = static_cast<quint32>( generateRandomLongValue( mersenneTwister ) );
150  }
151  block.setData( QByteArray( reinterpret_cast<const char *>( uInt32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::UInt32 ) * cols ) );
152  break;
153  }
155  {
156  std::vector<float> float32Row( cols );
157  for ( int col = 0; col < cols; col++ )
158  {
159  float32Row[col] = static_cast<float>( generateRandomDoubleValue( mersenneTwister ) );
160  }
161  block.setData( QByteArray( reinterpret_cast<const char *>( float32Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Float32 ) * cols ) );
162  break;
163  }
165  {
166  std::vector<double> float64Row( cols );
167  for ( int col = 0; col < cols; col++ )
168  {
169  float64Row[col] = generateRandomDoubleValue( mersenneTwister );
170  }
171  block.setData( QByteArray( reinterpret_cast<const char *>( float64Row.data() ), QgsRasterBlock::typeSize( Qgis::DataType::Float64 ) * cols ) );
172  break;
173  }
174  default:
175  break;
176  }
177  provider->writeBlock( &block, 1, 0, row );
178  feedback->setProgress( row * step );
179  }
180 
181  QVariantMap outputs;
182  outputs.insert( QStringLiteral( "OUTPUT" ), outputFile );
183  return outputs;
184 }
185 
186 //
187 //QgsRandomUniformRasterAlgorithm
188 //
189 QString QgsRandomUniformRasterAlgorithm::name() const
190 {
191  return QStringLiteral( "createrandomuniformrasterlayer" );
192 }
193 
194 QString QgsRandomUniformRasterAlgorithm::displayName() const
195 {
196  return QObject::tr( "Create random raster layer (uniform distribution)" );
197 }
198 
199 QStringList QgsRandomUniformRasterAlgorithm::tags() const
200 {
201  return QObject::tr( "raster,create,random" ).split( ',' );
202 }
203 
204 QString QgsRandomUniformRasterAlgorithm::shortHelpString() const
205 {
206  return QObject::tr( "Generates a raster layer for given extent and cell size "
207  "filled with random values.\n"
208  "By default, the values will range between the minimum and "
209  "maximum value of the specified output raster type. This can "
210  "be overridden by using the advanced parameters for lower and "
211  "upper bound value. If the bounds have the same value or both "
212  "are zero (default) the algorithm will create random values in "
213  "the full value range of the chosen raster data type. "
214  "Choosing bounds outside the acceptable range of the output "
215  "raster type will abort the algorithm." );
216 }
217 
218 QgsRandomUniformRasterAlgorithm *QgsRandomUniformRasterAlgorithm::createInstance() const
219 {
220  return new QgsRandomUniformRasterAlgorithm();
221 }
222 
223 void QgsRandomUniformRasterAlgorithm::addAlgorithmParams()
224 {
225  QStringList rasterDataTypes = QStringList();
226  rasterDataTypes << QStringLiteral( "Byte" )
227  << QStringLiteral( "Integer16" )
228  << QStringLiteral( "Unsigned Integer16" )
229  << QStringLiteral( "Integer32" )
230  << QStringLiteral( "Unsigned Integer32" )
231  << QStringLiteral( "Float32" )
232  << QStringLiteral( "Float64" );
233 
234  std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 5, false );
235  rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
236  addParameter( rasterTypeParameter.release() );
237 
238  std::unique_ptr< QgsProcessingParameterNumber > lowerBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "LOWER_BOUND" ), QStringLiteral( "Lower bound for random number range" ), QgsProcessingParameterNumber::Double, QVariant(), true );
239  lowerBoundParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
240  addParameter( lowerBoundParameter.release() );
241 
242  std::unique_ptr< QgsProcessingParameterNumber > upperBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "UPPER_BOUND" ), QStringLiteral( "Upper bound for random number range" ), QgsProcessingParameterNumber::Double, QVariant(), true );
243  upperBoundParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
244  addParameter( upperBoundParameter.release() );
245 }
246 
247 Qgis::DataType QgsRandomUniformRasterAlgorithm::getRasterDataType( int typeId )
248 {
249  switch ( typeId )
250  {
251  case 0:
252  return Qgis::DataType::Byte;
253  case 1:
254  return Qgis::DataType::Int16;
255  case 2:
256  return Qgis::DataType::UInt16;
257  case 3:
258  return Qgis::DataType::Int32;
259  case 4:
260  return Qgis::DataType::UInt32;
261  case 5:
263  case 6:
265  default:
267  }
268 }
269 
270 bool QgsRandomUniformRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
271 {
272  mRandomUpperBound = parameterAsDouble( parameters, QStringLiteral( "UPPER_BOUND" ), context );
273  mRandomLowerBound = parameterAsDouble( parameters, QStringLiteral( "LOWER_BOUND" ), context );
274 
275  if ( mRandomLowerBound > mRandomUpperBound )
276  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." ) );
277 
278  int typeId = parameterAsInt( parameters, QStringLiteral( "OUTPUT_TYPE" ), context );
279  Qgis::DataType rasterDataType = getRasterDataType( typeId );
280 
281  switch ( rasterDataType )
282  {
284  if ( mRandomLowerBound < std::numeric_limits<quint8>::min() || mRandomUpperBound > std::numeric_limits<quint8>::max() )
285  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" ) ) );
286  if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
287  {
288  //if parameters unset (=both are 0 or equal) --> use the whole value range
289  mRandomUpperBound = std::numeric_limits<quint8>::max();
290  mRandomLowerBound = std::numeric_limits<quint8>::min();
291  }
292  break;
294  if ( mRandomLowerBound < std::numeric_limits<qint16>::min() || mRandomUpperBound > std::numeric_limits<qint16>::max() )
295  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" ) ) );
296  if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
297  {
298  mRandomUpperBound = std::numeric_limits<qint16>::max();
299  mRandomLowerBound = std::numeric_limits<qint16>::min();
300  }
301  break;
303  if ( mRandomLowerBound < std::numeric_limits<quint16>::min() || mRandomUpperBound > std::numeric_limits<quint16>::max() )
304  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" ) ) );
305  if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
306  {
307  mRandomUpperBound = std::numeric_limits<quint16>::max();
308  mRandomLowerBound = std::numeric_limits<quint16>::min();
309  }
310  break;
312  if ( mRandomLowerBound < std::numeric_limits<qint32>::min() || mRandomUpperBound > std::numeric_limits<qint32>::max() )
313  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" ) ) );
314  if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
315  {
316  mRandomUpperBound = std::numeric_limits<qint32>::max();
317  mRandomLowerBound = std::numeric_limits<qint32>::min();
318  }
319  break;
321  if ( mRandomLowerBound < std::numeric_limits<quint32>::min() || mRandomUpperBound > std::numeric_limits<quint32>::max() )
322  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" ) ) );
323  if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
324  {
325  mRandomUpperBound = std::numeric_limits<quint32>::max();
326  mRandomLowerBound = std::numeric_limits<quint32>::min();
327  }
328  break;
330  if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
331  {
332  mRandomUpperBound = std::numeric_limits<float>::max();
333  mRandomLowerBound = std::numeric_limits<float>::min();
334  }
335  break;
337  if ( ( qgsDoubleNear( mRandomLowerBound, 0.0 ) && qgsDoubleNear( mRandomUpperBound, 0.0 ) ) || qgsDoubleNear( mRandomUpperBound, mRandomLowerBound ) )
338  {
339  mRandomUpperBound = std::numeric_limits<double>::max();
340  mRandomLowerBound = std::numeric_limits<double>::min();
341  }
342  break;
343  default:
344  break;
345  }
346 
347  mRandomUniformIntDistribution = std::uniform_int_distribution<long>( mRandomLowerBound, mRandomUpperBound );
348  mRandomUniformDoubleDistribution = std::uniform_real_distribution<double>( mRandomLowerBound, mRandomUpperBound );
349 
350  return true;
351 }
352 
353 long QgsRandomUniformRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
354 {
355  return mRandomUniformIntDistribution( mersenneTwister );
356 }
357 
358 double QgsRandomUniformRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
359 {
360  return mRandomUniformDoubleDistribution( mersenneTwister );
361 }
362 
363 //
364 // QgsRandomBinomialRasterAlgorithm
365 //
366 QString QgsRandomBinomialRasterAlgorithm::name() const
367 {
368  return QStringLiteral( "createrandombinomialrasterlayer" );
369 }
370 
371 QString QgsRandomBinomialRasterAlgorithm::displayName() const
372 {
373  return QObject::tr( "Create random raster layer (binomial distribution)" );
374 }
375 
376 QStringList QgsRandomBinomialRasterAlgorithm::tags() const
377 {
378  return QObject::tr( "raster,create,binomial,random" ).split( ',' );
379 }
380 
381 QString QgsRandomBinomialRasterAlgorithm::shortHelpString() const
382 {
383  return QObject::tr( "Generates a raster layer for given extent and cell size "
384  "filled with binomially distributed random values.\n"
385  "By default, the values will be chosen given an N of 10 and a probability of 0.5. "
386  "This can be overridden by using the advanced parameter for N and probability. "
387  "The raster data type is set to Integer types (Integer16 by default). "
388  "The binomial distribution random values are defined as positive integer numbers. "
389  "A floating point raster will represent a cast of integer values "
390  "to floating point." );
391 }
392 
393 QgsRandomBinomialRasterAlgorithm *QgsRandomBinomialRasterAlgorithm::createInstance() const
394 {
395  return new QgsRandomBinomialRasterAlgorithm();
396 }
397 
398 
399 void QgsRandomBinomialRasterAlgorithm::addAlgorithmParams( )
400 {
401  QStringList rasterDataTypes = QStringList();
402  rasterDataTypes << QStringLiteral( "Integer16" )
403  << QStringLiteral( "Unsigned Integer16" )
404  << QStringLiteral( "Integer32" )
405  << QStringLiteral( "Unsigned Integer32" )
406  << QStringLiteral( "Float32" )
407  << QStringLiteral( "Float64" );
408 
409  std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
410  rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
411  addParameter( rasterTypeParameter.release() );
412 
413  std::unique_ptr< QgsProcessingParameterNumber > nParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "N" ), QStringLiteral( "N" ), QgsProcessingParameterNumber::Integer, 10, true, 0 );
414  nParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
415  addParameter( nParameter.release() );
416 
417  std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), QgsProcessingParameterNumber::Double, 0.5, true, 0 );
418  probabilityParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
419  addParameter( probabilityParameter.release() );
420 }
421 
422 Qgis::DataType QgsRandomBinomialRasterAlgorithm::getRasterDataType( int typeId )
423 {
424  switch ( typeId )
425  {
426  case 0:
427  return Qgis::DataType::Int16;
428  case 1:
429  return Qgis::DataType::UInt16;
430  case 2:
431  return Qgis::DataType::Int32;
432  case 3:
433  return Qgis::DataType::UInt32;
434  case 4:
436  case 5:
438  default:
440  }
441 }
442 
443 bool QgsRandomBinomialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
444 {
445  int n = parameterAsInt( parameters, QStringLiteral( "N" ), context );
446  double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
447  mRandombinomialDistribution = std::binomial_distribution<long>( n, probability );
448  return true;
449 }
450 
451 long QgsRandomBinomialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
452 {
453  return mRandombinomialDistribution( mersenneTwister );
454 }
455 
456 double QgsRandomBinomialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
457 {
458  return static_cast<double>( mRandombinomialDistribution( mersenneTwister ) );
459 }
460 
461 //
462 // QgsRandomExponentialRasterAlgorithm
463 //
464 QString QgsRandomExponentialRasterAlgorithm::name() const
465 {
466  return QStringLiteral( "createrandomexponentialrasterlayer" );
467 }
468 
469 QString QgsRandomExponentialRasterAlgorithm::displayName() const
470 {
471  return QObject::tr( "Create random raster layer (exponential distribution)" );
472 }
473 
474 QStringList QgsRandomExponentialRasterAlgorithm::tags() const
475 {
476  return QObject::tr( "raster,create,random,exponential" ).split( ',' );
477 }
478 
479 QString QgsRandomExponentialRasterAlgorithm::shortHelpString() const
480 {
481  return QObject::tr( "Generates a raster layer for given extent and cell size "
482  "filled with exponentially distributed random values.\n"
483  "By default, the values will be chosen given a lambda of 1.0. "
484  "This can be overridden by using the advanced parameter for lambda. "
485  "The raster data type is set to Float32 by default as "
486  "the exponential distribution random values are floating point numbers." );
487 }
488 
489 QgsRandomExponentialRasterAlgorithm *QgsRandomExponentialRasterAlgorithm::createInstance() const
490 {
491  return new QgsRandomExponentialRasterAlgorithm();
492 }
493 
494 
495 void QgsRandomExponentialRasterAlgorithm::addAlgorithmParams()
496 {
497  QStringList rasterDataTypes = QStringList();
498  rasterDataTypes << QStringLiteral( "Float32" )
499  << QStringLiteral( "Float64" );
500 
501  std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
502  rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
503  addParameter( rasterTypeParameter.release() );
504 
505  std::unique_ptr< QgsProcessingParameterNumber > lambdaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "LAMBDA" ), QStringLiteral( "Lambda" ), QgsProcessingParameterNumber::Double, 1.0, true, 0.000001 );
506  lambdaParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
507  addParameter( lambdaParameter.release() );
508 }
509 
510 Qgis::DataType QgsRandomExponentialRasterAlgorithm::getRasterDataType( int typeId )
511 {
512  switch ( typeId )
513  {
514  case 0:
516  case 1:
518  default:
520  }
521 }
522 
523 bool QgsRandomExponentialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
524 {
525  double lambda = parameterAsDouble( parameters, QStringLiteral( "LAMBDA" ), context );
526  mRandomExponentialDistribution = std::exponential_distribution<double>( lambda );
527  return true;
528 }
529 
530 long QgsRandomExponentialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
531 {
532  return static_cast<long>( mRandomExponentialDistribution( mersenneTwister ) );
533 }
534 
535 double QgsRandomExponentialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
536 {
537  return mRandomExponentialDistribution( mersenneTwister );
538 }
539 
540 //
541 // QgsRandomGammaRasterAlgorithm
542 //
543 QString QgsRandomGammaRasterAlgorithm::name() const
544 {
545  return QStringLiteral( "createrandomgammarasterlayer" );
546 }
547 
548 QString QgsRandomGammaRasterAlgorithm::displayName() const
549 {
550  return QObject::tr( "Create random raster layer (gamma distribution)" );
551 }
552 
553 QStringList QgsRandomGammaRasterAlgorithm::tags() const
554 {
555  return QObject::tr( "raster,create,random,gamma" ).split( ',' );
556 }
557 
558 QString QgsRandomGammaRasterAlgorithm::shortHelpString() const
559 {
560  return QObject::tr( "Generates a raster layer for given extent and cell size "
561  "filled with gamma distributed random values.\n"
562  "By default, the values will be chosen given an alpha and beta value of 1.0. "
563  "This can be overridden by using the advanced parameter for alpha and beta. "
564  "The raster data type is set to Float32 by default as "
565  "the gamma distribution random values are floating point numbers." );
566 }
567 
568 QgsRandomGammaRasterAlgorithm *QgsRandomGammaRasterAlgorithm::createInstance() const
569 {
570  return new QgsRandomGammaRasterAlgorithm();
571 }
572 
573 
574 void QgsRandomGammaRasterAlgorithm::addAlgorithmParams()
575 {
576  QStringList rasterDataTypes = QStringList();
577  rasterDataTypes << QStringLiteral( "Float32" )
578  << QStringLiteral( "Float64" );
579 
580  std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
581  rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
582  addParameter( rasterTypeParameter.release() );
583 
584  std::unique_ptr< QgsProcessingParameterNumber > alphaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "ALPHA" ), QStringLiteral( "Alpha" ), QgsProcessingParameterNumber::Double, 1.0, true, 0.000001 );
585  alphaParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
586  addParameter( alphaParameter.release() );
587 
588  std::unique_ptr< QgsProcessingParameterNumber > betaParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "BETA" ), QStringLiteral( "Beta" ), QgsProcessingParameterNumber::Double, 1.0, true, 0.000001 );
589  betaParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
590  addParameter( betaParameter.release() );
591 }
592 
593 Qgis::DataType QgsRandomGammaRasterAlgorithm::getRasterDataType( int typeId )
594 {
595  switch ( typeId )
596  {
597  case 0:
599  case 1:
601  default:
603  }
604 }
605 
606 bool QgsRandomGammaRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
607 {
608  double alpha = parameterAsDouble( parameters, QStringLiteral( "ALPHA" ), context );
609  double beta = parameterAsDouble( parameters, QStringLiteral( "BETA" ), context );
610  mRandomGammaDistribution = std::gamma_distribution<double>( alpha, beta );
611  return true;
612 }
613 
614 long QgsRandomGammaRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
615 {
616  return static_cast<long>( mRandomGammaDistribution( mersenneTwister ) );
617 }
618 
619 double QgsRandomGammaRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
620 {
621  return mRandomGammaDistribution( mersenneTwister );
622 }
623 
624 //
625 // QgsRandomGeometricRasterAlgorithm
626 //
627 QString QgsRandomGeometricRasterAlgorithm::name() const
628 {
629  return QStringLiteral( "createrandomgeometricrasterlayer" );
630 }
631 
632 QString QgsRandomGeometricRasterAlgorithm::displayName() const
633 {
634  return QObject::tr( "Create random raster layer (geometric distribution)" );
635 }
636 
637 QStringList QgsRandomGeometricRasterAlgorithm::tags() const
638 {
639  return QObject::tr( "raster,create,random,geometric" ).split( ',' );
640 }
641 
642 QString QgsRandomGeometricRasterAlgorithm::shortHelpString() const
643 {
644  return QObject::tr( "Generates a raster layer for given extent and cell size "
645  "filled with geometrically distributed random values.\n"
646  "By default, the values will be chosen given a probability of 0.5. "
647  "This can be overridden by using the advanced parameter for mean "
648  "value. The raster data type is set to Integer types (Integer16 by default). "
649  "The geometric distribution random values are defined as positive integer numbers. "
650  "A floating point raster will represent a cast of "
651  "integer values to floating point." );
652 }
653 
654 QgsRandomGeometricRasterAlgorithm *QgsRandomGeometricRasterAlgorithm::createInstance() const
655 {
656  return new QgsRandomGeometricRasterAlgorithm();
657 }
658 
659 
660 void QgsRandomGeometricRasterAlgorithm::addAlgorithmParams()
661 {
662  QStringList rasterDataTypes = QStringList();
663  rasterDataTypes << QStringLiteral( "Integer16" )
664  << QStringLiteral( "Unsigned Integer16" )
665  << QStringLiteral( "Integer32" )
666  << QStringLiteral( "Unsigned Integer32" )
667  << QStringLiteral( "Float32" )
668  << QStringLiteral( "Float64" );
669 
670  std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
671  rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
672  addParameter( rasterTypeParameter.release() );
673 
674  std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), QgsProcessingParameterNumber::Double, 0.5, true, 0.00001 );
675  probabilityParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
676  addParameter( probabilityParameter.release() );
677 }
678 
679 Qgis::DataType QgsRandomGeometricRasterAlgorithm::getRasterDataType( int typeId )
680 {
681  switch ( typeId )
682  {
683  case 0:
684  return Qgis::DataType::Int16;
685  case 1:
686  return Qgis::DataType::UInt16;
687  case 2:
688  return Qgis::DataType::Int32;
689  case 3:
690  return Qgis::DataType::UInt32;
691  case 4:
693  case 5:
695  default:
697  }
698 }
699 
700 bool QgsRandomGeometricRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
701 {
702  double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
703  mRandomGeometricDistribution = std::geometric_distribution<long>( probability );
704  return true;
705 }
706 
707 long QgsRandomGeometricRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
708 {
709  return mRandomGeometricDistribution( mersenneTwister );
710 }
711 
712 double QgsRandomGeometricRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
713 {
714  return static_cast<double>( mRandomGeometricDistribution( mersenneTwister ) );
715 }
716 
717 //
718 // QgsRandomNegativeBinomialRasterAlgorithm
719 //
720 QString QgsRandomNegativeBinomialRasterAlgorithm::name() const
721 {
722  return QStringLiteral( "createrandomnegativebinomialrasterlayer" );
723 }
724 
725 QString QgsRandomNegativeBinomialRasterAlgorithm::displayName() const
726 {
727  return QObject::tr( "Create random raster layer (negative binomial distribution)" );
728 }
729 
730 QStringList QgsRandomNegativeBinomialRasterAlgorithm::tags() const
731 {
732  return QObject::tr( "raster,create,random,negative,binomial,negative-binomial" ).split( ',' );
733 }
734 
735 QString QgsRandomNegativeBinomialRasterAlgorithm::shortHelpString() const
736 {
737  return QObject::tr( "Generates a raster layer for given extent and cell size "
738  "filled with negative binomially distributed random values.\n"
739  "By default, the values will be chosen given a distribution parameter k of 10.0 "
740  "and a probability of 0.5. "
741  "This can be overridden by using the advanced parameters for k and probability. "
742  "The raster data type is set to Integer types (Integer 16 by default). "
743  "The negative binomial distribution random values are defined as positive integer numbers. "
744  "A floating point raster will represent a cast of "
745  "integer values to floating point." );
746 }
747 
748 QgsRandomNegativeBinomialRasterAlgorithm *QgsRandomNegativeBinomialRasterAlgorithm::createInstance() const
749 {
750  return new QgsRandomNegativeBinomialRasterAlgorithm();
751 }
752 
753 
754 void QgsRandomNegativeBinomialRasterAlgorithm::addAlgorithmParams( )
755 {
756  QStringList rasterDataTypes = QStringList();
757  rasterDataTypes << QStringLiteral( "Integer16" )
758  << QStringLiteral( "Unsigned Integer16" )
759  << QStringLiteral( "Integer32" )
760  << QStringLiteral( "Unsigned Integer32" )
761  << QStringLiteral( "Float32" )
762  << QStringLiteral( "Float64" );
763 
764  std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
765  rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
766  addParameter( rasterTypeParameter.release() );
767 
768  std::unique_ptr< QgsProcessingParameterNumber > kParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "K_PARAMETER" ), QStringLiteral( "Distribution parameter k" ), QgsProcessingParameterNumber::Integer, 10, true, 0.00001 );
769  kParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
770  addParameter( kParameter.release() );
771 
772  std::unique_ptr< QgsProcessingParameterNumber > probabilityParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "PROBABILITY" ), QStringLiteral( "Probability" ), QgsProcessingParameterNumber::Double, 0.5, true, 0.00001 );
773  probabilityParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
774  addParameter( probabilityParameter.release() );
775 }
776 
777 Qgis::DataType QgsRandomNegativeBinomialRasterAlgorithm::getRasterDataType( int typeId )
778 {
779  switch ( typeId )
780  {
781  case 0:
782  return Qgis::DataType::Int16;
783  case 1:
784  return Qgis::DataType::UInt16;
785  case 2:
786  return Qgis::DataType::Int32;
787  case 3:
788  return Qgis::DataType::UInt32;
789  case 4:
791  case 5:
793  default:
795  }
796 }
797 
798 bool QgsRandomNegativeBinomialRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
799 {
800  int k = parameterAsInt( parameters, QStringLiteral( "K_PARAMETER" ), context );
801  double probability = parameterAsDouble( parameters, QStringLiteral( "PROBABILITY" ), context );
802  mRandomNegativeBinomialDistribution = std::negative_binomial_distribution<long>( k, probability );
803  return true;
804 }
805 
806 long QgsRandomNegativeBinomialRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
807 {
808  return mRandomNegativeBinomialDistribution( mersenneTwister );
809 }
810 
811 double QgsRandomNegativeBinomialRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
812 {
813  return static_cast<double>( mRandomNegativeBinomialDistribution( mersenneTwister ) );
814 }
815 
816 //
817 // QgsRandomNormalRasterAlgorithm
818 //
819 QString QgsRandomNormalRasterAlgorithm::name() const
820 {
821  return QStringLiteral( "createrandomnormalrasterlayer" );
822 }
823 
824 QString QgsRandomNormalRasterAlgorithm::displayName() const
825 {
826  return QObject::tr( "Create random raster layer (normal distribution)" );
827 }
828 
829 QStringList QgsRandomNormalRasterAlgorithm::tags() const
830 {
831  return QObject::tr( "raster,create,normal,distribution,random" ).split( ',' );
832 }
833 
834 QString QgsRandomNormalRasterAlgorithm::shortHelpString() const
835 {
836  return QObject::tr( "Generates a raster layer for given extent and cell size "
837  "filled with normally distributed random values.\n"
838  "By default, the values will be chosen given a mean of 0.0 and "
839  "a standard deviation of 1.0. This can be overridden by "
840  "using the advanced parameters for mean and standard deviation "
841  "value. The raster data type is set to Float32 by default "
842  "as the normal distribution random values are floating point numbers." );
843 }
844 
845 QgsRandomNormalRasterAlgorithm *QgsRandomNormalRasterAlgorithm::createInstance() const
846 {
847  return new QgsRandomNormalRasterAlgorithm();
848 }
849 
850 void QgsRandomNormalRasterAlgorithm::addAlgorithmParams()
851 {
852  QStringList rasterDataTypes = QStringList();
853  rasterDataTypes << QStringLiteral( "Float32" )
854  << QStringLiteral( "Float64" );
855 
856  std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
857  rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
858  addParameter( rasterTypeParameter.release() );
859 
860  std::unique_ptr< QgsProcessingParameterNumber > meanParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MEAN" ), QStringLiteral( "Mean of normal distribution" ), QgsProcessingParameterNumber::Double, 0, true );
861  meanParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
862  addParameter( meanParameter.release() );
863 
864  std::unique_ptr< QgsProcessingParameterNumber > stdevParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "STDDEV" ), QStringLiteral( "Standard deviation of normal distribution" ), QgsProcessingParameterNumber::Double, 1, true, 0 );
865  stdevParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
866  addParameter( stdevParameter.release() );
867 }
868 
869 Qgis::DataType QgsRandomNormalRasterAlgorithm::getRasterDataType( int typeId )
870 {
871  switch ( typeId )
872  {
873  case 0:
875  case 1:
877  default:
879  }
880 }
881 
882 bool QgsRandomNormalRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
883 {
884  double mean = parameterAsDouble( parameters, QStringLiteral( "MEAN" ), context );
885  double stddev = parameterAsDouble( parameters, QStringLiteral( "STDDEV" ), context );
886  mRandomNormalDistribution = std::normal_distribution<double>( mean, stddev );
887  return true;
888 }
889 
890 long QgsRandomNormalRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
891 {
892  return static_cast<long>( mRandomNormalDistribution( mersenneTwister ) );
893 }
894 
895 double QgsRandomNormalRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
896 {
897  return mRandomNormalDistribution( mersenneTwister );
898 }
899 
900 //
901 // QgsRandomPoissonRasterAlgorithm
902 //
903 QString QgsRandomPoissonRasterAlgorithm::name() const
904 {
905  return QStringLiteral( "createrandompoissonrasterlayer" );
906 }
907 
908 QString QgsRandomPoissonRasterAlgorithm::displayName() const
909 {
910  return QObject::tr( "Create random raster layer (poisson distribution)" );
911 }
912 
913 QStringList QgsRandomPoissonRasterAlgorithm::tags() const
914 {
915  return QObject::tr( "raster,create,random,poisson" ).split( ',' );
916 }
917 
918 QString QgsRandomPoissonRasterAlgorithm::shortHelpString() const
919 {
920  return QObject::tr( "Generates a raster layer for given extent and cell size "
921  "filled with poisson distributed random values.\n"
922  "By default, the values will be chosen given a mean of 1.0. "
923  "This can be overridden by using the advanced parameter for mean "
924  "value. The raster data type is set to Integer types (Integer16 by default). "
925  "The poisson distribution random values are positive integer numbers. "
926  "A floating point raster will represent a cast of integer values to floating point." );
927 }
928 
929 QgsRandomPoissonRasterAlgorithm *QgsRandomPoissonRasterAlgorithm::createInstance() const
930 {
931  return new QgsRandomPoissonRasterAlgorithm();
932 }
933 
934 
935 void QgsRandomPoissonRasterAlgorithm::addAlgorithmParams()
936 {
937  QStringList rasterDataTypes = QStringList();
938  rasterDataTypes << QStringLiteral( "Integer16" )
939  << QStringLiteral( "Unsigned Integer16" )
940  << QStringLiteral( "Integer32" )
941  << QStringLiteral( "Unsigned Integer32" )
942  << QStringLiteral( "Float32" )
943  << QStringLiteral( "Float64" );
944 
945  std::unique_ptr< QgsProcessingParameterDefinition > rasterTypeParameter = std::make_unique< QgsProcessingParameterEnum >( QStringLiteral( "OUTPUT_TYPE" ), QObject::tr( "Output raster data type" ), rasterDataTypes, false, 0, false );
946  rasterTypeParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
947  addParameter( rasterTypeParameter.release() );
948 
949  std::unique_ptr< QgsProcessingParameterNumber > upperBoundParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "MEAN" ), QStringLiteral( "Mean" ), QgsProcessingParameterNumber::Double, 1.0, true, 0 );
950  upperBoundParameter->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
951  addParameter( upperBoundParameter.release() );
952 }
953 
954 Qgis::DataType QgsRandomPoissonRasterAlgorithm::getRasterDataType( int typeId )
955 {
956  switch ( typeId )
957  {
958  case 0:
959  return Qgis::DataType::Int16;
960  case 1:
961  return Qgis::DataType::UInt16;
962  case 2:
963  return Qgis::DataType::Int32;
964  case 3:
965  return Qgis::DataType::UInt32;
966  case 4:
968  case 5:
970  default:
972  }
973 }
974 
975 bool QgsRandomPoissonRasterAlgorithm::prepareRandomParameters( const QVariantMap &parameters, QgsProcessingContext &context )
976 {
977  double mean = parameterAsDouble( parameters, QStringLiteral( "MEAN" ), context );
978  mRandomPoissonDistribution = std::poisson_distribution<long>( mean );
979  return true;
980 }
981 
982 long QgsRandomPoissonRasterAlgorithm::generateRandomLongValue( std::mt19937 &mersenneTwister )
983 {
984  return mRandomPoissonDistribution( mersenneTwister );
985 }
986 
987 double QgsRandomPoissonRasterAlgorithm::generateRandomDoubleValue( std::mt19937 &mersenneTwister )
988 {
989  return static_cast<double>( mRandomPoissonDistribution( mersenneTwister ) );
990 }
991 
DataType
Raster data types.
Definition: qgis.h:119
@ Float32
Thirty two bit floating point (float)
@ Int16
Sixteen bit signed integer (qint16)
@ UInt16
Sixteen bit unsigned integer (quint16)
@ Byte
Eight bit unsigned integer (quint8)
@ Int32
Thirty two bit signed integer (qint32)
@ Float64
Sixty four bit floating point (double)
@ 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:598