bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
HDFEOS2ArraySwathGeoField.cc
1
2// Retrieves the latitude and longitude of the HDF-EOS2 Swath without using dimension maps
3//
4// Authors: Kent Yang <myang6@hdfgroup.org>
5// Copyright (c) The HDF Group
7// For the swath without using dimension maps, for most cases, the retrieving of latitude and
8// longitude is the same as retrieving other fields. Some MODIS latitude and longitude need
9// to be arranged specially.
10
11#ifdef USE_HDFEOS2_LIB
12
13#include "config.h"
14
15#include "HDFEOS2ArraySwathGeoField.h"
16#include <iostream>
17#include <sstream>
18#include <cassert>
19#include <libdap/debug.h>
20#include <libdap/InternalErr.h>
21#include "BESDebug.h"
22#include "HDF4RequestHandler.h"
23
24using namespace std;
25using namespace libdap;
26#define SIGNED_BYTE_TO_INT32 1
27
28bool
29HDFEOS2ArraySwathGeoField::read ()
30{
31
32 BESDEBUG("h4","Coming to HDFEOS2ArraySwathGeoField read "<<endl);
33
34 if (length() == 0)
35 return true;
36
37 bool check_pass_fileid_key = HDF4RequestHandler::get_pass_fileid();
38
39 // Declare offset, count and step
40 vector<int>offset;
41 offset.resize(rank);
42 vector<int>count;
43 count.resize(rank);
44 vector<int>step;
45 step.resize(rank);
46
47 // Obtain offset,step and count from the client expression constraint
48 int nelms = format_constraint (offset.data(), step.data(), count.data());
49
50 // Just declare offset,count and step in the int32 type.
51 vector<int32>offset32;
52 offset32.resize(rank);
53 vector<int32>count32;
54 count32.resize(rank);
55 vector<int32>step32;
56 step32.resize(rank);
57
58 // Just obtain the offset,count and step in the datatype of int32.
59 for (int i = 0; i < rank; i++) {
60 offset32[i] = (int32) offset[i];
61 count32[i] = (int32) count[i];
62 step32[i] = (int32) step[i];
63 }
64
65 int32 (*openfunc) (char *, intn);
66 int32 (*attachfunc) (int32, char *);
67 intn (*detachfunc) (int32);
68 intn (*fieldinfofunc) (int32, char *, int32 *, int32 *, int32 *, char *);
69 intn (*readfieldfunc) (int32, char *, int32 *, int32 *, int32 *, void *);
70
71 // Define function pointers to handle the swath
72 string datasetname;
73 openfunc = SWopen;
74 attachfunc = SWattach;
75 detachfunc = SWdetach;
76 fieldinfofunc = SWfieldinfo;
77 readfieldfunc = SWreadfield;
78 datasetname = swathname;
79
80 // We may eventually combine the following code with other code, so
81 // we don't add many comments from here to the end of the file.
82 // The jira ticket about combining code is HFRHANDLER-166.
83 int32 sfid = -1;
84 int32 swathid = -1;
85
86 if (false == check_pass_fileid_key) {
87 sfid = openfunc (const_cast < char *>(filename.c_str ()), DFACC_READ);
88 if (sfid < 0) {
89 ostringstream eherr;
90 eherr << "File " << filename.c_str () << " cannot be open.";
91 throw InternalErr (__FILE__, __LINE__, eherr.str ());
92 }
93 }
94 else
95 sfid = swathfd;
96
97 swathid = attachfunc (sfid, const_cast < char *>(datasetname.c_str ()));
98
99 if (swathid < 0) {
100 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
101 ostringstream eherr;
102 eherr << "Swath " << datasetname.c_str () << " cannot be attached.";
103 throw InternalErr (__FILE__, __LINE__, eherr.str ());
104 }
105
106
107 int32 tmp_rank = -1;
108 vector<int32>tmp_dims;
109 tmp_dims.resize(rank);
110 char tmp_dimlist[1024];
111 int32 type =-1;
112 intn r = -1;
113 r = fieldinfofunc (swathid, const_cast < char *>(fieldname.c_str ()),
114 &tmp_rank, tmp_dims.data(), &type, tmp_dimlist);
115 if (r != 0) {
116 detachfunc (swathid);
117 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
118 ostringstream eherr;
119 eherr << "Field " << fieldname.c_str () << " information cannot be obtained.";
120 throw InternalErr (__FILE__, __LINE__, eherr.str ());
121 }
122
123
124 switch (type) {
125 case DFNT_INT8:
126 {
127 vector<int8>val;
128 val.resize(nelms);
129 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), offset32.data(), step32.data(), count32.data(), val.data());
130 if (r != 0) {
131 detachfunc (swathid);
132 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
133 ostringstream eherr;
134 eherr << "field " << fieldname.c_str () << "cannot be read.";
135 throw InternalErr (__FILE__, __LINE__, eherr.str ());
136
137 }
138
139
140#ifndef SIGNED_BYTE_TO_INT32
141 set_value ((dods_byte *) val.data(), nelms);
142#else
143 vector<int32>newval;
144 newval.resize(nelms);
145
146 for (int counter = 0; counter < nelms; counter++)
147 newval[counter] = (int32) (val[counter]);
148 set_value ((dods_int32 *) newval.data(), nelms);
149#endif
150 }
151 break;
152 case DFNT_UINT8:
153 case DFNT_UCHAR8:
154 {
155 vector<uint8>val;
156 val.resize(nelms);
157 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), offset32.data(), step32.data(), count32.data(), val.data());
158 if (r != 0) {
159 detachfunc (swathid);
160 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
161 ostringstream eherr;
162 eherr << "field " << fieldname.c_str () << "cannot be read.";
163 throw InternalErr (__FILE__, __LINE__, eherr.str ());
164 }
165
166 set_value ((dods_byte *) val.data(), nelms);
167 }
168 break;
169
170 case DFNT_INT16:
171 {
172 vector<int16>val;
173 val.resize(nelms);
174 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), offset32.data(), step32.data(), count32.data(), val.data());
175 if (r != 0) {
176 detachfunc (swathid);
177 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
178 ostringstream eherr;
179 eherr << "field " << fieldname.c_str () << "cannot be read.";
180 throw InternalErr (__FILE__, __LINE__, eherr.str ());
181 }
182 // We found a special MODIS file that used int16 to store lat/lon. The scale-factor is 0.01.
183 // We cannot retrieve attributes from EOS. To make this work, we have to manually check the values of lat/lon;
184 // If lat/lon value is in thousands, we will hard code by applying the scale factor to calculate the latitude and longitude.
185 // We will see and may find a good solution in the future. KY 2010-7-12
186 bool needadjust = false;
187
188 if ((val[0] < -1000) || (val[0] > 1000))
189 needadjust = true;
190 if (!needadjust)
191 if ((val[nelms / 2] < -1000)
192 || (val[nelms / 2] > 1000))
193 needadjust = true;
194 if (!needadjust)
195 if ((val[nelms - 1] < -1000)
196 || (val[nelms - 1] > 1000))
197 needadjust = true;
198 if (true == needadjust) {
199 vector<float32>newval;
200 newval.resize(nelms);
201 float scale_factor = 0.01f;
202
203 for (int i = 0; i < nelms; i++)
204 newval[i] = scale_factor * (float32) val[i];
205 set_value ((dods_float32 *) newval.data(), nelms);
206 }
207
208 else {
209 set_value ((dods_int16 *) val.data(), nelms);
210 }
211 }
212 break;
213
214 case DFNT_UINT16:
215 {
217 val.resize(nelms);
218 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), offset32.data(), step32.data(), count32.data(), val.data());
219 if (r != 0) {
220 detachfunc (swathid);
221 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
222 ostringstream eherr;
223 eherr << "field " << fieldname.c_str () << "cannot be read.";
224 throw InternalErr (__FILE__, __LINE__, eherr.str ());
225 }
226
227 set_value ((dods_uint16 *) val.data(), nelms);
228 }
229 break;
230
231 case DFNT_INT32:
232 {
233 vector<int32>val;
234 val.resize(nelms);
235 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), offset32.data(), step32.data(), count32.data(), val.data());
236 if (r != 0) {
237 detachfunc (swathid);
238 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
239 ostringstream eherr;
240 eherr << "field " << fieldname.c_str () << "cannot be read.";
241 throw InternalErr (__FILE__, __LINE__, eherr.str ());
242 }
243
244 set_value ((dods_int32 *) val.data(), nelms);
245 }
246 break;
247
248 case DFNT_UINT32:
249 {
251 val.resize(nelms);
252 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), offset32.data(), step32.data(), count32.data(), val.data());
253 if (r != 0) {
254 detachfunc (swathid);
255 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
256 ostringstream eherr;
257 eherr << "field " << fieldname.c_str () << "cannot be read.";
258 throw InternalErr (__FILE__, __LINE__, eherr.str ());
259 }
260
261 set_value ((dods_uint32 *) val.data(), nelms);
262 }
263 break;
264 case DFNT_FLOAT32:
265 {
266
268 val.resize(nelms);
269 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), offset32.data(), step32.data(), count32.data(), val.data());
270 if (r != 0) {
271 detachfunc (swathid);
272 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
273 ostringstream eherr;
274 eherr << "field " << fieldname.c_str () << "cannot be read.";
275 throw InternalErr (__FILE__, __LINE__, eherr.str ());
276 }
277 set_value ((dods_float32 *) val.data(), nelms);
278 }
279 break;
280 case DFNT_FLOAT64:
281 {
283 val.resize(nelms);
284 r = readfieldfunc (swathid, const_cast < char *>(fieldname.c_str ()), offset32.data(), step32.data(), count32.data(), val.data());
285 if (r != 0) {
286 detachfunc (swathid);
287 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
288 ostringstream eherr;
289 eherr << "field " << fieldname.c_str () << "cannot be read.";
290 throw InternalErr (__FILE__, __LINE__, eherr.str ());
291 }
292
293 set_value ((dods_float64 *) val.data(), nelms);
294 }
295 break;
296 default:
297 detachfunc (swathid);
298 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
299 throw InternalErr (__FILE__, __LINE__, "unsupported data type.");
300 }
301
302 r = detachfunc (swathid);
303 if (r != 0) {
304 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
305 ostringstream eherr;
306 eherr << "Swath " << datasetname.c_str () << " cannot be detached.";
307 throw InternalErr (__FILE__, __LINE__, eherr.str ());
308 }
309
310 HDFCFUtil::close_fileid(-1,-1,-1,sfid,check_pass_fileid_key);
311
312 return false;
313}
314
315// Standard way of DAP handlers to pass the coordinates of the subsetted region to the handlers
316// Return the number of elements to read.
317int
318HDFEOS2ArraySwathGeoField::format_constraint (int *offset, int *step, int *count)
319{
320 int nels = 1;
321 int id = 0;
322
323 Dim_iter p = dim_begin ();
324 while (p != dim_end ()) {
325
326 int start = dimension_start (p, true);
327 int stride = dimension_stride (p, true);
328 int stop = dimension_stop (p, true);
329
330 // Check for illegal constraint
331 if (start > stop) {
332 ostringstream oss;
333 oss << "Array/Grid hyperslab start point "<< start <<
334 " is greater than stop point " << stop <<".";
335 throw Error(malformed_expr, oss.str());
336 }
337
338 offset[id] = start;
339 step[id] = stride;
340 count[id] = ((stop - start) / stride) + 1; // count of elements
341 nels *= count[id]; // total number of values for variable
342
343 BESDEBUG ("h4",
344 "=format_constraint():"
345 << "id=" << id << " offset=" << offset[id]
346 << " step=" << step[id]
347 << " count=" << count[id]
348 << endl);
349
350 id++;
351 p++;
352 }// end of while
353
354 return nels;
355}
356#endif
STL class.
STL class.
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)