pktools  2.6.6
Processing Kernel for geospatial data
ImgReaderGdal.h
1 /**********************************************************************
2 ImgReaderGdal.h: class to read raster files using GDAL API library
3 Copyright (C) 2008-2012 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 
31 //--------------------------------------------------------------------------
32 class ImgReaderGdal : public virtual ImgRasterGdal
33 {
34 public:
35  ImgReaderGdal(void);
36  ImgReaderGdal(const std::string& filename, const GDALAccess& readMode=GA_ReadOnly){open(filename, readMode);};
37  ~ImgReaderGdal(void);
38  void open(const std::string& filename, const GDALAccess& readMode=GA_ReadOnly);
39  void close(void);
40 
41  void setScale(double theScale, int band=0){
42  /* if(getRasterBand(band)->SetScale(theScale)==CE_Failure){ */
43  if(m_scale.size()!=nrOfBand()){//initialize
44  m_scale.resize(nrOfBand());
45  for(int iband=0;iband<nrOfBand();++iband)
46  m_scale[iband]=1.0;
47  }
48  m_scale[band]=theScale;
49  /* }; */
50  }
51  void setOffset(double theOffset, int band=0){
52  /* if(getRasterBand(band)->SetOffset(theOffset)==CE_Failure){ */
53  if(m_offset.size()!=nrOfBand()){
54  m_offset.resize(nrOfBand());
55  for(int iband=0;iband<nrOfBand();++iband)
56  m_offset[iband]=0.0;
57  }
58  m_offset[band]=theOffset;
59  /* }; */
60  }
61  template<typename T> void readData(T& value, const GDALDataType& dataType, int col, int row, int band=0) const;
62  template<typename T> void readData(std::vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int row, int band=0) const;
63  template<typename T> void readData(std::vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, double row, int band=0, RESAMPLE resample=NEAR) const;
64  template<typename T> void readDataBlock(Vector2d<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band=0) const;
65  template<typename T> void readDataBlock(std::vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band=0) const;
66  template<typename T> void readData(std::vector<T>& buffer, const GDALDataType& dataType, int row, int band=0) const;
67  template<typename T> void readData(std::vector<T>& buffer, const GDALDataType& dataType, double row, int band=0, RESAMPLE resample=NEAR) const;
68  void getMinMax(int startCol, int endCol, int startRow, int endRow, int band, double& minValue, double& maxValue) const;
69  void getMinMax(double& minValue, double& maxValue, int band=0) const;
70  double getMin(int& col, int& row, int band=0) const;
71  double getHistogram(std::vector<double>& histvector, double& min, double& max,unsigned int& nbin, int theBand=0, bool kde=false);
72  double getMax(int& col, int& row, int band=0) const;
73  void getRefPix(double& refX, double &refY, int band=0) const;
74  void getRange(std::vector<short>& range, int Band=0) const;
75  unsigned long int getNvalid(int band) const;
76 
77 protected:
78  void setCodec(const GDALAccess& readMode=GA_ReadOnly);
79 
80  std::vector<double> m_scale;
81  std::vector<double> m_offset;
82 };
83 
84 // adfGeoTransform[0] /* top left x */
85 // adfGeoTransform[1] /* w-e pixel resolution */
86 // adfGeoTransform[2] /* rotation, 0 if image is "north up" */
87 // adfGeoTransform[3] /* top left y */
88 // adfGeoTransform[4] /* rotation, 0 if image is "north up" */
89 // adfGeoTransform[5] /* n-s pixel resolution */
90 
91 template<typename T> void ImgReaderGdal::readData(T& value, const GDALDataType& dataType, int col, int row, int band) const
92 {
93  //fetch raster band
94  GDALRasterBand *poBand;
95  assert(band<nrOfBand()+1);
96  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
97  assert(col<nrOfCol());
98  assert(col>=0);
99  assert(row<nrOfRow());
100  assert(row>=0);
101  poBand->RasterIO(GF_Read,col,row,1,1,&value,1,1,dataType,0,0);
102  if(m_scale.size()>band)
103  value=static_cast<double>(value)*m_scale[band];
104  if(m_offset.size()>band)
105  value=static_cast<double>(value)+m_offset[band];
106 }
107 
108 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, const GDALDataType& dataType, int minCol, int maxCol, int row, int band) const
109 {
110  //fetch raster band
111  GDALRasterBand *poBand;
112  assert(band<nrOfBand()+1);
113  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
114  assert(minCol<nrOfCol());
115  assert(minCol>=0);
116  assert(maxCol<nrOfCol());
117  assert(minCol<=maxCol);
118  assert(row<nrOfRow());
119  assert(row>=0);
120  if(buffer.size()!=maxCol-minCol+1)
121  buffer.resize(maxCol-minCol+1);
122  poBand->RasterIO(GF_Read,minCol,row,buffer.size(),1,&(buffer[0]),buffer.size(),1,dataType,0,0);
123  if(m_scale.size()>band||m_offset.size()>band){
124  double theScale=1;
125  double theOffset=0;
126  if(m_scale.size()>band)
127  theScale=m_scale[band];
128  if(m_offset.size()>band)
129  theOffset=m_offset[band];
130  for(int index=0;index<buffer.size();++index)
131  buffer[index]=theScale*static_cast<double>(buffer[index])+theOffset;
132  }
133 }
134 
135 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, double row, int band, RESAMPLE resample) const
136 {
137  //todo: make upper and lower row depend on isGeo...
138  std::vector<T> readBuffer_upper;
139  std::vector<T> readBuffer_lower;
140  if(buffer.size()!=maxCol-minCol+1)
141  buffer.resize(maxCol-minCol+1);
142  double upperRow=row-0.5;
143  upperRow=static_cast<int>(upperRow);
144  double lowerRow=row+0.5;
145  lowerRow=static_cast<int>(lowerRow);
146  switch(resample){
147  case(BILINEAR):
148  if(lowerRow>=nrOfRow())
149  lowerRow=nrOfRow()-1;
150  if(upperRow<0)
151  upperRow=0;
152  readData(readBuffer_upper,GDT_Float64,minCol,maxCol,static_cast<int>(upperRow),band);
153  readData(readBuffer_lower,GDT_Float64,minCol,maxCol,static_cast<int>(lowerRow),band);
154  //do interpolation in y
155  for(int icol=0;icol<maxCol-minCol+1;++icol){
156  buffer[icol]=(lowerRow-row+0.5)*readBuffer_upper[icol]+(1-lowerRow+row-0.5)*readBuffer_lower[icol];
157  }
158  break;
159  default:
160  readData(buffer,GDT_Float64,minCol,maxCol,static_cast<int>(row),band);
161  break;
162  }
163 }
164 
165 template<typename T> void ImgReaderGdal::readDataBlock(Vector2d<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band) const
166 {
167  buffer.resize(maxRow-minRow+1);
168  for(int irow=minRow;irow<=maxRow;++irow){
169  buffer[irow-minRow].resize(maxCol-minCol+1);
170  readData(buffer[irow-minRow],dataType,minCol,maxCol,irow,band);
171  }
172 }
173 
174 template<typename T> void ImgReaderGdal::readDataBlock(std::vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band) const
175 {
176  double theScale=1;
177  double theOffset=0;
178  if(m_scale.size()>band)
179  theScale=m_scale[band];
180  if(m_offset.size()>band)
181  theOffset=m_offset[band];
182  //fetch raster band
183  GDALRasterBand *poBand;
184  assert(band<nrOfBand()+1);
185  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
186  if(minCol>=nrOfCol() ||
187  (minCol<0) ||
188  (maxCol>=nrOfCol()) ||
189  (minCol>maxCol) ||
190  (minRow>=nrOfRow()) ||
191  (minRow<0) ||
192  (maxRow>=nrOfRow()) ||
193  (minRow>maxRow)){
194  std::string errorString="block not within image boundaries";
195  throw(errorString);
196  }
197  /* assert(minCol<nrOfCol()); */
198  /* assert(minCol>=0); */
199  /* assert(maxCol<nrOfCol()); */
200  /* assert(minCol<=maxCol); */
201  /* assert(minRow<nrOfRow()); */
202  /* assert(minRow>=0); */
203  /* assert(maxRow<nrOfRow()); */
204  /* assert(minRow<=maxRow); */
205  if(buffer.size()!=(maxRow-minRow+1)*(maxCol-minCol+1))
206  buffer.resize((maxRow-minRow+1)*(maxCol-minCol+1));
207  poBand->RasterIO(GF_Read,minCol,minRow,maxCol-minCol+1,maxRow-minRow+1,&(buffer[0]),(maxCol-minCol+1),(maxRow-minRow+1),dataType,0,0);
208  if(m_scale.size()>band||m_offset.size()>band){
209  for(int index=0;index<buffer.size();++index)
210  buffer[index]=theScale*buffer[index]+theOffset;
211  }
212 }
213 
214 // template<typename T> void ImgReaderGdal::readDataBlock(vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band) const
215 // {
216 // assert(band<nrOfBand()+1);
217 // assert(minCol<nrOfCol());
218 // assert(minCol>=0);
219 // assert(maxCol<nrOfCol());
220 // assert(minCol<=maxCol);
221 // assert(minRow<nrOfRow());
222 // assert(minRow>=0);
223 // assert(maxRow<nrOfRow());
224 // assert(minRow<=maxRow);
225 // if(buffer.size()!=(maxRow-minRow+1)*(maxCol-minCol+1))
226 // buffer.resize((maxRow-minRow+1)*(maxCol-minCol+1));
227 // //fetch raster band
228 // GDALRasterBand *poBand;
229 // assert(band<nrOfBand()+1);
230 // poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
231 // for(int irow=0;irow<maxRow-minRow+1;++irow)
232 // poBand->RasterIO(GF_Read,minCol,minRow+irow,maxCol-minCol+1,1,&(buffer[irow*(maxCol-minCol+1)]),maxCol-minCol+1,1,dataType,0,0);
233 // }
234 
235 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, const GDALDataType& dataType, int row, int band) const
236 {
237  readData(buffer,dataType,0,nrOfCol()-1,row,band);
238 }
239 
240 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, const GDALDataType& dataType, double row, int band, RESAMPLE resample) const
241 {
242  readData(buffer,dataType,0,nrOfCol()-1,row,band,resample);
243 }
244 
245 
246 #endif // _IMGREADERGDAL_H_
247 
248 // //fetch raster band
249 // GDALRasterBand *poBand;
250 // assert(band<nrOfBand()+1);
251 // poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
252 // buffer.resize(maxCol-minCol+1);
253 // assert(minCol<nrOfCol());
254 // assert(row<nrOfRow());
255 // poBand->RasterIO(GF_Read,minCol,row,buffer.size(),1,&(buffer[0]),buffer.size(),1,GDT_Int16,0,0);