All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Utils.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/gdal/Utils.cpp
22 
23  \brief Utility functions for GDAL.
24 */
25 
26 // TerraLib
27 #include "../common/StringUtils.h"
28 #include "../common/UnitOfMeasure.h"
29 #include "../common/UnitsOfMeasureManager.h"
30 #include "../dataaccess/dataset/DataSetType.h"
31 #include "../geometry/Coord2D.h"
32 #include "../geometry/Envelope.h"
33 #include "../geometry/Geometry.h"
34 #include "../ogr/Utils.h"
35 #include "../raster/BandProperty.h"
36 #include "../raster/Grid.h"
37 #include "../raster/RasterFactory.h"
38 #include "../raster/RasterProperty.h"
39 #include "../srs/SpatialReferenceSystemManager.h"
40 #include "Band.h"
41 #include "Exception.h"
42 #include "Raster.h"
43 #include "Utils.h"
44 
45 // STL
46 #include <cmath>
47 #include <cstring>
48 #include <vector>
49 
50 // GDAL
51 #include <gdalwarper.h>
52 #include <ogr_api.h>
53 #include <ogr_spatialref.h>
54 #include <ogrsf_frmts.h>
55 
56 // Boost
57 #include <boost/algorithm/string.hpp>
58 #include <boost/format.hpp>
59 #include <boost/filesystem/path.hpp>
60 #include <boost/filesystem/operations.hpp>
61 #include <boost/graph/graph_concepts.hpp>
62 
63 std::string te::gdal::GetSubDataSetName(const std::string& name, const std::string& driverName)
64 {
65  std::vector<std::string> words;
66  boost::split(words, name, boost::is_any_of(":"), boost::token_compress_on);
67 
68  if (words.size() < 3)
69  return name;
70 
71  std::string sdname;
72 
73  if (driverName == "HDF4")
74  {
75  // HDF4_SDS:subdataset_type:file_name:subdataset_index
76  sdname = words[0] + ":" + words[1] + ":" + words[3];
77  if (words.size()>4)
78  sdname = sdname + ":" + words[4];
79  return sdname;
80  }
81  else if (driverName == "NITF")
82  {
83  // NITF_IM:image_index:file_name
84 
85  sdname = words[0] + ":" + words[1];
86  }
87  else if (driverName == "netCDF")
88  {
89  // NETCDF:filename:variable_name
90  sdname = words[0] + ":" + words[2];
91  }
92  else
93  {
94  // From GDAL documentation: "Currently, drivers which support subdatasets are: ADRG, ECRGTOC, GEORASTER,
95  // GTiff, HDF4, HDF5, netCDF, NITF, NTv2, OGDI, PDF, PostGISRaster, Rasterlite,
96  // RPFTOC, RS2, WCS, and WMS.". It seems that the default format is FORMAT:variable:file_name
97  for (size_t i=0; i<words.size()-1;++i)
98  sdname = sdname + ":" + words[i];
99  }
100 
101  return sdname;
102 }
103 
105 {
106  return GetGrid( gds, -1 );
107 }
108 
109 te::rst::Grid* te::gdal::GetGrid(GDALDataset* gds, const int multiResLevel)
110 {
111  if (!gds) return 0;
112  if( multiResLevel != -1 )
113  {
114  if( gds->GetRasterCount() <= 0 ) return 0;
115  if( multiResLevel >= gds->GetRasterBand( 1 )->GetOverviewCount() ) return 0;
116  }
117 
118  // Defining SRID
119 
120  int srid = TE_UNKNOWN_SRS;
121 
122  // The calling of GetProjectionRef isn't thread safe, even for distinct datasets
123  // under some linuxes
124  boost::unique_lock< boost::mutex > lockGuard( getStaticMutex() );
125  const char* projRef = gds->GetProjectionRef();
126  lockGuard.release();
127  getStaticMutex().unlock();
128 
129  if ( ( projRef != 0 ) && ( std::strlen( projRef ) > 0 ) )
130  {
131  char* projRef2 = (char*)projRef;
132  char** projWKTPtr = &(projRef2);
133  OGRSpatialReference oSRS;
134 
135  OGRErr ogrReturn = oSRS.importFromWkt( projWKTPtr );
136 
137  if( ogrReturn == OGRERR_NONE )
138  {
140  }
141  }
142 
143  // Defining the number of rows / lines
144 
145  unsigned int NRows = 0;
146  unsigned int nCols = 0;
147 
148  if( multiResLevel == -1 )
149  {
150  nCols = (unsigned int)gds->GetRasterXSize();
151  NRows = (unsigned int)gds->GetRasterYSize();
152  }
153  else
154  {
155  nCols = (unsigned int)gds->GetRasterBand( 1 )->GetOverview( multiResLevel )->GetXSize();
156  NRows = (unsigned int)gds->GetRasterBand( 1 )->GetOverview( multiResLevel )->GetYSize();
157  }
158 
159  // Defining bounding box
160 
161  double gtp[6];
162  te::rst::Grid* grid = 0;
163 
164  if( gds->GetGeoTransform(gtp) == CE_Failure )
165  {
166  grid = new te::rst::Grid(nCols, NRows, 1.0, 1.0, (te::gm::Envelope*)0, srid);
167  }
168  else
169  {
170  double gridAffineParams[ 6 ];
171  gridAffineParams[ 0 ] = gtp[ 1 ];
172  gridAffineParams[ 1 ] = gtp[ 2 ];
173  gridAffineParams[ 2 ] = gtp[ 0 ];
174  gridAffineParams[ 3 ] = gtp[ 4 ];
175  gridAffineParams[ 4 ] = gtp[ 5 ];
176  gridAffineParams[ 5 ] = gtp[ 3 ];
177 
178  if( multiResLevel == -1 )
179  {
180  grid = new te::rst::Grid(gridAffineParams, nCols, NRows, srid);
181  }
182  else
183  {
184  te::rst::Grid tempGrid(gridAffineParams, (unsigned int)gds->GetRasterXSize(),
185  (unsigned int)gds->GetRasterYSize(), srid);
186  grid = new te::rst::Grid( nCols, NRows, new te::gm::Envelope( *tempGrid.getExtent() ), srid );
187  }
188  }
189 
190  return grid;
191 }
192 
193 void te::gdal::GetBandProperties(GDALDataset* gds, std::vector<te::rst::BandProperty*>& bprops)
194 {
195  if (!gds)
196  return;
197 
198  bprops.clear();
199 
200  int nBands = 0;
201  bool hasPalette = false;
202 
203  if( gds->GetRasterCount() > 0 )
204  {
205  if( gds->GetRasterBand(1)->GetColorInterpretation() == GCI_PaletteIndex )
206  {
207  hasPalette = true;
208  assert( gds->GetRasterBand(1)->GetColorTable() );
209 
210  switch( gds->GetRasterBand(1)->GetColorTable()->GetPaletteInterpretation() )
211  {
212  case GPI_Gray :
213  nBands = 1;
214  break;
215  case GPI_RGB : // RGBA
216  nBands = 4;
217  break;
218  case GPI_CMYK :
219  nBands = 4;
220  break;
221  case GPI_HLS :
222  nBands = 3;
223  break;
224  default :
225  throw Exception(TE_TR("invalid palette interpretation"));
226  break;
227  }
228  }
229  else
230  {
231  nBands = gds->GetRasterCount();
232  }
233  }
234 
235  // retrieve the information about each band
236  for (int rasterIdx = 0; rasterIdx < nBands ; ++rasterIdx)
237  {
238  GDALRasterBand* rasterBand = gds->GetRasterBand( hasPalette ? 1 : ( 1 + rasterIdx) );
239  bprops.push_back( GetBandProperty( rasterBand, rasterIdx ) );
240  }
241 }
242 
244  const unsigned int bandIndex )
245 {
246  if (!gband)
247  return 0;
248 
249  te::rst::BandProperty* bprop = new te::rst::BandProperty(gband->GetBand()-1, GetTeDataType(gband->GetRasterDataType()), "");
250 
251  bprop->m_idx = bandIndex;
252 
253  // te::rst::BandProperty* rb = new te::rst::BandProperty(rasterIdx, dt);
254  bprop->m_colorInterp = GetTeColorInterpretation(gband->GetColorInterpretation());
255 
256  if( bprop->m_colorInterp == te::rst::PaletteIdxCInt )
257  {
258  switch( gband->GetColorTable()->GetPaletteInterpretation() )
259  {
260  case GPI_Gray :
261  switch( bandIndex )
262  {
263  case 0 :
265  break;
266  default :
267  throw Exception(TE_TR("invalid band index"));
268  break;
269  }
270  break;
271  case GPI_RGB : // RGBA
272  switch( bandIndex )
273  {
274  case 0 :
276  break;
277  case 1 :
279  break;
280  case 2 :
282  break;
283  case 3 :
285  break;
286  default :
287  throw Exception(TE_TR("invalid band index"));
288  break;
289  }
290  break;
291  case GPI_CMYK :
292  switch( bandIndex )
293  {
294  case 0 :
296  break;
297  case 1 :
299  break;
300  case 2 :
302  break;
303  case 3 :
305  break;
306  default :
307  throw Exception(TE_TR("invalid band index"));
308  break;
309  }
310  break;
311  case GPI_HLS :
312  switch( bandIndex )
313  {
314  case 0 :
316  break;
317  case 1 :
319  break;
320  case 2 :
322  break;
323  default :
324  throw Exception(TE_TR("invalid band index"));
325  break;
326  }
327  break;
328  default :
329  throw Exception(TE_TR("invalid palette interpretation"));
330  break;
331  }
332  }
333 
334  // find if there is a no data value
335  int noDataValueIsUsed = 0;
336  double nodataval = gband->GetNoDataValue(&noDataValueIsUsed);
337  if (noDataValueIsUsed)
338  bprop->m_noDataValue = nodataval;
339 
340  std::string unitName = gband->GetUnitType();
341  if (!unitName.empty())
343  bprop->m_valuesOffset = gband->GetOffset(0);
344  bprop->m_valuesScale = gband->GetScale(0);
345 
346  gband->GetBlockSize(&bprop->m_blkw, &bprop->m_blkh);
347  bprop->m_nblocksx = (gband->GetXSize() + bprop->m_blkw - 1) / bprop->m_blkw;
348  bprop->m_nblocksy = (gband->GetYSize() + bprop->m_blkh - 1) / bprop->m_blkh;
349 
350  return bprop;
351 }
352 
353 void te::gdal::GetBands(te::gdal::Raster* rst, std::vector<te::gdal::Band*>& bands)
354 {
355  if( !GetBands( rst, -1, bands ) )
356  {
357  throw Exception(TE_TR("Internal error"));
358  }
359 }
360 
361 bool te::gdal::GetBands(te::gdal::Raster* rst, int multiResLevel, std::vector<te::gdal::Band*>& bands)
362 {
363  bands.clear();
364 
365  if( rst == 0 ) return false;
366 
367  GDALDataset* gds = rst->getGDALDataset();
368 
369  if( gds == 0 ) return false;
370 
371  if( ( gds->GetAccess() != GA_ReadOnly ) && ( gds->GetAccess() != GA_Update ) )
372  return false;
373 
374  // Defining the number of bands
375 
376  int terralibBandsNumber = 0;
377 
378  if( gds->GetRasterCount() > 0 )
379  {
380  if( gds->GetRasterBand(1)->GetColorInterpretation() == GCI_PaletteIndex )
381  {
382  if( gds->GetRasterBand(1)->GetColorTable() == 0 )
383  {
384  throw Exception(TE_TR("invalid color table"));
385  }
386 
387  switch( gds->GetRasterBand(1)->GetColorTable()->GetPaletteInterpretation() )
388  {
389  case GPI_Gray :
390  terralibBandsNumber = 1;
391  break;
392  case GPI_RGB : // RGBA
393  terralibBandsNumber = 4;
394  break;
395  case GPI_CMYK :
396  terralibBandsNumber = 4;
397  break;
398  case GPI_HLS :
399  terralibBandsNumber = 3;
400  break;
401  default :
402  throw Exception(TE_TR("invalid palette interpretation"));
403  break;
404  }
405  }
406  else
407  {
408  terralibBandsNumber = rst->getGDALDataset()->GetRasterCount();
409  }
410  }
411 
412  // Creating terralib bands
413 
414  int gdalBandIndex = 1;
415  for (int terralibBandIndex = 0; terralibBandIndex < terralibBandsNumber; terralibBandIndex++)
416  {
417  if( multiResLevel == -1 )
418  {
419  bands.push_back(
420  new te::gdal::Band(
421  rst,
422  terralibBandIndex,
423  rst->getGDALDataset()->GetRasterBand( gdalBandIndex )
424  )
425  );
426  }
427  else
428  {
429  if( multiResLevel < gds->GetRasterBand( gdalBandIndex )->GetOverviewCount() )
430  {
431  bands.push_back(
432  new te::gdal::Band(
433  rst,
434  terralibBandIndex,
435  gds->GetRasterBand( gdalBandIndex )->GetOverview( multiResLevel )
436  )
437  );
438  }
439  else
440  {
441  while( ! bands.empty() )
442  {
443  delete( bands.back() );
444  bands.pop_back();
445  }
446 
447  return false;
448  }
449  }
450 
451  if( rst->getGDALDataset()->GetRasterBand(1)->GetColorInterpretation() !=
452  GCI_PaletteIndex )
453  {
454  ++gdalBandIndex;
455  }
456  }
457 
458  return true;
459 }
460 
462 {
463  GDALDataset* gds = (GDALDataset*) GDALOpen(strAccessInfo.c_str(), GA_ReadOnly);
464  if (!gds)
465  return 0;
466 
467  te::rst::Grid* grid = GetGrid(gds);
468 
469  std::vector<te::rst::BandProperty*> bprops;
470 
471  te::gdal::GetBandProperties(gds, bprops);
472 
473  std::map<std::string, std::string> rinfo;
474 
475  te::rst::RasterProperty* rp = new te::rst::RasterProperty(grid, bprops, rinfo);
476 
477  GDALClose(gds);
478 
479  return rp;
480 }
481 
482 te::gm::Envelope* te::gdal::GetExtent(std::string strAccessInfo)
483 {
484  GDALDataset* gds = (GDALDataset*) GDALOpen(strAccessInfo.c_str(), GA_ReadOnly);
485  if (!gds)
486  return 0;
487  te::rst::Grid* grid = te::gdal::GetGrid(gds);
488  GDALClose(gds);
489  te::gm::Envelope* ext = new te::gm::Envelope(*grid->getExtent());
490  delete grid;
491  return ext;
492 }
493 
494 GDALDataset* te::gdal::CreateRaster(const std::string& name, te::rst::Grid* g, const std::vector<te::rst::BandProperty*>& bands,
495  const std::map<std::string, std::string>& optParams)
496 {
497  std::string driverName = GetDriverName(name);
498 
499  GDALDriverManager* dManPtr = GetGDALDriverManager();
500 
501  GDALDriver* driverPtr = dManPtr->GetDriverByName(driverName.c_str());
502 
503  if(!driverPtr)
504  throw Exception("Could not create raster because the underlying driver was not found!");
505 
506  GDALDataType targetGDataType = te::gdal::GetGDALDataType(bands[0]->m_type);
507 
508  if (targetGDataType == GDT_Unknown)
509  throw Exception("Could not create raster because of unknown band data type!");
510 
511  char** papszOptions = 0;
512 
513  std::map<std::string, std::string>::const_iterator it = optParams.begin();
514 
515  std::map<std::string, std::string>::const_iterator it_end = optParams.end();
516 
517  while(it != it_end)
518  {
519  if(it->first == "URI" || it->first == "SOURCE")
520  {
521  ++it;
522 
523  continue;
524  }
525 
526  papszOptions = CSLSetNameValue(papszOptions, it->first.c_str(), it->second.c_str());
527 
528  ++it;
529  }
530 
531  GDALDataset* poDataset;
532 
533  if (driverName == "JPEG" || driverName == "PNG")
534  {
535  GDALDriver* tmpDriverPtr = dManPtr->GetDriverByName("MEM");
536 
537  poDataset = tmpDriverPtr->Create(name.c_str(),
538  g->getNumberOfColumns(),
539  g->getNumberOfRows(),
540  bands.size(),
541  targetGDataType,
542  papszOptions);
543  }
544  else
545  poDataset = driverPtr->Create(name.c_str(),
546  g->getNumberOfColumns(),
547  g->getNumberOfRows(),
548  bands.size(),
549  targetGDataType,
550  papszOptions);
551 
552  if(papszOptions)
553  CSLDestroy(papszOptions);
554 
555  if(poDataset == 0)
556  throw Exception("Could not create raster!");
557 
558  const double* cgt = g->getGeoreference();
559 
560  double gt[6];
561 
562  gt[0] = cgt[2];
563  gt[1] = cgt[0];
564  gt[2] = cgt[1];
565  gt[3] = cgt[5];
566  gt[4] = cgt[3];
567  gt[5] = cgt[4];
568 
569  poDataset->SetGeoTransform(gt);
570 
571  OGRSpatialReference oSRS;
572 
573  OGRErr osrsErrorReturn = oSRS.importFromEPSG(g->getSRID());
574  CPLErr setProjErrorReturn = CE_Fatal;
575 
576  if( osrsErrorReturn == OGRERR_NONE )
577  {
578  char* projWKTPtr = 0;
579 
580  osrsErrorReturn = oSRS.exportToWkt(&projWKTPtr);
581 
582  if( osrsErrorReturn == OGRERR_NONE )
583  {
584  setProjErrorReturn = poDataset->SetProjection(projWKTPtr);
585  }
586 
587  OGRFree(projWKTPtr);
588  }
589 
590  if( setProjErrorReturn != CE_None )
591  {
592  std::string wktStr = te::srs::SpatialReferenceSystemManager::getInstance().getWkt(
593  g->getSRID() );
594 
595  if( !wktStr.empty() )
596  {
597  setProjErrorReturn = poDataset->SetProjection(wktStr.c_str());
598  }
599  }
600 
601  int nb = static_cast<int>(bands.size());
602 
603  for(int dIdx = 0; dIdx < nb; ++dIdx)
604  {
605  GDALRasterBand* rasterBand = poDataset->GetRasterBand(1 + dIdx);
606 
607  GDALColorInterp ci = te::gdal::GetGDALColorInterpretation(bands[dIdx]->m_colorInterp);
608 
609  rasterBand->SetColorInterpretation(ci);
610 
611  if (ci == GCI_PaletteIndex)
612  {
613  GDALColorTable* gCTablePtr = new GDALColorTable(GPI_RGB);
614  GDALColorEntry gCEntry;
615 
616  for (unsigned int pIdx=0 ; pIdx < bands[dIdx]->m_palette.size(); ++pIdx)
617  {
618  gCEntry.c1 = (short)bands[dIdx]->m_palette[pIdx].c1;
619  gCEntry.c2 = (short)bands[dIdx]->m_palette[pIdx].c2;
620  gCEntry.c3 = (short)bands[dIdx]->m_palette[pIdx].c3;
621  gCEntry.c4 = (short)bands[dIdx]->m_palette[pIdx].c4;
622  gCTablePtr->SetColorEntry(pIdx, &gCEntry);
623  }
624 
625  rasterBand->SetColorTable(gCTablePtr);
626  delete gCTablePtr;
627  }
628  rasterBand->SetNoDataValue(bands[dIdx]->m_noDataValue);
629  rasterBand->SetOffset(bands[dIdx]->m_valuesOffset.real());
630  rasterBand->SetScale(bands[dIdx]->m_valuesScale.real());
631 
632  // maybe there is something else here...
633  }
634 
635  return poDataset;
636 
637 }
638 
640  const std::vector<te::rst::BandProperty*>& bands,
641  const std::map<std::string, std::string>& optParams)
642 {
643  assert(g);
644  assert(bands.size() > 0);
645 
646  std::string accessInfo = GetGDALConnectionInfo(optParams);
647  return te::gdal::CreateRaster(accessInfo, g, bands, optParams);
648 }
649 
650 GDALDataset* te::gdal::GetRasterHandle(const std::string strAccessInfo, te::common::AccessPolicy policy)
651 {
652  GDALAccess gpolicy = GA_ReadOnly;
653 
654  if(policy == te::common::WAccess || policy == te::common::RWAccess)
655  gpolicy = GA_Update;
656 
657  GDALDataset* gds = (GDALDataset*) GDALOpen(strAccessInfo.c_str(), gpolicy);
658 
659  return gds;
660 }
661 
662 std::string te::gdal::MakePGConnectionStr(const std::map<std::string, std::string>& dsInfo)
663 {
664 /*PG":host='<host>' port:'<port>' dbname='<dbname>' user='<user>' password='<password>' [schema='<schema>'] [table='<raster_table>'] [where='<sql_where>'] [mode='<working_mode>']"*/
665 
666  std::map<std::string, std::string>::const_iterator it = dsInfo.find("host");
667  std::map<std::string, std::string>::const_iterator it_end = dsInfo.end();
668  std::string connInfo = "PG:";
669 
670  if(it != it_end)
671  connInfo += " host = " + it->second;
672 
673  it = dsInfo.find("port");
674 
675  if(it != it_end)
676  connInfo += " port = " + it->second;
677 
678  it = dsInfo.find("dbname");
679 
680  if(it != it_end)
681  connInfo += " dbname = " + it->second;
682 
683  it = dsInfo.find("user");
684 
685  if(it != it_end)
686  connInfo += " user = " + it->second;
687 
688  it = dsInfo.find("password");
689 
690  if(it != it_end)
691  connInfo += " password = " + it->second;
692 
693  it = dsInfo.find("schema");
694 
695  if(it != it_end)
696  connInfo += " schema = " + it->second;
697 
698  it = dsInfo.find("table");
699 
700  if(it != it_end)
701  connInfo += " table = " + it->second;
702 
703  it = dsInfo.find("where");
704 
705  if(it != it_end)
706  connInfo += " where = " + it->second;
707 
708  it = dsInfo.find("mode");
709 
710  if(it != it_end)
711  connInfo += " mode = " + it->second;
712 
713  return connInfo;
714 }
715 
716 bool te::gdal::RecognizesSRID(unsigned int srid)
717 {
718  OGRSpatialReference oSRS;
719  oSRS.importFromEPSG(srid);
720  char* coutWKT = NULL;
721  oSRS.exportToWkt(&coutWKT);
722  std::string outwkt(coutWKT);
723  return (!outwkt.empty());
724 }
725 
726 /* This function is based on the WARP tutorial in http://www.gdal.org */
728 {
729  assert(rin);
730  assert(rout);
731 
732  te::gdal::Raster const* grin = static_cast<te::gdal::Raster const *>(rin);
733  te::gdal::Raster* grout = static_cast<te::gdal::Raster*>(rout);
734 
735  GDALDatasetH hSrcDS = grin->getGDALDataset();
736  if (hSrcDS == 0)
737  return false;
738 
739  GDALDatasetH hDstDS = grout->getGDALDataset();
740  if (hDstDS == 0)
741  return false;
742 
743  int nBands = GDALGetRasterCount(hSrcDS);
744 
745  /* Define warp options */
746  GDALWarpOptions *psWarpOptions = GDALCreateWarpOptions();
747  psWarpOptions->hSrcDS = hSrcDS;
748  psWarpOptions->hDstDS = hDstDS;
749  psWarpOptions->nBandCount = nBands;
750  psWarpOptions->panSrcBands = (int*)CPLMalloc(sizeof(int)*psWarpOptions->nBandCount);
751  psWarpOptions->panDstBands = (int*)CPLMalloc(sizeof(int)*psWarpOptions->nBandCount);
752  for (int b = 0; b < psWarpOptions->nBandCount; b++)
753  {
754  psWarpOptions->panSrcBands[b] = b+1;
755  psWarpOptions->panDstBands[b] = b+1;
756  }
757 
758  /* Establish reprojection transformer */
759  psWarpOptions->pTransformerArg = GDALCreateGenImgProjTransformer(hSrcDS, GDALGetProjectionRef(hSrcDS),
760  hDstDS, GDALGetProjectionRef(hDstDS),
761  FALSE, 0.0, 1);
762  psWarpOptions->pfnTransformer = GDALGenImgProjTransform;
763 
764  /* Initialize and execute the warp operation */
765  GDALWarpOperation oOperation;
766  oOperation.Initialize(psWarpOptions);
767  oOperation.WarpRegion(0, 0, GDALGetRasterXSize(hDstDS), GDALGetRasterYSize(hDstDS));
768 
769  /* Close transformer and images */
770  GDALDestroyGenImgProjTransformer(psWarpOptions->pTransformerArg);
771  GDALDestroyWarpOptions(psWarpOptions);
772 
773  return true;
774 }
775 
776 std::string te::gdal::GetDriverName(const std::string& name)
777 {
778 // check if it is a filename, and tries to use its extension
779  boost::filesystem::path mpath(name.c_str());
780 
781  std::string ext = te::common::Convert2UCase(mpath.extension().string());
782  if( ext[ 0 ] == '.' ) ext = ext.substr( 1, ext.size() - 1);
783 
784  std::multimap< std::string, std::string >::const_iterator exttMapIt =
785  GetGDALDriversUCaseExt2DriversMap().find( ext );
786 
787  if( exttMapIt == GetGDALDriversUCaseExt2DriversMap().end() )
788  {
789  return std::string();
790  }
791  else
792  {
793  return exttMapIt->second;
794  }
795 }
796 
797 std::string te::gdal::GetGDALConnectionInfo(const std::map<std::string, std::string>& connInfo)
798 {
799  std::map<std::string, std::string>::const_iterator it = connInfo.find("URI");
800 
801  if(it != connInfo.end())
802  return it->second;
803 
804  it = connInfo.find("SOURCE");
805 
806  if(it != connInfo.end())
807  return it->second;
808 
809  throw Exception(TE_TR("Invalid data source connection information!."));
810 }
811 
812 void te::gdal::Vectorize(GDALRasterBand* band, std::vector<te::gm::Geometry*>& geometries)
813 {
814 // create data source of geometries in memory
815  OGRSFDriver *ogrDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("Memory");
816 
817  OGRDataSource* ds = ogrDriver->CreateDataSource("ds_vectorize", NULL);
818 
819  OGRLayer* ogrLayer = ds->CreateLayer("vectorization", NULL, wkbMultiPolygon, NULL);
820 
821  ogrLayer->CreateField(new OGRFieldDefn("id", OFTInteger));
822 
823 // call polygonize function from gdal
824  if (GDALPolygonize(band, NULL , ogrLayer, 0, NULL, NULL, NULL) == CE_Failure)
825  return;
826 
827 // convert geometries to terralib
828  for (int g = 0; g < ogrLayer->GetFeatureCount(); g++)
829  geometries.push_back(te::ogr::Convert2TerraLib(ogrLayer->GetFeature(g)->GetGeometryRef()));
830 
831  OGRDataSource::DestroyDataSource(ds);
832 }
833 
834 void te::gdal::Rasterize(std::vector<te::gm::Geometry*> geometries, GDALDataset* outraster)
835 {
836 // define list of bands (using single band)
837  std::vector<int> bandList;
838 
839  bandList.push_back(1);
840 
841  std::vector<OGRGeometryH> ogrGeometries;
842 
843  std::vector<double> burnValues;
844 
845 // defining vector of ogr geometries and different values for each one in raster
846  int bvalue = 254;
847  for (std::size_t g = 0; g < geometries.size(); g++)
848  {
849  burnValues.push_back(bvalue % 255);
850 
851  bvalue = bvalue >= 127? bvalue - 126: bvalue > 255? 0: bvalue + 127;
852 
853  ogrGeometries.push_back(te::ogr::Convert2OGR(geometries[g]));
854  }
855 
856  GDALRasterizeGeometries(outraster, bandList.size(), &(bandList[0]), ogrGeometries.size(), &(ogrGeometries[0]), NULL, NULL, &(burnValues[0]), NULL, NULL, NULL);
857 }
858 
859 bool te::gdal::IsSubDataSet( const std::string& uri )
860 {
861  std::size_t firstIdx = uri.find( ":" );
862 
863  if( firstIdx < uri.size() )
864  {
865  std::size_t secondIdx = uri.find( ":", firstIdx + 1 );
866 
867  if( secondIdx < uri.size() )
868  {
869  return true;
870  }
871  else
872  {
873  return false;
874  }
875  }
876  else
877  {
878  return false;
879  }
880 }
881 
882 std::string te::gdal::GetParentDataSetName(const std::string& subDataSetName)
883 {
884  if( IsSubDataSet( subDataSetName ) )
885  {
886  std::size_t firstIdx = subDataSetName.find( ":" );
887 
888  if( firstIdx < subDataSetName.size() )
889  {
890  std::size_t secondIdx = subDataSetName.find( ":", firstIdx + 1 );
891 
892  if( secondIdx < subDataSetName.size() )
893  {
894  return subDataSetName.substr( secondIdx + 1, subDataSetName.size() - firstIdx - 1);
895  }
896  else
897  {
898  return subDataSetName;
899  }
900  }
901  else
902  {
903  return subDataSetName;
904  }
905  }
906  else
907  {
908  return subDataSetName;
909  }
910 }
911 
913 {
914  static boost::mutex getStaticMutexStaticMutex;
915  return getStaticMutexStaticMutex;
916 }
917 
918 const std::map< std::string, te::gdal::DriverMetadata >& te::gdal::GetGDALDriversMetadata()
919 {
920  static std::map< std::string, DriverMetadata > driversMetadata;
921 
922  if( driversMetadata.empty() )
923  {
924  GDALDriverManager* driverManagerPtr = GetGDALDriverManager();
925 
926  int driversCount = driverManagerPtr->GetDriverCount();
927  char** metaInfoPtr = 0;
928  const char* valuePtr = 0;
929 
930  for( int driverIndex = 0 ; driverIndex < driversCount ; ++driverIndex )
931  {
932  GDALDriver* driverPtr = driverManagerPtr->GetDriver(driverIndex);
933 
934  if( driverPtr )
935  {
936  DriverMetadata auxMD;
937  auxMD.m_driverName = driverPtr->GetDescription();
938 
939  metaInfoPtr = driverPtr->GetMetadata();
940 
941  if( metaInfoPtr )
942  {
943  valuePtr = CSLFetchNameValue( metaInfoPtr, "DMD_EXTENSION" );
944  if( valuePtr ) auxMD.m_extension = valuePtr;
945 
946  valuePtr = CSLFetchNameValue( metaInfoPtr, "DMD_LONGNAME" );
947  if( valuePtr ) auxMD.m_longName = valuePtr;
948 
949  valuePtr = CSLFetchNameValue( metaInfoPtr, "DMD_SUBDATASETS" );
950  if( ( valuePtr != 0 ) && ( std::strcmp( "YES", valuePtr ) == 0 ) )
951  {
952  auxMD.m_subDatasetsSupport = true;
953  }
954  else
955  {
956  auxMD.m_subDatasetsSupport = false;
957  }
958  }
959 
960  driversMetadata[ auxMD.m_driverName ] = auxMD;
961  }
962  }
963  }
964 
965  return driversMetadata;
966 }
967 
968 const std::multimap< std::string, std::string >& te::gdal::GetGDALDriversUCaseExt2DriversMap()
969 {
970  static std::multimap< std::string, std::string > extensions;
971 
972  if( extensions.empty() )
973  {
974  const std::map< std::string, DriverMetadata >& driversMetadata = GetGDALDriversMetadata();
975 
976  for( std::map< std::string, DriverMetadata >::const_iterator it = driversMetadata.begin() ;
977  it != driversMetadata.end() ; ++it )
978  {
979  if( ! it->second.m_extension.empty() )
980  {
981  extensions.insert( std::pair< std::string, std::string >(
982  te::common::Convert2UCase( it->second.m_extension ), it->first ) );;
983  }
984  }
985  }
986 
987  return extensions;
988 }
989 
GDALDataset * getGDALDataset() const
Returns the raster GDAL handler.
Definition: Raster.cpp:277
GDALColorInterp GetGDALColorInterpretation(te::rst::ColorInterp ci)
It translates a TerraLib ColorInterpretation to a GDAL ColorInterpretation.
Definition: Utils.h:148
TEGDALEXPORT void Vectorize(GDALRasterBand *band, std::vector< te::gm::Geometry * > &geometries)
Vectorizes a given raster band, using GDALPolygonize function.
Definition: Utils.cpp:812
unsigned int getNumberOfRows() const
Returns the grid number of rows.
Definition: Grid.cpp:209
const std::multimap< std::string, std::string > & GetGDALDriversUCaseExt2DriversMap()
Returns a map all GDAL supported Upper-case extensions to their respective driver names...
Definition: Utils.cpp:968
Palette indexes color interpretation.
Definition: Enums.h:58
This is a class that represents a GDAL Raster.
bool m_subDatasetsSupport
true if the driver has support for sub-datasets (DMD_SUBDATASETS).
Definition: Utils.h:66
std::size_t m_idx
The band index.
Definition: BandProperty.h:132
GDALDataType GetGDALDataType(int tet)
It translates a TerraLib DataType to a GDAL DataType.
Definition: Utils.h:96
Hue channel color interpretation.
Definition: Enums.h:63
Alpha channel color interpretation.
Definition: Enums.h:62
TEOGREXPORT OGRGeometry * Convert2OGR(const te::gm::Geometry *teGeom)
It converts the TerraLib Geometry to OGR Geometry.
Definition: Utils.cpp:80
void GetBands(te::gdal::Raster *rst, std::vector< te::gdal::Band * > &bands)
Gets the list of bands from a GDAL dataset.
Definition: Utils.cpp:353
std::string m_driverName
Driver name (driver description).
Definition: Utils.h:63
Index into a lookup table.
Definition: Enums.h:57
Lightness color interpretation.
Definition: Enums.h:65
te::rst::ColorInterp GetTeColorInterpretation(GDALColorInterp gci)
It translates a GDAL ColorInterpretation to a TerraLib ColorInterpretation.
Definition: Utils.h:121
Utilitary functions to access GDAL and match some of its concepts to TerraLib concepts.
TEGDALEXPORT void GetBandProperties(GDALDataset *gds, std::vector< te::rst::BandProperty * > &bprops)
Gets the list of bands definition from a GDAL dataset.
Definition: Utils.cpp:193
A raster band description.
Definition: BandProperty.h:61
This class represents Raster data.
Definition: Raster.h:61
int getSRID() const
Returns the grid spatial reference system identifier.
Definition: Grid.cpp:265
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
It gives access to values in one band (dimension) of a raster.
int m_nblocksy
The number of blocks in y.
Definition: BandProperty.h:146
void setUnitOfMeasure(te::common::UnitOfMeasurePtr u)
Sets the unit of measure of the values;.
Definition: BandProperty.h:125
const std::map< std::string, DriverMetadata > & GetGDALDriversMetadata()
Returns metadata from all registered GDAL drivers (key: driver name).
Definition: Utils.cpp:918
Red channel color interpretation.
Definition: Enums.h:59
te::rst::BandProperty * GetBandProperty(GDALRasterBand *gband, const unsigned int bandIndex)
Gets the properties of a single band from a GDAL dataset.
Definition: Utils.cpp:243
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
Definition: StringUtils.h:163
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits::max().
Definition: BandProperty.h:136
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:347
Cyan color interpretation.
Definition: Enums.h:66
Raster property.
This class represents raster band description.
Definition: Band.h:64
int GetTeDataType(GDALDataType gt)
It translates a GDAL DataType to a TerraLib DataType.
Definition: Utils.h:72
An exception class for the GDAL module.
AccessPolicy
Supported data access policies (can be used as bitfield).
Definition: Enums.h:40
GDALDataset * CreateRaster(te::rst::Grid *g, const std::vector< te::rst::BandProperty * > &bands, const std::map< std::string, std::string > &optParams)
Creates a raster data using GDAL.
Definition: Utils.cpp:639
GDALDataset * GetRasterHandle(std::string strAccessInfo, te::common::AccessPolicy policy=te::common::RAccess)
Get a handle to a raster file.
Definition: Utils.cpp:650
te::gm::Envelope * GetExtent(std::string strAccessInfo)
Gets the extent of a raster data decoded by GDAL.
Definition: Utils.cpp:482
static UnitsOfMeasureManager & getInstance()
It returns a reference to the singleton instance.
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:44
An abstract class for raster data strucutures.
Definition: Raster.h:71
const double * getGeoreference() const
Returns a list of 6 coefficients describing an affine transformation to georeference a grid...
Definition: Grid.cpp:248
std::string GetParentDataSetName(const std::string &subDataSetName)
It returns the parent dataset name from a Sub DataSet name.
Definition: Utils.cpp:882
TEOGREXPORT te::gm::Geometry * Convert2TerraLib(OGRGeometry *ogrGeom)
It converts the OGR Geometry to TerraLib Geometry.
Definition: Utils.cpp:55
std::complex< double > m_valuesScale
Scale is the values (real and imaginary) which is multiplied to grid values for this sample dimension...
Definition: BandProperty.h:138
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
unsigned int getNumberOfColumns() const
Returns the grid number of columns.
Definition: Grid.cpp:193
Key (black) color interpretation.
Definition: Enums.h:69
Yellow color interpretation.
Definition: Enums.h:68
std::string GetDriverName(const std::string &dsName)
It returns the GDAL driver name associated to a data source name.
Definition: Utils.cpp:776
GDAL driver metadata.
Definition: Utils.h:61
bool IsSubDataSet(const std::string &uri)
Returns true if the given URI is related to a sub-dataset.
Definition: Utils.cpp:859
bool ReprojectRaster(te::rst::Raster const *const rin, te::rst::Raster *rout)
Reprojects a raster to another SRS.
Definition: Utils.cpp:727
std::string m_extension
File extension (DMD_EXTENSION).
Definition: Utils.h:64
bool RecognizesSRID(unsigned int srid)
It returns true if GDAL recognizes the given SRS id.
Definition: Utils.cpp:716
std::string GetGDALConnectionInfo(const std::map< std::string, std::string > &connInfo)
It returns a GDAL connection string from the given map.
Definition: Utils.cpp:797
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
Definition: Grid.cpp:275
std::string MakePGConnectionStr(const std::map< std::string, std::string > &dsInfo)
Returns a PostGIS connection string from the set connection information. The connection string is to ...
Definition: Utils.cpp:662
std::complex< double > m_valuesOffset
Offset is the values (real and imaginary) to add to grid values for this sample dimension, default is 0.
Definition: BandProperty.h:137
TEGDALEXPORT void Rasterize(std::vector< te::gm::Geometry * > geometries, GDALDataset *outraster)
Rasterizes a given vector of geometries, using GDALRasterizeGeometries function.
Definition: Utils.cpp:834
UnitOfMeasurePtr find(unsigned int id) const
Returns a unit of measure identified by its identificaton.
Saturation color interpretation.
Definition: Enums.h:64
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
TEGDALEXPORT boost::mutex & getStaticMutex()
Returns a reference to a static mutex initialized when this module is initialized.
Definition: Utils.cpp:912
Blue channel color interpretation.
Definition: Enums.h:61
A rectified grid is the spatial support for raster data.
Definition: Grid.h:68
std::string m_longName
File long name (DMD_LONGNAME).
Definition: Utils.h:65
Green channel color interpretation.
Definition: Enums.h:60
std::string GetSubDataSetName(const std::string &name, const std::string &driverName)
It returns the Sub DataSet name from the given name or the same name.
Definition: Utils.cpp:63
TEGDALEXPORT te::rst::Grid * GetGrid(GDALDataset *gds)
Gets the grid definition from a GDAL dataset.
Definition: Utils.cpp:104
ColorInterp m_colorInterp
The color interpretation.
Definition: BandProperty.h:140
Magenta color interpretation.
Definition: Enums.h:67
TEOGREXPORT int Convert2TerraLibProjection(OGRSpatialReference *osrs)
It converts the OGR Projection to TerraLib Projection.
Definition: Utils.cpp:126
te::rst::RasterProperty * GetRasterProperty(std::string strAccessInfo)
Gets the complete description from a GDAL dataset.
Definition: Utils.cpp:461