bes  Updated for version 3.20.13
HDFEOS2.h
1 // This file is part of the hdf4 data handler for the OPeNDAP data server.
3 //
4 // Author: Kent Yang,Choonghwan Lee <myang6@hdfgroup.org>
5 // Copyright (c) 2010-2012 The HDF Group
7 
8 //#include <libdap/InternalErr.h>
9 #ifdef USE_HDFEOS2_LIB
10 
11 #ifndef _HDFEOS2_H
12 #define _HDFEOS2_H
13 #ifdef _WIN32
14 #ifdef _DEBUG
15 #define _CRTDBG_MAP_ALLOC
16 #include <stdlib.h>
17 #include <crtdbg.h>
18 #endif
19 #endif
20 
21 
22 #include <iostream>
23 #include <string>
24 #include <vector>
25 #include <map>
26 #include <set>
27 #include "mfhdf.h"
28 #include "hdf.h"
29 #include "HdfEosDef.h"
30 
31 
32 // Add MISR SOM projection header
33 #include "misrproj.h"
34 
35 #include "HDFEOS2EnumType.h"
36 
37 #ifdef _WIN32
38 #ifdef _MSC_VER
39 #pragma warning(disable:4290)
40 #endif
41 #endif
42 
63 namespace HDFEOS2
64 {
67  class Exception:public std::exception
68  {
69  public:
71  explicit Exception (const std::string & msg)
72  : message (msg)
73  {
74  }
75 
77  ~ Exception () throw () override = default;
78 
80  const char *what () const throw () override
81  {
82  return this->message.c_str ();
83  }
84 
87  virtual bool getFileType ()
88  {
89  return this->isHDFEOS2;
90  }
91 
93  virtual void setFileType (bool isHDFEOS2_flag)
94  {
95  this->isHDFEOS2 = isHDFEOS2_flag;
96  }
97 
99  virtual void setException (const std::string & exception_message)
100  {
101  this->message = exception_message;
102  }
103 
104  private:
105  std::string message;
106  bool isHDFEOS2 = true;
107  };
108 
117  template < typename T > class LightVector {
118  public:
119  LightVector () = default;
120 
121  LightVector (const LightVector < T > &that)
122  {
123  this->data = new T[that.length];
124  for (unsigned int i = 0; i < that.length; ++i)
125  this->data[i] = that[i];
126  this->length = that.length;
127  this->capacity = that.length;
128  }
129 
130  ~LightVector () {
131  if (this->data)
132  delete[]data;
133  }
134 
135  void push_back (const T & d)
136  {
137  this->reserve (this->length + 1);
138  this->data[this->length] = d;
139  ++this->length;
140  }
141 
142  void reserve (unsigned int len)
143  {
144  if (this->capacity >= len)
145  return;
146 
147  this->capacity = len;
148  T *old = this->data;
149 
150  this->data = new T[len];
151  if (old) {
152  for (unsigned int i = 0; i < this->length; ++i)
153  this->data[i] = old[i];
154  delete[]old;
155  }
156  }
157 
158  void resize (unsigned int len)
159  {
161  if (this->length == len)
162  return;
163  else if (this->length < len) {
164  if (this->capacity < len) {
165  this->capacity = len;
166  T *old = this->data;
167 
168  this->data = new T[len];
169  if (old) {
170  for (unsigned int i = 0; i < this->length; ++i)
171  this->data[i] = old[i];
172  delete[]old;
173  }
174  }
175  }
176  else {
177  this->capacity = len;
178  T *old = this->data;
179 
180  this->data = new T[len];
181  for (unsigned int i = 0; i < len; ++i)
182  this->data[i] = old[i];
183  if (old)
184  delete[]old;
185  }
186  this->length = len;
187  }
188 
189  unsigned int size () const
190  {
191  return this->length;
192  }
193 
194  T & operator[] (unsigned int i)
195  {
196  return this->data[i];
197  }
198  const T & operator[] (unsigned int i) const
199  {
200  return this->data[i];
201  }
202 
203  LightVector < T > &operator= (const LightVector < T > &that)
204  {
205  if (this != &that) {
206  this->data = new T[that.length];
207  for (unsigned int i = 0; i < that.length; ++i)
208  this->data[i] = that[i];
209  this->length = that.length;
210  this->capacity = that.length;
211  }
212  return *this;
213  }
214 
215  private:
216  T * data = nullptr;
217  unsigned int length = 0;
218  unsigned int capacity = 0;
219  };
220 
221  class SwathDimensionAdjustment;
222 
226  class Dimension
227  {
228  public:
229  const std::string & getName () const
230  {
231  return this->name;
232  }
233  int32 getSize () const
234  {
235  return this->dimsize;
236  }
237 
238  protected:
239  Dimension (const std::string & eos_dname, int32 eos_dimsize)
240  : name (eos_dname), dimsize (eos_dimsize)
241  {
242  }
243 
244  private:
245  std::string name;
246  int32 dimsize;
247 
248  friend class File;
249  friend class Dataset;
250  friend class SwathDimensionAdjustment;
251  };
252 
255  class Field
256  {
257  public:
258  Field ()
259  {
260  name ="";
261  rank =-1;
262  type =-1;
263  ll_dim0_offset = 0;
264  ll_dim0_inc = 0;
265  ll_dim1_offset = 0;
266  ll_dim1_inc = 0;
267  coordinates="";
268  newname = "";
269  units="";
270  }
271  virtual ~ Field ();
272 
274  const std::string & getName () const
275  {
276  return this->name;
277  }
278 
280  const std::string & getNewName () const
281  {
282  return this->newname;
283  }
284 
286  int32 getRank () const
287  {
288  return this->rank;
289  }
290 
292  int32 getType () const
293  {
294  return this->type;
295  }
296 
298  const std::vector < Dimension * >&getCorrectedDimensions () const
299  {
300  return this->correcteddims;
301  }
302 
304  std::vector < Dimension * >*getCorrectedDimensionsPtr ()
305  {
306  return &(this->correcteddims);
307  }
308 
310  void setCorrectedDimensions (std::vector < Dimension * >eos_dims)
311  {
312  correcteddims = eos_dims;
313  }
314 
316  const std::string getCoordinate () const
317  {
318  return this->coordinates;
319  }
320 
322  void setCoordinates (const std::string& coor)
323  {
324  coordinates = coor;
325  }
326 
328  std::string getUnits () const
329  {
330  return this->units;
331  }
332 
334  void setUnits (const std::string& uni)
335  {
336  units = uni;
337  }
338 
340  float getAddedFillValue () const
341  {
342  return this->addedfv;
343  }
344 
345  // Add the "_FillValue" attribute
346  // This is for supporting the old versions of HDF-EOS2 data(AIRS) because
347  // some data products have fillvalue(-9999.0) but don't specify the fillvalue.
348  // We add the fillvalue to ensure the netCDF client can successfully display the data.
349  // KY 2013-06-30
350  void addFillValue (float fv)
351  {
352  addedfv = fv;
353  }
354 
356  bool haveAddedFillValue () const
357  {
358  return this->haveaddedfv;
359  }
360 
362  void setAddedFillValue (bool havefv)
363  {
364  haveaddedfv = havefv;
365  }
366 
367 
368  // Obtain fieldtype values
369  // For fieldtype values:
370  // 0 is general fields
371  // 1 is latitude.
372  // 2 is longtitude.
373  // 3 is defined level.
374  // 4 is an inserted natural number.
375  // 5 is time.
376 
377  int getFieldType () const
378  {
379  return this->fieldtype;
380  }
381 
383  const std::vector < Dimension * >&getDimensions () const
384  {
385  return this->dims;
386  }
387 
389  const std::vector < char >&getFillValue () const
390  {
391  return this->filler;
392  }
393 
397  int getLLDim0Offset () const
398  {
399  return this->ll_dim0_offset;
400  }
401  int getLLDim0Inc () const
402  {
403  return this->ll_dim0_inc;
404  }
405  int getLLDim1Offset () const
406  {
407  return this->ll_dim1_offset;
408  }
409  int getLLDim1Inc () const
410  {
411  return this->ll_dim1_inc;
412  }
413 
414 
416  bool getYDimMajor () const
417  {
418  return this->ydimmajor;
419  }
420 
422  bool getSpecialLon () const
423  {
424  return this->speciallon;
425  }
426 
428  int getSpecialLLFormat () const
429  {
430  return this->specialformat;
431  }
432 
434  bool getCondensedDim () const
435  {
436  return this->condenseddim;
437  }
438 
440  bool UseDimMap () const
441  {
442  return this->dmap;
443  }
444 
445 //No need to check field_cache in the DDS level.
446 //May remove the debugging info. totally in the next release.
447 //KY 2014-10-23
448 #if 0
450  // 2 exactly cached
451  // 1 maybe cached, need to check the
452  // file size when accessing the data
453  const short UseFieldCache () const
454  {
455  return this->field_cache;
456  }
457 #endif
458  private:
459  // field name
460  std::string name;
461 
462  // field dimension rank
463  int32 rank;
464 
465  // field datatype
466  int32 type;
467 
468  // field dimensions with original dimension names
469  std::vector < Dimension * >dims;
470 
471  // field dimensions with the corrected(CF) dimension names
472  std::vector < Dimension * >correcteddims;
473 
474  // This is for reading the fillvalue.
475  // HDF-EOS2 provides a special routine to read fillvalue.
476  // Up to HDF-EOS2 version 2.18, this is the only field attribute
477  // that HDF-EOS2 APIs provide. KY 2013-07-01
478 
479  std::vector < char >filler;
480 
481  // Coordinate attributes that includes coordinate variable list.
482  std::string coordinates;
483 
484  // newname is to record CF Grid/Swath name + "_"+ CF field name(special characters replaced by underscores).
485  std::string newname;
486 
487 
488  // This flag will specify the fieldtype.
489  // 0 means this field is general field.
490  // 1 means this field is lat.
491  // 2 means this field is lon.
492  // 3 means this field is other dimension variable.
493  // 4 means this field is added other dimension variable with nature number.
494  // 5 means time, but currently the units is not correct.
495  int fieldtype = 0;
496 
497  // Latitude and longitude retrieved by HDF-EOS2 are always
498  // 2-D arrays(XDim * YDim). However, for some projections
499  // (geographic etc.), latiude and longitude can be condensed to
500  // 1-D arrays. The handler will track such projections and condense
501  // the latitude and longitude to 1-D arrays. This can reduce
502  // the disk storage and can greatly improve the performance for
503  // the visualization tool to access the latitude and longitde.
504  // condenseddim is the flag internally used by the handler to track this.
505  bool condenseddim = false;
506 
507  // This flag is to mark if the data should follow COARDS.
508  bool iscoard = false;
509 
510  // This flag is to check if the field is YDim major(temp(YDim,XDim). This
511  // flag is necessary when calling GDij2ll to retrieve latitude and longitude.
512  bool ydimmajor = true;
513 
514  // SOme special longitude is from 0 to 360.We need to check this case with this flag.
515  bool speciallon = false;
516 
517  // This flag specifies the special latitude/longitude coordinate format
518  // The latiude and longitude should represent as DDDMMMSSS format
519  // However, we found some files simply represent lat/lon as -180.0000000 or -90.000000.
520  // Some other files use default. So we this flag to record this and correctly retrieve
521  // the latitude and longitude values in the DAP output.
522  // 0 means normal
523  // 1 means the coordinate is -180 to 180
524  // 2 means the coordinate is default(0)
525  int specialformat = 0;
526 
527  // CF units attribute(mostly to add latitude and longitude CF units).
528  std::string units;
529 
530  // Some data products have fillvalue(-9999.0) but don't specify the fillvalue.
531  // We add the fillvalue to ensure the netCDF client can successfully display the data.
532  // haveaddedfv and addedfv are to check if having added fillvalues.
533  bool haveaddedfv = false;
534  int ll_dim0_offset;
535  int ll_dim0_inc;
536  int ll_dim1_offset;
537  int ll_dim1_inc;
538 
539  float addedfv = -9999.0;
540 
541  // Check if this swath uses the dimension map.
542  bool dmap = false;
543 
544  friend class Dataset;
545  friend class SwathDimensionAdjustment;
546  friend class GridDataset;
547  friend class SwathDataset;
548  friend class File;
549  };
550 
551 #if 0
552  // For future improvement of the modulization
553  class GeoField:public Field
554  {
555 
556  protected:
557  bool condenseddim;
558  bool ydimmajor;
559  bool speciallon;
560 
561  };
562 #endif
563 
565  class Attribute
566  {
567  public:
568 
570  const std::string & getName () const
571  {
572  return this->name;
573  }
574 
576  const std::string & getNewName () const
577  {
578  return this->newname;
579  }
580 
582  int32 getType () const
583  {
584  return this->type;
585  }
586 
588  int32 getCount () const
589  {
590  return this->count;
591  }
592 
594  const std::vector < char >&getValue () const
595  {
596  return this->value;
597  }
598 
599  private:
600 
602  std::string name;
603 
605  std::string newname;
606 
608  int32 type;
609 
611  int32 count;
612 
614  std::vector < char >value;
615 
616  friend class Dataset;
617  };
618 
622  class Dataset
623  {
624  public:
626  const std::string & getName () const
627  {
628  return this->name;
629  }
631  const std::vector < Dimension * >&getDimensions () const
632  {
633  return this->dims;
634  }
636  const std::vector < Field * >&getDataFields () const
637  {
638  return this->datafields;
639  }
640 
642  const std::vector < Attribute * >&getAttributes () const
643  {
644  return this->attrs;
645  }
646 
648  SOType getScaleType () const
649  {
650  return this->scaletype;
651  }
652 
653 
654  protected:
655  explicit Dataset (const std::string & n)
656  : datasetid (-1), addfvalueattr(false),name (n),scaletype(DEFAULT_CF_EQU)
657  {
658 
659  }
660 
661  virtual ~ Dataset ();
662 
665  void ReadDimensions (int32 (*entries) (int32, int32, int32 *),
666  int32 (*inq) (int32, char *, int32 *),
667  std::vector < Dimension * >&dims) throw (Exception);
668 
672  void ReadFields (int32 (*entries) (int32, int32, int32 *),
673  int32 (*inq) (int32, char *, int32 *, int32 *),
674  intn (*fldinfo) (int32, char *, int32 *, int32 *,
675  int32 *, char *),
676  intn (*readfld) (int32, char *, int32 *, int32 *,
677  int32 *, VOIDP),
678  intn (*getfill) (int32, char *, VOIDP),
679  bool geofield, std::vector < Field * >&fields)
680  throw (Exception);
681 
684  void ReadAttributes (int32 (*inq) (int32, char *, int32 *),
685  intn (*attrinfo) (int32, char *, int32 *, int32 *),
686  intn (*readattr) (int32, char *, VOIDP),
687  std::vector < Attribute * >&attrs)
688  throw (Exception);
689 
696  void SetScaleType(const std::string & EOS2ObjName) throw(Exception);
697 
698  int obtain_dimsize_with_dimname(const std::string& dimname);
699  protected:
701  int32 datasetid;
702 
706  bool addfvalueattr;
707 
709  std::string name;
710 
712  std::vector < Dimension * >dims;
713 
715  std::vector < Field * >datafields;
716 
718  std::vector < Attribute * >attrs;
719 
722  std::map < std::string, std::string > dimcvarlist;
723 
725  std::map < std::string, std::string > ncvarnamelist;
726 
728  std::map < std::string, std::string > ndimnamelist;
729 
730  // Some MODIS files don't use the CF linear equation y = scale * x + offset,
731  // The scaletype distinguishs products following different scale and offset rules.
732  // Note the assumption here: we assume that all fields will
733  // use one scale and offset function in a file. If
734  // multiple scale and offset equations are used in one file, our
735  // function will fail. So far only one scale and offset equation is
736  // applied for NASA HDF-EOS2 files we observed. KY 2012-6-13
737  // Since I found one MODIS product(MOD09GA) uses different scale offset
738  // equations for different grids. I had to move the scaletype to the
739  // group level. Hopefully this is the final fix. Truly hope that
740  // this will not happen at the field level since it will be too messy to
741  // check. KY 2012-11-21
742  SOType scaletype;
743 
744  friend class File;
745  };
746 
749  class GridDataset:public Dataset
750  {
751  public:
752  class Info
753  {
754  public:
755 
757  int32 getX ()const
758  {
759  return this->xdim;
760  }
761 
763  int32 getY () const
764  {
765  return this->ydim;
766  }
767 
773  const float64 *getUpLeft () const
774  {
775  return this->upleft;
776  }
777 
783  const float64 *getLowRight () const
784  {
785  return this->lowright;
786  }
787  protected:
788  Info() = default;
789 
790  private:
791  int32 xdim = -1;
792  int32 ydim = -1;
793  float64 upleft[2];
794  float64 lowright[2];
795 
796  friend class GridDataset;
797  };
798 
799  class Projection
800  {
801  public:
804 
807  int32 getCode () const
808  {
809  return this->code;
810  }
811 
813  int32 getZone () const
814  {
815  return this->zone;
816  }
817 
819  int32 getSphere () const
820  {
821  return this->sphere;
822  }
823 
825  const float64 *getParam () const
826  {
827  return this->param;
828  }
829 
831  int32 getPix () const
832  {
833  return this->pix;
834  }
835 
837  int32 getOrigin () const
838  {
839  return this->origin;
840  }
841 
842  protected:
843  Projection() = default;
844 
845  private:
846  int32 code = -1;
847  int32 zone = -1;
848  int32 sphere = -1;
849  float64 param[16];
850  int32 pix = -1;
851  int32 origin =-1;
852 
853  friend class GridDataset;
854  };
855 
858  class Calculated
859  {
860  public:
861 
864  bool isYDimMajor () throw (Exception);
865 #if 0
869 #endif
870 
871  protected:
872 
873  explicit Calculated (const GridDataset * eos_grid)
874  : grid (eos_grid)
875  {
876  }
877 
878  Calculated & operator= (const Calculated & victim)
879  {
880  if (this != &victim) {
881  this->grid = victim.grid;
882  this->ydimmajor = victim.ydimmajor;
883  }
884  return *this;
885  }
886 
889  void DetectMajorDimension () throw (Exception);
890 
892  int DetectFieldMajorDimension () throw (Exception);
893 
894 
895  private:
896  const GridDataset *grid;
897  bool ydimmajor = false;
898 
899  friend class GridDataset;
900  friend class File;
901  };
902 
903  public:
905  static GridDataset *Read (int32 fd, const std::string & gridname) throw (Exception);
906 
907  ~ GridDataset () override;
908 
910  const Info & getInfo () const
911  {
912  return this->info;
913  }
914 
916  const Projection & getProjection () const
917  {
918  return this->proj;
919  }
920 
922  Calculated & getCalculated () const;
923 
925  void setDimxName (const std::string &dxname)
926  {
927  dimxname = dxname;
928  }
930  void setDimyName (const std::string &dyname)
931  {
932  dimyname = dyname;
933  }
934 
936  bool getLatLonFlag () const
937  {
938  return this->ownllflag;
939  }
940 
941  private:
942  explicit GridDataset (const std::string & g_name)
943  : Dataset (g_name), calculated(0)
944  {
945  }
946 
947  private:
948 
950  Info info;
951 
953  Projection proj;
954 
957  mutable Calculated calculated;
958 
960  bool ownllflag = false;
961 
963  bool iscoard = false;
964 
966  Field *latfield = nullptr;
967  Field *lonfield = nullptr;
968 
970  std::string dimxname;
971  std::string dimyname;
972 
973  friend class File;
974 
975  };
976 
977  class File;
978 
982 
983  class SwathDataset:public Dataset
984  {
985 
986  public:
1001 
1002  class DimensionMap
1003  {
1004 
1005  public:
1006  const std::string & getGeoDimension () const
1007  {
1008  return this->geodim;
1009  }
1010  const std::string & getDataDimension () const
1011  {
1012  return this->datadim;
1013  }
1014  int32 getOffset () const
1015  {
1016  return this->offset;
1017  }
1018  int32 getIncrement () const
1019  {
1020  return this->increment;
1021  }
1022 
1023  protected:
1024  DimensionMap (const std::string & eos_geodim, const std::string & eos_datadim, int32 eos_offset, int32 dimmap_increment)
1025  : geodim (eos_geodim), datadim (eos_datadim), offset (eos_offset), increment (dimmap_increment)
1026  {
1027  }
1028 
1029  private:
1030 
1031  std::string geodim;
1032  std::string datadim;
1033  int32 offset;
1034  int32 increment;
1035 
1036  friend class SwathDataset;
1037  friend class SwathDimensionAdjustment;
1038  friend class File;
1039  };
1040 
1044  class IndexMap
1045  {
1046  public:
1047  const std::string & getGeoDimension () const
1048  {
1049  return this->geo;
1050  }
1051  const std::string & getDataDimension () const
1052  {
1053  return this->data;
1054  }
1055  const LightVector < int32 > &getIndices () const
1056  {
1057  return this->indices;
1058  }
1059 
1060  private:
1061  std::string geo;
1062  std::string data;
1063  LightVector < int32 > indices;
1064 
1065  friend class SwathDataset;
1066  };
1067 
1068  public:
1070  static SwathDataset *Read (int32 fd, const std::string & swathname) throw (Exception);
1071 
1072  ~ SwathDataset () override;
1073 
1075  const std::vector < DimensionMap * >&getDimensionMaps () const
1076  {
1077  return this->dimmaps;
1078  }
1079  const std::vector < IndexMap * >&getIndexMaps () const
1080  {
1081  return this->indexmaps;
1082  }
1083 
1085  const std::vector < Field * >&getGeoFields () const
1086  {
1087  return this->geofields;
1088  }
1089 
1090 
1092  void set_num_map (int this_num_map)
1093  {
1094  num_map = this_num_map;
1095  }
1096  int get_num_map () const
1097  {
1098  return num_map;
1099  };
1100 
1101  private:
1102  explicit SwathDataset (const std::string & swath_name)
1103  : Dataset (swath_name) {
1104  }
1105 
1106 
1109  int ReadDimensionMaps (std::vector < DimensionMap * >&dimmaps) throw (Exception);
1110 
1111  bool obtain_dmap_offset_inc(const std::string& o_dimname,const std::string& n_dimmname,int&,int&) ;
1112 
1114  void ReadIndexMaps (std::vector < IndexMap * >&indexmaps) throw (Exception);
1115 
1119 
1121  std::vector < DimensionMap * >dimmaps;
1122 
1124  std::vector < IndexMap * >indexmaps;
1125 
1127  std::set < std::string > nonmisscvdimlist;
1128 
1130  std::vector < Field * >geofields;
1131 
1134  int num_map = 0;
1135 
1136  bool GeoDim_in_vars = false;
1137 
1138  friend class File;
1139  };
1140 
1144  class PointDataset:public Dataset
1145  {
1146  public:
1147  static PointDataset *Read (int32 fd, const std::string & point_name) throw (Exception);
1148  ~ PointDataset () override;
1149 
1150  private:
1151  explicit PointDataset (const std::string & point_name)
1152  : Dataset (point_name)
1153  {
1154  }
1155  };
1156 
1157 
1160  class File
1161  {
1162  public:
1163 
1165  static File *Read (const char *path,int32 gridfd,int32 swathfd) throw (Exception);
1166 
1167 
1171  void Prepare(const char *path) throw(Exception);
1172 
1174  bool check_special_1d_grid() throw(Exception);
1175 
1176 
1179  bool getOneLatLon () const
1180  {
1181  return this->onelatlon;
1182  }
1183 
1185  ~File ();
1186 
1187  const std::string & getPath () const
1188  {
1189  return this->path;
1190  }
1191 
1192  const std::vector < GridDataset * >&getGrids () const
1193  {
1194  return this->grids;
1195  }
1196 
1197  const std::vector < SwathDataset * >&getSwaths () const
1198  {
1199  return this->swaths;
1200  }
1201 
1202  bool getMultiDimMaps() const
1203  {
1204  return this->multi_dimmap;
1205  }
1206  const std::vector < PointDataset * >&getPoints () const
1207  {
1208  return this->points;
1209  }
1210 
1211  std::string get_first_grid_name() const
1212  {
1213  return this->grids[0]->getName();
1214  }
1215 
1216 #if 0
1224 #endif
1225 
1226 
1227  protected:
1228  explicit File (const char *eos2_file_path)
1229  : path (eos2_file_path)
1230  {
1231  }
1232 
1233  private:
1234 
1236  std::string path;
1237 
1239  std::vector < GridDataset * >grids;
1240 
1242  std::vector < SwathDataset * >swaths;
1243 
1245  std::vector < PointDataset * >points;
1246 
1247  // This is for the case that only one lat/lon
1248  // set is provided for multiple grid cases.
1249  // The current case is that the user provides
1250  // the latitude and longitude under a special grid.
1251  // By default, the grid name is "location". This will
1252  // cover the AIRS grid case.
1253  bool onelatlon = false;
1254 
1256  bool iscoard = false;
1257 
1264  bool handle_swath_dimmap = false;
1265 
1269  bool backward_handle_swath_dimmap = false;
1270 
1272  bool multi_dimmap = false;
1273 
1274  protected:
1275  /*
1276  A grid's X-dimension can have different names: XDim, LatDim, etc.
1277  * Y-dimension also has YDim, LonDim, etc.
1278  * This function returns the name of X-dimension which is used in
1279  * the given file.
1280  * For better performance, we check the first grid or swath only.
1281  */
1282  std::string get_geodim_x_name ();
1283  std::string get_geodim_y_name ();
1284 
1285  // Internal function used by
1286  // get_geodim_x_name and get_geodim_y_name functions.
1287  // This function is not intended to be used outside the
1288  // get_geodim_x_name and get_geodim_y_name functions.
1289  void _find_geodim_names ();
1290 
1291  std::string _geodim_x_name;
1292  std::string _geodim_y_name;
1293  static const char *_geodim_x_names[];
1294  static const char *_geodim_y_names[];
1295 
1305  std::string get_latfield_name ();
1306  std::string get_lonfield_name ();
1307 
1308  // Internal function used by
1309  // get_latfield_name and get_lonfield_name functions.
1310  // This function is not intended to be used outside
1311  // the get_latfield_name and get_lonfield_name functions.
1312  void _find_latlonfield_names ();
1313 
1314  std::string _latfield_name;
1315  std::string _lonfield_name;
1316  static const char *_latfield_names[];
1317  static const char *_lonfield_names[];
1318 
1324  std::string get_geogrid_name ();
1325 
1326  // Internal function used by
1327  // the get_geogrid_name function.
1328  // This function is not intended to be used outside the get_geogrid_name function.
1329  void _find_geogrid_name ();
1330 
1331  std::string _geogrid_name;
1332  static const char *_geogrid_names[];
1333 
1334 
1335  // All the following functions are called by the Prepare() function.
1336 
1337  // Check if we have the dedicated lat/lon grid.
1338  void check_onelatlon_grids();
1339 
1340  // For one grid, need to handle the third-dimension(both existing and missing) coordinate variables
1341  void handle_one_grid_zdim(GridDataset*);
1342 
1343  // For one grid, need to handle lat/lon(both existing lat/lon and calculated lat/lon from EOS2 APIs)
1344  void handle_one_grid_latlon(GridDataset*) throw(Exception);
1345 
1346  // For the case of which all grids have one dedicated lat/lon grid,
1347  // this function shows how to handle lat/lon fields.
1348  void handle_onelatlon_grids() throw (Exception);
1349 
1350  // Handle the dimension name to coordinate variable map for grid.
1351  void handle_grid_dim_cvar_maps() throw(Exception);
1352 
1353  // Follow COARDS for grids.
1354  void handle_grid_coards() throw(Exception);
1355 
1356  // Create the corrected dimension vector for each field when COARDS is not followed.
1357  void update_grid_field_corrected_dims() throw(Exception);
1358 
1359  // Handle CF attributes for grids.
1360  // The CF attributes include "coordinates", "units" for coordinate variables and "_FillValue".
1361  void handle_grid_cf_attrs() throw(Exception);
1362 
1363  // Special handling SOM(Space Oblique Mercator) projection files
1364  void handle_grid_SOM_projection() throw(Exception);
1365 
1366  bool find_dim_in_dims(const std::vector<Dimension*>&dims,const std::string &dim_name) const;
1367 
1368  // Check if we need to handle dim. map and set handle_swath_dimmap if necessary.
1369  // The input parameter is the number of swath.
1370  void check_swath_dimmap(int numswath) throw(Exception);
1371 
1372  void check_swath_dimmap_bk_compat(int numswath);
1373 
1374  // Create the dimension name to coordinate variable name map for lat/lon.
1375  // The input parameter is the number of dimension maps in this file.
1376  void create_swath_latlon_dim_cvar_map() throw(Exception);
1377 
1378  // Create the dimension name to coordinate variable name map for non lat/lon coordinate variables.
1379  void create_swath_nonll_dim_cvar_map() throw(Exception);
1380 
1381  // Handle swath dimension name to coordinate variable name maps.
1382  // The input parameter is the number of dimension maps in this file.
1383  void handle_swath_dim_cvar_maps() throw(Exception);
1384 
1385  // Handle CF attributes for swaths.
1386  // The CF attributes include "coordinates", "units" for coordinate variables and "_FillValue".
1387  void handle_swath_cf_attrs() throw(Exception);
1388 
1389  bool check_ll_in_coords(const std::string& vname) throw(Exception);
1390 
1394  // is not to keep original latitude/longitude. Now some MODIS files
1395  // have the variables that still use the low resolution. See HFRHANDLER-332.
1396  void check_dm_geo_dims_in_vars();
1397 
1399  void create_swath_latlon_dim_cvar_map_for_dimmap(SwathDataset*,Field*,Field*) throw(Exception);
1400 
1401  void create_geo_varnames_list(std::vector<std::string> &,const std::string &,
1402  const std::string &,int,bool);
1403 
1404  void create_geo_dim_var_maps(SwathDataset*, Field*, const std::vector<std::string>&,
1405  const std::vector<std::string>&,
1406  std::vector<Dimension*>&, std::vector<Dimension*>&);
1407  void create_geo_vars(SwathDataset*,Field*,Field*,const std::vector<std::string>&,const std::vector<std::string>&,
1408  std::vector<Dimension*>&, std::vector<Dimension*>&) throw(Exception);
1409 
1410  void update_swath_dims_for_dimmap(SwathDataset*,
1411  const std::vector<Dimension*>&, const std::vector<Dimension*>&);
1412 
1413 
1414 
1415  private:
1416 
1417  // HDF-EOS2 Grid File ID. Notice this ID is not an individual grid ID but the grid file ID returned by
1418  // calling the HDF-EOS2 API GDopen.
1419  int32 gridfd = -1;
1420 
1421  // HDF-EOS2 Swath File ID. Notice this ID is not an individual swath ID but the swath file ID returned by
1422  // calling the HDF-EOS2 API SWopen.
1423  int32 swathfd = -1;
1424 
1437 
1439  };
1440 
1441 
1442  struct Utility
1443  {
1444 
1446  static bool ReadNamelist (const char *path,
1447  int32 (*inq) (char *, char *, int32 *),
1448  std::vector < std::string > &names);
1449 
1450 
1451  };
1452 
1453 }
1454 #endif
1455 
1456 #endif