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