QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 }
29 
31 {
32  QgsDebugMsgLevel( "Entered", 4 );
33  QgsRasterNuller * nuller = new QgsRasterNuller( nullptr );
34  nuller->mNoData = mNoData;
35  nuller->mOutputNoData = mOutputNoData;
36  nuller->mHasOutputNoData = mHasOutputNoData;
37  return nuller;
38 }
39 
41 {
42  if ( bandNo > mOutputNoData.size() )
43  {
44  mOutputNoData.resize( bandNo );
45  mHasOutputNoData.resize( bandNo );
46  }
47  mOutputNoData[bandNo-1] = noData;
48  mHasOutputNoData[bandNo-1] = true;
49 }
50 
52 {
53  if ( bandNo > mNoData.size() )
54  {
55  mNoData.resize( bandNo );
56  }
57  mNoData[bandNo-1] = noData;
58 }
59 
61 {
62  if ( mInput ) return mInput->bandCount();
63  return 0;
64 }
65 
67 {
68  if ( mInput ) return mInput->dataType( bandNo );
69  return QGis::UnknownDataType;
70 }
71 
72 QgsRasterBlock * QgsRasterNuller::block( int bandNo, QgsRectangle const & extent, int width, int height )
73 {
74  return block2( bandNo, extent, width, height );
75 }
76 
77 QgsRasterBlock * QgsRasterNuller::block2( int bandNo, QgsRectangle const & extent, int width, int height, QgsRasterBlockFeedback* feedback )
78 {
79  QgsDebugMsgLevel( "Entered", 4 );
80  if ( !mInput )
81  {
82  return new QgsRasterBlock();
83  }
84 
85  QgsRasterBlock *inputBlock = mInput->block2( bandNo, extent, width, height, feedback );
86  if ( !inputBlock )
87  {
88  return new QgsRasterBlock();
89  }
90 
91  // We don't support nuller for color types
92  if ( QgsRasterBlock::typeIsColor( inputBlock->dataType() ) )
93  {
94  return inputBlock;
95  }
96 
97  QgsRasterBlock *outputBlock = nullptr;
98 
99  if ( mHasOutputNoData.value( bandNo - 1 ) || inputBlock->hasNoDataValue() )
100  {
101  double noDataValue;
102  if ( mHasOutputNoData.value( bandNo - 1 ) )
103  {
104  noDataValue = mOutputNoData.value( bandNo - 1 );
105  }
106  else
107  {
108  noDataValue = inputBlock->noDataValue();
109  }
110  outputBlock = new QgsRasterBlock( inputBlock->dataType(), width, height, noDataValue );
111  }
112  else
113  {
114  outputBlock = new QgsRasterBlock( inputBlock->dataType(), width, height );
115  }
116 
117  for ( int i = 0; i < height; i++ )
118  {
119  for ( int j = 0; j < width; j++ )
120  {
121  double value = inputBlock->value( i, j );
122 
123  bool isNoData = inputBlock->isNoData( i, j );
124  if ( QgsRasterRange::contains( value, mNoData.value( bandNo - 1 ) ) )
125  {
126  isNoData = true;
127  }
128  outputBlock->setValue( i, j, inputBlock->value( i, j ) );
129  if ( isNoData )
130  {
131  outputBlock->setIsNoData( i, j );
132  }
133  else
134  {
135  outputBlock->setValue( i, j, value );
136  }
137  }
138  }
139  delete inputBlock;
140 
141  return outputBlock;
142 }
143 
virtual int bandCount() const =0
Get number of bands.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Unknown or unspecified type.
Definition: qgis.h:135
static bool contains(double value, const QgsRasterRangeList &rangeList)
Test if value is within the list of ranges.
bool setValue(int row, int column, double value)
Set value on position.
Raster pipe that deals with null values.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height) override
Read block of data using given extent and size.
QgsRasterBlock * block2(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
bool isNoData(int row, int column)
Check if value at position is no data.
virtual QgsRasterBlock * block2(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)
Read block of data using given extent and size.
T value(int i) const
bool setIsNoData(int row, int column)
Set no data on pixel.
QgsRasterNuller * clone() const override
Clone itself, create deep copy.
void resize(int size)
Raster data container.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:34
static bool typeIsColor(QGis::DataType type)
Returns true if data type is color.
QgsRasterRangeList noData(int bandNo) const
virtual QGis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
Base class for processing filters like renderers, reprojector, resampler etc.
void setOutputNoDataValue(int bandNo, double noData)
Set output no data value.
void setNoData(int bandNo, const QgsRasterRangeList &noData)
virtual QgsRectangle extent()
Get the extent of the interface.
QGis::DataType dataType() const
Returns data type.
QgsRasterNuller(QgsRasterInterface *input=nullptr)
DataType
Raster data types.
Definition: qgis.h:133
double value(int row, int column) const
Read a single value if type of block is numeric.
bool hasNoDataValue() const
True if the block has no data value.
QGis::DataType dataType(int bandNo) const override
Returns data type for the band specified by number.
QgsRasterInterface * mInput
int size() const
double noDataValue() const
Return no data value.
Feedback object tailored for raster block reading.
int bandCount() const override
Get number of bands.