Elaboradar  0.1
image.cpp
1 #include "image.h"
2 #include <memory>
3 #ifdef HAVE_GDAL
4 #include <gdal.h>
5 #include <gdal_priv.h>
6 #endif
7 
8 using namespace std;
9 
10 namespace radarelab {
11 
13 {
14 #ifdef HAVE_GDAL
15  static bool initialized = false;
16  if (initialized) return;
17  GDALAllRegister();
18  initialized = true;
19 #else
20  throw std::runtime_error("GDAL support was not enabled at compile time");
21 #endif
22 }
23 
24 #ifdef HAVE_GDAL
25 template<typename T> GDALDataType get_gdal_datatype() { throw std::runtime_error("get_gdal_datatype called for unsupported type"); }
26 template<> GDALDataType get_gdal_datatype<unsigned char>() { return GDT_Byte; }
27 template<> GDALDataType get_gdal_datatype<unsigned short>() { return GDT_UInt16; }
28 template<> GDALDataType get_gdal_datatype<short>() { return GDT_Int16; }
29 template<> GDALDataType get_gdal_datatype<double>() { return GDT_Float64; }
30 template<> GDALDataType get_gdal_datatype<int>() { return GDT_Int32; }
31 template<> GDALDataType get_gdal_datatype<unsigned>() { return GDT_UInt32; }
32 
33 
34 template<typename T>
35 class MatrixDataset : public GDALDataset
36 {
37 public:
38  const Matrix2D<T>& image;
39 
40  MatrixDataset(const Matrix2D<T>& image);
41 
42  //int GetRasterXSize() override { return image.cols(); }
43  //int GetRasterYSize() override { return image.rows(); }
44  //int GetRasterCount() override { return 1; }
45 
46  //const char* GetProjectionRef() override { }
47 
48  // CPLErr GetGeoTransform (double *) override
49 };
50 
51 template<typename T>
52 class MatrixRasterBand : public GDALRasterBand
53 {
54 public:
55  const Matrix2D<T>& image;
56 
57  MatrixRasterBand(MatrixDataset<T>& ds)
58  : image(ds.image)
59  {
60  poDS = &ds;
61  nBand = 1;
62  nBlockXSize = image.cols();
63  nBlockYSize = image.rows();
64  // SetDescription(name.c_str());
65 
66  eDataType = get_gdal_datatype<T>();
67  }
68 
69  // const char* GetUnitType() override {}
70 
71  CPLErr IReadBlock(int xblock, int yblock, void *buf) override
72  {
73  if (xblock != 0 || yblock != 0)
74  {
75  CPLError(CE_Failure, CPLE_AppDefined, "Invalid block number");
76  return CE_Failure;
77  }
78 
79  memcpy(buf, image.data(), image.size() * sizeof(T));
80 
81  return CE_None;
82  }
83 
84  // double GetOffset(int* pbSuccess=NULL) override {}
85  // double GetScale(int* pbSuccess=NULL) override {}
86  // double GetNoDataValue(int* pbSuccess=NULL) override {};
87 };
88 
89 template<typename T>
90 MatrixDataset<T>::MatrixDataset(const Matrix2D<T>& image)
91  : image(image)
92 {
93  nRasterXSize = image.cols();
94  nRasterYSize = image.rows();
95  SetBand(1, new MatrixRasterBand<T>(*this));
96 }
97 
98 template<typename T>
99 void write_image(const Matrix2D<T>& image, const std::string& fname, const std::string& format)
100 {
101  unique_ptr<MatrixDataset<T>> src(new MatrixDataset<T>(image));
102  GDALDriver *driver = GetGDALDriverManager()->GetDriverByName(format.c_str());
103  if (driver == NULL)
104  throw std::runtime_error("driver not found for " + format);
105 
106  GDALDataset* dst = driver->CreateCopy(fname.c_str(), src.get(), false, NULL, NULL, NULL);
107  if (dst == NULL)
108  throw std::runtime_error("cannot create " + fname);
109  GDALClose(dst);
110 }
111 
112 
113 #else
114 template<typename T>
115 void write_image(const Matrix2D<T>& image, const std::string& fname, const std::string& format)
116 {
117  throw std::runtime_error("GDAL support was not enabled at compile time");
118 }
119 #endif
120 
121 template void write_image(const Matrix2D<unsigned char>&, const std::string&, const std::string&);
122 template void write_image(const Matrix2D<unsigned short>&, const std::string&, const std::string&);
123 template void write_image(const Matrix2D<double>&, const std::string&, const std::string&);
124 template void write_image(const Matrix2D<int>&, const std::string&, const std::string&);
125 template void write_image(const Matrix2D<unsigned>&, const std::string&, const std::string&);
126 template void write_image(const Matrix2D<short>&, const std::string&, const std::string&);
127 
128 std::string gdal_extension_for_format(const std::string& format)
129 {
130 #ifdef HAVE_GDAL
131  GDALDriver *driver = GetGDALDriverManager()->GetDriverByName(format.c_str());
132  if (driver == NULL)
133  throw std::runtime_error("driver not found for " + format);
134 
135  const char* ext = driver->GetMetadataItem(GDAL_DMD_EXTENSION, NULL);
136  if (ext == NULL)
137  throw std::runtime_error("extension not found for format " + format);
138  return ext;
139 #else
140  throw std::runtime_error("GDAL support was not enabled at compile time");
141 #endif
142 }
143 
144 }
void gdal_init_once()
Initialize the GDAL library when called for the first time; does nothing all other times.
Definition: image.cpp:12
String functions.
Definition: cart.cpp:4