bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
HDFEOS2ArraySwathGeoDimMapExtraField.cc
1
2// Retrieves the latitude and longitude of the HDF-EOS2 Swath having dimension maps
3// Authors: Kent Yang <myang6@hdfgroup.org>
4// Copyright (c) The HDF Group
6// SOME MODIS products provide the latitude and longitude files for
7// swaths that use dimension maps. The files are still HDF-EOS2 files.
8// The name of such a file 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 vector<char> swathname(swathnamesize+1);
120 numswath = inqfunc (const_cast < char *>(filename.c_str ()), swathname.data(),
121 &swathnamesize);
122 if (numswath == -1) {
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.data());
130 if (swathid < 0) {
131 closefunc (fileid);
132 ostringstream eherr;
133 string swname_str(swathname.begin(),swathname.end());
134 eherr << "Grid/Swath " << swname_str.c_str() << " cannot be attached.";
135 throw InternalErr (__FILE__, __LINE__, eherr.str ());
136 }
137
138
139 int32 tmp_rank = 0;
140 int32 tmp_dims[rank];
141 char tmp_dimlist[1024];
142 int32 type = 0;
143 intn r = -1;
144 r = fieldinfofunc (swathid, const_cast < char *>(fieldname.c_str ()),
145 &tmp_rank, tmp_dims, &type, tmp_dimlist);
146 if (r != 0) {
147 detachfunc (swathid);
148 closefunc (fileid);
149 ostringstream eherr;
150 eherr << "Field " << fieldname.c_str () << " information cannot be obtained.";
151 throw InternalErr (__FILE__, __LINE__, eherr.str ());
152 }
153
154
155 switch (type) {
156
157 case DFNT_INT8:
158 {
159 vector<int8>val;
160 val.resize(nelms);
161 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
162 offset32.data(), step32.data(), count32.data(), val.data());
163 if (r != 0) {
164 detachfunc (swathid);
165 closefunc (fileid);
166 ostringstream eherr;
167 eherr << "field " << fieldname.c_str () << "cannot be read.";
168 throw InternalErr (__FILE__, __LINE__, eherr.str ());
169 }
170
171#ifndef SIGNED_BYTE_TO_INT32
172 set_value ((dods_byte *) val.data(), nelms);
173#else
174
175 vector<int32>newval;
176 newval.resize(nelms);
177 for (int counter = 0; counter < nelms; counter++)
178 newval[counter] = (int32) (val[counter]);
179
180 set_value ((dods_int32 *) newval.data(), nelms);
181#endif
182 }
183
184 break;
185 case DFNT_UINT8:
186 case DFNT_UCHAR8:
187 {
188 vector<uint>val;
189 val.resize(nelms);
190
191 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
192 offset32.data(), step32.data(), count32.data(), val.data());
193 if (r != 0) {
194 detachfunc (swathid);
195 closefunc (fileid);
196 ostringstream eherr;
197 eherr << "field " << fieldname.c_str () << "cannot be read.";
198 throw InternalErr (__FILE__, __LINE__, eherr.str ());
199 }
200
201 set_value ((dods_byte *) val.data(), nelms);
202 }
203 break;
204
205 case DFNT_INT16:
206 {
207 vector<int16>val;
208 val.resize(nelms);
209 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
210 offset32.data(), step32.data(), count32.data(), val.data());
211 if (r != 0) {
212 detachfunc (swathid);
213 closefunc (fileid);
214 ostringstream eherr;
215 eherr << "field " << fieldname.c_str () << "cannot be read.";
216 throw InternalErr (__FILE__, __LINE__, eherr.str ());
217 }
218
219 set_value ((dods_int16 *) val.data(), nelms);
220 }
221 break;
222 case DFNT_UINT16:
223 {
225 val.resize(nelms);
226 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
227 offset32.data(), step32.data(), count32.data(), val.data());
228 if (r != 0) {
229 detachfunc (swathid);
230 closefunc (fileid);
231 ostringstream eherr;
232 eherr << "field " << fieldname.c_str () << "cannot be read.";
233 throw InternalErr (__FILE__, __LINE__, eherr.str ());
234 }
235
236 set_value ((dods_uint16 *) val.data(), nelms);
237 }
238 break;
239 case DFNT_INT32:
240 {
241 vector<int32>val;
242 val.resize(nelms);
243 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
244 offset32.data(), step32.data(), count32.data(), val.data());
245 if (r != 0) {
246 detachfunc (swathid);
247 closefunc (fileid);
248 ostringstream eherr;
249 eherr << "field " << fieldname.c_str () << "cannot be read.";
250 throw InternalErr (__FILE__, __LINE__, eherr.str ());
251 }
252
253 set_value ((dods_int32 *) val.data(), nelms);
254 }
255 break;
256 case DFNT_UINT32:
257 {
259 val.resize(nelms);
260 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
261 offset32.data(), step32.data(), count32.data(), val.data());
262 if (r != 0) {
263 detachfunc (swathid);
264 closefunc (fileid);
265 ostringstream eherr;
266 eherr << "field " << fieldname.c_str () << "cannot be read.";
267 throw InternalErr (__FILE__, __LINE__, eherr.str ());
268 }
269
270 set_value ((dods_uint32 *) val.data(), nelms);
271 }
272 break;
273 case DFNT_FLOAT32:
274 {
276 val.resize(nelms);
277 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
278 offset32.data(), step32.data(), count32.data(), val.data());
279 if (r != 0) {
280 detachfunc (swathid);
281 closefunc (fileid);
282 ostringstream eherr;
283 eherr << "field " << fieldname.c_str () << "cannot be read.";
284 throw InternalErr (__FILE__, __LINE__, eherr.str ());
285 }
286
287 set_value ((dods_float32 *) val.data(), nelms);
288 }
289 break;
290 case DFNT_FLOAT64:
291 {
293 val.resize(nelms);
294 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()),
295 offset32.data(), step32.data(), count32.data(), val.data());
296 if (r != 0) {
297 detachfunc (swathid);
298 closefunc (fileid);
299 ostringstream eherr;
300 eherr << "field " << fieldname.c_str () << "cannot be read.";
301 throw InternalErr (__FILE__, __LINE__, eherr.str ());
302 }
303 set_value ((dods_float64 *) val.data(), nelms);
304 }
305 break;
306 default:
307 {
308 detachfunc(swathid);
309 closefunc(fileid);
310 throw InternalErr (__FILE__, __LINE__, "unsupported data type.");
311 }
312 }
313
314 r = detachfunc (swathid);
315 if (r != 0) {
316 closefunc (fileid);
317 throw InternalErr (__FILE__, __LINE__, "The swath cannot be detached.");
318 }
319
320
321 r = closefunc (fileid);
322 if (r != 0) {
323 ostringstream eherr;
324
325 eherr << "Grid/Swath " << filename.c_str () << " cannot be closed.";
326 throw InternalErr (__FILE__, __LINE__, eherr.str ());
327 }
328
329 return false;
330}
331
332// Standard way of DAP handlers to pass the coordinates of the subsetted region to the handlers
333// Return the number of elements to read.
334int
335HDFEOS2ArraySwathGeoDimMapExtraField::format_constraint (int *offset, int *step, int *count)
336{
337 int nels = 1;
338 int id = 0;
339
340 Dim_iter p = dim_begin ();
341 while (p != dim_end ()) {
342
343 int start = dimension_start (p, true);
344 int stride = dimension_stride (p, true);
345 int stop = dimension_stop (p, true);
346
347 // Check for illegal constraint
348 if (start > stop) {
349 ostringstream oss;
350 oss << "Array/Grid hyperslab start point "<< start <<
351 " is greater than stop point " << stop <<".";
352 throw Error(malformed_expr, oss.str());
353 }
354
355 offset[id] = start;
356 step[id] = stride;
357 count[id] = ((stop - start) / stride) + 1; // count of elements
358 nels *= count[id]; // total number of values for variable
359
360 BESDEBUG ("h4",
361 "=format_constraint():"
362 << "id=" << id << " offset=" << offset[id]
363 << " step=" << step[id]
364 << " count=" << count[id]
365 << endl);
366
367 id++;
368 p++;
369 }// while
370
371 return nels;
372}
373
374#endif
STL class.
STL class.