pktools 2.6.7
Processing Kernel for geospatial data
ImgReaderGdal.h
1/**********************************************************************
2ImgReaderGdal.h: class to read raster files using GDAL API library
3Copyright (C) 2008-2016 Pieter Kempeneers
4
5This file is part of pktools
6
7pktools is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12pktools is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along 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
36class ImgReaderGdal : public virtual ImgRasterGdal
37{
38public:
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
82protected:
84 void setCodec(const GDALAccess& readMode=GA_ReadOnly);
86private:
87};
88
95template<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
126template<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
163template<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
220template<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
243template<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
280template<typename T> void ImgReaderGdal::readData(std::vector<T>& buffer, int row, int band)
281{
282 readData(buffer,0,nrOfCol()-1,row,band);
283}
284
291template<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_
int nrOfRow(void) const
Get the number of rows of this dataset.
bool isNoData(double value) const
Check if value is nodata in this dataset.
GDALDataset * m_gds
instance of the GDAL dataset of this dataset
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)
int nrOfCol(void) const
Get the number of columns of this dataset.
Definition: ImgRasterGdal.h:98
std::vector< double > m_scale
Vector containing the scale factor to be applied (one scale value for each band)
void setCodec(const GDALAccess &readMode=GA_ReadOnly)
Set GDAL dataset number of columns, rows, bands and geotransform.
unsigned long int getNvalid(int band)
Calculate the number of valid pixels (with a value not defined as no data).
~ImgReaderGdal(void)
destructor
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
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 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...
void close(void)
Set the memory (in MB) to cache a number of rows in memory.
void open(const std::string &filename, const GDALAccess &readMode=GA_ReadOnly)
Open an image.
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...
ImgReaderGdal(void)
default constructor. Image needs to be opened later with one of the open methods.
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 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).
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...
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 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...