pktools  2.6.3
Processing Kernel for geospatial data
ImgWriterGdal.cc
1 /**********************************************************************
2 ImgWriterGdal.cc: class to write 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 <iostream>
21 #include <iomanip>
22 #include <time.h>
23 #include "ogr_spatialref.h"
24 #include "ImgWriterGdal.h"
25 
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 
30 //---------------------------------------------------------------------------
31 ImgWriterGdal::ImgWriterGdal(void)
32  : m_gds(NULL), m_ncol(0), m_nrow(0), m_nband(0)
33 {}
34 
35 // ImgWriterGdal::ImgWriterGdal(void)
36 // : m_gds(NULL), m_magic_x(1), m_magic_y(1), m_isGeoRef(false), m_ncol(0), m_nrow(0), m_nband(0), m_interleave("BAND"), m_compression("LZW")
37 // {}
38 
39 ImgWriterGdal::~ImgWriterGdal(void)
40 {
41  // delete m_gds;
42 // GDALDumpOpenDatasets(stderr);
43 // GDALDestroyDriverManager();//could still be be used by other objects
44 }
45 
46 //---------------------------------------------------------------------------
47 void ImgWriterGdal::open(const std::string& filename, const ImgReaderGdal& imgSrc, const std::vector<std::string>& options)
48 {
49  // m_isGeoRef=imgSrc.isGeoRef();
50  m_filename=filename;
51  m_ncol=imgSrc.nrOfCol();
52  m_nrow=imgSrc.nrOfRow();
53  m_nband=imgSrc.nrOfBand();
54  m_type=imgSrc.getDataType();
55  m_options=options;
56  // m_interleave=imgSrc.getInterleave();
57  // m_compression=imgSrc.getCompression();
58  // imgSrc.getMagicPixel(m_magic_x,m_magic_y);
59  setCodec(imgSrc);
60 }
61 
62 // void ImgWriterGdal::open(const std::string& filename, int ncol, int nrow, int nband, const GDALDataType& dataType, const std::string& imageType, const std::string& interleave, const std::string& compression, int magicX, int magicY)
63 // {
64 // m_isGeoRef=false;
65 // m_filename = filename;
66 // m_ncol = ncol;
67 // m_nrow = nrow;
68 // m_nband = nband;
69 // m_type=dataType;
70 // m_interleave = interleave;
71 // m_compression=compression;
72 // m_magic_x=magicX;
73 // m_magic_y=magicY;
74 // setCodec(imageType);
75 // }
76 
77 void ImgWriterGdal::open(const std::string& filename, int ncol, int nrow, int nband, const GDALDataType& dataType, const std::string& imageType, const std::vector<std::string>& options)
78 {
79  // m_isGeoRef=false;
80  m_filename = filename;
81  m_ncol = ncol;
82  m_nrow = nrow;
83  m_nband = nband;
84  m_type=dataType;
85  // m_interleave = interleave;
86  // m_compression=compression;
87  m_options=options;
88  // m_magic_x=magicX;
89  // m_magic_y=magicY;
90  setCodec(imageType);
91 }
92 
93 //---------------------------------------------------------------------------
94 void ImgWriterGdal::close(void)
95 {
96  GDALClose(m_gds);
97  char **papszOptions=NULL;
98  for(std::vector<std::string>::const_iterator optionIt=m_options.begin();optionIt!=m_options.end();++optionIt)
99  papszOptions=CSLAddString(papszOptions,optionIt->c_str());
100  CSLDestroy(papszOptions);
101 }
102 
103 //---------------------------------------------------------------------------
104 void ImgWriterGdal::setCodec(const ImgReaderGdal& imgSrc){
105  GDALAllRegister();
106  GDALDriver *poDriver;
107  poDriver = GetGDALDriverManager()->GetDriverByName(imgSrc.getDriverDescription().c_str());
108  if( poDriver == NULL ){
109  std::string errorString="FileOpenError";
110  throw(errorString);
111  }
112  char **papszMetadata;
113  papszMetadata = poDriver->GetMetadata();
114  //todo: try and catch if CREATE is not supported (as in PNG)
115  assert( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ));
116  char **papszOptions=NULL;
117  for(std::vector<std::string>::const_iterator optionIt=m_options.begin();optionIt!=m_options.end();++optionIt)
118  papszOptions=CSLAddString(papszOptions,optionIt->c_str());
119  // char **papszOptions=NULL;
120  // std::ostringstream compressList;
121  // compressList << "COMPRESS=" << m_compression;
122  // papszOptions = CSLAddString(papszOptions,(compressList.str()).c_str());
123  // std::ostringstream interleaveList;
124  // interleaveList << "INTERLEAVE=" << m_interleave;
125  // papszOptions = CSLAddString(papszOptions,(interleaveList.str()).c_str());
126  m_gds=poDriver->Create(m_filename.c_str(),m_ncol,m_nrow,m_nband,m_type,papszOptions);
127  // if(imgSrc.isGeoRef()){
128  setProjection(imgSrc.getProjection());
129  double gt[6];
130  imgSrc.getGeoTransform(gt);
131  setGeoTransform(gt);
132  // }
133  m_gds->SetMetadata(imgSrc.getMetadata() );
134  m_gds->SetMetadataItem( "TIFFTAG_DOCUMENTNAME", m_filename.c_str());
135  std::string versionString="pktools ";
136  versionString+=VERSION;
137  versionString+=" by Pieter Kempeneers";
138  m_gds->SetMetadataItem( "TIFFTAG_SOFTWARE", versionString.c_str());
139  time_t rawtime;
140  time ( &rawtime );
141 
142  time_t tim=time(NULL);
143  tm *now=localtime(&tim);
144  std::ostringstream datestream;
145  //date std::string must be 20 characters long...
146  datestream << now->tm_year+1900;
147  if(now->tm_mon+1<10)
148  datestream << ":0" << now->tm_mon+1;
149  else
150  datestream << ":" << now->tm_mon+1;
151  if(now->tm_mday<10)
152  datestream << ":0" << now->tm_mday;
153  else
154  datestream << ":" << now->tm_mday;
155  if(now->tm_hour<10)
156  datestream << " 0" << now->tm_hour;
157  else
158  datestream << " " << now->tm_hour;
159  if(now->tm_min<10)
160  datestream << ":0" << now->tm_min;
161  else
162  datestream << ":" << now->tm_min;
163  if(now->tm_sec<10)
164  datestream << ":0" << now->tm_sec;
165  else
166  datestream << ":" << now->tm_sec;
167  m_gds->SetMetadataItem( "TIFFTAG_DATETIME", datestream.str().c_str());
168 // list<std::string> lmeta;
169 // imgReader.getMetadata(lmeta);
170 // list<std::string>::const_iterator lit=lmeta.begin();
171 // while(lit!=lmeta.end()){
172 // cout << *lit << endl;
173 // ++lit;
174 // }
175  // m_gds->SetMetadataItem( "INTERLEAVE", m_interleave.c_str(), "IMAGE_STRUCTURE" );
176  // m_gds->SetMetadataItem( "COMPRESS", m_compression.c_str(), "IMAGE_STRUCTURE" );
177  if(imgSrc.getColorTable()!=NULL)
178  setColorTable(imgSrc.getColorTable());
179 }
180 
181 void ImgWriterGdal::setCodec(const std::string& imageType)
182 {
183  GDALAllRegister();
184  GDALDriver *poDriver;
185  poDriver = GetGDALDriverManager()->GetDriverByName(imageType.c_str());
186  if( poDriver == NULL ){
187  std::ostringstream s;
188  s << "FileOpenError (" << imageType << ")";
189  throw(s.str());
190  }
191  char **papszMetadata;
192  papszMetadata = poDriver->GetMetadata();
193  //todo: try and catch if CREATE is not supported (as in PNG)
194  assert( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ));
195  char **papszOptions=NULL;
196  for(std::vector<std::string>::const_iterator optionIt=m_options.begin();optionIt!=m_options.end();++optionIt)
197  papszOptions=CSLAddString(papszOptions,optionIt->c_str());
198  // std::ostringstream compressList;
199  // compressList << "COMPRESS=" << m_compression;
200  // papszOptions = CSLAddString(papszOptions,(compressList.str()).c_str());
201  // std::ostringstream interleaveList;
202  // interleaveList << "INTERLEAVE=" << m_interleave;
203  // papszOptions = CSLAddString(papszOptions,(interleaveList.str()).c_str());
204  m_gds=poDriver->Create(m_filename.c_str(),m_ncol,m_nrow,m_nband,m_type,papszOptions);
205 
206  // m_gds->SetMetadataItem( "INTERLEAVE", m_interleave.c_str(), "IMAGE_STRUCTURE" );
207  // m_gds->SetMetadataItem( "COMPRESSION", m_compression.c_str(), "IMAGE_STRUCTURE" );
208  m_gds->SetMetadataItem( "TIFFTAG_DOCUMENTNAME", m_filename.c_str());
209  std::string versionString="pktools ";
210  versionString+=VERSION;
211  versionString+=" by Pieter Kempeneers";
212  m_gds->SetMetadataItem( "TIFFTAG_SOFTWARE", versionString.c_str());
213  time_t rawtime;
214  time ( &rawtime );
215 
216  time_t tim=time(NULL);
217  tm *now=localtime(&tim);
218  std::ostringstream datestream;
219  //date std::string must be 20 characters long...
220  datestream << now->tm_year+1900;
221  if(now->tm_mon+1<10)
222  datestream << ":0" << now->tm_mon+1;
223  else
224  datestream << ":" << now->tm_mon+1;
225  if(now->tm_mday<10)
226  datestream << ":0" << now->tm_mday;
227  else
228  datestream << ":" << now->tm_mday;
229  if(now->tm_hour<10)
230  datestream << " 0" << now->tm_hour;
231  else
232  datestream << " " << now->tm_hour;
233  if(now->tm_min<10)
234  datestream << ":0" << now->tm_min;
235  else
236  datestream << ":" << now->tm_min;
237  if(now->tm_sec<10)
238  datestream << ":0" << now->tm_sec;
239  else
240  datestream << ":" << now->tm_sec;
241  m_gds->SetMetadataItem( "TIFFTAG_DATETIME", datestream.str().c_str());
242 // m_gds->SetMetadataItem( "TIFFTAG_DATETIME", ctime(&rawtime));
243 }
244 
245 void ImgWriterGdal::setMetadata(char** metadata)
246 {
247  assert(m_gds);
248  m_gds->SetMetadata(metadata);
249 }
250 
251 std::string ImgWriterGdal::getProjection(void) const
252 {
253  assert(m_gds);
254  std::string theProjection=m_gds->GetProjectionRef();
255  //due to error in Gdal? AUTHORITY fields do not seem to work!
256  // size_t startpos,endpos;
257  // while((startpos=theProjection.find(",AUTHORITY"))!=string::npos){
258  // endpos=theProjection.find("]",startpos+1,1)+1;
259  // theProjection.erase(startpos,endpos-startpos);
260  // }
261  return theProjection;
262 }
263 
264 //---------------------------------------------------------------------------
265 void ImgWriterGdal::setGeoTransform(double* gt){
266  // m_isGeoRef=true;
267  m_gt[0]=gt[0];
268  m_gt[1]=gt[1];
269  m_gt[2]=gt[2];
270  m_gt[3]=gt[3];
271  m_gt[4]=gt[4];
272  m_gt[5]=gt[5];
273  if(m_gds)
274  m_gds->SetGeoTransform(m_gt);
275 }
276 
277 // void ImgWriterGdal::setGeoTransform(double ulx, double uly, double deltaX, double deltaY, double rot1, double rot2)
278 // {
279 // m_isGeoRef=true;
280 // m_ulx=ulx;
281 // m_uly=uly;
282 // m_delta_x=deltaX;
283 // m_delta_y=deltaY;
284 // double adfGeoTransform[6];// { 444720, 30, 0, 3751320, 0, -30 };
285 // adfGeoTransform[0]=ulx;
286 // adfGeoTransform[1]=deltaX;
287 // adfGeoTransform[2]=rot1;
288 // adfGeoTransform[3]=uly;
289 // adfGeoTransform[4]=rot2;
290 // adfGeoTransform[5]=-deltaY;//convention of GDAL!
291 // if(m_gds)
292 // m_gds->SetGeoTransform(adfGeoTransform);
293 // }
294 
295 void ImgWriterGdal::copyGeoTransform(const ImgReaderGdal& imgSrc)
296 {
297  setProjection(imgSrc.getProjection());
298  double gt[6];
299  imgSrc.getGeoTransform(gt);
300  setGeoTransform(gt);
301  // imgSrc.getGeoTransform(ulx,uly,deltaX,deltaY,rot1,rot2);
302  // setGeoTransform(ulx,uly,deltaX,deltaY,rot1,rot2);
303 }
304 
305 std::string ImgWriterGdal::setProjectionProj4(const std::string& projection)
306 {
307  // if(!m_isGeoRef)
308  // m_isGeoRef=true;
309 
310  OGRSpatialReference theRef;
311  theRef.SetFromUserInput(projection.c_str());
312  char *wktString;
313  theRef.exportToWkt(&wktString);
314  assert(m_gds);
315  m_gds->SetProjection(wktString);
316  return(wktString);
317 
318  // OGRSpatialReferenceH hSRS;
319  // char *pszResult = NULL;
320 
321  // CPLErrorReset();
322 
323  // hSRS = OSRNewSpatialReference( NULL );
324  // if( OSRSetFromUserInput( hSRS, projection.c_str() ) == OGRERR_NONE )
325  // OSRExportToWkt( hSRS, &pszResult );
326  // else
327  // {
328  // std::ostringstream s;
329  // s << "Error in set projection " << projection;
330  // throw(s.str());
331  // }
332  // std::string theProjection=pszResult;
333  // assert(m_gds);
334  // m_gds->SetProjection(theProjection.c_str());
335  // OSRDestroySpatialReference( hSRS );
336 
337  // return theProjection;
338 }
339 
340 void ImgWriterGdal::setProjection(const std::string& projection)
341 {
342  // if(!m_isGeoRef)
343  // m_isGeoRef=true;
344  OGRSpatialReference oSRS;
345  char *pszSRS_WKT = NULL;
346  assert(m_gds);
347  m_gds->SetProjection(projection.c_str());
348  CPLFree(pszSRS_WKT);
349 }
350 
351 //default projection: ETSR-LAEA
352 std::string ImgWriterGdal::setProjection(void)
353 {
354  std::string theProjection;
355  OGRSpatialReference oSRS;
356  char *pszSRS_WKT = NULL;
358  oSRS.SetGeogCS("ETRS89","European_Terrestrial_Reference_System_1989","GRS 1980",6378137,298.2572221010042,"Greenwich",0,"degree",0.0174532925199433);
359  // cout << setprecision(16) << "major axis: " << oSRS.GetSemiMajor(NULL) << endl;//notice that major axis can be set to a different value than the default to the well known standard corresponding to the name (European_Terrestrial_Reference_System_1989), but that new value, while recognized by GetSemiMajor, will not be written in the geotiff tag!
360  oSRS.SetProjCS( "ETRS89 / ETRS-LAEA" );
361  oSRS.SetLAEA(52,10,4321000,3210000);
362  oSRS.exportToWkt( &pszSRS_WKT );
363  theProjection=pszSRS_WKT;
364  CPLFree( pszSRS_WKT );
365  assert(m_gds);
366  m_gds->SetProjection(theProjection.c_str());
367  return(theProjection);
368 }
369 
370 bool ImgWriterGdal::getBoundingBox(double& ulx, double& uly, double& lrx, double& lry) const
371 {
372  double gt[6];// { 444720, 30, 0, 3751320, 0, -30 };
373  m_gds->GetGeoTransform(gt);
374 
375  //assuming
376  //adfGeotransform[0]: ULX (upper left X coordinate)
377  //adfGeotransform[1]: $cos(\alpha)\cdot\textrm{Xres}$
378  //adfGeotransform[2]: $-sin(\alpha)\cdot\textrm{Xres}$
379  //adfGeotransform[3]: ULY (upper left Y coordinate)
380  //adfGeotransform[4]: $-sin(\alpha)\cdot\textrm{Yres}$
381  //adfGeotransform[5]: $-cos(\alpha)\cdot\textrm{Yres}$
382 
383  ulx=gt[0];
384  uly=gt[3];
385  lrx=gt[0]+nrOfCol()*gt[1]+nrOfRow()*gt[2];
386  lry=gt[3]+nrOfCol()*gt[4]+nrOfRow()*gt[5];
387  if(isGeoRef()){
388  // ulx=m_ulx;
389  // uly=m_uly;
390  // lrx=ulx+nrOfCol()*m_delta_x;
391  // lry=uly-nrOfRow()*m_delta_y;
392  return true;
393  }
394  else{
395  // ulx=0;
396  // uly=nrOfRow()-1;
397  // lrx=nrOfCol()-1;
398  // lry=0;
399  return false;
400  }
401 }
402 
403 bool ImgWriterGdal::getCentrePos(double& x, double& y) const
404 {
405  double gt[6];// { 444720, 30, 0, 3751320, 0, -30 };
406  m_gds->GetGeoTransform(gt);
407 
408  //assuming
409  //adfGeotransform[0]: ULX (upper left X coordinate)
410  //adfGeotransform[1]: $cos(\alpha)\cdot\textrm{Xres}$
411  //adfGeotransform[2]: $-sin(\alpha)\cdot\textrm{Xres}$
412  //adfGeotransform[3]: ULY (upper left Y coordinate)
413  //adfGeotransform[4]: $-sin(\alpha)\cdot\textrm{Yres}$
414  //adfGeotransform[5]: $-cos(\alpha)\cdot\textrm{Yres}$
415  x=gt[0]+(nrOfCol()/2.0)*gt[1]+(nrOfRow()/2.0)*gt[2];
416  y=gt[3]+(nrOfCol()/2.0)*gt[4]+(nrOfRow()/2.0)*gt[5];
417  if(isGeoRef()){
418  // x=m_ulx+nrOfCol()/2.0*m_delta_x;
419  // y=m_uly-nrOfRow()/2.0*m_delta_y;
420  return true;
421  }
422  else
423  return false;
424 }
425 
426 bool ImgWriterGdal::geo2image(double x, double y, double& i, double& j) const
427 {
428  //double values are returned, caller is responsible for interpolation step
429  //double values are returned, caller is responsible for interpolation step
430  double gt[6];// { 444720, 30, 0, 3751320, 0, -30 };
431  m_gds->GetGeoTransform(gt);
432  //assuming
433  //adfGeotransform[0]: ULX (upper left X coordinate)
434  //adfGeotransform[1]: $cos(\alpha)\cdot\textrm{Xres}$
435  //adfGeotransform[2]: $-sin(\alpha)\cdot\textrm{Xres}$
436  //adfGeotransform[3]: ULY (upper left Y coordinate)
437  //adfGeotransform[4]: $-sin(\alpha)\cdot\textrm{Yres}$
438  //adfGeotransform[5]: $-cos(\alpha)\cdot\textrm{Yres}$
439  double denom=(gt[1]-gt[2]*gt[4]/gt[5]);
440  double eps=0.00001;
441  if(fabs(denom)>eps){
442  i=(x-gt[0]-gt[2]/gt[5]*(y-gt[3]))/denom;
443  j=(y-gt[3]-gt[4]*(x-gt[0]-gt[2]/gt[5]*(y-gt[3]))/denom)/gt[5];
444  }
445  if(isGeoRef()){
446  // double ulx=m_ulx;
447  // double uly=m_uly;
448  // i=(x-ulx)/m_delta_x;
449  // j=(uly-y)/m_delta_y;
450  return true;
451  }
452  else{
453  // i=x;
454  // j=nrOfRow()-y;
455  return false;
456  }
457 }
458 
459 //centre of pixel is always returned (regardless of magic pixel reference)!
460 bool ImgWriterGdal::image2geo(double i, double j, double& x, double& y) const
461 {
462  double gt[6];// { 444720, 30, 0, 3751320, 0, -30 };
463  m_gds->GetGeoTransform(gt);
464 
465  //assuming
466  //adfGeotransform[0]: ULX (upper left X coordinate)
467  //adfGeotransform[1]: $cos(\alpha)\cdot\textrm{Xres}$
468  //adfGeotransform[2]: $-sin(\alpha)\cdot\textrm{Xres}$
469  //adfGeotransform[3]: ULY (upper left Y coordinate)
470  //adfGeotransform[4]: $-sin(\alpha)\cdot\textrm{Yres}$
471  //adfGeotransform[5]: $-cos(\alpha)\cdot\textrm{Yres}$
472 
473  x=gt[0]+(0.5+i)*gt[1]+(0.5+j)*gt[2];
474  y=gt[3]+(0.5+i)*gt[4]+(0.5+j)*gt[5];
475 
476  if(isGeoRef()){
477  // x=m_ulx+(0.5+i)*m_delta_x;
478  // y=m_uly-(0.5+j)*m_delta_y;
479  return true;
480  }
481  else
482  return false;
483 }
484 
485 bool ImgWriterGdal::covers(double x, double y) const
486 {
487  double theULX, theULY, theLRX, theLRY;
488  getBoundingBox(theULX,theULY,theLRX,theLRY);
489  return((x > theULX)&&
490  (x < theLRX)&&
491  (y < theULY)&&
492  (y >theLRY));
493 }
494 
495 bool ImgWriterGdal::covers(double ulx, double uly, double lrx, double lry) const
496 {
497  double theULX, theULY, theLRX, theLRY;
498  getBoundingBox(theULX,theULY,theLRX,theLRY);
499  return((ulx < theLRX)&&(lrx > theULX)&&(lry < theULY)&&(uly > theLRY));
500 }
501 
502 std::string ImgWriterGdal::getGeoTransform() const
503 {
504  double gt[6];// { 444720, 30, 0, 3751320, 0, -30 };
505  if(m_gds)
506  m_gds->GetGeoTransform(gt);
507  else{//virtual writer
508  gt[0]=m_gt[0];
509  gt[1]=m_gt[1];
510  gt[2]=m_gt[2];
511  gt[3]=m_gt[3];
512  gt[4]=m_gt[4];
513  gt[5]=m_gt[5];
514  }
515  std::ostringstream s;
516  s << "[" << gt[0] << "," << gt[1] << "," << gt[2] << "," << gt[3] << "," << gt[4] << "," << gt[5] << "]";
517  return(s.str());
518 }
519 
520 void ImgWriterGdal::getGeoTransform(double* gt) const{
521  if(m_gds)
522  m_gds->GetGeoTransform(gt);
523  else{//virtual writer
524  gt[0]=m_gt[0];
525  gt[1]=m_gt[1];
526  gt[2]=m_gt[2];
527  gt[3]=m_gt[3];
528  gt[4]=m_gt[4];
529  gt[5]=m_gt[5];
530  }
531 }
532 
533 // void ImgWriterGdal::getGeoTransform(double& ulx, double& uly, double& deltaX, double& deltaY, double& rot1, double& rot2) const
534 // {
535 // if(m_gds){
536 // double adfGeoTransform[6];// { 444720, 30, 0, 3751320, 0, -30 };
537 // m_gds->GetGeoTransform(adfGeoTransform);
538 // ulx=adfGeoTransform[0];
539 // deltaX=adfGeoTransform[1];
540 // rot1=adfGeoTransform[2];
541 // uly=adfGeoTransform[3];
542 // rot2=adfGeoTransform[4];
543 // deltaY=-adfGeoTransform[5];//convention of GDAL!
544 // }
545 // else{//virtual writer
546 // ulx=m_ulx;
547 // uly=m_uly;
548 // deltaX=m_delta_x;
549 // deltaY=m_delta_y;
550 // rot1=0;
551 // rot2=0;
552 // }
553 // }
554 
555 GDALDataType ImgWriterGdal::getDataType(int band) const
556 {
557  assert(band<m_nband+1);
558  return (m_gds->GetRasterBand(band+1))->GetRasterDataType();
559 }
560 
561 GDALRasterBand* ImgWriterGdal::getRasterBand(int band)
562 {
563  assert(band<m_nband+1);
564  return (m_gds->GetRasterBand(band+1));
565 }
566 
567 //filename is ascii file containing 5 columns: index R G B ALFA (0:transparent, 255:solid)
568 void ImgWriterGdal::setColorTable(const std::string& filename, int band)
569 {
570  //todo: fool proof table in file (no checking currently done...)
571  std::ifstream ftable(filename.c_str(),std::ios::in);
572  std::string line;
573 // poCT=new GDALColorTable();
574  GDALColorTable colorTable;
575  short nline=0;
576  while(getline(ftable,line)){
577  ++nline;
578  std::istringstream ist(line);
579  GDALColorEntry sEntry;
580  short id;
581  ist >> id >> sEntry.c1 >> sEntry.c2 >> sEntry.c3 >> sEntry.c4;
582 // poCT->SetColorEntry(id,&sEntry);
583  colorTable.SetColorEntry(id,&sEntry);
584  }
585  // assert(nline==colorTable.GetColorEntryCount());
586 // (m_gds->GetRasterBand(band+1))->SetColorTable(poCT);
587  (m_gds->GetRasterBand(band+1))->SetColorTable(&colorTable);
588 }
589 
590 void ImgWriterGdal::setColorTable(GDALColorTable* colorTable, int band)
591 {
592  (m_gds->GetRasterBand(band+1))->SetColorTable(colorTable);
593 }
594 
595 //write an entire image from memory to file
596 bool ImgWriterGdal::writeData(void* pdata, const GDALDataType& dataType, int band) const{
597  //fetch raster band
598  GDALRasterBand *poBand;
599  if(band>=nrOfBand()+1){
600  std::ostringstream s;
601  s << "band (" << band << ") exceeds nrOfBand (" << nrOfBand() << ")";
602  throw(s.str());
603  }
604  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
605  poBand->RasterIO(GF_Write,0,0,nrOfCol(),nrOfRow(),pdata,nrOfCol(),nrOfRow(),dataType,0,0);
606  return true;
607 }