bes  Updated for version 3.20.8
HDFEOS2ArraySwathGeoField.cc
1 // Retrieves the latitude and longitude of the HDF-EOS2 Swath without using dimension maps
3 //
4 // Authors: MuQun Yang <myang6@hdfgroup.org>
5 // Copyright (c) 2010-2012 The HDF Group
7 // For the swath without using dimension maps, for most cases, the retrieving of latitude and
8 // longitude is the same as retrieving other fields. Some MODIS latitude and longitude need
9 // to be arranged specially.
10 
11 #ifdef USE_HDFEOS2_LIB
12 
13 #include "config.h"
14 
15 #include "HDFEOS2ArraySwathGeoField.h"
16 #include <iostream>
17 #include <sstream>
18 #include <cassert>
19 #include <debug.h>
20 #include "InternalErr.h"
21 #include "BESDebug.h"
22 #include "HDF4RequestHandler.h"
23 
24 using namespace std;
25 using namespace libdap;
26 #define SIGNED_BYTE_TO_INT32 1
27 
28 bool
29 HDFEOS2ArraySwathGeoField::read ()
30 {
31 
32  BESDEBUG("h4","Coming to HDFEOS2ArraySwathGeoField read "<<endl);
33 
34  if(length() == 0)
35  return true;
36 #if 0
37  string check_pass_fileid_key_str="H4.EnablePassFileID";
38  bool check_pass_fileid_key = false;
39  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
40 #endif
41 
42  bool check_pass_fileid_key = HDF4RequestHandler::get_pass_fileid();
43 
44  // Declare offset, count and step
45  vector<int>offset;
46  offset.resize(rank);
47  vector<int>count;
48  count.resize(rank);
49  vector<int>step;
50  step.resize(rank);
51 
52  // Obtain offset,step and count from the client expression constraint
53  int nelms = format_constraint (&offset[0], &step[0], &count[0]);
54 
55  // Just declare offset,count and step in the int32 type.
56  vector<int32>offset32;
57  offset32.resize(rank);
58  vector<int32>count32;
59  count32.resize(rank);
60  vector<int32>step32;
61  step32.resize(rank);
62 
63  // Just obtain the offset,count and step in the datatype of int32.
64  for (int i = 0; i < rank; i++) {
65  offset32[i] = (int32) offset[i];
66  count32[i] = (int32) count[i];
67  step32[i] = (int32) step[i];
68  }
69 
70  int32 (*openfunc) (char *, intn);
71  int32 (*attachfunc) (int32, char *);
72  intn (*detachfunc) (int32);
73  intn (*fieldinfofunc) (int32, char *, int32 *, int32 *, int32 *, char *);
74  intn (*readfieldfunc) (int32, char *, int32 *, int32 *, int32 *, void *);
75 
76  // Define function pointers to handle the swath
77  string datasetname;
78  openfunc = SWopen;
79  attachfunc = SWattach;
80  detachfunc = SWdetach;
81  fieldinfofunc = SWfieldinfo;
82  readfieldfunc = SWreadfield;
83  datasetname = swathname;
84 
85  // We may eventually combine the following code with other code, so
86  // we don't add many comments from here to the end of the file.
87  // The jira ticket about combining code is HFRHANDLER-166.
88  int32 sfid = -1;
89  int32 swathid = -1;
90 
91  if(false == check_pass_fileid_key) {
92  sfid = openfunc (const_cast < char *>(filename.c_str ()), DFACC_READ);
93  if (sfid < 0) {
94  ostringstream eherr;
95  eherr << "File " << filename.c_str () << " cannot be open.";
96  throw InternalErr (__FILE__, __LINE__, eherr.str ());
97  }
98  }
99  else
100  sfid = swathfd;
101 
102  swathid = attachfunc (sfid, const_cast < char *>(datasetname.c_str ()));
103 
104  if (swathid < 0) {
105  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
106  ostringstream eherr;
107  eherr << "Swath " << datasetname.c_str () << " cannot be attached.";
108  throw InternalErr (__FILE__, __LINE__, eherr.str ());
109  }
110 
111 
112  int32 tmp_rank = -1;
113  vector<int32>tmp_dims;
114  tmp_dims.resize(rank);
115  char tmp_dimlist[1024];
116  int32 type =-1;
117  intn r = -1;
118  r = fieldinfofunc (swathid, const_cast < char *>(fieldname.c_str ()),
119  &tmp_rank, &tmp_dims[0], &type, tmp_dimlist);
120  if (r != 0) {
121  detachfunc (swathid);
122  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
123  ostringstream eherr;
124  eherr << "Field " << fieldname.c_str () << " information cannot be obtained.";
125  throw InternalErr (__FILE__, __LINE__, eherr.str ());
126  }
127 
128 
129  switch (type) {
130  case DFNT_INT8:
131  {
132  vector<int8>val;
133  val.resize(nelms);
134  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
135  if (r != 0) {
136  detachfunc (swathid);
137  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
138  ostringstream eherr;
139  eherr << "field " << fieldname.c_str () << "cannot be read.";
140  throw InternalErr (__FILE__, __LINE__, eherr.str ());
141 
142  }
143 
144 
145 #ifndef SIGNED_BYTE_TO_INT32
146  set_value ((dods_byte *) &val[0], nelms);
147 #else
148  vector<int32>newval;
149  newval.resize(nelms);
150 
151  for (int counter = 0; counter < nelms; counter++)
152  newval[counter] = (int32) (val[counter]);
153  set_value ((dods_int32 *) &newval[0], nelms);
154 #endif
155  }
156  break;
157  case DFNT_UINT8:
158  case DFNT_UCHAR8:
159  {
160  vector<uint8>val;
161  val.resize(nelms);
162  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
163  if (r != 0) {
164  detachfunc (swathid);
165  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
166  ostringstream eherr;
167  eherr << "field " << fieldname.c_str () << "cannot be read.";
168  throw InternalErr (__FILE__, __LINE__, eherr.str ());
169  }
170 
171  set_value ((dods_byte *) &val[0], nelms);
172  }
173  break;
174 
175  case DFNT_INT16:
176  {
177  vector<int16>val;
178  val.resize(nelms);
179  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
180  if (r != 0) {
181  detachfunc (swathid);
182  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
183  ostringstream eherr;
184  eherr << "field " << fieldname.c_str () << "cannot be read.";
185  throw InternalErr (__FILE__, __LINE__, eherr.str ());
186  }
187  // We found a special MODIS file that used int16 to store lat/lon. The scale-factor is 0.01.
188  // We cannot retrieve attributes from EOS. To make this work, we have to manually check the values of lat/lon;
189  // If lat/lon value is in thousands, we will hard code by applying the scale factor to calculate the latitude and longitude.
190  // We will see and may find a good solution in the future. KY 2010-7-12
191  bool needadjust = false;
192 
193  if ((val[0] < -1000) || (val[0] > 1000))
194  needadjust = true;
195  if (!needadjust)
196  if ((val[nelms / 2] < -1000)
197  || (val[nelms / 2] > 1000))
198  needadjust = true;
199  if (!needadjust)
200  if ((val[nelms - 1] < -1000)
201  || (val[nelms - 1] > 1000))
202  needadjust = true;
203  if (true == needadjust) {
204  vector<float32>newval;
205  newval.resize(nelms);
206  float scale_factor = 0.01;
207 
208  for (int i = 0; i < nelms; i++)
209  newval[i] = scale_factor * (float32) val[i];
210  set_value ((dods_float32 *) &newval[0], nelms);
211  }
212 
213  else {
214  set_value ((dods_int16 *) &val[0], nelms);
215  }
216  }
217  break;
218 
219  case DFNT_UINT16:
220  {
221  vector<uint16>val;
222  val.resize(nelms);
223  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
224  if (r != 0) {
225  detachfunc (swathid);
226  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
227  ostringstream eherr;
228  eherr << "field " << fieldname.c_str () << "cannot be read.";
229  throw InternalErr (__FILE__, __LINE__, eherr.str ());
230  }
231 
232  set_value ((dods_uint16 *) &val[0], nelms);
233  }
234  break;
235 
236  case DFNT_INT32:
237  {
238  vector<int32>val;
239  val.resize(nelms);
240  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
241  if (r != 0) {
242  detachfunc (swathid);
243  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
244  ostringstream eherr;
245  eherr << "field " << fieldname.c_str () << "cannot be read.";
246  throw InternalErr (__FILE__, __LINE__, eherr.str ());
247  }
248 
249  set_value ((dods_int32 *) &val[0], nelms);
250  }
251  break;
252 
253  case DFNT_UINT32:
254  {
255  vector<uint32>val;
256  val.resize(nelms);
257  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
258  if (r != 0) {
259  detachfunc (swathid);
260  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
261  ostringstream eherr;
262  eherr << "field " << fieldname.c_str () << "cannot be read.";
263  throw InternalErr (__FILE__, __LINE__, eherr.str ());
264  }
265 
266  set_value ((dods_uint32 *) &val[0], nelms);
267  }
268  break;
269  case DFNT_FLOAT32:
270  {
271 
272  vector<float32>val;
273  val.resize(nelms);
274  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
275  if (r != 0) {
276  detachfunc (swathid);
277  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
278  ostringstream eherr;
279  eherr << "field " << fieldname.c_str () << "cannot be read.";
280  throw InternalErr (__FILE__, __LINE__, eherr.str ());
281  }
282  set_value ((dods_float32 *) &val[0], nelms);
283  }
284  break;
285  case DFNT_FLOAT64:
286  {
287  vector<float64>val;
288  val.resize(nelms);
289  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), &offset32[0], &step32[0], &count32[0], &val[0]);
290  if (r != 0) {
291  detachfunc (swathid);
292  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
293  ostringstream eherr;
294  eherr << "field " << fieldname.c_str () << "cannot be read.";
295  throw InternalErr (__FILE__, __LINE__, eherr.str ());
296  }
297 
298  set_value ((dods_float64 *) &val[0], nelms);
299  }
300  break;
301  default:
302  detachfunc (swathid);
303  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
304  throw InternalErr (__FILE__, __LINE__, "unsupported data type.");
305  }
306 
307  r = detachfunc (swathid);
308  if (r != 0) {
309  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
310  ostringstream eherr;
311  eherr << "Swath " << datasetname.c_str () << " cannot be detached.";
312  throw InternalErr (__FILE__, __LINE__, eherr.str ());
313  }
314 
315  HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
316 
317 #if 0
318  r = closefunc (sfid);
319  if (r != 0) {
320  ostringstream eherr;
321  eherr << "Swath " << filename.c_str () << " cannot be closed.";
322  throw InternalErr (__FILE__, __LINE__, eherr.str ());
323  }
324 #endif
325 
326  return false;
327 }
328 
329 // Standard way of DAP handlers to pass the coordinates of the subsetted region to the handlers
330 // Return the number of elements to read.
331 int
332 HDFEOS2ArraySwathGeoField::format_constraint (int *offset, int *step, int *count)
333 {
334  long nels = 1;
335  int id = 0;
336 
337  Dim_iter p = dim_begin ();
338  while (p != dim_end ()) {
339 
340  int start = dimension_start (p, true);
341  int stride = dimension_stride (p, true);
342  int stop = dimension_stop (p, true);
343 
344  // Check for illegal constraint
345  if (start > stop) {
346  ostringstream oss;
347  oss << "Array/Grid hyperslab start point "<< start <<
348  " is greater than stop point " << stop <<".";
349  throw Error(malformed_expr, oss.str());
350  }
351 
352  offset[id] = start;
353  step[id] = stride;
354  count[id] = ((stop - start) / stride) + 1; // count of elements
355  nels *= count[id]; // total number of values for variable
356 
357  BESDEBUG ("h4",
358  "=format_constraint():"
359  << "id=" << id << " offset=" << offset[id]
360  << " step=" << step[id]
361  << " count=" << count[id]
362  << endl);
363 
364  id++;
365  p++;
366  }// while (p != dim_end ())
367 
368  return nels;
369 }
370 #endif
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)
Definition: HDFCFUtil.cc:3688