FileGeoTIFF.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31 #ifndef DRAIN_FILE_GEO_TIFF
32 #define DRAIN_FILE_GEO_TIFF
33 
34 #include "FileTIFF.h"
35 
36 #ifndef USE_GEOTIFF_NO
37 
38 #include <geotiff.h>
39 #include <geotiffio.h>
40 #include <geo_normalize.h>
41 
42 #include "drain/util/Flags.h"
43 //#include "drain/util/TreeXML.h"
44 #include "TreeXML-GDAL.h"
45 
46 
47 
48 namespace drain
49 {
50 
51 namespace image
52 {
53 
54 
55 
61 class FileGeoTIFF : public FileTIFF {
62 public:
63 
64  // typedef std::map<short, std::list<std::pair<geokey_t, drain::Variable> > > epsg_map_t;
65  // static epsg_map_t epsgConf;
66 
67  FileGeoTIFF() : FileTIFF(), gtif(nullptr){
68  //gdalInfo.data.setType(GDAL::tag_t::ROOT);
69  gdalMetadata(GDAL::tag_t::ROOT);
70  }
71 
72  FileGeoTIFF(const std::string & path, const std::string & mode = "w") : FileTIFF(), gtif(nullptr){
73  //gdalInfo.data.setType(GDAL::tag_t::ROOT);
74  gdalMetadata(GDAL::tag_t::ROOT);
75  open(path, mode);
76  }
77 
78  virtual inline
79  ~FileGeoTIFF(){
80  //gt_close();
81  close();
82  }
83 
85  virtual
86  void open(const std::string & path, const std::string & mode = "w");
87 
88 
89  template <typename T>
90  void setGeoTiffField(geokey_t tag, T value){
91  if ((std::is_enum<T>::value) || (std::is_integral<T>::value)){
92  GTIFKeySet(gtif, tag, TYPE_SHORT, 1, static_cast<short int>(value));
93  }
94  else if (std::is_floating_point<T>::value){
95  GTIFKeySet(gtif, tag, TYPE_FLOAT, 1, value);
96  }
97  else {
98  drain::Logger mout(__FILE__, __FUNCTION__);
99  mout.warn("TAG: ", tag, ", value:", value, ", type=", typeid(T).name()); // , drain::Type::call<drain::nameGetter>(typeid(T)));
100  mout.error("Not implemented");
101  }
102  }
103 
104 
106  void writeMetadata();
107 
108 
109  virtual
110  void close();
111 
113  inline virtual
114  bool isOpen() const {
115  return FileTIFF::isOpen() && (gtif != nullptr);
116  }
117 
119 
122  // static
123  // bool strictCompliance;
124 
125  typedef enum {UNDEFINED=0, TIFF=1, GEOTIFF=2, EPSG=6, STRICT=10} TiffCompliance;
126 
127  //typedef drain::EnumFlagger<drain::SingleFlagger<TiffCompliance> > tiffComplianceFlagger;
128  typedef drain::EnumFlagger<drain::MultiFlagger<TiffCompliance> > complianceFlagger;
129 
130  static
131  complianceFlagger compliancyFlagger;
132 
133  static
134  std::string compliancy;
135  //TiffCompliance compliance;
137  // static bool plainEPSG;
138 
139  TreeGDAL gdalMetadata;
143  void setGdalScale(double scale=1.0, double offset=0.0);
144 
146 
149  void setGdalNoData(const std::string & nodata);
150 
151 
152  template <class T>
153  void setGdal(const std::string & key, const T & value, int sample=-1, const std::string & role = ""){
154 
155  TreeGDAL & elem = gdalMetadata[key](GDAL::ITEM);
156  //elem->setType(GDAL::UNDEFINED);
157  //elem->setType(GDAL::ITEM);
158 
159  //NodeGDAL gdalItem = gdalMetadata[key](NodeGDAL::ITEM).data;
160 
161  NodeGDAL & item = elem.data;
162  item.name = key;
163  item.setText(value);
164  /*
165  this->name = name;
166  this->ctext = ctext.toStr();
167  this->sample = sample;
168  */
169 
170  if (sample >= 0){
171  //item.sample = sample;
172  item.set("sample", sample); // create Variable
173  if (role.empty()){
174  item.role = key;
176  }
177  else {
178  item.role = role;
179  }
180  }
181 
182  //item.set("name", "gdalItem.name"); // KLUDGE
183  //iItem.set("role", "gdalItem.role"); // KLUDGE
184  }
185 
187 
190  void setGeoMetaData(const drain::image::GeoFrame & frame);
191 
193 
196  void setProjectionEPSG(short epsg);
197 
199 
202  void setProjection(const std::string & proj);
203 
205  void setProjection(const drain::Proj6 & proj);
206 
208  void setProjectionLongLat();
209 
210 
211 
212  /*
213  template <typename T>
214  inline
215  tagtype_t getTagType(){
216  const typename tagtype_map_t::const_iterator it = tagtype_map.find(&typeid(T));
217  if (it != tagtype_map.end()){
218  return it->second;
219  }
220  else {
221  drain::Logger mout(__FILE__, __FUNCTION__);
222  mout.warn("unknown/unsupported GTIFF tag basetype: ", typeid(T).name());
223  return TYPE_UNKNOWN;
224  }
225  }
226  */
227 
228 protected:
229 
230 
231  GTIF *gtif;
232 
233  /*
234  typedef std::map<const std::type_info *,tagtype_t> tagtype_map_t;
235 
236  static
237  const tagtype_map_t tagtype_map;
238  */
239 
240 };
241 
242 template <>
243 inline
244 void FileGeoTIFF::setGeoTiffField(geokey_t tag, const char *value){
245  GTIFKeySet(gtif, tag, TYPE_ASCII, strlen(value)+1, value);
246 }
247 
248 template <>
249 inline
250 void FileGeoTIFF::setGeoTiffField(geokey_t tag, const std::string & value){
251  GTIFKeySet(gtif, tag, TYPE_ASCII, value.size()+1, value.c_str());
252 }
253 
254 
255 } // image::
256 
257 template <>
259 
260 /*
261 template <>
262 template <>
263 image::TreeGDAL & image::TreeGDAL::operator()(const image::NodeGDAL::tag_t & type);
264 */
265 
266 } // drain::
267 #endif
268 
269 #endif
270 
271 
272 /*
273 
274 template <>
275 inline
276 tagtype_t FileGeoTIFF::getTagType<unsigned char>(){ return TYPE_BYTE;};
277 
278 template <>
279 inline
280 tagtype_t FileGeoTIFF::getTagType<unsigned short>(){ return TYPE_SHORT;}
281 
282 template <>
283 inline
284 tagtype_t FileGeoTIFF::getTagType<unsigned long>(){ return TYPE_LONG;};
285 
286 template <>
287 inline
288 tagtype_t FileGeoTIFF::getTagType<std::string>(){ return TYPE_ASCII;};
289 
290 template <>
291 inline
292 tagtype_t FileGeoTIFF::getTagType<float>(){ return TYPE_FLOAT;};
293 
294 template <>
295 inline
296 tagtype_t FileGeoTIFF::getTagType<double>(){ return TYPE_DOUBLE;};
297 
298 template <>
299 inline
300 tagtype_t FileGeoTIFF::getTagType<signed char>(){ return TYPE_SBYTE;};
301 
302 template <>
303 inline
304 tagtype_t FileGeoTIFF::getTagType<signed short>(){ return TYPE_SSHORT;};
305 
306 template <>
307 inline
308 tagtype_t FileGeoTIFF::getTagType<signed long>(){ return TYPE_SLONG;};
309 //inline getTagType<>(){ return TYPE_UNKNOWN);
310 //inline getTagType<>(){ return TYPE_RATIONAL);
311 */
Flagger accepting values of enum type E.
Definition: Flags.h:763
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Logger & error(const TT &... args)
Echoes.
Definition: Log.h:412
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:426
Definition: Proj6.h:257
static std::string & lowerCase(std::string &s, size_t n=std::numeric_limits< size_t >::max())
Turns n first characters lowercase. ASCII only.
Definition: String.cpp:270
Definition: FileGeoTIFF.h:61
TiffCompliance
Require strict GeoTIFF compliance.
Definition: FileGeoTIFF.h:125
void setGdalScale(double scale=1.0, double offset=0.0)
Definition: FileGeoTIFF.cpp:247
void setGdalNoData(const std::string &nodata)
This is between Tiff and GeoTiff?
Definition: FileGeoTIFF.cpp:257
void setGeoMetaData(const drain::image::GeoFrame &frame)
Sets projection and bounding box. Adjusts spatial resolution accordingly.
Definition: FileGeoTIFF.cpp:290
virtual void open(const std::string &path, const std::string &mode="w")
Opens a GeoTIFF file.
Definition: FileGeoTIFF.cpp:163
void setProjectionLongLat()
Sets projection to plain longitude-latitude mapping.
Definition: FileGeoTIFF.cpp:482
void setProjectionEPSG(short epsg)
Set projection using EPSG code. This is the recommended way.
Definition: FileGeoTIFF.cpp:422
TreeGDAL gdalMetadata
Use EPSG specific support only, if found. Else use also fromProj4Str().
Definition: FileGeoTIFF.h:139
void writeMetadata()
Completes GeoTIFF structure.
Definition: FileGeoTIFF.cpp:197
virtual bool isOpen() const
Todo: subclass.
Definition: FileGeoTIFF.h:114
void setProjection(const std::string &proj)
Sets projection given in Proj.4 string format.
Definition: FileGeoTIFF.cpp:359
For writing images in basic TIFF format. Reading not supported currently.
Definition: FileTIFF.h:58
Array with georeferencing support.
Definition: GeoFrame.h:58
Definition: TreeXML-GDAL.h:59
Definition: DataSelector.cpp:1277
Definition: Flags.h:744