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"
51 #include <gdalwarper.h>
53 #include <ogr_spatialref.h>
54 #include <ogrsf_frmts.h>
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>
65 std::vector<std::string> words;
66 boost::split(words, name, boost::is_any_of(
":"), boost::token_compress_on);
73 if (driverName ==
"HDF4")
76 sdname = words[0] +
":" + words[1] +
":" + words[3];
78 sdname = sdname +
":" + words[4];
81 else if (driverName ==
"NITF")
85 sdname = words[0] +
":" + words[1];
87 else if (driverName ==
"netCDF")
90 sdname = words[0] +
":" + words[2];
97 for (
size_t i=0; i<words.size()-1;++i)
98 sdname = sdname +
":" + words[i];
112 if( multiResLevel != -1 )
114 if( gds->GetRasterCount() <= 0 )
return 0;
115 if( multiResLevel >= gds->GetRasterBand( 1 )->GetOverviewCount() )
return 0;
125 const char* projRef = gds->GetProjectionRef();
129 if ( ( projRef != 0 ) && ( std::strlen( projRef ) > 0 ) )
131 char* projRef2 = (
char*)projRef;
132 char** projWKTPtr = &(projRef2);
133 OGRSpatialReference oSRS;
135 OGRErr ogrReturn = oSRS.importFromWkt( projWKTPtr );
137 if( ogrReturn == OGRERR_NONE )
145 unsigned int NRows = 0;
146 unsigned int nCols = 0;
148 if( multiResLevel == -1 )
150 nCols = (
unsigned int)gds->GetRasterXSize();
151 NRows = (
unsigned int)gds->GetRasterYSize();
155 nCols = (
unsigned int)gds->GetRasterBand( 1 )->GetOverview( multiResLevel )->GetXSize();
156 NRows = (
unsigned int)gds->GetRasterBand( 1 )->GetOverview( multiResLevel )->GetYSize();
164 if( gds->GetGeoTransform(gtp) == CE_Failure )
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 ];
178 if( multiResLevel == -1 )
180 grid =
new te::rst::Grid(gridAffineParams, nCols, NRows, srid);
184 te::rst::Grid tempGrid(gridAffineParams, (
unsigned int)gds->GetRasterXSize(),
185 (
unsigned int)gds->GetRasterYSize(), srid);
201 bool hasPalette =
false;
203 if( gds->GetRasterCount() > 0 )
205 if( gds->GetRasterBand(1)->GetColorInterpretation() == GCI_PaletteIndex )
208 assert( gds->GetRasterBand(1)->GetColorTable() );
210 switch( gds->GetRasterBand(1)->GetColorTable()->GetPaletteInterpretation() )
225 throw Exception(
TE_TR(
"invalid palette interpretation"));
231 nBands = gds->GetRasterCount();
236 for (
int rasterIdx = 0; rasterIdx < nBands ; ++rasterIdx)
238 GDALRasterBand* rasterBand = gds->GetRasterBand( hasPalette ? 1 : ( 1 + rasterIdx) );
244 const unsigned int bandIndex )
251 bprop->
m_idx = bandIndex;
258 switch( gband->GetColorTable()->GetPaletteInterpretation() )
267 throw Exception(
TE_TR(
"invalid band index"));
287 throw Exception(
TE_TR(
"invalid band index"));
307 throw Exception(
TE_TR(
"invalid band index"));
324 throw Exception(
TE_TR(
"invalid band index"));
329 throw Exception(
TE_TR(
"invalid palette interpretation"));
335 int noDataValueIsUsed = 0;
336 double nodataval = gband->GetNoDataValue(&noDataValueIsUsed);
337 if (noDataValueIsUsed)
340 std::string unitName = gband->GetUnitType();
341 if (!unitName.empty())
357 throw Exception(
TE_TR(
"Internal error"));
365 if( rst == 0 )
return false;
369 if( gds == 0 )
return false;
371 if( ( gds->GetAccess() != GA_ReadOnly ) && ( gds->GetAccess() != GA_Update ) )
376 int terralibBandsNumber = 0;
378 if( gds->GetRasterCount() > 0 )
380 if( gds->GetRasterBand(1)->GetColorInterpretation() == GCI_PaletteIndex )
382 if( gds->GetRasterBand(1)->GetColorTable() == 0 )
384 throw Exception(
TE_TR(
"invalid color table"));
387 switch( gds->GetRasterBand(1)->GetColorTable()->GetPaletteInterpretation() )
390 terralibBandsNumber = 1;
393 terralibBandsNumber = 4;
396 terralibBandsNumber = 4;
399 terralibBandsNumber = 3;
402 throw Exception(
TE_TR(
"invalid palette interpretation"));
414 int gdalBandIndex = 1;
415 for (
int terralibBandIndex = 0; terralibBandIndex < terralibBandsNumber; terralibBandIndex++)
417 if( multiResLevel == -1 )
429 if( multiResLevel < gds->GetRasterBand( gdalBandIndex )->GetOverviewCount() )
435 gds->GetRasterBand( gdalBandIndex )->GetOverview( multiResLevel )
441 while( ! bands.empty() )
443 delete( bands.back() );
451 if( rst->
getGDALDataset()->GetRasterBand(1)->GetColorInterpretation() !=
463 GDALDataset* gds = (GDALDataset*) GDALOpen(strAccessInfo.c_str(), GA_ReadOnly);
469 std::vector<te::rst::BandProperty*> bprops;
473 std::map<std::string, std::string> rinfo;
484 GDALDataset* gds = (GDALDataset*) GDALOpen(strAccessInfo.c_str(), GA_ReadOnly);
495 const std::map<std::string, std::string>& optParams)
499 GDALDriverManager* dManPtr = GetGDALDriverManager();
501 GDALDriver* driverPtr = dManPtr->GetDriverByName(driverName.c_str());
504 throw Exception(
"Could not create raster because the underlying driver was not found!");
508 if (targetGDataType == GDT_Unknown)
509 throw Exception(
"Could not create raster because of unknown band data type!");
511 char** papszOptions = 0;
513 std::map<std::string, std::string>::const_iterator it = optParams.begin();
515 std::map<std::string, std::string>::const_iterator it_end = optParams.end();
519 if(it->first ==
"URI" || it->first ==
"SOURCE")
526 papszOptions = CSLSetNameValue(papszOptions, it->first.c_str(), it->second.c_str());
531 GDALDataset* poDataset;
533 if (driverName ==
"JPEG" || driverName ==
"PNG")
535 GDALDriver* tmpDriverPtr = dManPtr->GetDriverByName(
"MEM");
537 poDataset = tmpDriverPtr->Create(name.c_str(),
545 poDataset = driverPtr->Create(name.c_str(),
553 CSLDestroy(papszOptions);
556 throw Exception(
"Could not create raster!");
569 poDataset->SetGeoTransform(gt);
571 OGRSpatialReference oSRS;
573 OGRErr osrsErrorReturn = oSRS.importFromEPSG(g->
getSRID());
574 CPLErr setProjErrorReturn = CE_Fatal;
576 if( osrsErrorReturn == OGRERR_NONE )
578 char* projWKTPtr = 0;
580 osrsErrorReturn = oSRS.exportToWkt(&projWKTPtr);
582 if( osrsErrorReturn == OGRERR_NONE )
584 setProjErrorReturn = poDataset->SetProjection(projWKTPtr);
590 if( setProjErrorReturn != CE_None )
595 if( !wktStr.empty() )
597 setProjErrorReturn = poDataset->SetProjection(wktStr.c_str());
601 int nb =
static_cast<int>(bands.size());
603 for(
int dIdx = 0; dIdx < nb; ++dIdx)
605 GDALRasterBand* rasterBand = poDataset->GetRasterBand(1 + dIdx);
609 rasterBand->SetColorInterpretation(ci);
611 if (ci == GCI_PaletteIndex)
613 GDALColorTable* gCTablePtr =
new GDALColorTable(GPI_RGB);
614 GDALColorEntry gCEntry;
616 for (
unsigned int pIdx=0 ; pIdx < bands[dIdx]->m_palette.size(); ++pIdx)
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);
625 rasterBand->SetColorTable(gCTablePtr);
628 rasterBand->SetNoDataValue(bands[dIdx]->m_noDataValue);
629 rasterBand->SetOffset(bands[dIdx]->m_valuesOffset.real());
630 rasterBand->SetScale(bands[dIdx]->m_valuesScale.real());
640 const std::vector<te::rst::BandProperty*>& bands,
641 const std::map<std::string, std::string>& optParams)
644 assert(bands.size() > 0);
652 GDALAccess gpolicy = GA_ReadOnly;
657 GDALDataset* gds = (GDALDataset*) GDALOpen(strAccessInfo.c_str(), gpolicy);
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:";
671 connInfo +=
" host = " + it->second;
673 it = dsInfo.find(
"port");
676 connInfo +=
" port = " + it->second;
678 it = dsInfo.find(
"dbname");
681 connInfo +=
" dbname = " + it->second;
683 it = dsInfo.find(
"user");
686 connInfo +=
" user = " + it->second;
688 it = dsInfo.find(
"password");
691 connInfo +=
" password = " + it->second;
693 it = dsInfo.find(
"schema");
696 connInfo +=
" schema = " + it->second;
698 it = dsInfo.find(
"table");
701 connInfo +=
" table = " + it->second;
703 it = dsInfo.find(
"where");
706 connInfo +=
" where = " + it->second;
708 it = dsInfo.find(
"mode");
711 connInfo +=
" mode = " + it->second;
718 OGRSpatialReference oSRS;
719 oSRS.importFromEPSG(srid);
720 char* coutWKT = NULL;
721 oSRS.exportToWkt(&coutWKT);
722 std::string outwkt(coutWKT);
723 return (!outwkt.empty());
743 int nBands = GDALGetRasterCount(hSrcDS);
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++)
754 psWarpOptions->panSrcBands[b] = b+1;
755 psWarpOptions->panDstBands[b] = b+1;
759 psWarpOptions->pTransformerArg = GDALCreateGenImgProjTransformer(hSrcDS, GDALGetProjectionRef(hSrcDS),
760 hDstDS, GDALGetProjectionRef(hDstDS),
762 psWarpOptions->pfnTransformer = GDALGenImgProjTransform;
765 GDALWarpOperation oOperation;
766 oOperation.Initialize(psWarpOptions);
767 oOperation.WarpRegion(0, 0, GDALGetRasterXSize(hDstDS), GDALGetRasterYSize(hDstDS));
770 GDALDestroyGenImgProjTransformer(psWarpOptions->pTransformerArg);
771 GDALDestroyWarpOptions(psWarpOptions);
779 boost::filesystem::path mpath(name.c_str());
782 if( ext[ 0 ] ==
'.' ) ext = ext.substr( 1, ext.size() - 1);
784 std::multimap< std::string, std::string >::const_iterator exttMapIt =
789 return std::string();
793 return exttMapIt->second;
799 std::map<std::string, std::string>::const_iterator it = connInfo.find(
"URI");
801 if(it != connInfo.end())
804 it = connInfo.find(
"SOURCE");
806 if(it != connInfo.end())
809 throw Exception(
TE_TR(
"Invalid data source connection information!."));
815 OGRSFDriver *ogrDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(
"Memory");
817 OGRDataSource* ds = ogrDriver->CreateDataSource(
"ds_vectorize", NULL);
819 OGRLayer* ogrLayer = ds->CreateLayer(
"vectorization", NULL, wkbMultiPolygon, NULL);
821 ogrLayer->CreateField(
new OGRFieldDefn(
"id", OFTInteger));
824 if (GDALPolygonize(band, NULL , ogrLayer, 0, NULL, NULL, NULL) == CE_Failure)
828 for (
int g = 0; g < ogrLayer->GetFeatureCount(); g++)
831 OGRDataSource::DestroyDataSource(ds);
837 std::vector<int> bandList;
839 bandList.push_back(1);
841 std::vector<OGRGeometryH> ogrGeometries;
843 std::vector<double> burnValues;
847 for (std::size_t g = 0; g < geometries.size(); g++)
849 burnValues.push_back(bvalue % 255);
851 bvalue = bvalue >= 127? bvalue - 126: bvalue > 255? 0: bvalue + 127;
856 GDALRasterizeGeometries(outraster, bandList.size(), &(bandList[0]), ogrGeometries.size(), &(ogrGeometries[0]), NULL, NULL, &(burnValues[0]), NULL, NULL, NULL);
861 std::size_t firstIdx = uri.find(
":" );
863 if( firstIdx < uri.size() )
865 std::size_t secondIdx = uri.find(
":", firstIdx + 1 );
867 if( secondIdx < uri.size() )
886 std::size_t firstIdx = subDataSetName.find(
":" );
888 if( firstIdx < subDataSetName.size() )
890 std::size_t secondIdx = subDataSetName.find(
":", firstIdx + 1 );
892 if( secondIdx < subDataSetName.size() )
894 return subDataSetName.substr( secondIdx + 1, subDataSetName.size() - firstIdx - 1);
898 return subDataSetName;
903 return subDataSetName;
908 return subDataSetName;
914 static boost::mutex getStaticMutexStaticMutex;
915 return getStaticMutexStaticMutex;
920 static std::map< std::string, DriverMetadata > driversMetadata;
922 if( driversMetadata.empty() )
924 GDALDriverManager* driverManagerPtr = GetGDALDriverManager();
926 int driversCount = driverManagerPtr->GetDriverCount();
927 char** metaInfoPtr = 0;
928 const char* valuePtr = 0;
930 for(
int driverIndex = 0 ; driverIndex < driversCount ; ++driverIndex )
932 GDALDriver* driverPtr = driverManagerPtr->GetDriver(driverIndex);
939 metaInfoPtr = driverPtr->GetMetadata();
943 valuePtr = CSLFetchNameValue( metaInfoPtr,
"DMD_EXTENSION" );
946 valuePtr = CSLFetchNameValue( metaInfoPtr,
"DMD_LONGNAME" );
949 valuePtr = CSLFetchNameValue( metaInfoPtr,
"DMD_SUBDATASETS" );
950 if( ( valuePtr != 0 ) && ( std::strcmp(
"YES", valuePtr ) == 0 ) )
965 return driversMetadata;
970 static std::multimap< std::string, std::string > extensions;
972 if( extensions.empty() )
976 for( std::map< std::string, DriverMetadata >::const_iterator it = driversMetadata.begin() ;
977 it != driversMetadata.end() ; ++it )
979 if( ! it->second.m_extension.empty() )
981 extensions.insert( std::pair< std::string, std::string >(
GDALDataset * getGDALDataset() const
Returns the raster GDAL handler.
GDALColorInterp GetGDALColorInterpretation(te::rst::ColorInterp ci)
It translates a TerraLib ColorInterpretation to a GDAL ColorInterpretation.
TEGDALEXPORT void Vectorize(GDALRasterBand *band, std::vector< te::gm::Geometry * > &geometries)
Vectorizes a given raster band, using GDALPolygonize function.
unsigned int getNumberOfRows() const
Returns the grid number of rows.
const std::multimap< std::string, std::string > & GetGDALDriversUCaseExt2DriversMap()
Returns a map all GDAL supported Upper-case extensions to their respective driver names...
Palette indexes color interpretation.
This is a class that represents a GDAL Raster.
std::size_t m_idx
The band index.
GDALDataType GetGDALDataType(int tet)
It translates a TerraLib DataType to a GDAL DataType.
Hue channel color interpretation.
Alpha channel color interpretation.
TEOGREXPORT OGRGeometry * Convert2OGR(const te::gm::Geometry *teGeom)
It converts the TerraLib Geometry to OGR Geometry.
void GetBands(te::gdal::Raster *rst, std::vector< te::gdal::Band * > &bands)
Gets the list of bands from a GDAL dataset.
Index into a lookup table.
Lightness color interpretation.
te::rst::ColorInterp GetTeColorInterpretation(GDALColorInterp gci)
It translates a GDAL ColorInterpretation to a TerraLib ColorInterpretation.
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.
A raster band description.
This class represents Raster data.
int getSRID() const
Returns the grid spatial reference system identifier.
int m_nblocksx
The number of blocks in x.
It gives access to values in one band (dimension) of a raster.
int m_nblocksy
The number of blocks in y.
void setUnitOfMeasure(te::common::UnitOfMeasurePtr u)
Sets the unit of measure of the values;.
const std::map< std::string, DriverMetadata > & GetGDALDriversMetadata()
Returns metadata from all registered GDAL drivers (key: driver name).
Red channel color interpretation.
te::rst::BandProperty * GetBandProperty(GDALRasterBand *gband, const unsigned int bandIndex)
Gets the properties of a single band from a GDAL dataset.
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits::max().
#define TE_TR(message)
It marks a string in order to get translated.
Cyan color interpretation.
This class represents raster band description.
int GetTeDataType(GDALDataType gt)
It translates a GDAL DataType to a TerraLib DataType.
An exception class for the GDAL module.
AccessPolicy
Supported data access policies (can be used as bitfield).
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.
GDALDataset * GetRasterHandle(std::string strAccessInfo, te::common::AccessPolicy policy=te::common::RAccess)
Get a handle to a raster file.
te::gm::Envelope * GetExtent(std::string strAccessInfo)
Gets the extent of a raster data decoded by GDAL.
static UnitsOfMeasureManager & getInstance()
It returns a reference to the singleton instance.
An Envelope defines a 2D rectangular region.
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
An abstract class for raster data strucutures.
const double * getGeoreference() const
Returns a list of 6 coefficients describing an affine transformation to georeference a grid...
std::string GetParentDataSetName(const std::string &subDataSetName)
It returns the parent dataset name from a Sub DataSet name.
TEOGREXPORT te::gm::Geometry * Convert2TerraLib(OGRGeometry *ogrGeom)
It converts the OGR Geometry to TerraLib Geometry.
std::complex< double > m_valuesScale
Scale is the values (real and imaginary) which is multiplied to grid values for this sample dimension...
int m_blkw
Block width (pixels).
unsigned int getNumberOfColumns() const
Returns the grid number of columns.
Key (black) color interpretation.
Yellow color interpretation.
std::string GetDriverName(const std::string &dsName)
It returns the GDAL driver name associated to a data source name.
bool IsSubDataSet(const std::string &uri)
Returns true if the given URI is related to a sub-dataset.
bool ReprojectRaster(te::rst::Raster const *const rin, te::rst::Raster *rout)
Reprojects a raster to another SRS.
bool RecognizesSRID(unsigned int srid)
It returns true if GDAL recognizes the given SRS id.
std::string GetGDALConnectionInfo(const std::map< std::string, std::string > &connInfo)
It returns a GDAL connection string from the given map.
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
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 ...
std::complex< double > m_valuesOffset
Offset is the values (real and imaginary) to add to grid values for this sample dimension, default is 0.
TEGDALEXPORT void Rasterize(std::vector< te::gm::Geometry * > geometries, GDALDataset *outraster)
Rasterizes a given vector of geometries, using GDALRasterizeGeometries function.
UnitOfMeasurePtr find(unsigned int id) const
Returns a unit of measure identified by its identificaton.
Saturation color interpretation.
int m_blkh
Block height (pixels).
TEGDALEXPORT boost::mutex & getStaticMutex()
Returns a reference to a static mutex initialized when this module is initialized.
Blue channel color interpretation.
A rectified grid is the spatial support for raster data.
Green channel color interpretation.
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.
TEGDALEXPORT te::rst::Grid * GetGrid(GDALDataset *gds)
Gets the grid definition from a GDAL dataset.
ColorInterp m_colorInterp
The color interpretation.
Magenta color interpretation.
TEOGREXPORT int Convert2TerraLibProjection(OGRSpatialReference *osrs)
It converts the OGR Projection to TerraLib Projection.
te::rst::RasterProperty * GetRasterProperty(std::string strAccessInfo)
Gets the complete description from a GDAL dataset.