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