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.
int nrOfBand(void) const
Get the number of bands of 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 nrOfRow(void) const
Get the number of rows of this dataset.
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
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.
std::vector< double > m_offset
Vector containing the offset factor to be applied (one offset value for each band) ...
int nrOfCol(void) const
Get the number of columns of this dataset.
Definition: ImgRasterGdal.h:98