pktools  2.6.5
Processing Kernel for geospatial data
ImgReaderGdal.cc
1 /**********************************************************************
2 ImgReaderGdal.cc: 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 #include "ImgReaderGdal.h"
21 #include <assert.h>
22 #include <sstream>
23 #include <iostream>
24 #include <gsl/gsl_cdf.h>
25 
26 ImgReaderGdal::ImgReaderGdal(void)
27  : m_gds(NULL), m_ncol(0), m_nrow(0), m_nband(0)
28 {}
29 
30 void ImgReaderGdal::open(const std::string& filename)//, double magicX, double magicY)
31 {
32  m_filename = filename;
33  setCodec();//magicX,magicY);
34 }
35 
36 ImgReaderGdal::~ImgReaderGdal(void)
37 {
38  // delete m_gds;
39 // GDALDumpOpenDatasets(stderr);
40 // GDALDestroyDriverManager();//could be used by other objects...
41 }
42 
43 //--------------------------------------------------------------------------
44 void ImgReaderGdal::close(void)
45 {
46  GDALClose(m_gds);
47 }
48 
49 void ImgReaderGdal::setCodec()//double magicX, double magicY)
50 {
51  GDALAllRegister();
52  m_gds = (GDALDataset *) GDALOpen(m_filename.c_str(), GA_ReadOnly );
53  if(m_gds == NULL){
54  std::string errorString="FileOpenError";
55  throw(errorString);
56  }
57  m_ncol= m_gds->GetRasterXSize();
58  m_nrow= m_gds->GetRasterYSize();
59  m_nband= m_gds->GetRasterCount();
60  // m_isGeoRef=( static_cast<std::string>(m_gds->GetProjectionRef()) != "" );
61  // m_magic_x=magicX;
62  // m_magic_y=magicY;
63  double adfGeoTransform[6];
64  m_gds->GetGeoTransform( adfGeoTransform );
65  // if( m_gds->GetGeoTransform( adfGeoTransform ) == CE_None ){
66  m_gt[0]=adfGeoTransform[0];
67  m_gt[1]=adfGeoTransform[1];
68  m_gt[2]=adfGeoTransform[2];
69  m_gt[3]=adfGeoTransform[3];
70  m_gt[4]=adfGeoTransform[4];
71  m_gt[5]=adfGeoTransform[5];
72  // }
73  // else{
74  // m_gt[0]=0;
75  // m_gt[1]=1;
76  // m_gt[2]=0;
77  // m_gt[3]=0;
78  // m_gt[4]=0;
79  // m_gt[5]=1;
80  // }
81 }
82 
83 std::string ImgReaderGdal::getProjection(void) const
84 {
85  std::string theProjection=m_gds->GetProjectionRef();
86  // size_t startpos,endpos;
87  // while((startpos=theProjection.find(",AUTHORITY"))!=std::string::npos){
88  // endpos=theProjection.find("]",startpos+1,1)+1;
89  // theProjection.erase(startpos,endpos-startpos);
90  // }
91  return theProjection;
92 }
93 
94 std::string ImgReaderGdal::getProjectionRef(void) const
95 {
96  std::string theProjection;
97  if(m_gds->GetProjectionRef())
98  return(m_gds->GetProjectionRef());
99  else
100  return "";
101 }
102 
103 GDALDataType ImgReaderGdal::getDataType(int band) const
104 {
105  assert(band<m_nband+1);
106  return (m_gds->GetRasterBand(band+1))->GetRasterDataType();
107 }
108 
109 GDALRasterBand* ImgReaderGdal::getRasterBand(int band)
110 {
111  assert(band<m_nband+1);
112  return (m_gds->GetRasterBand(band+1));
113 }
114 
115 GDALColorTable* ImgReaderGdal::getColorTable(int band) const
116 {
117  assert(band<m_nband+1);
118  return (m_gds->GetRasterBand(band+1))->GetColorTable();
119 }
120 
121 std::string ImgReaderGdal::getDriverDescription() const
122 {
123  return m_gds->GetDriver()->GetDescription();
124 }
125 
126 void ImgReaderGdal::getGeoTransform(double* gt) const{
127  m_gds->GetGeoTransform(gt);
128 }
129 
130 // void ImgReaderGdal::getGeoTransform(double& ulx, double& uly, double& deltaX, double& deltaY, double& rot1, double& rot2) const
131 // {
132 // double adfGeoTransform[6];// { 444720, 30, 0, 3751320, 0, -30 };
133 // m_gds->GetGeoTransform(adfGeoTransform);
134 // ulx=adfGeoTransform[0];
135 // deltaX=adfGeoTransform[1];
136 // rot1=adfGeoTransform[2];
137 // uly=adfGeoTransform[3];
138 // rot2=adfGeoTransform[4];
139 // deltaY=-adfGeoTransform[5];//convention of GDAL!
140 // }
141 
142 std::string ImgReaderGdal::getGeoTransform() const
143 {
144  double gt[6];// { 444720, 30, 0, 3751320, 0, -30 };
145  m_gds->GetGeoTransform(gt);
146  std::ostringstream s;
147  s << "[" << gt[0] << "," << gt[1] << "," << gt[2] << "," << gt[3] << "," << gt[4] << "," << gt[5] << "]";
148  return(s.str());
149  // if(!isGeoRef())
150  // return("");
151  // else{
152  // double adfGeoTransform[6];// { 444720, 30, 0, 3751320, 0, -30 };
153  // m_gds->GetGeoTransform(adfGeoTransform);
154  // double ulx=adfGeoTransform[0];
155  // double deltaX=adfGeoTransform[1];
156  // double rot1=adfGeoTransform[2];
157  // double uly=adfGeoTransform[3];
158  // double rot2=adfGeoTransform[4];
159  // double deltaY=-adfGeoTransform[5];//convention of GDAL!
160  // std::ostringstream s;
161  // s << "[" << ulx << "," << deltaX << "," << rot1 << "," << uly << "," << rot2 << "," << -deltaY << "]";
162  // return(s.str());
163  // }
164 }
165 
166 char** ImgReaderGdal::getMetadata()
167 {
168  if(m_gds->GetMetadata()!=NULL)
169  return(m_gds->GetMetadata());
170  else
171  return (char**)"";
172 }
173 
174 char** ImgReaderGdal::getMetadata() const
175 {
176  if(m_gds->GetMetadata()!=NULL)
177  return(m_gds->GetMetadata());
178  else
179  return (char**)"";
180 }
181 
182 void ImgReaderGdal::getMetadata(std::list<std::string>& metadata) const
183 {
184  char** cmetadata=m_gds->GetMetadata();
185  while(*cmetadata!=NULL){
186  metadata.push_back(*(cmetadata));
187  ++cmetadata;
188  }
189 }
190 
191 std::string ImgReaderGdal::getDescription() const
192 {
193  if(m_gds->GetDriver()->GetDescription()!=NULL)
194  return m_gds->GetDriver()->GetDescription();
195  else
196  return "";
197 }
198 
199 std::string ImgReaderGdal::getMetadataItem() const
200 {
201  if(m_gds->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME )!=NULL)
202  return m_gds->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME );
203  else
204  return "";
205 }
206 std::string ImgReaderGdal::getImageDescription() const
207 {
208  if(m_gds->GetDriver()->GetMetadataItem("TIFFTAG_IMAGEDESCRIPTION")!=NULL)
209  return m_gds->GetDriver()->GetMetadataItem("TIFFTAG_IMAGEDESCRIPTION");
210  else
211  return "";
212 }
213 
214 std::string ImgReaderGdal::getInterleave() const
215 {
216  if(m_gds->GetMetadataItem( "INTERLEAVE", "IMAGE_STRUCTURE"))
217  return m_gds->GetMetadataItem( "INTERLEAVE", "IMAGE_STRUCTURE");
218  else
219  return("BAND");
220 }
221 
222 std::string ImgReaderGdal::getCompression() const
223 {
224  if(m_gds->GetMetadataItem( "COMPRESSION", "IMAGE_STRUCTURE"))
225  return m_gds->GetMetadataItem( "COMPRESSION", "IMAGE_STRUCTURE");
226  else
227  return("NONE");
228 }
229 
230 bool ImgReaderGdal::getBoundingBox(double& ulx, double& uly, double& lrx, double& lry) const
231 {
232  double gt[6];// { 444720, 30, 0, 3751320, 0, -30 };
233  m_gds->GetGeoTransform(gt);
234 
235  //assuming
236  //adfGeotransform[0]: ULX (upper left X coordinate)
237  //adfGeotransform[1]: $cos(\alpha)\cdot\textrm{Xres}$
238  //adfGeotransform[2]: $-sin(\alpha)\cdot\textrm{Xres}$
239  //adfGeotransform[3]: ULY (upper left Y coordinate)
240  //adfGeotransform[4]: $-sin(\alpha)\cdot\textrm{Yres}$
241  //adfGeotransform[5]: $-cos(\alpha)\cdot\textrm{Yres}$
242  ulx=gt[0];
243  uly=gt[3];
244  lrx=gt[0]+nrOfCol()*gt[1]+nrOfRow()*gt[2];
245  lry=gt[3]+nrOfCol()*gt[4]+nrOfRow()*gt[5];
246  if(isGeoRef()){
247  // ulx=m_ulx;
248  // uly=m_uly;
249  // lrx=ulx+nrOfCol()*m_delta_x;
250  // lry=uly-nrOfRow()*m_delta_y;
251  return true;
252  }
253  else{
254  // ulx=0;
255  // uly=nrOfRow()-1;
256  // lrx=nrOfCol()-1;
257  // lry=0;
258  return false;
259  }
260 }
261 
262 bool ImgReaderGdal::getCenterPos(double& x, double& y) const
263 {
264  double gt[6];// { 444720, 30, 0, 3751320, 0, -30 };
265  m_gds->GetGeoTransform(gt);
266 
267  //assuming
268  //adfGeotransform[0]: ULX (upper left X coordinate)
269  //adfGeotransform[1]: $cos(\alpha)\cdot\textrm{Xres}$
270  //adfGeotransform[2]: $-sin(\alpha)\cdot\textrm{Xres}$
271  //adfGeotransform[3]: ULY (upper left Y coordinate)
272  //adfGeotransform[4]: $-sin(\alpha)\cdot\textrm{Yres}$
273  //adfGeotransform[5]: $-cos(\alpha)\cdot\textrm{Yres}$
274  x=gt[0]+(nrOfCol()/2.0)*gt[1]+(nrOfRow()/2.0)*gt[2];
275  y=gt[3]+(nrOfCol()/2.0)*gt[4]+(nrOfRow()/2.0)*gt[5];
276  if(isGeoRef()){
277  // x=m_ulx+(nrOfCol()/2.0)*m_delta_x;
278  // y=m_uly-(nrOfRow()/2.0)*m_delta_y;
279  return true;
280  }
281  else{
282  // x=nrOfCol()/2.0;
283  // y=nrOfRow()/2.0;
284  return false;
285  }
286 }
287 
288 //i and j represent fraction of pixels, return true if image is georeferenced
289 bool ImgReaderGdal::geo2image(double x, double y, double& i, double& j) const
290 {
291  //double values are returned, caller is responsible for interpolation step
292  double gt[6];// { 444720, 30, 0, 3751320, 0, -30 };
293  m_gds->GetGeoTransform(gt);
294  //assuming
295  //adfGeotransform[0]: ULX (upper left X coordinate)
296  //adfGeotransform[1]: $cos(\alpha)\cdot\textrm{Xres}$
297  //adfGeotransform[2]: $-sin(\alpha)\cdot\textrm{Xres}$
298  //adfGeotransform[3]: ULY (upper left Y coordinate)
299  //adfGeotransform[4]: $-sin(\alpha)\cdot\textrm{Yres}$
300  //adfGeotransform[5]: $-cos(\alpha)\cdot\textrm{Yres}$
301 
302  double denom=(gt[1]-gt[2]*gt[4]/gt[5]);
303  double eps=0.00001;
304  if(fabs(denom)>eps){
305  i=(x-gt[0]-gt[2]/gt[5]*(y-gt[3]))/denom;
306  j=(y-gt[3]-gt[4]*(x-gt[0]-gt[2]/gt[5]*(y-gt[3]))/denom)/gt[5];
307  }
308  if(isGeoRef()){
309  // double ulx=m_ulx;
310  // double uly=m_uly;
311  // i=(x-ulx)/m_delta_x;
312  // j=(uly-y)/m_delta_y;
313  return true;
314  }
315  else{
316  // i=x;
317  // j=nrOfRow()-y;
318  return false;
319  }
320 }
321 
322 //x and y represent center of pixel, return true if image is georeferenced
323 bool ImgReaderGdal::image2geo(double i, double j, double& x, double& y) const
324 {
325  double gt[6];// { 444720, 30, 0, 3751320, 0, -30 };
326  m_gds->GetGeoTransform(gt);
327 
328  //assuming
329  //adfGeotransform[0]: ULX (upper left X coordinate)
330  //adfGeotransform[1]: $cos(\alpha)\cdot\textrm{Xres}$
331  //adfGeotransform[2]: $-sin(\alpha)\cdot\textrm{Xres}$
332  //adfGeotransform[3]: ULY (upper left Y coordinate)
333  //adfGeotransform[4]: $-sin(\alpha)\cdot\textrm{Yres}$
334  //adfGeotransform[5]: $-cos(\alpha)\cdot\textrm{Yres}$
335 
336  x=gt[0]+(0.5+i)*gt[1]+(0.5+j)*gt[2];
337  y=gt[3]+(0.5+i)*gt[4]+(0.5+j)*gt[5];
338  if(isGeoRef()){
339  // x=m_ulx+(0.5+i)*m_delta_x;
340  // y=m_uly-(0.5+j)*m_delta_y;
341  return true;
342  }
343  else{
344  // x=0.5+i;
345  // y=nrOfRow()-(0.5+j);
346  return false;
347  }
348 }
349 
350 bool ImgReaderGdal::covers(double x, double y) const
351 {
352  double theULX, theULY, theLRX, theLRY;
353  getBoundingBox(theULX,theULY,theLRX,theLRY);
354  return((x > theULX)&&
355  (x < theLRX)&&
356  (y < theULY)&&
357  (y >theLRY));
358 }
359 
360 bool ImgReaderGdal::covers(double ulx, double uly, double lrx, double lry) const
361 {
362  double theULX, theULY, theLRX, theLRY;
363  getBoundingBox(theULX,theULY,theLRX,theLRY);
364  return((ulx < theLRX)&&(lrx > theULX)&&(lry < theULY)&&(uly > theLRY));
365 }
366 
367 double ImgReaderGdal::getMin(int& x, int& y, int band) const{
368  double minValue=0;
369  std::vector<double> lineBuffer(nrOfCol());
370  bool isValid=false;
371  for(int irow=0;irow<nrOfRow();++irow){
372  readData(lineBuffer,GDT_Float64,irow,band);
373  for(int icol=0;icol<nrOfCol();++icol){
374  if(isNoData(lineBuffer[icol]))
375  continue;
376  if(isValid){
377  if(lineBuffer[icol]<minValue){
378  y=irow;
379  x=icol;
380  minValue=lineBuffer[icol];
381  }
382  }
383  else{
384  y=irow;
385  x=icol;
386  minValue=lineBuffer[icol];
387  isValid=true;
388  }
389  }
390  }
391  if(isValid)
392  return minValue;
393  else
394  throw(static_cast<std::string>("Warning: not initialized"));
395 }
396 
397 double ImgReaderGdal::getMax(int& x, int& y, int band) const{
398  double maxValue=0;
399  std::vector<double> lineBuffer(nrOfCol());
400  bool isValid=false;
401  for(int irow=0;irow<nrOfRow();++irow){
402  readData(lineBuffer,GDT_Float64,irow,band);
403  for(int icol=0;icol<nrOfCol();++icol){
404  if(isNoData(lineBuffer[icol]))
405  continue;
406  if(isValid){
407  if(lineBuffer[icol]>maxValue){
408  y=irow;
409  x=icol;
410  maxValue=lineBuffer[icol];
411  }
412  }
413  else{
414  y=irow;
415  x=icol;
416  maxValue=lineBuffer[icol];
417  isValid=true;
418  }
419  }
420  }
421  if(isValid)
422  return maxValue;
423  else
424  throw(static_cast<std::string>("Warning: not initialized"));
425 }
426 
427 void ImgReaderGdal::getMinMax(int startCol, int endCol, int startRow, int endRow, int band, double& minValue, double& maxValue) const
428 {
429  bool isConstraint=(maxValue>minValue);
430  double minConstraint=minValue;
431  double maxConstraint=maxValue;
432  std::vector<double> lineBuffer(endCol-startCol+1);
433  bool isValid=false;
434  assert(endRow<nrOfRow());
435  for(int irow=startCol;irow<endRow+1;++irow){
436  readData(lineBuffer,GDT_Float64,startCol,endCol,irow,band);
437  for(int icol=0;icol<lineBuffer.size();++icol){
438  if(isNoData(lineBuffer[icol]))
439  continue;
440  if(isValid){
441  if(isConstraint){
442  if(lineBuffer[icol]<minConstraint)
443  continue;
444  if(lineBuffer[icol]>maxConstraint)
445  continue;
446  }
447  if(lineBuffer[icol]<minValue)
448  minValue=lineBuffer[icol];
449  if(lineBuffer[icol]>maxValue)
450  maxValue=lineBuffer[icol];
451  }
452  else{
453  if(isConstraint){
454  if(lineBuffer[icol]<minConstraint)
455  continue;
456  if(lineBuffer[icol]>maxConstraint)
457  continue;
458  }
459  minValue=lineBuffer[icol];
460  maxValue=lineBuffer[icol];
461  isValid=true;
462  }
463  }
464  }
465  if(!isValid)
466  throw(static_cast<std::string>("Warning: not initialized"));
467 }
468 
469 void ImgReaderGdal::getMinMax(double& minValue, double& maxValue, int band) const
470 {
471  bool isConstraint=(maxValue>minValue);
472  double minConstraint=minValue;
473  double maxConstraint=maxValue;
474  std::vector<double> lineBuffer(nrOfCol());
475  bool isValid=false;
476  for(int irow=0;irow<nrOfRow();++irow){
477  readData(lineBuffer,GDT_Float64,irow,band);
478  for(int icol=0;icol<nrOfCol();++icol){
479  if(isNoData(lineBuffer[icol]))
480  continue;
481  if(isValid){
482  if(isConstraint){
483  if(lineBuffer[icol]<minConstraint)
484  continue;
485  if(lineBuffer[icol]>maxConstraint)
486  continue;
487  }
488  if(lineBuffer[icol]<minValue)
489  minValue=lineBuffer[icol];
490  if(lineBuffer[icol]>maxValue)
491  maxValue=lineBuffer[icol];
492  }
493  else{
494  if(isConstraint){
495  if(lineBuffer[icol]<minConstraint)
496  continue;
497  if(lineBuffer[icol]>maxConstraint)
498  continue;
499  }
500  minValue=lineBuffer[icol];
501  maxValue=lineBuffer[icol];
502  isValid=true;
503  }
504  }
505  }
506  if(!isValid)
507  throw(static_cast<std::string>("Warning: not initialized"));
508 }
509 
510 double ImgReaderGdal::getHistogram(std::vector<double>& histvector, double& min, double& max, unsigned int& nbin, int theBand, bool kde){
511  double minValue=0;
512  double maxValue=0;
513 
514  if(min>=max)
515  getMinMax(minValue,maxValue,theBand);
516  else{
517  minValue=min;
518  maxValue=max;
519  }
520  if(min<max&&min>minValue)
521  minValue=min;
522  if(min<max&&max<maxValue)
523  maxValue=max;
524  min=minValue;
525  max=maxValue;
526 
527  double sigma=0;
528  if(kde){
529  double meanValue=0;
530  double stdDev=0;
531  GDALProgressFunc pfnProgress;
532  void* pProgressData;
533  GDALRasterBand* rasterBand;
534  rasterBand=getRasterBand(theBand);
535  rasterBand->ComputeStatistics(0,&minValue,&maxValue,&meanValue,&stdDev,pfnProgress,pProgressData);
536  //rest minvalue and MaxValue as ComputeStatistics does not account for nodata, scale and offset
537  minValue=min;
538  maxValue=max;
539 
540  if(m_scale.size()>theBand){
541  stdDev*=m_scale[theBand];
542  }
543  sigma=1.06*stdDev*pow(getNvalid(theBand),-0.2);
544  }
545 
546  double scale=0;
547  if(maxValue>minValue){
548  if(nbin==0)
549  nbin=maxValue-minValue+1;
550  scale=static_cast<double>(nbin-1)/(maxValue-minValue);
551  }
552  else
553  nbin=1;
554  assert(nbin>0);
555  if(histvector.size()!=nbin){
556  histvector.resize(nbin);
557  for(int i=0;i<nbin;histvector[i++]=0);
558  }
559  double nvalid=0;
560  unsigned long int nsample=0;
561  unsigned long int ninvalid=0;
562  std::vector<double> lineBuffer(nrOfCol());
563  for(int irow=0;irow<nrOfRow();++irow){
564  readData(lineBuffer,GDT_Float64,irow,theBand);
565  for(int icol=0;icol<nrOfCol();++icol){
566  if(isNoData(lineBuffer[icol]))
567  ++ninvalid;
568  else if(lineBuffer[icol]>maxValue)
569  ++ninvalid;
570  else if(lineBuffer[icol]<minValue)
571  ++ninvalid;
572  else if(nbin==1)
573  ++histvector[0];
574  else{//scale to [0:nbin]
575  if(sigma>0){
576  //create kde for Gaussian basis function
577  //todo: speed up by calculating first and last bin with non-zero contriubtion...
578  //todo: calculate real surface below pdf by using gsl_cdf_gaussian_P(x-mean+binsize,sigma)-gsl_cdf_gaussian_P(x-mean,sigma)
579  //hiero
580  for(int ibin=0;ibin<nbin;++ibin){
581  double icenter=minValue+static_cast<double>(maxValue-minValue)*(ibin+0.5)/nbin;
582  double thePdf=gsl_ran_gaussian_pdf(lineBuffer[icol]-icenter, sigma);
583  histvector[ibin]+=thePdf;
584  nvalid+=thePdf;
585  }
586  }
587  else{
588  int theBin=static_cast<unsigned long int>(scale*(lineBuffer[icol]-minValue));
589  assert(theBin>=0);
590  assert(theBin<nbin);
591  ++histvector[theBin];
592  ++nvalid;
593  }
594  // else if(lineBuffer[icol]==maxValue)
595  // ++histvector[nbin-1];
596  // else
597  // ++histvector[static_cast<int>(static_cast<double>(lineBuffer[icol]-minValue)/(maxValue-minValue)*(nbin-1))];
598  }
599  }
600  }
601  // unsigned long int nvalid=nrOfCol()*nrOfRow()-ninvalid;
602  return nvalid;
603 }
604 
605 void ImgReaderGdal::getRange(std::vector<short>& range, int band) const
606 {
607  std::vector<short> lineBuffer(nrOfCol());
608  range.clear();
609  for(int irow=0;irow<nrOfRow();++irow){
610  readData(lineBuffer,GDT_Int16,irow,band);
611  for(int icol=0;icol<nrOfCol();++icol){
612  if(find(range.begin(),range.end(),lineBuffer[icol])==range.end())
613  range.push_back(lineBuffer[icol]);
614  }
615  }
616  sort(range.begin(),range.end());
617 }
618 
619 unsigned long int ImgReaderGdal::getNvalid(int band) const
620 {
621  unsigned long int nvalid=0;
622  if(m_noDataValues.size()){
623  std::vector<double> lineBuffer(nrOfCol());
624  for(int irow=0;irow<nrOfRow();++irow){
625  readData(lineBuffer,GDT_Float64,irow,band);
626  for(int icol=0;icol<nrOfCol();++icol){
627  if(isNoData(lineBuffer[icol]))
628  continue;
629  else
630  ++nvalid;
631  }
632  }
633  return nvalid;
634  }
635  else
636  return(nrOfCol()*nrOfRow());
637 }
638 
639 int ImgReaderGdal::getNoDataValues(std::vector<double>& noDataValues) const
640 {
641  if(m_noDataValues.size()){
642  noDataValues=m_noDataValues;
643  return m_noDataValues.size();
644  }
645  else
646  return 0;
647 }
648 
649 int ImgReaderGdal::pushNoDataValue(double noDataValue)
650 {
651  if(find(m_noDataValues.begin(),m_noDataValues.end(),noDataValue)==m_noDataValues.end())
652  m_noDataValues.push_back(noDataValue);
653  return(m_noDataValues.size());
654 }
655 
656 // bool ImgReaderGdal::setNoDataValue(double noDataValue,int band)
657 // {
658 // GDALRasterBand *poBand;
659 // poBand = m_gds->GetRasterBand(band+1);
660 // if(poBand->SetNoDataValue(noDataValue)!=CE_None)
661 // return false;
662 // else
663 // return true;
664 // }
665 
666 void ImgReaderGdal::getRefPix(double& refX, double &refY, int band) const
667 {
668  std::vector<double> lineBuffer(nrOfCol());
669  double validCol=0;
670  double validRow=0;
671  int nvalidCol=0;
672  int nvalidRow=0;
673  for(int irow=0;irow<nrOfRow();++irow){
674  readData(lineBuffer,GDT_Float64,irow,band);
675  for(int icol=0;icol<nrOfCol();++icol){
676  // bool valid=(find(m_noDataValues.begin(),m_noDataValues.end(),lineBuffer[icol])==m_noDataValues.end());
677  // if(valid){
678  if(!isNoData(lineBuffer[icol])){
679  validCol+=icol+1;
680  ++nvalidCol;
681  validRow+=irow+1;
682  ++nvalidRow;
683  }
684  }
685  }
686  if(isGeoRef()){
687  //reference coordinate is lower left corner of pixel in center of gravity
688  //we need geo coordinates for exactly this location: validCol(Row)/nvalidCol(Row)-0.5
689  double cgravi=validCol/nvalidCol-0.5;
690  double cgravj=validRow/nvalidRow-0.5;
691  double refpixeli=floor(cgravi);
692  double refpixelj=ceil(cgravj-1);
693  //but image2geo provides location at center of pixel (shifted half pixel right down)
694  image2geo(refpixeli,refpixelj,refX,refY);
695  //refX and refY now refer to center of gravity pixel
696  refX-=0.5*getDeltaX();//shift to left corner
697  refY-=0.5*getDeltaY();//shift to lower left corner
698  }
699  else{
700  refX=floor(validCol/nvalidCol-0.5);//left corner
701  refY=floor(validRow/nvalidRow-0.5);//upper corner
702  //shift to lower left corner of pixel
703  refY+=1;
704 
705  }
706 }