bes Updated for version 3.20.13
HDFEOS2ArraySwathGeoDimMapExtraField.cc
1
2// 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
26using namespace std;
27using namespace libdap;
28
29#define SIGNED_BYTE_TO_INT32 1
30
31
32bool
33HDFEOS2ArraySwathGeoDimMapExtraField::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.data(),step.data(),count.data());
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.data(), step32.data(), count32.data(), val.data());
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.data(), 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.data(), 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.data(), step32.data(), count32.data(), val.data());
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.data(), 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.data(), step32.data(), count32.data(), val.data());
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.data(), 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.data(), step32.data(), count32.data(), val.data());
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.data(), 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.data(), step32.data(), count32.data(), val.data());
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.data(), 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.data(), step32.data(), count32.data(), val.data());
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.data(), 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.data(), step32.data(), count32.data(), val.data());
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.data(), 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.data(), step32.data(), count32.data(), val.data());
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.data(), 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.
336int
337HDFEOS2ArraySwathGeoDimMapExtraField::format_constraint (int *offset, int *step, int *count)
338{
339 int 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