QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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:79
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:81
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.