QGIS API Documentation  3.13.0-Master (b73bd58cfb)
qgsrasternuller.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasternuller.cpp
3  ---------------------
4  begin : August 2012
5  copyright : (C) 2012 by Radim Blazek
6  email : radim dot blazek 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 
18 #include "qgsrasterdataprovider.h"
19 #include "qgsrasternuller.h"
20 
22  : QgsRasterInterface( input )
23 {
24 }
25 
27 {
28  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );
29  QgsRasterNuller *nuller = new QgsRasterNuller( nullptr );
30  nuller->mNoData = mNoData;
31  nuller->mOutputNoData = mOutputNoData;
32  nuller->mHasOutputNoData = mHasOutputNoData;
33  return nuller;
34 }
35 
37 {
38  if ( bandNo > mOutputNoData.size() )
39  {
40  mOutputNoData.resize( bandNo );
41  mHasOutputNoData.resize( bandNo );
42  }
43  mOutputNoData[bandNo - 1] = noData;
44  mHasOutputNoData[bandNo - 1] = true;
45 }
46 
48 {
49  if ( bandNo > mNoData.size() )
50  {
51  mNoData.resize( bandNo );
52  }
53  mNoData[bandNo - 1] = noData;
54 }
55 
57 {
58  if ( mInput ) return mInput->bandCount();
59  return 0;
60 }
61 
63 {
64  if ( mInput ) return mInput->dataType( bandNo );
65  return Qgis::UnknownDataType;
66 }
67 
68 QgsRasterBlock *QgsRasterNuller::block( int bandNo, QgsRectangle const &extent, int width, int height, QgsRasterBlockFeedback *feedback )
69 {
70  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );
71  if ( !mInput )
72  {
73  return new QgsRasterBlock();
74  }
75 
76  std::unique_ptr< QgsRasterBlock > inputBlock( mInput->block( bandNo, extent, width, height, feedback ) );
77  if ( !inputBlock )
78  {
79  return new QgsRasterBlock();
80  }
81 
82  // We don't support nuller for color types
83  if ( QgsRasterBlock::typeIsColor( inputBlock->dataType() ) )
84  {
85  return inputBlock.release();
86  }
87 
88  std::unique_ptr< QgsRasterBlock > outputBlock( new QgsRasterBlock( inputBlock->dataType(), width, height ) );
89  if ( mHasOutputNoData.value( bandNo - 1 ) || inputBlock->hasNoDataValue() )
90  {
91  double noDataValue;
92  if ( mHasOutputNoData.value( bandNo - 1 ) )
93  {
94  noDataValue = mOutputNoData.value( bandNo - 1 );
95  }
96  else
97  {
98  noDataValue = inputBlock->noDataValue();
99  }
100  outputBlock->setNoDataValue( noDataValue );
101  }
102 
103  bool isNoData = false;
104  for ( int i = 0; i < height; i++ )
105  {
106  for ( int j = 0; j < width; j++ )
107  {
108  double value = inputBlock->valueAndNoData( i, j, isNoData );
109 
110  if ( QgsRasterRange::contains( value, mNoData.value( bandNo - 1 ) ) )
111  {
112  isNoData = true;
113  }
114  outputBlock->setValue( i, j, inputBlock->value( i, j ) );
115  if ( isNoData )
116  {
117  outputBlock->setIsNoData( i, j );
118  }
119  else
120  {
121  outputBlock->setValue( i, j, value );
122  }
123  }
124  }
125  return outputBlock.release();
126 }
127 
virtual int bandCount() const =0
Gets number of bands.
A rectangle specified with double values.
Definition: qgsrectangle.h:41
bool contains(double value) const
Returns true if this range contains the specified value.
virtual QgsRectangle extent() const
Gets the extent of the interface.
static bool typeIsColor(Qgis::DataType type)
Returns true if data type is color.
Raster pipe that deals with null values.
DataType
Raster data types.
Definition: qgis.h:101
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
Qgis::DataType dataType(int bandNo) const override
Returns data type for the band specified by number.
QgsRasterNuller * clone() const override
Clone itself, create deep copy.
Raster data container.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)=0
Read block of data using given extent and size.
Unknown or unspecified type.
Definition: qgis.h:103
QgsRasterRangeList noData(int bandNo) const
Base class for processing filters like renderers, reprojector, resampler etc.
void setOutputNoDataValue(int bandNo, double noData)
Sets the output no data value.
void setNoData(int bandNo, const QgsRasterRangeList &noData)
QgsRasterNuller(QgsRasterInterface *input=nullptr)
QList< QgsRasterRange > QgsRasterRangeList
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
QgsRasterInterface * mInput
Feedback object tailored for raster block reading.
int bandCount() const override
Gets number of bands.