bes  Updated for version 3.20.8
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 "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), isHDFEOS2 (true)
73  {
74  }
75 
77  virtual ~ Exception () throw ()
78  {
79  }
80 
82  virtual const char *what () const throw ()
83  {
84  return this->message.c_str ();
85  }
86 
89  virtual bool getFileType ()
90  {
91  return this->isHDFEOS2;
92  }
93 
95  virtual void setFileType (bool isHDFEOS2_flag)
96  {
97  this->isHDFEOS2 = isHDFEOS2_flag;
98  }
99 
101  virtual void setException (std::string exception_message)
102  {
103  this->message = exception_message;
104  }
105 
106  private:
107  std::string message;
108  bool isHDFEOS2;
109  };
110 
119  template < typename T > class LightVector {
120  public:
121  LightVector ()
122  : data (0), length (0), capacity (0) {
123  }
124 
125  LightVector (const LightVector < T > &that)
126  {
127  this->data = new T[that.length];
128  for (unsigned int i = 0; i < that.length; ++i)
129  this->data[i] = that[i];
130  this->length = that.length;
131  this->capacity = that.length;
132  }
133 
134  ~LightVector () {
135  if (this->data)
136  delete[]data;
137  }
138 
139  void push_back (const T & d)
140  {
141  this->reserve (this->length + 1);
142  this->data[this->length] = d;
143  ++this->length;
144  }
145 
146  void reserve (unsigned int len)
147  {
148  if (this->capacity >= len)
149  return;
150 
151  this->capacity = len;
152  T *old = this->data;
153 
154  this->data = new T[len];
155  if (old) {
156  for (unsigned int i = 0; i < this->length; ++i)
157  this->data[i] = old[i];
158  delete[]old;
159  }
160  }
161 
162  void resize (unsigned int len)
163  {
165  if (this->length == len)
166  return;
167  else if (this->length < len) {
168  if (this->capacity < len) {
169  this->capacity = len;
170  T *old = this->data;
171 
172  this->data = new T[len];
173  if (old) {
174  for (unsigned int i = 0; i < this->length; ++i)
175  this->data[i] = old[i];
176  delete[]old;
177  }
178  }
179  }
180  else {
181  this->capacity = len;
182  T *old = this->data;
183 
184  this->data = new T[len];
185  for (unsigned int i = 0; i < len; ++i)
186  this->data[i] = old[i];
187  if (old)
188  delete[]old;
189  }
190  this->length = len;
191  }
192 
193  unsigned int size () const
194  {
195  return this->length;
196  }
197 
198  T & operator[] (unsigned int i)
199  {
200  return this->data[i];
201  }
202  const T & operator[] (unsigned int i) const
203  {
204  return this->data[i];
205  }
206 
207  LightVector < T > &operator= (const LightVector < T > &that)
208  {
209  if (this != &that) {
210  this->data = new T[that.length];
211  for (unsigned int i = 0; i < that.length; ++i)
212  this->data[i] = that[i];
213  this->length = that.length;
214  this->capacity = that.length;
215  }
216  return *this;
217  }
218 
219  private:
220  T * data;
221  unsigned int length;
222  unsigned int capacity;
223  };
224 
225  class SwathDimensionAdjustment;
226 
230  class Dimension
231  {
232  public:
233  const std::string & getName () const
234  {
235  return this->name;
236  }
237  int32 getSize () const
238  {
239  return this->dimsize;
240  }
241 
242  protected:
243  Dimension (const std::string & eos_dname, int32 eos_dimsize)
244  : name (eos_dname), dimsize (eos_dimsize)
245  {
246  }
247 
248  private:
249  std::string name;
250  int32 dimsize;
251 
252  friend class File;
253  friend class Dataset;
254  friend class SwathDimensionAdjustment;
255  };
256 
259  class Field
260  {
261  public:
262  Field ()
263  :fieldtype (0), condenseddim (false), iscoard (false), ydimmajor (true), speciallon (false), specialformat (0), haveaddedfv (false), addedfv (-9999.0), dmap (false)/*, field_cache(0)*/
264 
265  {
266  name ="";
267  rank =-1;
268  type =-1;
269  ll_dim0_offset = 0;
270  ll_dim0_inc = 0;
271  ll_dim1_offset = 0;
272  ll_dim1_inc = 0;
273  coordinates="";
274  newname = "";
275  units="";
276  }
277  virtual ~ Field ();
278 
279  public:
280 
282  const std::string & getName () const
283  {
284  return this->name;
285  }
286 
288  const std::string & getNewName () const
289  {
290  return this->newname;
291  }
292 
294  int32 getRank () const
295  {
296  return this->rank;
297  }
298 
300  int32 getType () const
301  {
302  return this->type;
303  }
304 
306  const std::vector < Dimension * >&getCorrectedDimensions () const
307  {
308  return this->correcteddims;
309  }
310 
312  std::vector < Dimension * >*getCorrectedDimensionsPtr ()
313  {
314  return &(this->correcteddims);
315  }
316 
318  void setCorrectedDimensions (std::vector < Dimension * >eos_dims)
319  {
320  correcteddims = eos_dims;
321  }
322 
324  const std::string getCoordinate () const
325  {
326  return this->coordinates;
327  }
328 
330  void setCoordinates (std::string coor)
331  {
332  coordinates = coor;
333  }
334 
336  const std::string getUnits () const
337  {
338  return this->units;
339  }
340 
342  void setUnits (std::string uni)
343  {
344  units = uni;
345  }
346 
348  float getAddedFillValue () const
349  {
350  return this->addedfv;
351  }
352 
353  // Add the "_FillValue" attribute
354  // This is for supporting the old versions of HDF-EOS2 data(AIRS) because
355  // some data products have fillvalue(-9999.0) but don't specify the fillvalue.
356  // We add the fillvalue to ensure the netCDF client can successfully display the data.
357  // KY 2013-06-30
358  void addFillValue (float fv)
359  {
360  addedfv = fv;
361  }
362 
364  bool haveAddedFillValue () const
365  {
366  return this->haveaddedfv;
367  }
368 
370  void setAddedFillValue (bool havefv)
371  {
372  haveaddedfv = havefv;
373  }
374 
375 
376  // Obtain fieldtype values
377  // For fieldtype values:
378  // 0 is general fields
379  // 1 is latitude.
380  // 2 is longtitude.
381  // 3 is defined level.
382  // 4 is an inserted natural number.
383  // 5 is time.
384 
385  int getFieldType () const
386  {
387  return this->fieldtype;
388  }
389 
391  const std::vector < Dimension * >&getDimensions () const
392  {
393  return this->dims;
394  }
395 
397  const std::vector < char >&getFillValue () const
398  {
399  return this->filler;
400  }
401 
405  const int getLLDim0Offset () const
406  {
407  return this->ll_dim0_offset;
408  }
409  const int getLLDim0Inc () const
410  {
411  return this->ll_dim0_inc;
412  }
413  const int getLLDim1Offset () const
414  {
415  return this->ll_dim1_offset;
416  }
417  const int getLLDim1Inc () const
418  {
419  return this->ll_dim1_inc;
420  }
421 
422 
424  bool getYDimMajor () const
425  {
426  return this->ydimmajor;
427  }
428 
430  bool getSpecialLon () const
431  {
432  return this->speciallon;
433  }
434 
436  int getSpecialLLFormat () const
437  {
438  return this->specialformat;
439  }
440 
442  bool getCondensedDim () const
443  {
444  return this->condenseddim;
445  }
446 
448  bool UseDimMap () const
449  {
450  return this->dmap;
451  }
452 
453 //No need to check field_cache in the DDS level.
454 //May remove the debugging info. totally in the next release.
455 //KY 2014-10-23
456 #if 0
458  // 2 exactly cached
459  // 1 maybe cached, need to check the
460  // file size when accessing the data
461  const short UseFieldCache () const
462  {
463  return this->field_cache;
464  }
465 #endif
466  protected:
467  // field name
468  std::string name;
469 
470  // field dimension rank
471  int32 rank;
472 
473  // field datatype
474  int32 type;
475 
476  // field dimensions with original dimension names
477  std::vector < Dimension * >dims;
478 
479  // field dimensions with the corrected(CF) dimension names
480  std::vector < Dimension * >correcteddims;
481 
482  // This is for reading the fillvalue.
483  // HDF-EOS2 provides a special routine to read fillvalue.
484  // Up to HDF-EOS2 version 2.18, this is the only field attribute
485  // that HDF-EOS2 APIs provide. KY 2013-07-01
486 
487  std::vector < char >filler;
488 
489  // Coordinate attributes that includes coordinate variable list.
490  std::string coordinates;
491 
492  // newname is to record CF Grid/Swath name + "_"+ CF field name(special characters replaced by underscores).
493  std::string newname;
494 
495 
496  // This flag will specify the fieldtype.
497  // 0 means this field is general field.
498  // 1 means this field is lat.
499  // 2 means this field is lon.
500  // 3 means this field is other dimension variable.
501  // 4 means this field is added other dimension variable with nature number.
502  // 5 means time, but currently the units is not correct.
503  int fieldtype;
504 
505  // Latitude and longitude retrieved by HDF-EOS2 are always
506  // 2-D arrays(XDim * YDim). However, for some projections
507  // (geographic etc.), latiude and longitude can be condensed to
508  // 1-D arrays. The handler will track such projections and condense
509  // the latitude and longitude to 1-D arrays. This can reduce
510  // the disk storage and can greatly improve the performance for
511  // the visualization tool to access the latitude and longitde.
512  // condenseddim is the flag internally used by the handler to track this.
513  bool condenseddim;
514 
515  // This flag is to mark if the data should follow COARDS.
516  bool iscoard;
517 
518  // This flag is to check if the field is YDim major(temp(YDim,XDim). This
519  // flag is necessary when calling GDij2ll to retrieve latitude and longitude.
520  bool ydimmajor;
521 
522  // SOme special longitude is from 0 to 360.We need to check this case with this flag.
523  bool speciallon;
524 
525  // This flag specifies the special latitude/longitude coordinate format
526  // The latiude and longitude should represent as DDDMMMSSS format
527  // However, we found some files simply represent lat/lon as -180.0000000 or -90.000000.
528  // Some other files use default. So we this flag to record this and correctly retrieve
529  // the latitude and longitude values in the DAP output.
530  // 0 means normal
531  // 1 means the coordinate is -180 to 180
532  // 2 means the coordinate is default(0)
533  int specialformat;
534 
535  // CF units attribute(mostly to add latitude and longitude CF units).
536  std::string units;
537 
538  // Some data products have fillvalue(-9999.0) but don't specify the fillvalue.
539  // We add the fillvalue to ensure the netCDF client can successfully display the data.
540  // haveaddedfv and addedfv are to check if having added fillvalues.
541  bool haveaddedfv;
542  int ll_dim0_offset;
543  int ll_dim0_inc;
544  int ll_dim1_offset;
545  int ll_dim1_inc;
546 
547  float addedfv;
548 
549  // Check if this swath uses the dimension map.
550  bool dmap;
551 
552  friend class Dataset;
553  friend class SwathDimensionAdjustment;
554  friend class GridDataset;
555  friend class SwathDataset;
556  friend class File;
557  };
558 
559 #if 0
560  // For future improvement of the modulization
561  class GeoField:public Field
562  {
563 
564  protected:
565  bool condenseddim;
566  bool ydimmajor;
567  bool speciallon;
568 
569  };
570 #endif
571 
573  class Attribute
574  {
575  public:
576 
578  const std::string & getName () const
579  {
580  return this->name;
581  }
582 
584  const std::string & getNewName () const
585  {
586  return this->newname;
587  }
588 
590  int32 getType () const
591  {
592  return this->type;
593  }
594 
596  int32 getCount () const
597  {
598  return this->count;
599  }
600 
602  const std::vector < char >&getValue () const
603  {
604  return this->value;
605  }
606 
607  private:
608 
610  std::string name;
611 
613  std::string newname;
614 
616  int32 type;
617 
619  int32 count;
620 
622  std::vector < char >value;
623 
624  friend class Dataset;
625  };
626 
630  class Dataset
631  {
632  public:
634  const std::string & getName () const
635  {
636  return this->name;
637  }
639  const std::vector < Dimension * >&getDimensions () const
640  {
641  return this->dims;
642  }
644  const std::vector < Field * >&getDataFields () const
645  {
646  return this->datafields;
647  }
648 
650  const std::vector < Attribute * >&getAttributes () const
651  {
652  return this->attrs;
653  }
654 
656  SOType getScaleType () const
657  {
658  return this->scaletype;
659  }
660 
661 
662  protected:
663  explicit Dataset (const std::string & n)
664  : datasetid (-1), addfvalueattr(false),name (n),scaletype(DEFAULT_CF_EQU)
665  {
666 
667  }
668 
669  virtual ~ Dataset ();
670 
673  void ReadDimensions (int32 (*entries) (int32, int32, int32 *),
674  int32 (*inq) (int32, char *, int32 *),
675  std::vector < Dimension * >&dims) throw (Exception);
676 
680  void ReadFields (int32 (*entries) (int32, int32, int32 *),
681  int32 (*inq) (int32, char *, int32 *, int32 *),
682  intn (*fldinfo) (int32, char *, int32 *, int32 *,
683  int32 *, char *),
684  intn (*readfld) (int32, char *, int32 *, int32 *,
685  int32 *, VOIDP),
686  intn (*getfill) (int32, char *, VOIDP),
687  bool geofield, std::vector < Field * >&fields)
688  throw (Exception);
689 
692  void ReadAttributes (int32 (*inq) (int32, char *, int32 *),
693  intn (*attrinfo) (int32, char *, int32 *, int32 *),
694  intn (*readattr) (int32, char *, VOIDP),
695  std::vector < Attribute * >&attrs)
696  throw (Exception);
697 
704  void SetScaleType(const std::string EOS2ObjName) throw(Exception);
705 
706  int obtain_dimsize_with_dimname(const std::string& dimname);
707  protected:
709  int32 datasetid;
710 
714  bool addfvalueattr;
715 
717  std::string name;
718 
720  std::vector < Dimension * >dims;
721 
723  std::vector < Field * >datafields;
724 
726  std::vector < Attribute * >attrs;
727 
730  std::map < std::string, std::string > dimcvarlist;
731 
733  std::map < std::string, std::string > ncvarnamelist;
734 
736  std::map < std::string, std::string > ndimnamelist;
737 
738  // Some MODIS files don't use the CF linear equation y = scale * x + offset,
739  // The scaletype distinguishs products following different scale and offset rules.
740  // Note the assumption here: we assume that all fields will
741  // use one scale and offset function in a file. If
742  // multiple scale and offset equations are used in one file, our
743  // function will fail. So far only one scale and offset equation is
744  // applied for NASA HDF-EOS2 files we observed. KY 2012-6-13
745  // Since I found one MODIS product(MOD09GA) uses different scale offset
746  // equations for different grids. I had to move the scaletype to the
747  // group level. Hopefully this is the final fix. Truly hope that
748  // this will not happen at the field level since it will be too messy to
749  // check. KY 2012-11-21
750  SOType scaletype;
751 
752  friend class File;
753  };
754 
757  class GridDataset:public Dataset
758  {
759  public:
760  class Info
761  {
762  public:
763 
765  int32 getX ()const
766  {
767  return this->xdim;
768  }
769 
771  int32 getY () const
772  {
773  return this->ydim;
774  }
775 
781  const float64 *getUpLeft () const
782  {
783  return this->upleft;
784  }
785 
791  const float64 *getLowRight () const
792  {
793  return this->lowright;
794  }
795  protected:
796  Info() {
797  xdim = -1;
798  ydim = -1;
799  }
800 
801  private:
802  int32 xdim;
803  int32 ydim;
804  float64 upleft[2];
805  float64 lowright[2];
806 
807  friend class GridDataset;
808  };
809 
810  class Projection
811  {
812  public:
815 
818  int32 getCode () const
819  {
820  return this->code;
821  }
822 
824  int32 getZone () const
825  {
826  return this->zone;
827  }
828 
830  int32 getSphere () const
831  {
832  return this->sphere;
833  }
834 
836  const float64 *getParam () const
837  {
838  return this->param;
839  }
840 
842  int32 getPix () const
843  {
844  return this->pix;
845  }
846 
848  int32 getOrigin () const
849  {
850  return this->origin;
851  }
852 
853  protected:
854  Projection() {
855  code = -1;
856  zone = -1;
857  sphere = -1;
858  pix = -1;
859  origin = -1;
860 
861  }
862  private:
863  int32 code;
864  int32 zone;
865  int32 sphere;
866  float64 param[16];
867  int32 pix;
868  int32 origin;
869 
870  friend class GridDataset;
871  };
872 
875  class Calculated
876  {
877  public:
878 
881  bool isYDimMajor () throw (Exception);
885 
886  protected:
887 
888  explicit Calculated (const GridDataset * eos_grid)
889  : grid (eos_grid), ydimmajor (false)
890  {
891  }
892 
893  Calculated & operator= (const Calculated & victim)
894  {
895  if (this != &victim) {
896  this->grid = victim.grid;
897  this->ydimmajor = victim.ydimmajor;
898  }
899  return *this;
900  }
901 
904  void DetectMajorDimension () throw (Exception);
905 
907  int DetectFieldMajorDimension () throw (Exception);
908 
909 
910  private:
911  const GridDataset *grid;
912  bool ydimmajor;
913 
914  friend class GridDataset;
915  friend class File;
916  };
917 
918  public:
920  static GridDataset *Read (int32 fd, const std::string & gridname) throw (Exception);
921 
922  virtual ~ GridDataset ();
923 
925  const Info & getInfo () const
926  {
927  return this->info;
928  }
929 
931  const Projection & getProjection () const
932  {
933  return this->proj;
934  }
935 
937  Calculated & getCalculated () const;
938 
940  void setDimxName (std::string dxname)
941  {
942  dimxname = dxname;
943  }
945  void setDimyName (std::string dyname)
946  {
947  dimyname = dyname;
948  }
949 
951  bool getLatLonFlag () const
952  {
953  return this->ownllflag;
954  }
955 
956  private:
957  explicit GridDataset (const std::string & g_name)
958  : Dataset (g_name), calculated (0), ownllflag (false), iscoard (false)
959  {
960  latfield = NULL;
961  lonfield = NULL;
962  }
963 
964  private:
965 
967  Info info;
968 
970  Projection proj;
971 
974  mutable Calculated calculated;
975 
977  bool ownllflag;
978 
980  bool iscoard;
981 
983  Field *latfield;
984  Field *lonfield;
985 
987  std::string dimxname;
988  std::string dimyname;
989 
990  friend class File;
991 
992  };
993 
994  class File;
995 
999 
1000  class SwathDataset:public Dataset
1001  {
1002 
1003  public:
1018 
1019  class DimensionMap
1020  {
1021 
1022  public:
1023  const std::string & getGeoDimension () const
1024  {
1025  return this->geodim;
1026  }
1027  const std::string & getDataDimension () const
1028  {
1029  return this->datadim;
1030  }
1031  int32 getOffset () const
1032  {
1033  return this->offset;
1034  }
1035  int32 getIncrement () const
1036  {
1037  return this->increment;
1038  }
1039 
1040  protected:
1041  DimensionMap (const std::string & eos_geodim, const std::string & eos_datadim, int32 eos_offset, int32 dimmap_increment)
1042  : geodim (eos_geodim), datadim (eos_datadim), offset (eos_offset), increment (dimmap_increment)
1043  {
1044  }
1045 
1046  private:
1047 
1048  std::string geodim;
1049  std::string datadim;
1050  int32 offset;
1051  int32 increment;
1052 
1053  friend class SwathDataset;
1054  friend class SwathDimensionAdjustment;
1055  friend class File;
1056  };
1057 
1061  class IndexMap
1062  {
1063  public:
1064  const std::string & getGeoDimension () const
1065  {
1066  return this->geo;
1067  }
1068  const std::string & getDataDimension () const
1069  {
1070  return this->data;
1071  }
1072  const LightVector < int32 > &getIndices () const
1073  {
1074  return this->indices;
1075  }
1076 
1077  private:
1078  std::string geo;
1079  std::string data;
1080  LightVector < int32 > indices;
1081 
1082  friend class SwathDataset;
1083  };
1084 
1085  public:
1087  static SwathDataset *Read (int32 fd, const std::string & swathname) throw (Exception);
1088 
1089  virtual ~ SwathDataset ();
1090 
1092  const std::vector < DimensionMap * >&getDimensionMaps () const
1093  {
1094  return this->dimmaps;
1095  }
1096  const std::vector < IndexMap * >&getIndexMaps () const
1097  {
1098  return this->indexmaps;
1099  }
1100 
1102  const std::vector < Field * >&getGeoFields () const
1103  {
1104  return this->geofields;
1105  }
1106 
1107 
1109  void set_num_map (int this_num_map)
1110  {
1111  num_map = this_num_map;
1112  }
1113  int get_num_map () const
1114  {
1115  return num_map;
1116  };
1117 
1118  private:
1119  explicit SwathDataset (const std::string & swath_name)
1120  : Dataset (swath_name),num_map(0),GeoDim_in_vars(false) {
1121  }
1122 
1123 
1126  int ReadDimensionMaps (std::vector < DimensionMap * >&dimmaps) throw (Exception);
1127 
1128  bool obtain_dmap_offset_inc(const std::string& o_dimname,const std::string& n_dimmname,int&,int&) ;
1129 
1131  void ReadIndexMaps (std::vector < IndexMap * >&indexmaps) throw (Exception);
1132 
1136 
1138  std::vector < DimensionMap * >dimmaps;
1139 
1141  std::vector < IndexMap * >indexmaps;
1142 
1144  std::set < std::string > nonmisscvdimlist;
1145 
1147  std::vector < Field * >geofields;
1148 
1151  int num_map;
1152 
1153  bool GeoDim_in_vars;
1154 
1155  friend class File;
1156  };
1157 
1161  class PointDataset:public Dataset
1162  {
1163  public:
1164  static PointDataset *Read (int32 fd, const std::string & point_name) throw (Exception);
1165  virtual ~ PointDataset ();
1166 
1167  private:
1168  explicit PointDataset (const std::string & point_name)
1169  : Dataset (point_name)
1170  {
1171  }
1172  };
1173 
1174 
1177  class File
1178  {
1179  public:
1180 
1182  static File *Read (const char *path,int32 gridfd,int32 swathfd) throw (Exception);
1183 
1184 
1188  void Prepare(const char *path) throw(Exception);
1189 
1191  bool check_special_1d_grid() throw(Exception);
1192 
1193 
1196  bool getOneLatLon ()
1197  {
1198  return this->onelatlon;
1199  }
1200 
1202  ~File ();
1203 
1204  const std::string & getPath () const
1205  {
1206  return this->path;
1207  }
1208 
1209  const std::vector < GridDataset * >&getGrids () const
1210  {
1211  return this->grids;
1212  }
1213 
1214  const std::vector < SwathDataset * >&getSwaths () const
1215  {
1216  return this->swaths;
1217  }
1218 
1219  const bool getMultiDimMaps() const
1220  {
1221  return this->multi_dimmap;
1222  }
1223  const std::vector < PointDataset * >&getPoints () const
1224  {
1225  return this->points;
1226  }
1227 
1228  const std::string get_first_grid_name() const
1229  { return this->grids[0]->getName();}
1230 #if 0
1238 #endif
1239 
1240 
1241  protected:
1242  explicit File (const char *eos2_file_path)
1243  : path (eos2_file_path), onelatlon (false), iscoard (false), handle_swath_dimmap(false),backward_handle_swath_dimmap(false),multi_dimmap(false),gridfd (-1), swathfd (-1)
1244  {
1245  }
1246 
1247  private:
1248 
1250  std::string path;
1251 
1253  std::vector < GridDataset * >grids;
1254 
1256  std::vector < SwathDataset * >swaths;
1257 
1259  std::vector < PointDataset * >points;
1260 
1261  // This is for the case that only one lat/lon
1262  // set is provided for multiple grid cases.
1263  // The current case is that the user provides
1264  // the latitude and longitude under a special grid.
1265  // By default, the grid name is "location". This will
1266  // cover the AIRS grid case.
1267  bool onelatlon;
1268 
1270  bool iscoard;
1271 
1278  bool handle_swath_dimmap;
1279 
1283  bool backward_handle_swath_dimmap;
1284 
1286  bool multi_dimmap;
1287 
1288  protected:
1289  /*
1290  A grid's X-dimension can have different names: XDim, LatDim, etc.
1291  * Y-dimension also has YDim, LonDim, etc.
1292  * This function returns the name of X-dimension which is used in
1293  * the given file.
1294  * For better performance, we check the first grid or swath only.
1295  */
1296  std::string get_geodim_x_name ();
1297  std::string get_geodim_y_name ();
1298 
1299  // Internal function used by
1300  // get_geodim_x_name and get_geodim_y_name functions.
1301  // This function is not intended to be used outside the
1302  // get_geodim_x_name and get_geodim_y_name functions.
1303  void _find_geodim_names ();
1304 
1305  std::string _geodim_x_name;
1306  std::string _geodim_y_name;
1307  static const char *_geodim_x_names[];
1308  static const char *_geodim_y_names[];
1309 
1319  std::string get_latfield_name ();
1320  std::string get_lonfield_name ();
1321 
1322  // Internal function used by
1323  // get_latfield_name and get_lonfield_name functions.
1324  // This function is not intended to be used outside
1325  // the get_latfield_name and get_lonfield_name functions.
1326  void _find_latlonfield_names ();
1327 
1328  std::string _latfield_name;
1329  std::string _lonfield_name;
1330  static const char *_latfield_names[];
1331  static const char *_lonfield_names[];
1332 
1338  std::string get_geogrid_name ();
1339 
1340  // Internal function used by
1341  // the get_geogrid_name function.
1342  // This function is not intended to be used outside the get_geogrid_name function.
1343  void _find_geogrid_name ();
1344 
1345  std::string _geogrid_name;
1346  static const char *_geogrid_names[];
1347 
1348 
1349  // All the following functions are called by the Prepare() function.
1350 
1351  // Check if we have the dedicated lat/lon grid.
1352  void check_onelatlon_grids();
1353 
1354  // For one grid, need to handle the third-dimension(both existing and missing) coordinate variables
1355  void handle_one_grid_zdim(GridDataset*);
1356 
1357  // For one grid, need to handle lat/lon(both existing lat/lon and calculated lat/lon from EOS2 APIs)
1358  void handle_one_grid_latlon(GridDataset*) throw(Exception);
1359 
1360  // For the case of which all grids have one dedicated lat/lon grid,
1361  // this function shows how to handle lat/lon fields.
1362  void handle_onelatlon_grids() throw (Exception);
1363 
1364  // Handle the dimension name to coordinate variable map for grid.
1365  void handle_grid_dim_cvar_maps() throw(Exception);
1366 
1367  // Follow COARDS for grids.
1368  void handle_grid_coards() throw(Exception);
1369 
1370  // Create the corrected dimension vector for each field when COARDS is not followed.
1371  void update_grid_field_corrected_dims() throw(Exception);
1372 
1373  // Handle CF attributes for grids.
1374  // The CF attributes include "coordinates", "units" for coordinate variables and "_FillValue".
1375  void handle_grid_cf_attrs() throw(Exception);
1376 
1377  // Special handling SOM(Space Oblique Mercator) projection files
1378  void handle_grid_SOM_projection() throw(Exception);
1379 
1380  bool find_dim_in_dims(const std::vector<Dimension*>&dims,const std::string &dim_name);
1381 
1382  // Check if we need to handle dim. map and set handle_swath_dimmap if necessary.
1383  // The input parameter is the number of swath.
1384  void check_swath_dimmap(int numswath) throw(Exception);
1385 
1386  void check_swath_dimmap_bk_compat(int numswath);
1387 
1388  // Create the dimension name to coordinate variable name map for lat/lon.
1389  // The input parameter is the number of dimension maps in this file.
1390  void create_swath_latlon_dim_cvar_map() throw(Exception);
1391 
1392  // Create the dimension name to coordinate variable name map for non lat/lon coordinate variables.
1393  void create_swath_nonll_dim_cvar_map() throw(Exception);
1394 
1395  // Handle swath dimension name to coordinate variable name maps.
1396  // The input parameter is the number of dimension maps in this file.
1397  void handle_swath_dim_cvar_maps() throw(Exception);
1398 
1399  // Handle CF attributes for swaths.
1400  // The CF attributes include "coordinates", "units" for coordinate variables and "_FillValue".
1401  void handle_swath_cf_attrs() throw(Exception);
1402 
1403  bool check_ll_in_coords(const std::string& vname) throw(Exception);
1404 
1408  // is not to keep original latitude/longitude. Now some MODIS files
1409  // have the variables that still use the low resolution. See HFRHANDLER-332.
1410  void check_dm_geo_dims_in_vars();
1411 
1413  void create_swath_latlon_dim_cvar_map_for_dimmap(SwathDataset*,Field*,Field*) throw(Exception);
1414 
1415  void create_geo_varnames_list(std::vector<std::string> &,const std::string &,
1416  const std::string &,int,bool);
1417 
1418  void create_geo_dim_var_maps(SwathDataset*, Field*, const std::vector<std::string>&,
1419  const std::vector<std::string>&,
1420  std::vector<Dimension*>&, std::vector<Dimension*>&);
1421  void create_geo_vars(SwathDataset*,Field*,Field*,const std::vector<std::string>&,const std::vector<std::string>&,
1422  std::vector<Dimension*>&, std::vector<Dimension*>&) throw(Exception);
1423 
1424  void update_swath_dims_for_dimmap(SwathDataset*,
1425  const std::vector<Dimension*>&, const std::vector<Dimension*>&);
1426 
1427 
1428 
1429  private:
1430 
1431  // HDF-EOS2 Grid File ID. Notice this ID is not an individual grid ID but the grid file ID returned by
1432  // calling the HDF-EOS2 API GDopen.
1433  int32 gridfd;
1434 
1435  // HDF-EOS2 Swath File ID. Notice this ID is not an individual swath ID but the swath file ID returned by
1436  // calling the HDF-EOS2 API SWopen.
1437  int32 swathfd;
1438 
1451 
1453  };
1454 
1455 
1456  struct Utility
1457  {
1458 
1460  static bool ReadNamelist (const char *path,
1461  int32 (*inq) (char *, char *, int32 *),
1462  std::vector < std::string > &names);
1463 
1464 
1465  };
1466 
1467 }
1468 #endif
1469 
1470 #endif