OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDFEOS2ArraySwathGeoDimMapExtraField.cc
Go to the documentation of this file.
1 // Retrieves the latitude and longitude of the HDF-EOS2 Swath having dimension maps
3 // Authors: MuQun Yang <myang6@hdfgroup.org>
4 // Copyright (c) 2010-2012 The HDF Group
6 // SOME MODIS products provide the latitude and longitude files for
7 // swaths using dimension map. The files are still HDF-EOS2 files.
8 // The file name is determined at the hdfdesc.cc.
9 // Since the latitude and longitude fields are stored as
10 // the real data fields in an HDF-EOS2 file,
11 // The read function is essentially the same as retrieving the data value of a
12 // general HDF-EOS2 field.
13 
14 #ifdef USE_HDFEOS2_LIB
16 #include <iostream>
17 #include <sstream>
18 #include <cassert>
19 #include <debug.h>
20 #include "HDFEOS2.h"
21 #include "HDFCFUtil.h"
22 #include "InternalErr.h"
23 #include "BESDebug.h"
24 
25 using namespace std;
26 #define SIGNED_BYTE_TO_INT32 1
27 
28 
29 bool
30 HDFEOS2ArraySwathGeoDimMapExtraField::read ()
31 {
32 
33  BESDEBUG("h4","Coming to HDFEOS2ArraySwathGeoDimMapExtraField read "<<endl);
34  // Declare offset, count and step
35  vector<int>offset;
36  offset.resize(rank);
37  vector<int>count;
38  count.resize(rank);
39  vector<int>step;
40  step.resize(rank);
41 
42  // Obtain offset,step and count from the client expression constraint
43  int nelms = format_constraint(&offset[0],&step[0],&count[0]);
44 
45  // Just declare offset,count and step in the int32 type.
46  vector<int32>offset32;
47  offset32.resize(rank);
48  vector<int32>count32;
49  count32.resize(rank);
50  vector<int32>step32;
51  step32.resize(rank);
52 
53  // Just obtain the offset,count and step in the datatype of int32.
54  for (int i = 0; i < rank; i++) {
55  offset32[i] = (int32) offset[i];
56  count32[i] = (int32) count[i];
57  step32[i] = (int32) step[i];
58  }
59 
60  int32 (*openfunc) (char *, intn);
61  intn (*closefunc) (int32);
62  int32 (*attachfunc) (int32, char *);
63  intn (*detachfunc) (int32);
64  intn (*fieldinfofunc) (int32, char *, int32 *, int32 *, int32 *, char *);
65  intn (*readfieldfunc) (int32, char *, int32 *, int32 *, int32 *, void *);
66  int32 (*inqfunc) (char *, char *, int32 *);
67 
68 
69  // Define function pointers to handle the swath
70  openfunc = SWopen;
71  closefunc = SWclose;
72  attachfunc = SWattach;
73  detachfunc = SWdetach;
74  fieldinfofunc = SWfieldinfo;
75  readfieldfunc = SWreadfield;
76  inqfunc = SWinqswath;
77 
78  // We may eventually combine the following code with other code, so
79  // we don't add many comments from here to the end of the file.
80  // The jira ticket about combining code is HFRHANDLER-166.
81  int32 fileid = -1, swathid = -1;
82 
83  fileid = openfunc (const_cast < char *>(filename.c_str ()), DFACC_READ);
84  if (fileid < 0) {
85  ostringstream eherr;
86  eherr << "File " << filename.c_str () << " cannot be open.";
87  throw InternalErr (__FILE__, __LINE__, eherr.str ());
88  }
89 
90  // Check if this file only contains one swath
91  int numswath = 0;
92  int32 swathnamesize = 0;
93  numswath = inqfunc (const_cast < char *>(filename.c_str ()), NULL,
94  &swathnamesize);
95 
96  if (numswath == -1) {
97  closefunc (fileid);
98  ostringstream eherr;
99  eherr << "File " << filename.c_str () << " cannot obtain the swath list.";
100  throw InternalErr (__FILE__, __LINE__, eherr.str ());
101  }
102 
103  if (numswath != 1) {
104  closefunc (fileid);
105  ostringstream eherr;
106  eherr << " Currently we only support reading geo-location fields from one swath."
107  << " This file has more than one swath. ";
108  throw InternalErr (__FILE__, __LINE__, eherr.str ());
109  }
110 
111  char *swathname = new char[swathnamesize + 1];
112  numswath = inqfunc (const_cast < char *>(filename.c_str ()), swathname,
113  &swathnamesize);
114  if (numswath == -1) {
115  delete[]swathname;
116  closefunc (fileid);
117  ostringstream eherr;
118  eherr << "File " << filename.c_str () << " cannot obtain the swath list.";
119  throw InternalErr (__FILE__, __LINE__, eherr.str ());
120  }
121 
122  swathid = attachfunc (fileid, swathname);
123  if (swathid < 0) {
124  closefunc (fileid);
125  ostringstream eherr;
126  eherr << "Grid/Swath " << swathname << " cannot be attached.";
127  delete[]swathname;
128  throw InternalErr (__FILE__, __LINE__, eherr.str ());
129  }
130 
131  delete[]swathname;
132 
133  int32 tmp_rank = 0, tmp_dims[rank];
134  char tmp_dimlist[1024];
135  int32 type = 0;
136  intn r = -1;
137  r = fieldinfofunc (swathid, const_cast < char *>(fieldname.c_str ()),
138  &tmp_rank, tmp_dims, &type, tmp_dimlist);
139  if (r != 0) {
140  detachfunc (swathid);
141  closefunc (fileid);
142  ostringstream eherr;
143  eherr << "Field " << fieldname.c_str () << " information cannot be obtained.";
144  throw InternalErr (__FILE__, __LINE__, eherr.str ());
145  }
146 
147 
148  switch (type) {
149 
150  case DFNT_INT8:
151  {
152  vector<int8>val;
153  val.resize(nelms);
154  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
155  &offset32[0], &step32[0], &count32[0], &val[0]);
156  if (r != 0) {
157  detachfunc (swathid);
158  closefunc (fileid);
159  ostringstream eherr;
160  eherr << "field " << fieldname.c_str () << "cannot be read.";
161  throw InternalErr (__FILE__, __LINE__, eherr.str ());
162  }
163 
164 #ifndef SIGNED_BYTE_TO_INT32
165  set_value ((dods_byte *) &val[0], nelms);
166 #else
167 
168  vector<int32>newval;
169  newval.resize(nelms);
170  for (int counter = 0; counter < nelms; counter++)
171  newval[counter] = (int32) (val[counter]);
172 
173  set_value ((dods_int32 *) &newval[0], nelms);
174 #endif
175  }
176 
177  break;
178  case DFNT_UINT8:
179  case DFNT_UCHAR8:
180  {
181  vector<uint>val;
182  val.resize(nelms);
183 
184  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
185  &offset32[0], &step32[0], &count32[0], &val[0]);
186  if (r != 0) {
187  detachfunc (swathid);
188  closefunc (fileid);
189  ostringstream eherr;
190  eherr << "field " << fieldname.c_str () << "cannot be read.";
191  throw InternalErr (__FILE__, __LINE__, eherr.str ());
192  }
193 
194  set_value ((dods_byte *) &val[0], nelms);
195  }
196  break;
197 
198  case DFNT_INT16:
199  {
200  vector<int16>val;
201  val.resize(nelms);
202  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
203  &offset32[0], &step32[0], &count32[0], &val[0]);
204  if (r != 0) {
205  detachfunc (swathid);
206  closefunc (fileid);
207  ostringstream eherr;
208  eherr << "field " << fieldname.c_str () << "cannot be read.";
209  throw InternalErr (__FILE__, __LINE__, eherr.str ());
210  }
211 
212  set_value ((dods_int16 *) &val[0], nelms);
213  }
214  break;
215  case DFNT_UINT16:
216  {
217  vector<uint16>val;
218  val.resize(nelms);
219  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
220  &offset32[0], &step32[0], &count32[0], &val[0]);
221  if (r != 0) {
222  detachfunc (swathid);
223  closefunc (fileid);
224  ostringstream eherr;
225  eherr << "field " << fieldname.c_str () << "cannot be read.";
226  throw InternalErr (__FILE__, __LINE__, eherr.str ());
227  }
228 
229  set_value ((dods_uint16 *) &val[0], nelms);
230  }
231  break;
232  case DFNT_INT32:
233  {
234  vector<int32>val;
235  val.resize(nelms);
236  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
237  &offset32[0], &step32[0], &count32[0], &val[0]);
238  if (r != 0) {
239  detachfunc (swathid);
240  closefunc (fileid);
241  ostringstream eherr;
242  eherr << "field " << fieldname.c_str () << "cannot be read.";
243  throw InternalErr (__FILE__, __LINE__, eherr.str ());
244  }
245 
246  set_value ((dods_int32 *) &val[0], nelms);
247  }
248  break;
249  case DFNT_UINT32:
250  {
251  vector<uint32>val;
252  val.resize(nelms);
253  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
254  &offset32[0], &step32[0], &count32[0], &val[0]);
255  if (r != 0) {
256  detachfunc (swathid);
257  closefunc (fileid);
258  ostringstream eherr;
259  eherr << "field " << fieldname.c_str () << "cannot be read.";
260  throw InternalErr (__FILE__, __LINE__, eherr.str ());
261  }
262 
263  set_value ((dods_uint32 *) &val[0], nelms);
264  }
265  break;
266  case DFNT_FLOAT32:
267  {
268  vector<float32>val;
269  val.resize(nelms);
270  r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
271  &offset32[0], &step32[0], &count32[0], &val[0]);
272  if (r != 0) {
273  detachfunc (swathid);
274  closefunc (fileid);
275  ostringstream eherr;
276  eherr << "field " << fieldname.c_str () << "cannot be read.";
277  throw InternalErr (__FILE__, __LINE__, eherr.str ());
278  }
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 ()),
288  &offset32[0], &step32[0], &count32[0], &val[0]);
289  if (r != 0) {
290  detachfunc (swathid);
291  closefunc (fileid);
292  ostringstream eherr;
293  eherr << "field " << fieldname.c_str () << "cannot be read.";
294  throw InternalErr (__FILE__, __LINE__, eherr.str ());
295  }
296  set_value ((dods_float64 *) &val[0], nelms);
297  }
298  break;
299  default:
300  {
301  detachfunc(swathid);
302  closefunc(fileid);
303  InternalErr (__FILE__, __LINE__, "unsupported data type.");
304  }
305  }
306 
307  r = detachfunc (swathid);
308  if (r != 0) {
309  closefunc (fileid);
310  throw InternalErr (__FILE__, __LINE__, "The swath cannot be detached.");
311  }
312 
313 
314  r = closefunc (fileid);
315  if (r != 0) {
316  ostringstream eherr;
317 
318  eherr << "Grid/Swath " << filename.c_str () << " cannot be closed.";
319  throw InternalErr (__FILE__, __LINE__, eherr.str ());
320  }
321 
322  return false;
323 }
324 
325 // Standard way of DAP handlers to pass the coordinates of the subsetted region to the handlers
326 // Return the number of elements to read.
327 int
328 HDFEOS2ArraySwathGeoDimMapExtraField::format_constraint (int *offset, int *step, int *count)
329 {
330  long nels = 1;
331  int id = 0;
332 
333  Dim_iter p = dim_begin ();
334 
335  while (p != dim_end ()) {
336 
337  int start = dimension_start (p, true);
338  int stride = dimension_stride (p, true);
339  int stop = dimension_stop (p, true);
340 
341 
342  // Check for illegical constraint
343  if (stride < 0 || start < 0 || stop < 0 || start > stop) {
344  ostringstream oss;
345 
346  oss << "Array/Grid hyperslab indices are bad: [" << start <<
347  ":" << stride << ":" << stop << "]";
348  throw Error (malformed_expr, oss.str ());
349  }
350 
351  // Check for an empty constraint and use the whole dimension if so.
352  if (start == 0 && stop == 0 && stride == 0) {
353  start = dimension_start (p, false);
354  stride = dimension_stride (p, false);
355  stop = dimension_stop (p, false);
356  }
357 
358  offset[id] = start;
359  step[id] = stride;
360  count[id] = ((stop - start) / stride) + 1; // count of elements
361  nels *= count[id]; // total number of values for variable
362 
363  BESDEBUG ("h4",
364  "=format_constraint():"
365  << "id=" << id << " offset=" << offset[id]
366  << " step=" << step[id]
367  << " count=" << count[id]
368  << endl);
369 
370  id++;
371  p++;
372  }
373 
374  return nels;
375 }
376 #endif
STL namespace.
#define NULL
Definition: wcsUtil.h:65
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64