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