triskele/src/IImage.cpp
2018-08-06 10:53:08 +02:00

126 lines
3.8 KiB
C++

#include "IImage.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
using namespace triskele;
using namespace std;
size_t
IImage::gdalCount = 0;
IImage::IImage (const string &imageFileName)
: geoTransform (6, 0),
fileName (imageFileName),
gdalInputDataset (nullptr),
gdalOutputDataset (nullptr),
read (false)
{
}
IImage::~IImage () {
close ();
}
void
IImage::readImage () {
DEF_LOG ("IImage::readImage", "fileName: " << fileName << " c_str:" << fileName.c_str ());
BOOST_ASSERT (gdalInputDataset == nullptr);
BOOST_ASSERT (gdalOutputDataset == nullptr);
close ();
if (!gdalCount++)
GDALAllRegister ();
dataType = GDT_Unknown;
gdalInputDataset = (GDALDataset *) GDALOpen (fileName.c_str (), GA_ReadOnly);
if (!gdalInputDataset) {
cerr << "GDALError: can't define dataset" << endl;
return;
}
size = Size (gdalInputDataset->GetRasterXSize (),
gdalInputDataset->GetRasterYSize ());
bandCount = gdalInputDataset->GetRasterCount ();
LOG ("size: " << size << " x " << bandCount);
read = true;
projectionRef = gdalInputDataset->GetProjectionRef ();
CPLErr err = gdalInputDataset->GetGeoTransform (&geoTransform[0]);
if (err != CE_None)
cerr << "IImage::readImage: can't read geoTransform from " << fileName << endl;
else
LOG ("geoTransform: " << geoTransform [0] << " " << geoTransform [1] << " " << geoTransform [2] << " " << geoTransform [3] << " " << geoTransform [4] << " " << geoTransform [5]);
for (DimChanel band = 0; band < bandCount; ++band) {
GDALRasterBand &poBand = *gdalInputDataset->GetRasterBand (band+1);
GDALDataType bandType = poBand.GetRasterDataType ();
LOG ("band " << band << " " << GDALGetDataTypeName (bandType));
if (dataType == GDT_Unknown) {
dataType = bandType;
continue;
}
if (dataType != bandType) {
dataType = GDT_Unknown;
LOG ("Can't parse inconsistant bands");
// exit (1);
return;
}
}
LOG ("gdalCount: " << gdalCount);
}
void
IImage::createImage (const Size &size, const GDALDataType &dataType, const DimChanel &nbBands) {
DEF_LOG ("IImage::createImage", "fileName: " << fileName);
BOOST_ASSERT (gdalInputDataset == nullptr);
BOOST_ASSERT (gdalOutputDataset == nullptr);
this->size = size;
this->dataType = dataType;
if (!gdalCount++)
GDALAllRegister ();
string fileExtension = boost::filesystem::extension (fileName);
boost::algorithm::to_lower (fileExtension);
if (!boost::iequals (fileExtension, ".tif") &&
!boost::iequals (fileExtension, ".tiff")) {
cerr << "!!! Warning !!!" << endl
<< "Output image not a TIF file <" << fileName << endl;
BOOST_ASSERT (false);
}
GDALDriver *driverTiff = GetGDALDriverManager ()->GetDriverByName ("GTiff");
remove (fileName.c_str ());
gdalOutputDataset = driverTiff->Create (fileName.c_str (), size.width, size.height, nbBands, dataType, NULL);
LOG("gdalCount: " << gdalCount);
}
void
IImage::createImage (const Size &size, const GDALDataType &dataType, const DimChanel &nbBands,
const IImage &inputImage, const Point &topLeft)
{
createImage (size, dataType, nbBands);
string projectionRef;
vector<double> geoTransform;
inputImage.getGeo (projectionRef, geoTransform);
setGeo (projectionRef, geoTransform, topLeft);
}
void
IImage::close () {
DEF_LOG ("IImage::close", "fileName: " << fileName);
if (gdalOutputDataset) {
GDALClose (gdalOutputDataset);
gdalOutputDataset = nullptr;
if (!--gdalCount)
GDALDestroyDriverManager ();
}
if (gdalInputDataset) {
GDALClose (gdalInputDataset);
gdalInputDataset = nullptr;
if (!--gdalCount)
GDALDestroyDriverManager ();
}
BOOST_ASSERT (gdalCount >= 0);
LOG ("gdalCount:" << gdalCount);
read = false;
}