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