pktools  2.6.7
Processing Kernel for geospatial data
ImgReaderGdal.h
1 /**********************************************************************
2 ImgReaderGdal.h: class to read raster files using GDAL API library
3 Copyright (C) 2008-2016 Pieter Kempeneers
4 
5 This file is part of pktools
6 
7 pktools is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 pktools is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with pktools. If not, see <http://www.gnu.org/licenses/>.
19 ***********************************************************************/
20 #ifndef _IMGREADERGDAL_H_
21 #define _IMGREADERGDAL_H_
22 
23 #include "ImgRasterGdal.h"
24 #include <assert.h>
25 #include <fstream>
26 #include <string>
27 #include <sstream>
28 #include "gdal_priv.h"
29 #include "base/Vector2d.h"
30 
36 class ImgReaderGdal : public virtual ImgRasterGdal
37 {
38 public:
40  ImgReaderGdal(void);
42  ImgReaderGdal(const std::string& filename, const GDALAccess& readMode=GA_ReadOnly){open(filename, readMode);};
44  ~ImgReaderGdal(void);
46  void open(const std::string& filename, const GDALAccess& readMode=GA_ReadOnly);
48 
50  void close(void);
52  template<typename T> void readData(T& value, int col, int row, int band=0);
54  template<typename T> void readData(std::vector<T>& buffer, int minCol, int maxCol, int row, int band=0);
56  template<typename T> void readData(std::vector<T>& buffer, int minCol, int maxCol, double row, int band=0, RESAMPLE resample=NEAR);
58  template<typename T> void readDataBlock(Vector2d<T>& buffer2d, int minCol, int maxCol, int minRow, int maxRow, int band=0);
60  template<typename T> void readDataBlock(std::vector<T>& buffer , int minCol, int maxCol, int minRow, int maxRow, int band=0);
62  template<typename T> void readData(std::vector<T>& buffer, int row, int band=0);
64  template<typename T> void readData(std::vector<T>& buffer, double row, int band=0, RESAMPLE resample=NEAR);
66  void getMinMax(int startCol, int endCol, int startRow, int endRow, int band, double& minValue, double& maxValue);
68  void getMinMax(double& minValue, double& maxValue, int band=0);
70  double getMin(int& col, int& row, int band=0);
72  double getMax(int& col, int& row, int band=0);
74  double getHistogram(std::vector<double>& histvector, double& min, double& max,unsigned int& nbin, int theBand=0, bool kde=false);
76  void getRefPix(double& refX, double &refY, int band=0);
78  void getRange(std::vector<short>& range, int Band=0);
80  unsigned long int getNvalid(int band);
81 
82 protected:
84  void setCodec(const GDALAccess& readMode=GA_ReadOnly);
86 private:
87 };
88 
95 template<typename T> void ImgReaderGdal::readData(T& value, int col, int row, int band)
96 {
97  assert(band<nrOfBand()+1);
98  assert(col<nrOfCol());
99  assert(col>=0);
100  assert(row<nrOfRow());
101  assert(row>=0);
102  double dvalue=0;
103  double theScale=1;
104  double theOffset=0;
105  if(m_scale.size()>band||m_offset.size()>band){
106  if(m_scale.size()>band)
107  theScale=m_scale[band];
108  if(m_offset.size()>band)
109  theOffset=m_offset[band];
110  }
111  //fetch raster band
112  GDALRasterBand *poBand;
113  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
114  poBand->RasterIO(GF_Read,col,row,1,1,&value,1,1,getGDALDataType<T>(),0,0);
115  dvalue=theScale*value+theOffset;
116  value=static_cast<T>(dvalue);
117 }
118 
126 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, int minCol, int maxCol, int row, int band)
127 {
128  assert(band<nrOfBand()+1);
129  assert(minCol<nrOfCol());
130  assert(minCol>=0);
131  assert(maxCol<nrOfCol());
132  assert(minCol<=maxCol);
133  assert(row<nrOfRow());
134  assert(row>=0);
135  double theScale=1;
136  double theOffset=0;
137  if(m_scale.size()>band||m_offset.size()>band){
138  if(m_scale.size()>band)
139  theScale=m_scale[band];
140  if(m_offset.size()>band)
141  theOffset=m_offset[band];
142  }
143  //fetch raster band
144  GDALRasterBand *poBand;
145  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
146  if(buffer.size()!=maxCol-minCol+1)
147  buffer.resize(maxCol-minCol+1);
148  poBand->RasterIO(GF_Read,minCol,row,buffer.size(),1,&(buffer[0]),buffer.size(),1,getGDALDataType<T>(),0,0);
149  if(m_scale.size()>band||m_offset.size()>band){
150  for(int index=0;index<buffer.size();++index)
151  buffer[index]=theScale*static_cast<double>(buffer[index])+theOffset;
152  }
153 }
154 
163 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, int minCol, int maxCol, double row, int band, RESAMPLE resample)
164 {
165  double eps=0.00001;
166  std::vector<T> readBuffer_upper;
167  std::vector<T> readBuffer_lower;
168  double upperRow, lowerRow;
169  if(buffer.size()!=maxCol-minCol+1)
170  buffer.resize(maxCol-minCol+1);
171  /* double upperRow=row-0.5; */
172  /* upperRow=static_cast<int>(upperRow); */
173  /* double lowerRow=row+0.5; */
174  /* lowerRow=static_cast<int>(lowerRow); */
175  switch(resample){
176  case(BILINEAR):
177  /* if(lowerRow>=nrOfRow()) */
178  /* lowerRow=nrOfRow()-1; */
179  upperRow=static_cast<int>(row-0.5+eps);
180  if(upperRow<0)
181  upperRow=0;
182  if(upperRow>=nrOfRow())
183  upperRow=nrOfRow()-1;
184  lowerRow=upperRow+1.0;
185  if(lowerRow>=nrOfRow())
186  lowerRow=nrOfRow()-1;
187 
188  readData(readBuffer_upper,minCol,maxCol,static_cast<int>(upperRow),band);
189  readData(readBuffer_lower,minCol,maxCol,static_cast<int>(lowerRow),band);
190  //do interpolation in y
191  for(int icol=0;icol<maxCol-minCol+1;++icol){
192  /* buffer[icol]=(lowerRow-row+0.5)*readBuffer_upper[icol]+(1-lowerRow+row-0.5)*readBuffer_lower[icol]; */
193  if(!isNoData(readBuffer_upper[icol])){
194  if(!isNoData(readBuffer_lower[icol])){
195  buffer[icol]=(lowerRow-row+0.5)*readBuffer_upper[icol]+(1-lowerRow+row-0.5)*readBuffer_lower[icol];
196  }
197  else{
198  buffer[icol]=readBuffer_upper[icol];
199  }
200  }
201  else{
202  buffer[icol]=readBuffer_lower[icol];
203  }
204  }
205  break;
206  default:
207  readData(buffer,minCol,maxCol,static_cast<int>(row),band);
208  break;
209  }
210 }
211 
220 template<typename T> void ImgReaderGdal::readDataBlock(Vector2d<T>& buffer2d, int minCol, int maxCol, int minRow, int maxRow, int band)
221 {
222  buffer2d.resize(maxRow-minRow+1);
223  typename std::vector<T> buffer;
224  readDataBlock(buffer,minCol,maxCol,minRow,maxRow,band);
225  typename std::vector<T>::const_iterator startit=buffer.begin();
226  typename std::vector<T>::const_iterator endit=startit;
227  for(int irow=minRow;irow<=maxRow;++irow){
228  buffer2d[irow-minRow].resize(maxCol-minCol+1);
229  endit+=maxCol-minCol+1;
230  buffer2d[irow-minRow].assign(startit,endit);
231  startit+=maxCol-minCol+1;
232  }
233 }
234 
243 template<typename T> void ImgReaderGdal::readDataBlock(std::vector<T>& buffer, int minCol, int maxCol, int minRow, int maxRow, int band)
244 {
245  double theScale=1;
246  double theOffset=0;
247  if(m_scale.size()>band)
248  theScale=m_scale[band];
249  if(m_offset.size()>band)
250  theOffset=m_offset[band];
251  if(minCol>=nrOfCol() ||
252  (minCol<0) ||
253  (maxCol>=nrOfCol()) ||
254  (minCol>maxCol) ||
255  (minRow>=nrOfRow()) ||
256  (minRow<0) ||
257  (maxRow>=nrOfRow()) ||
258  (minRow>maxRow)){
259  std::string errorString="block not within image boundaries";
260  throw(errorString);
261  }
262  if(buffer.size()!=(maxRow-minRow+1)*(maxCol-minCol+1))
263  buffer.resize((maxRow-minRow+1)*(maxCol-minCol+1));
264  //fetch raster band
265  GDALRasterBand *poBand;
266  assert(band<nrOfBand()+1);
267  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
268  poBand->RasterIO(GF_Read,minCol,minRow,maxCol-minCol+1,maxRow-minRow+1,&(buffer[0]),(maxCol-minCol+1),(maxRow-minRow+1),getGDALDataType<T>(),0,0);
269  if(m_scale.size()>band||m_offset.size()>band){
270  for(int index=0;index<buffer.size();++index)
271  buffer[index]=theScale*buffer[index]+theOffset;
272  }
273 }
274 
280 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, int row, int band)
281 {
282  readData(buffer,0,nrOfCol()-1,row,band);
283 }
284 
291 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, double row, int band, RESAMPLE resample)
292 {
293  readData(buffer,0,nrOfCol()-1,row,band,resample);
294 }
295 
296 #endif // _IMGREADERGDAL_H_
~ImgReaderGdal(void)
destructor
double getMin(int &col, int &row, int band=0)
Get the minimum cell values for a specific band and report the column and row in which the minimum va...
unsigned long int getNvalid(int band)
Calculate the number of valid pixels (with a value not defined as no data).
bool isNoData(double value) const
Check if value is nodata in this dataset.
ImgReaderGdal(const std::string &filename, const GDALAccess &readMode=GA_ReadOnly)
constructor opening an image. Set memory (in MB) to cache a number of rows in memory ...
Definition: ImgReaderGdal.h:42
double getHistogram(std::vector< double > &histvector, double &min, double &max, unsigned int &nbin, int theBand=0, bool kde=false)
Calculate the image histogram for a specific band using a defined number of bins and constrained by a...
void close(void)
Set the memory (in MB) to cache a number of rows in memory.
int nrOfCol(void) const
Get the number of columns of this dataset.
Definition: ImgRasterGdal.h:98
GDALDataset * m_gds
instance of the GDAL dataset of this dataset
void readData(T &value, int col, int row, int band=0)
Read a single pixel cell value at a specific column and row for a specific band (all indices start co...
Definition: ImgReaderGdal.h:95
int nrOfRow(void) const
Get the number of rows of this dataset.
void getRange(std::vector< short > &range, int Band=0)
Calculate the range of cell values in the image for a specific band (start counting from 0)...
void setCodec(const GDALAccess &readMode=GA_ReadOnly)
Set GDAL dataset number of columns, rows, bands and geotransform.
std::vector< double > m_scale
Vector containing the scale factor to be applied (one scale value for each band)
void getMinMax(int startCol, int endCol, int startRow, int endRow, int band, double &minValue, double &maxValue)
Get the minimum and maximum cell values for a specific band in a region of interest defined by startC...
ImgReaderGdal(void)
default constructor. Image needs to be opened later with one of the open methods. ...
double getMax(int &col, int &row, int band=0)
Get the maximum cell values for a specific band and report the column and row in which the maximum va...
void getRefPix(double &refX, double &refY, int band=0)
Calculate the reference pixel as the centre of gravity pixel (weighted average of all values not taki...
void readDataBlock(Vector2d< T > &buffer2d, int minCol, int maxCol, int minRow, int maxRow, int band=0)
Read pixel cell values for a range of columns and rows for a specific band (all indices start countin...
void open(const std::string &filename, const GDALAccess &readMode=GA_ReadOnly)
Open an image.
int nrOfBand(void) const
Get the number of bands of this dataset.
std::vector< double > m_offset
Vector containing the offset factor to be applied (one offset value for each band) ...