pktools  2.6.5
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 <assert.h>
24 #include <fstream>
25 #include <string>
26 #include <sstream>
27 #include "gdal_priv.h"
28 #include "base/Vector2d.h"
29 
30 enum RESAMPLE { NEAR = 0, BILINEAR = 1, BICUBIC = 2 };
31 
32 //--------------------------------------------------------------------------
34 {
35 public:
36  ImgReaderGdal(void);
37  ImgReaderGdal(const std::string& filename){open(filename);};
38  ~ImgReaderGdal(void);
39  void open(const std::string& filename);//, double magicX=1, double magicY=1);
40  void close(void);
41  std::string getFileName() const {return m_filename;};
42  int nrOfCol(void) const { return m_ncol;};
43  int nrOfRow(void) const { return m_nrow;};
44  int nrOfBand(void) const { return m_nband;};
45  bool isGeoRef() const {double gt[6];getGeoTransform(gt);if(gt[5]<0) return true;else return false;};
46  std::string getProjection(void) const;
47  std::string getProjectionRef(void) const;
48  std::string getGeoTransform() const;
49  void getGeoTransform(double* gt) const;
50  /* void getGeoTransform(double& ulx, double& uly, double& deltaX, double& deltaY, double& rot1, double& rot2) const; */
51  std::string getDescription() const;
52  std::string getMetadataItem() const;
53  std::string getImageDescription() const;
54  bool getBoundingBox (double& ulx, double& uly, double& lrx, double& lry) const;
55  bool getCenterPos(double& x, double& y) const;
56  double getUlx() const {double ulx, uly, lrx,lry;getBoundingBox(ulx,uly,lrx,lry);return(ulx);};
57  double getUly() const {double ulx, uly, lrx,lry;getBoundingBox(ulx,uly,lrx,lry);return(uly);};
58  double getLrx() const {double ulx, uly, lrx,lry;getBoundingBox(ulx,uly,lrx,lry);return(lrx);};
59  double getLry() const {double ulx, uly, lrx,lry;getBoundingBox(ulx,uly,lrx,lry);return(lry);};
60  // bool getMagicPixel(double& magicX, double& magicY) const {magicX=m_magic_x;magicY=m_magic_y;};
61  void setScale(double theScale, int band=0){
62  /* if(getRasterBand(band)->SetScale(theScale)==CE_Failure){ */
63  if(m_scale.size()!=nrOfBand()){//initialize
64  m_scale.resize(nrOfBand());
65  for(int iband=0;iband<nrOfBand();++iband)
66  m_scale[iband]=1.0;
67  }
68  m_scale[band]=theScale;
69  /* }; */
70  }
71  void setOffset(double theOffset, int band=0){
72  /* if(getRasterBand(band)->SetOffset(theOffset)==CE_Failure){ */
73  if(m_offset.size()!=nrOfBand()){
74  m_offset.resize(nrOfBand());
75  for(int iband=0;iband<nrOfBand();++iband)
76  m_offset[iband]=0.0;
77  }
78  m_offset[band]=theOffset;
79  /* }; */
80  }
81  int getNoDataValues(std::vector<double>& noDataValues) const;
82  bool isNoData(double value) const{if(m_noDataValues.empty()) return false;else return find(m_noDataValues.begin(),m_noDataValues.end(),value)!=m_noDataValues.end();};
83  int pushNoDataValue(double noDataValue);
84  int setNoData(const std::vector<double> nodata){m_noDataValues=nodata; return(m_noDataValues.size());};
85  CPLErr GDALSetNoDataValue(double noDataValue, int band=0) {return getRasterBand(band)->SetNoDataValue(noDataValue);};
86  bool covers(double x, double y) const;
87  bool covers(double ulx, double uly, double lrx, double lry) const;
88  bool geo2image(double x, double y, double& i, double& j) const;
89  bool image2geo(double i, double j, double& x, double& y) const;
90  double getDeltaX(void) const {double gt[6];getGeoTransform(gt);return gt[1];};
91  double getDeltaY(void) const {double gt[6];getGeoTransform(gt);return -gt[5];};
92  template<typename T> void readData(T& value, const GDALDataType& dataType, int col, int row, int band=0) const;
93  template<typename T> void readData(std::vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int row, int band=0) const;
94  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;
95  template<typename T> void readDataBlock(Vector2d<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band=0) const;
96  template<typename T> void readDataBlock(std::vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band=0) const;
97  template<typename T> void readData(std::vector<T>& buffer, const GDALDataType& dataType, int row, int band=0) const;
98  template<typename T> void readData(std::vector<T>& buffer, const GDALDataType& dataType, double row, int band=0, RESAMPLE resample=NEAR) const;
99  void getMinMax(int startCol, int endCol, int startRow, int endRow, int band, double& minValue, double& maxValue) const;
100  void getMinMax(double& minValue, double& maxValue, int band=0) const;
101  double getMin(int& col, int& row, int band=0) const;
102  double getHistogram(std::vector<double>& histvector, double& min, double& max,unsigned int& nbin, int theBand=0, bool kde=false);
103  double getMax(int& col, int& row, int band=0) const;
104  void getRefPix(double& refX, double &refY, int band=0) const;
105  void getRange(std::vector<short>& range, int Band=0) const;
106  unsigned long int getNvalid(int band) const;
107  GDALDataType getDataType(int band=0) const;
108  GDALRasterBand* getRasterBand(int band=0);
109  GDALColorTable* getColorTable(int band=0) const;
110  std::string getDriverDescription() const;
111  std::string getImageType() const{return getDriverDescription();};
112 // std::string getImageType() const{return "GTiff";};
113  std::string getInterleave() const;
114  std::string getCompression() const;
115  GDALDataset* getDataset(){return m_gds;};
116  char** getMetadata();
117  char** getMetadata() const;
118  void getMetadata(std::list<std::string>& metadata) const;
119 
120 protected:
121  void setCodec();//double magicX, double magicY);
122 
123  std::string m_filename;
124  GDALDataset *m_gds;
125  int m_ncol;
126  int m_nrow;
127  int m_nband;
128  double m_gt[6];
129  /* double m_ulx; */
130  /* double m_uly; */
131  /* double m_delta_x; */
132  /* double m_delta_y; */
133  /* bool m_isGeoRef; */
134  std::vector<double> m_noDataValues;
135  std::vector<double> m_scale;
136  std::vector<double> m_offset;
137 };
138 
139 // adfGeoTransform[0] /* top left x */
140 // adfGeoTransform[1] /* w-e pixel resolution */
141 // adfGeoTransform[2] /* rotation, 0 if image is "north up" */
142 // adfGeoTransform[3] /* top left y */
143 // adfGeoTransform[4] /* rotation, 0 if image is "north up" */
144 // adfGeoTransform[5] /* n-s pixel resolution */
145 
146 template<typename T> void ImgReaderGdal::readData(T& value, const GDALDataType& dataType, int col, int row, int band) const
147 {
148  //fetch raster band
149  GDALRasterBand *poBand;
150  assert(band<nrOfBand()+1);
151  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
152  assert(col<nrOfCol());
153  assert(col>=0);
154  assert(row<nrOfRow());
155  assert(row>=0);
156  poBand->RasterIO(GF_Read,col,row,1,1,&value,1,1,dataType,0,0);
157  if(m_scale.size()>band)
158  value=static_cast<double>(value)*m_scale[band];
159  if(m_offset.size()>band)
160  value=static_cast<double>(value)+m_offset[band];
161 }
162 
163 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, const GDALDataType& dataType, int minCol, int maxCol, int row, int band) const
164 {
165  //fetch raster band
166  GDALRasterBand *poBand;
167  assert(band<nrOfBand()+1);
168  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
169  assert(minCol<nrOfCol());
170  assert(minCol>=0);
171  assert(maxCol<nrOfCol());
172  assert(minCol<=maxCol);
173  assert(row<nrOfRow());
174  assert(row>=0);
175  if(buffer.size()!=maxCol-minCol+1)
176  buffer.resize(maxCol-minCol+1);
177  poBand->RasterIO(GF_Read,minCol,row,buffer.size(),1,&(buffer[0]),buffer.size(),1,dataType,0,0);
178  if(m_scale.size()>band||m_offset.size()>band){
179  double theScale=1;
180  double theOffset=0;
181  if(m_scale.size()>band)
182  theScale=m_scale[band];
183  if(m_offset.size()>band)
184  theOffset=m_offset[band];
185  for(int index=0;index<buffer.size();++index)
186  buffer[index]=theScale*static_cast<double>(buffer[index])+theOffset;
187  }
188 }
189 
190 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, double row, int band, RESAMPLE resample) const
191 {
192  //todo: make upper and lower row depend on isGeo...
193  std::vector<T> readBuffer_upper;
194  std::vector<T> readBuffer_lower;
195  if(buffer.size()!=maxCol-minCol+1)
196  buffer.resize(maxCol-minCol+1);
197  double upperRow=row-0.5;
198  upperRow=static_cast<int>(upperRow);
199  double lowerRow=row+0.5;
200  lowerRow=static_cast<int>(lowerRow);
201  switch(resample){
202  case(BILINEAR):
203  if(lowerRow>=nrOfRow())
204  lowerRow=nrOfRow()-1;
205  if(upperRow<0)
206  upperRow=0;
207  readData(readBuffer_upper,GDT_Float64,minCol,maxCol,static_cast<int>(upperRow),band);
208  readData(readBuffer_lower,GDT_Float64,minCol,maxCol,static_cast<int>(lowerRow),band);
209  //do interpolation in y
210  for(int icol=0;icol<maxCol-minCol+1;++icol){
211  buffer[icol]=(lowerRow-row+0.5)*readBuffer_upper[icol]+(1-lowerRow+row-0.5)*readBuffer_lower[icol];
212  }
213  break;
214  default:
215  readData(buffer,GDT_Float64,minCol,maxCol,static_cast<int>(row),band);
216  break;
217  }
218 }
219 
220 template<typename T> void ImgReaderGdal::readDataBlock(Vector2d<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band) const
221 {
222  buffer.resize(maxRow-minRow+1);
223  for(int irow=minRow;irow<=maxRow;++irow){
224  buffer[irow-minRow].resize(maxCol-minCol+1);
225  readData(buffer[irow-minRow],dataType,minCol,maxCol,irow,band);
226  }
227 }
228 
229 template<typename T> void ImgReaderGdal::readDataBlock(std::vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band) const
230 {
231  double theScale=1;
232  double theOffset=0;
233  if(m_scale.size()>band)
234  theScale=m_scale[band];
235  if(m_offset.size()>band)
236  theOffset=m_offset[band];
237  //fetch raster band
238  GDALRasterBand *poBand;
239  assert(band<nrOfBand()+1);
240  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
241  if(minCol>=nrOfCol() ||
242  (minCol<0) ||
243  (maxCol>=nrOfCol()) ||
244  (minCol>maxCol) ||
245  (minRow>=nrOfRow()) ||
246  (minRow<0) ||
247  (maxRow>=nrOfRow()) ||
248  (minRow>maxRow)){
249  std::string errorString="block not within image boundaries";
250  throw(errorString);
251  }
252  /* assert(minCol<nrOfCol()); */
253  /* assert(minCol>=0); */
254  /* assert(maxCol<nrOfCol()); */
255  /* assert(minCol<=maxCol); */
256  /* assert(minRow<nrOfRow()); */
257  /* assert(minRow>=0); */
258  /* assert(maxRow<nrOfRow()); */
259  /* assert(minRow<=maxRow); */
260  if(buffer.size()!=(maxRow-minRow+1)*(maxCol-minCol+1))
261  buffer.resize((maxRow-minRow+1)*(maxCol-minCol+1));
262  poBand->RasterIO(GF_Read,minCol,minRow,maxCol-minCol+1,maxRow-minRow+1,&(buffer[0]),(maxCol-minCol+1),(maxRow-minRow+1),dataType,0,0);
263  if(m_scale.size()>band||m_offset.size()>band){
264  for(int index=0;index<buffer.size();++index)
265  buffer[index]=theScale*buffer[index]+theOffset;
266  }
267 }
268 
269 // template<typename T> void ImgReaderGdal::readDataBlock(vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band) const
270 // {
271 // assert(band<nrOfBand()+1);
272 // assert(minCol<nrOfCol());
273 // assert(minCol>=0);
274 // assert(maxCol<nrOfCol());
275 // assert(minCol<=maxCol);
276 // assert(minRow<nrOfRow());
277 // assert(minRow>=0);
278 // assert(maxRow<nrOfRow());
279 // assert(minRow<=maxRow);
280 // if(buffer.size()!=(maxRow-minRow+1)*(maxCol-minCol+1))
281 // buffer.resize((maxRow-minRow+1)*(maxCol-minCol+1));
282 // //fetch raster band
283 // GDALRasterBand *poBand;
284 // assert(band<nrOfBand()+1);
285 // poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
286 // for(int irow=0;irow<maxRow-minRow+1;++irow)
287 // poBand->RasterIO(GF_Read,minCol,minRow+irow,maxCol-minCol+1,1,&(buffer[irow*(maxCol-minCol+1)]),maxCol-minCol+1,1,dataType,0,0);
288 // }
289 
290 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, const GDALDataType& dataType, int row, int band) const
291 {
292  readData(buffer,dataType,0,nrOfCol()-1,row,band);
293 }
294 
295 template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, const GDALDataType& dataType, double row, int band, RESAMPLE resample) const
296 {
297  readData(buffer,dataType,0,nrOfCol()-1,row,band,resample);
298 }
299 
300 
301 #endif // _IMGREADERGDAL_H_
302 
303 // //fetch raster band
304 // GDALRasterBand *poBand;
305 // assert(band<nrOfBand()+1);
306 // poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
307 // buffer.resize(maxCol-minCol+1);
308 // assert(minCol<nrOfCol());
309 // assert(row<nrOfRow());
310 // poBand->RasterIO(GF_Read,minCol,row,buffer.size(),1,&(buffer[0]),buffer.size(),1,GDT_Int16,0,0);