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