1 /*****************************************************************************
2 * $Id: GDapi.c 29336 2015-06-14 17:37:21Z rouault $
3 *
4 * This module has a number of additions and improvements over the original
5 * implementation to be suitable for usage in GDAL HDF driver.
6 *
7 * Andrey Kiselev <dron@ak4719.spb.edu> is responsible for all the changes.
8 ****************************************************************************/
9
10 /*
11 Copyright (C) 1996 Hughes and Applied Research Corporation
12
13 Permission to use, modify, and distribute this software and its documentation
14 for any purpose without fee is hereby granted, provided that the above
15 copyright notice appear in all copies and that both that copyright notice and
16 this permission notice appear in supporting documentation.
17 */
18 /*****************************************************************************
19 REVISIONS:
20
21 Aug 31, 1999 Abe Taaheri Changed memory allocation for utility strings to
22 the size of UTLSTR_MAX_SIZE.
23 Added error check for memory unavailibilty in
24 several functions.
25 Added check for NULL metabuf returned from
26 EHmeta... functions. NULL pointer retruned from
27 EHmeta... functions indicate that memory could not
28 be allocated for metabuf.
29 Jun 27, 2000 Abe Taaheri Added support for EASE grid that uses
30 Behrmann Cylinderical Equal Area (BCEA) projection
31 Oct 23, 2000 Abe Taaheri Updated for ISINUS projection, so that both codes
32 31 and 99 can be used for this projection.
33 Jan 15, 2003 Abe Taaheri Modified for generalization of EASE Grid.
34
35 Jun 05, 2003 Bruce Beaumont / Abe Taaheri
36
37 Fixed SQUARE definition.
38 Added static projection number/name translation
39 Added projection table lookup in GDdefproj.
40 Removed projection table from GDdefproj
41 Added projection table lookup in GDprojinfo
42 Removed projection table from GDprojinfo
43 Added cast for compcode in call to SDsetcompress
44 in GDdeffield to avoid compiler errors
45 Removed declaration for unused variable endptr
46 in GDSDfldsrch
47 Removed initialization code for unused variables
48 in GDSDfldsrch
49 Removed declarations for unused variables
50 BCEA_scale, r0, s0, xMtr0, xMtr1, yMtr0,
51 and yMtr1 in GDll2ij
52 Removed initialization code for unused variables
53 in GDll2ij
54 Added code in GEO projection handling to allow
55 map to span dateline in GDll2ij
56 Changed "for each point" loop in GDll2ij to
57 return -2147483648.0 for xVal and yVal if
58 for_trans returned an error instead of
59 returning an error to the caller
60 (Note: MAXLONG is defined as 2147483647.0 in
61 function cproj.c of GCTP)
62 Added code in GDij2ll to use for_trans to
63 translate the BCEA corner points from packed
64 degrees to meters
65 Removed declarations for unused variables
66 BCEA_scale, r0, s0, xMtr, yMtr, epsilon,
67 beta, qp_cea, kz_cea, eccen, eccen_sq,
68 phi1, sinphi1, cosphi1, lon, lat, xcor,
69 ycor, and nlatlon from GDij2ll
70 Removed initialization code for unused variables
71 in GDij2ll
72 Added declarations for xMtr0, yMtr0, xMtr1, and
73 yMtr1 in GDij2ll
74 Added special-case code for BCEA
75 Changed "for each point" loop in GDij2ll to
76 return PGSd_GCT_IN_ERROR (1.0e51) for
77 longitude and latitude values if inv_trans
78 returned an error instead of return an error
79 to the caller
80 Removed declaration for unused variable ii in
81 GDgetpixvalues
82 Removed declaration for unused variable
83 numTileDims in GDtileinfo
84 Added error message and error return at the
85 end of GDll2mm_cea
86 Added return statement to GDll2mm_cea
87 ******************************************************************************/
88 #include "cpl_string.h"
89 #include "stdio.h"
90 #include "mfhdf.h"
91 #include "hcomp.h"
92 #include <math.h>
93 #include "HdfEosDef.h"
94
95 #include "hdf4compat.h"
96
97 extern void for_init(int32, int32, float64 *, int32, char *, char *, int32 *,
98 int32 (*for_trans[])());
99 extern void inv_init(int32, int32, float64 *, int32, char *, char *, int32 *,
100 int32 (*inv_trans[])());
101
102 #define GDIDOFFSET 4194304
103 #define SQUARE(x) ((x) * (x)) /* x**2 */
104 #define M_PI1 3.14159265358979323846
105
106 static int32 GDXSDcomb[512*5];
107 static char GDXSDname[HDFE_NAMBUFSIZE];
108 static char GDXSDdims[HDFE_DIMBUFSIZE];
109
110
111 #define NGRID 200
112 /* Grid Structure External Arrays */
113 struct gridStructure
114 {
115 int32 active;
116 int32 IDTable;
117 int32 VIDTable[2];
118 int32 fid;
119 int32 nSDS;
120 int32 *sdsID;
121 int32 compcode;
122 intn compparm[5];
123 int32 tilecode;
124 int32 tilerank;
125 int32 tiledims[8];
126 };
127 static struct gridStructure GDXGrid[NGRID];
128
129
130
131 #define NGRIDREGN 256
132 struct gridRegion
133 {
134 int32 fid;
135 int32 gridID;
136 int32 xStart;
137 int32 xCount;
138 int32 yStart;
139 int32 yCount;
140 int32 somStart;
141 int32 somCount;
142 float64 upleftpt[2];
143 float64 lowrightpt[2];
144 int32 StartVertical[8];
145 int32 StopVertical[8];
146 char *DimNamePtr[8];
147 };
148 static struct gridRegion *GDXRegion[NGRIDREGN];
149
150 /* define a macro for the string size of the utility strings and some dimension
151 list strings. The value of 80 in the previous version of this code
152 may not be enough in some cases. The length now is 512 which seems to
153 be more than enough to hold larger strings. */
154
155 #define UTLSTR_MAX_SIZE 512
156
157 /* Static projection table */
158 static const struct {
159 int32 projcode;
160 char *projname;
161 } Projections[] = {
162 {GCTP_GEO, "GCTP_GEO"},
163 {GCTP_UTM, "GCTP_UTM"},
164 {GCTP_SPCS, "GCTP_SPCS"},
165 {GCTP_ALBERS, "GCTP_ALBERS"},
166 {GCTP_LAMCC, "GCTP_LAMCC"},
167 {GCTP_MERCAT, "GCTP_MERCAT"},
168 {GCTP_PS, "GCTP_PS"},
169 {GCTP_POLYC, "GCTP_POLYC"},
170 {GCTP_EQUIDC, "GCTP_EQUIDC"},
171 {GCTP_TM, "GCTP_TM"},
172 {GCTP_STEREO, "GCTP_STEREO"},
173 {GCTP_LAMAZ, "GCTP_LAMAZ"},
174 {GCTP_AZMEQD, "GCTP_AZMEQD"},
175 {GCTP_GNOMON, "GCTP_GNOMON"},
176 {GCTP_ORTHO, "GCTP_ORTHO"},
177 {GCTP_GVNSP, "GCTP_GVNSP"},
178 {GCTP_SNSOID, "GCTP_SNSOID"},
179 {GCTP_EQRECT, "GCTP_EQRECT"},
180 {GCTP_MILLER, "GCTP_MILLER"},
181 {GCTP_VGRINT, "GCTP_VGRINT"},
182 {GCTP_HOM, "GCTP_HOM"},
183 {GCTP_ROBIN, "GCTP_ROBIN"},
184 {GCTP_SOM, "GCTP_SOM"},
185 {GCTP_ALASKA, "GCTP_ALASKA"},
186 {GCTP_GOOD, "GCTP_GOOD"},
187 {GCTP_MOLL, "GCTP_MOLL"},
188 {GCTP_IMOLL, "GCTP_IMOLL"},
189 {GCTP_HAMMER, "GCTP_HAMMER"},
190 {GCTP_WAGIV, "GCTP_WAGIV"},
191 {GCTP_WAGVII, "GCTP_WAGVII"},
192 {GCTP_OBLEQA, "GCTP_OBLEQA"},
193 {GCTP_ISINUS1, "GCTP_ISINUS1"},
194 {GCTP_CEA, "GCTP_CEA"},
195 {GCTP_BCEA, "GCTP_BCEA"},
196 {GCTP_ISINUS, "GCTP_ISINUS"},
197 {-1, NULL}
198 };
199
200 /* Compression Codes */
201 static const char *HDFcomp[] = {
202 "HDFE_COMP_NONE",
203 "HDFE_COMP_RLE",
204 "HDFE_COMP_NBIT",
205 "HDFE_COMP_SKPHUFF",
206 "HDFE_COMP_DEFLATE"
207 };
208
209 /* Origin Codes */
210 static const char *originNames[] = {
211 "HDFE_GD_UL",
212 "HDFE_GD_UR",
213 "HDFE_GD_LL",
214 "HDFE_GD_LR"
215 };
216
217 /* Pixel Registration Codes */
218 static const char *pixregNames[] = {
219 "HDFE_CENTER",
220 "HDFE_CORNER"
221 };
222
223 /* Grid Function Prototypes (internal routines) */
224 static intn GDchkgdid(int32, char *, int32 *, int32 *, int32 *);
225 static intn GDSDfldsrch(int32, int32, const char *, int32 *, int32 *,
226 int32 *, int32 *, int32 [], int32 *);
227 static intn GDwrrdfield(int32, char *, char *,
228 int32 [], int32 [], int32 [], VOIDP datbuf);
229 static intn GDwrrdattr(int32, char *, int32, int32, char *, VOIDP);
230 static intn GDll2ij(int32, int32, float64 [], int32, int32, int32, float64[],
231 float64[], int32, float64[], float64[], int32[], int32[],
232 float64[], float64[]);
233 static intn GDgetdefaults(int32, int32, float64[], int32,
234 float64[], float64[]);
235 static intn GDtangentpnts(int32, float64[], float64[], float64[], float64[],
236 float64 [], int32 *);
237 static intn GDwrrdtile(int32, char *, char *, int32 [], VOIDP);
238 static intn GDll2mm_cea(int32,int32, int32, float64[], int32, int32,
239 float64[], float64[], int32, float64[],float64[],
240 float64[], float64[], float64 *, float64 *);
241
242 static intn GDmm2ll_cea(int32, int32, int32, float64[], int32, int32,
243 float64[], float64[], int32, float64[], float64[],
244 float64[], float64[]);
245
246 /*----------------------------------------------------------------------------|
247 | BEGIN_PROLOG |
248 | |
249 | FUNCTION: GDopen |
250 | |
251 | DESCRIPTION: Opens or creates HDF file in order to create, read, or write |
252 | a grid. |
253 | |
254 | |
255 | Return Value Type Units Description |
256 | ============ ====== ========= ===================================== |
257 | fid int32 HDF-EOS file ID |
258 | |
259 | INPUTS: |
260 | filename char Filename |
261 | access intn HDF access code |
262 | |
263 | |
264 | OUTPUTS: |
265 | None |
266 | |
267 | NOTES: |
268 | |
269 | |
270 | Date Programmer Description |
271 | ====== ============ ================================================= |
272 | Jun 96 Joel Gales Original Programmer |
273 | |
274 | END_PROLOG |
275 -----------------------------------------------------------------------------*/
276 int32
GDopen(char * filename,intn access)277 GDopen(char *filename, intn access)
278
279 {
280 int32 fid /* HDF-EOS file ID */ ;
281
282 /* Call EHopen to perform file access */
283 /* ---------------------------------- */
284 fid = EHopen(filename, access);
285
286 return (fid);
287
288 }
289
290
291
292 /*----------------------------------------------------------------------------|
293 | BEGIN_PROLOG |
294 | |
295 | FUNCTION: GDcreate |
296 | |
297 | DESCRIPTION: Creates a grid within the file. |
298 | |
299 | |
300 | Return Value Type Units Description |
301 | ============ ====== ========= ===================================== |
302 | gridID int32 Grid structure ID |
303 | |
304 | INPUTS: |
305 | fid int32 File ID |
306 | gridname char Grid structure name |
307 | xdimsize int32 Number of columns in grid |
308 | ydimsize int32 Number of rows in grid |
309 | upleftpt float64 Location (m/deg) of upper left corner |
310 | lowrightpt float64 Location (m/deg) of lower right corner |
311 | |
312 | |
313 | OUTPUTS: |
314 | None |
315 | |
316 | NOTES: |
317 | |
318 | |
319 | Date Programmer Description |
320 | ====== ============ ================================================= |
321 | Jun 96 Joel Gales Original Programmer |
322 | Aug 96 Joel Gales Make metadata ODL compliant |
323 | Aug 96 Joel Gales Check grid name for ODL compliance |
324 | |
325 | END_PROLOG |
326 -----------------------------------------------------------------------------*/
327 int32
GDcreate(int32 fid,char * gridname,int32 xdimsize,int32 ydimsize,float64 upleftpt[],float64 lowrightpt[])328 GDcreate(int32 fid, char *gridname, int32 xdimsize, int32 ydimsize,
329 float64 upleftpt[], float64 lowrightpt[])
330 {
331 intn i; /* Loop index */
332 intn ngridopen = 0; /* # of grid structures open */
333 intn status = 0; /* routine return status variable */
334
335 uint8 access; /* Read/Write file access code */
336
337 int32 HDFfid; /* HDF file id */
338 int32 vgRef; /* Vgroup reference number */
339 int32 vgid[3]; /* Vgroup ID array */
340 int32 gridID = -1;/* HDF-EOS grid ID */
341
342 int32 sdInterfaceID; /* HDF SDS interface ID */
343 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
344 int32 nGrid = 0; /* Grid counter */
345
346 char name[80]; /* Vgroup name */
347 char class[80]; /* Vgroup class */
348 char errbuf[256];/* Buffer for error message */
349 char utlbuf[1024]; /* Utility buffer */
350 char header[128];/* Structural metadata header string */
351 char footer[256];/* Structural metadata footer string */
352 char refstr1[128]; /* Upper left ref string (metadata) */
353 char refstr2[128]; /* Lower right ref string (metadata) */
354
355
356 /*
357 * Check HDF-EOS file ID, get back HDF file ID, SD interface ID and
358 * access code
359 */
360 status = EHchkfid(fid, gridname, &HDFfid, &sdInterfaceID, &access);
361
362
363 /* Check gridname for length */
364 /* ------------------------- */
365 if ((intn) strlen(gridname) > VGNAMELENMAX)
366 {
367 status = -1;
368 HEpush(DFE_GENAPP, "GDcreate", __FILE__, __LINE__);
369 HEreport("Gridname \"%s\" must be less than %d characters.\n",
370 gridname, VGNAMELENMAX);
371 }
372
373
374
375 if (status == 0)
376 {
377 /* Determine number of grids currently opened */
378 /* ------------------------------------------- */
379 for (i = 0; i < NGRID; i++)
380 {
381 ngridopen += GDXGrid[i].active;
382 }
383
384
385 /* Setup file interface */
386 /* -------------------- */
387 if (ngridopen < NGRID)
388 {
389
390 /* Check that grid has not been previously opened */
391 /* ----------------------------------------------- */
392 vgRef = -1;
393
394 while (1)
395 {
396 vgRef = Vgetid(HDFfid, vgRef);
397
398 /* If no more Vgroups then exist while loop */
399 /* ---------------------------------------- */
400 if (vgRef == -1)
401 {
402 break;
403 }
404
405 /* Get name and class of Vgroup */
406 /* ---------------------------- */
407 vgid[0] = Vattach(HDFfid, vgRef, "r");
408 Vgetname(vgid[0], name);
409 Vgetclass(vgid[0], class);
410 Vdetach(vgid[0]);
411
412
413 /* If GRID then increment # grid counter */
414 /* ------------------------------------- */
415 if (strcmp(class, "GRID") == 0)
416 {
417 nGrid++;
418 }
419
420
421 /* If grid already exist, return error */
422 /* ------------------------------------ */
423 if (strcmp(name, gridname) == 0 &&
424 strcmp(class, "GRID") == 0)
425 {
426 status = -1;
427 HEpush(DFE_GENAPP, "GDcreate", __FILE__, __LINE__);
428 HEreport("\"%s\" already exists.\n", gridname);
429 break;
430 }
431 }
432
433
434 if (status == 0)
435 {
436 /* Create Root Vgroup for Grid */
437 /* ---------------------------- */
438 vgid[0] = Vattach(HDFfid, -1, "w");
439
440
441 /* Set Name and Class (GRID) */
442 /* -------------------------- */
443 Vsetname(vgid[0], gridname);
444 Vsetclass(vgid[0], "GRID");
445
446
447
448 /* Create Data Fields Vgroup */
449 /* ------------------------- */
450 vgid[1] = Vattach(HDFfid, -1, "w");
451 Vsetname(vgid[1], "Data Fields");
452 Vsetclass(vgid[1], "GRID Vgroup");
453 Vinsert(vgid[0], vgid[1]);
454
455
456
457 /* Create Attributes Vgroup */
458 /* ------------------------ */
459 vgid[2] = Vattach(HDFfid, -1, "w");
460 Vsetname(vgid[2], "Grid Attributes");
461 Vsetclass(vgid[2], "GRID Vgroup");
462 Vinsert(vgid[0], vgid[2]);
463
464
465
466 /* Establish Grid in Structural MetaData Block */
467 /* -------------------------------------------- */
468 sprintf(header, "%s%d%s%s%s%s%d%s%s%d%s",
469 "\tGROUP=GRID_", (int)(nGrid + 1),
470 "\n\t\tGridName=\"", gridname, "\"\n",
471 "\t\tXDim=", (int)xdimsize, "\n",
472 "\t\tYDim=", (int)ydimsize, "\n");
473
474
475 sprintf(footer,
476 "%s%s%s%s%s%s%s%d%s",
477 "\t\tGROUP=Dimension\n",
478 "\t\tEND_GROUP=Dimension\n",
479 "\t\tGROUP=DataField\n",
480 "\t\tEND_GROUP=DataField\n",
481 "\t\tGROUP=MergedFields\n",
482 "\t\tEND_GROUP=MergedFields\n",
483 "\tEND_GROUP=GRID_", (int)(nGrid + 1), "\n");
484
485
486
487 /* Build Ref point Col-Row strings */
488 /* ------------------------------- */
489 if (upleftpt == NULL ||
490 (upleftpt[0] == 0 && upleftpt[1] == 0 &&
491 lowrightpt[0] == 0 && lowrightpt[1] == 0))
492 {
493 strcpy(refstr1, "DEFAULT");
494 strcpy(refstr2, "DEFAULT");
495 }
496 else
497 {
498 CPLsprintf(refstr1, "%s%f%s%f%s",
499 "(", upleftpt[0], ",", upleftpt[1], ")");
500
501 CPLsprintf(refstr2, "%s%f%s%f%s",
502 "(", lowrightpt[0], ",", lowrightpt[1], ")");
503 }
504
505 sprintf(utlbuf,
506 "%s%s%s%s%s%s%s%s",
507 header,
508 "\t\tUpperLeftPointMtrs=", refstr1, "\n",
509 "\t\tLowerRightMtrs=", refstr2, "\n",
510 footer);
511
512 status = EHinsertmeta(sdInterfaceID, "", "g", 1002L,
513 utlbuf, NULL);
514
515 }
516 }
517 else
518 {
519 /* Too many files opened */
520 /* --------------------- */
521 status = -1;
522 strcpy(errbuf,
523 "No more than %d grids may be open simutaneously");
524 strcat(errbuf, " (%s)");
525 HEpush(DFE_DENIED, "GDcreate", __FILE__, __LINE__);
526 HEreport(errbuf, NGRID, gridname);
527 }
528
529
530 /* Assign gridID # & Load grid and GDXGrid.fid table entries */
531 /* --------------------------------------------------------- */
532 if (status == 0)
533 {
534
535 for (i = 0; i < NGRID; i++)
536 {
537 if (GDXGrid[i].active == 0)
538 {
539 gridID = i + idOffset;
540 GDXGrid[i].active = 1;
541 GDXGrid[i].IDTable = vgid[0];
542 GDXGrid[i].VIDTable[0] = vgid[1];
543 GDXGrid[i].VIDTable[1] = vgid[2];
544 GDXGrid[i].fid = fid;
545 status = 0;
546 break;
547 }
548 }
549
550 }
551 }
552 return (gridID);
553 }
554
555
556
557 /*----------------------------------------------------------------------------|
558 | BEGIN_PROLOG |
559 | |
560 | FUNCTION: GDattach |
561 | |
562 | DESCRIPTION: Attaches to an existing grid within the file. |
563 | |
564 | |
565 | Return Value Type Units Description |
566 | ============ ====== ========= ===================================== |
567 | gridID int32 grid structure ID |
568 | |
569 | INPUTS: |
570 | fid int32 HDF-EOS file id |
571 | gridname char grid sructure name |
572 | |
573 | |
574 | OUTPUTS: |
575 | None |
576 | |
577 | NOTES: |
578 | |
579 | |
580 | Date Programmer Description |
581 | ====== ============ ================================================= |
582 | Jun 96 Joel Gales Original Programmer |
583 | Sep 99 Abe Taaheri Modified test for memory allocation check when no |
584 | SDSs are in the grid, NCR24147 |
585 | |
586 | END_PROLOG |
587 -----------------------------------------------------------------------------*/
588 int32
GDattach(int32 fid,char * gridname)589 GDattach(int32 fid, char *gridname)
590
591 {
592 intn i; /* Loop index */
593 intn j; /* Loop index */
594 intn ngridopen = 0; /* # of grid structures open */
595 intn status; /* routine return status variable */
596
597 uint8 acs; /* Read/Write file access code */
598
599 int32 HDFfid; /* HDF file id */
600 int32 vgRef; /* Vgroup reference number */
601 int32 vgid[3]; /* Vgroup ID array */
602 int32 gridID = -1;/* HDF-EOS grid ID */
603 int32 *tags; /* Pnt to Vgroup object tags array */
604 int32 *refs; /* Pnt to Vgroup object refs array */
605 int32 dum; /* dummy varible */
606 int32 sdInterfaceID; /* HDF SDS interface ID */
607 int32 nObjects; /* # of objects in Vgroup */
608 int32 nSDS; /* SDS counter */
609 int32 index; /* SDS index */
610 int32 sdid; /* SDS object ID */
611 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
612
613 char name[80]; /* Vgroup name */
614 char class[80]; /* Vgroup class */
615 char errbuf[256];/* Buffer for error message */
616 char acsCode[1]; /* Read/Write access char: "r/w" */
617
618
619 /* Check HDF-EOS file ID, get back HDF file ID and access code */
620 /* ----------------------------------------------------------- */
621 status = EHchkfid(fid, gridname, &HDFfid, &dum, &acs);
622
623
624 if (status == 0)
625 {
626 /* Convert numeric access code to character */
627 /* ---------------------------------------- */
628
629 acsCode[0] = (acs == 1) ? 'w' : 'r';
630
631 /* Determine number of grids currently opened */
632 /* ------------------------------------------- */
633 for (i = 0; i < NGRID; i++)
634 {
635 ngridopen += GDXGrid[i].active;
636 }
637
638
639 /* If room for more ... */
640 /* -------------------- */
641 if (ngridopen < NGRID)
642 {
643
644 /* Search Vgroups for Grid */
645 /* ------------------------ */
646 vgRef = -1;
647
648 while (1)
649 {
650 vgRef = Vgetid(HDFfid, vgRef);
651
652 /* If no more Vgroups then exist while loop */
653 /* ---------------------------------------- */
654 if (vgRef == -1)
655 {
656 break;
657 }
658
659 /* Get name and class of Vgroup */
660 /* ---------------------------- */
661 vgid[0] = Vattach(HDFfid, vgRef, "r");
662 Vgetname(vgid[0], name);
663 Vgetclass(vgid[0], class);
664
665
666 /*
667 * If Vgroup with gridname and class GRID found, load tables
668 */
669
670 if (strcmp(name, gridname) == 0 &&
671 strcmp(class, "GRID") == 0)
672 {
673 /* Attach to "Data Fields" and "Grid Attributes" Vgroups */
674 /* ----------------------------------------------------- */
675 tags = (int32 *) malloc(sizeof(int32) * 2);
676 if(tags == NULL)
677 {
678 HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
679 return(-1);
680 }
681 refs = (int32 *) malloc(sizeof(int32) * 2);
682 if(refs == NULL)
683 {
684 HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
685 free(tags);
686 return(-1);
687 }
688 Vgettagrefs(vgid[0], tags, refs, 2);
689 vgid[1] = Vattach(HDFfid, refs[0], acsCode);
690 vgid[2] = Vattach(HDFfid, refs[1], acsCode);
691 free(tags);
692 free(refs);
693
694
695 /* Setup External Arrays */
696 /* --------------------- */
697 for (i = 0; i < NGRID; i++)
698 {
699 /* Find empty entry in array */
700 /* ------------------------- */
701 if (GDXGrid[i].active == 0)
702 {
703 /*
704 * Set gridID, Set grid entry active, Store root
705 * Vgroup ID, Store sub Vgroup IDs, Store HDF-EOS
706 * file ID
707 */
708 gridID = i + idOffset;
709 GDXGrid[i].active = 1;
710 GDXGrid[i].IDTable = vgid[0];
711 GDXGrid[i].VIDTable[0] = vgid[1];
712 GDXGrid[i].VIDTable[1] = vgid[2];
713 GDXGrid[i].fid = fid;
714 break;
715 }
716 }
717
718 /* Get SDS interface ID */
719 /* -------------------- */
720 status = GDchkgdid(gridID, "GDattach", &dum,
721 &sdInterfaceID, &dum);
722
723
724 /* Get # of entries within Data Vgroup & search for SDS */
725 /* ---------------------------------------------------- */
726 nObjects = Vntagrefs(vgid[1]);
727
728 if (nObjects > 0)
729 {
730 /* Get tag and ref # for Data Vgroup objects */
731 /* ----------------------------------------- */
732 tags = (int32 *) malloc(sizeof(int32) * nObjects);
733 if(tags == NULL)
734 {
735 HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
736 return(-1);
737 }
738 refs = (int32 *) malloc(sizeof(int32) * nObjects);
739 if(refs == NULL)
740 {
741 HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
742 free(tags);
743 return(-1);
744 }
745 Vgettagrefs(vgid[1], tags, refs, nObjects);
746
747 /* Count number of SDS & allocate SDS ID array */
748 /* ------------------------------------------- */
749 nSDS = 0;
750 for (j = 0; j < nObjects; j++)
751 {
752 if (tags[j] == DFTAG_NDG)
753 {
754 nSDS++;
755 }
756 }
757 GDXGrid[i].sdsID = (int32 *) calloc(nSDS, 4);
758 if(GDXGrid[i].sdsID == NULL && nSDS != 0)
759 {
760 HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
761 free(tags);
762 free(refs);
763 return(-1);
764 }
765 nSDS = 0;
766
767
768
769 /* Fill SDS ID array */
770 /* ----------------- */
771 for (j = 0; j < nObjects; j++)
772 {
773 /* If object is SDS then get id */
774 /* ---------------------------- */
775 if (tags[j] == DFTAG_NDG)
776 {
777 index = SDreftoindex(sdInterfaceID, refs[j]);
778 sdid = SDselect(sdInterfaceID, index);
779 GDXGrid[i].sdsID[nSDS] = sdid;
780 nSDS++;
781 GDXGrid[i].nSDS++;
782 }
783 }
784 free(tags);
785 free(refs);
786 }
787 break;
788 }
789
790 /* Detach Vgroup if not desired Grid */
791 /* --------------------------------- */
792 Vdetach(vgid[0]);
793 }
794
795 /* If Grid not found then set up error message */
796 /* ------------------------------------------- */
797 if (gridID == -1)
798 {
799 HEpush(DFE_RANGE, "GDattach", __FILE__, __LINE__);
800 HEreport("Grid: \"%s\" does not exist within HDF file.\n",
801 gridname);
802 }
803 }
804 else
805 {
806 /* Too many files opened */
807 /* --------------------- */
808 gridID = -1;
809 strcpy(errbuf,
810 "No more than %d grids may be open simutaneously");
811 strcat(errbuf, " (%s)");
812 HEpush(DFE_DENIED, "GDattach", __FILE__, __LINE__);
813 HEreport(errbuf, NGRID, gridname);
814 }
815
816 }
817 return (gridID);
818 }
819
820
821 /*----------------------------------------------------------------------------|
822 | BEGIN_PROLOG |
823 | |
824 | FUNCTION: GDchkgdid |
825 | |
826 | DESCRIPTION: |
827 | |
828 | |
829 | Return Value Type Units Description |
830 | ============ ====== ========= ===================================== |
831 | status intn return status (0) SUCCEED, (-1) FAIL |
832 | |
833 | INPUTS: |
834 | gridID int32 grid structure ID |
835 | routname char Name of routine calling GDchkgdid |
836 | |
837 | OUTPUTS: |
838 | fid int32 File ID |
839 | sdInterfaceID int32 SDS interface ID |
840 | gdVgrpID int32 grid Vgroup ID |
841 | |
842 | |
843 | OUTPUTS: |
844 | None |
845 | |
846 | NOTES: |
847 | |
848 | |
849 | Date Programmer Description |
850 | ====== ============ ================================================= |
851 | Jun 96 Joel Gales Original Programmer |
852 | |
853 | END_PROLOG |
854 -----------------------------------------------------------------------------*/
855 static intn
GDchkgdid(int32 gridID,char * routname,int32 * fid,int32 * sdInterfaceID,int32 * gdVgrpID)856 GDchkgdid(int32 gridID, char *routname,
857 int32 * fid, int32 * sdInterfaceID, int32 * gdVgrpID)
858 {
859 intn status = 0; /* routine return status variable */
860 uint8 access; /* Read/Write access code */
861 int32 gID; /* Grid ID - offset */
862
863 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
864
865 static const char message1[] =
866 "Invalid grid id: %d in routine \"%s\". ID must be >= %d and < %d.\n";
867 static const char message2[] =
868 "Grid id %d in routine \"%s\" not active.\n";
869
870
871
872 /* Check for valid grid id */
873
874 if (gridID < idOffset || gridID >= NGRID + idOffset)
875 {
876 status = -1;
877 HEpush(DFE_RANGE, "GDchkgdid", __FILE__, __LINE__);
878 HEreport(message1, gridID, routname, idOffset, NGRID + idOffset);
879 }
880 else
881 {
882
883 /* Compute "reduced" ID */
884 /* -------------------- */
885 gID = gridID % idOffset;
886
887
888 /* Check for active grid ID */
889 /* ------------------------ */
890 if (GDXGrid[gID].active == 0)
891 {
892 status = -1;
893 HEpush(DFE_GENAPP, "GDchkgdid", __FILE__, __LINE__);
894 HEreport(message2, gridID, routname);
895 }
896 else
897 {
898
899 /* Get file & SDS ids and Grid key */
900 /* -------------------------------- */
901 status = EHchkfid(GDXGrid[gID].fid, " ",
902 fid, sdInterfaceID, &access);
903 *gdVgrpID = GDXGrid[gID].IDTable;
904 }
905 }
906 return (status);
907
908 }
909
910
911 /*----------------------------------------------------------------------------|
912 | BEGIN_PROLOG |
913 | |
914 | FUNCTION: GDdefdim |
915 | |
916 | DESCRIPTION: Defines a new dimension within the grid. |
917 | |
918 | |
919 | Return Value Type Units Description |
920 | ============ ====== ========= ===================================== |
921 | status intn return status (0) SUCCEED, (-1) FAIL |
922 | |
923 | INPUTS: |
924 | gridID int32 grid structure ID |
925 | dimname char Dimension name to define |
926 | dim int32 Dimemsion value |
927 | |
928 | |
929 | OUTPUTS: |
930 | None |
931 | |
932 | NOTES: |
933 | |
934 | |
935 | Date Programmer Description |
936 | ====== ============ ================================================= |
937 | Jun 96 Joel Gales Original Programmer |
938 | |
939 | END_PROLOG |
940 -----------------------------------------------------------------------------*/
941 intn
GDdefdim(int32 gridID,char * dimname,int32 dim)942 GDdefdim(int32 gridID, char *dimname, int32 dim)
943
944 {
945 intn status; /* routine return status variable */
946
947 int32 fid; /* HDF-EOS file id */
948 int32 sdInterfaceID; /* HDF SDS interface ID */
949 int32 gdVgrpID; /* Grid root Vgroup ID */
950 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
951
952 char gridname[80] /* Grid name */ ;
953
954
955 /* Check for valid grid id */
956 status = GDchkgdid(gridID, "GDdefinedim",
957 &fid, &sdInterfaceID, &gdVgrpID);
958
959
960 /* Make sure dimension >= 0 */
961 /* ------------------------ */
962 if (dim < 0)
963 {
964 status = -1;
965 HEpush(DFE_GENAPP, "GDdefdim", __FILE__, __LINE__);
966 HEreport("Dimension value for \"%s\" less than zero: %d.\n",
967 dimname, dim);
968 }
969
970
971 /* Write Dimension to Structural MetaData */
972 /* -------------------------------------- */
973 if (status == 0)
974 {
975 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
976 status = EHinsertmeta(sdInterfaceID, gridname, "g", 0L,
977 dimname, &dim);
978 }
979 return (status);
980
981 }
982
983 /*----------------------------------------------------------------------------|
984 | BEGIN_PROLOG |
985 | |
986 | FUNCTION: GDdefproj |
987 | |
988 | DESCRIPTION: Defines projection of grid. |
989 | |
990 | |
991 | Return Value Type Units Description |
992 | ============ ====== ========= ===================================== |
993 | status intn return status (0) SUCCEED, (-1) FAIL |
994 | |
995 | INPUTS: |
996 | gridID int32 Grid structure ID |
997 | projcode int32 GCTP projection code |
998 | zonecode int32 UTM zone code |
999 | spherecode int32 GCTP spheriod code |
1000 | projparm float64 Projection parameters |
1001 | |
1002 | OUTPUTS: |
1003 | None |
1004 | |
1005 | NOTES: |
1006 | |
1007 | |
1008 | Date Programmer Description |
1009 | ====== ============ ================================================= |
1010 | Jun 96 Joel Gales Original Programmer |
1011 | Jun 00 Abe Taaheri Added support for EASE grid |
1012 | |
1013 | END_PROLOG |
1014 -----------------------------------------------------------------------------*/
1015 intn
GDdefproj(int32 gridID,int32 projcode,int32 zonecode,int32 spherecode,float64 projparm[])1016 GDdefproj(int32 gridID, int32 projcode, int32 zonecode, int32 spherecode,
1017 float64 projparm[])
1018 {
1019 intn i; /* Loop index */
1020 intn projx; /* Projection table index */
1021 intn status = 0; /* routine return status variable */
1022
1023 int32 fid; /* HDF-EOS file ID */
1024 int32 sdInterfaceID; /* HDF SDS interface ID */
1025 int32 gdVgrpID; /* Grid root Vgroup ID */
1026 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1027 int32 slen; /* String length */
1028 float64 EHconvAng();
1029 char utlbuf[1024]; /* Utility Buffer */
1030 char projparmbuf[512]; /* Projection parameter metadata
1031 * string */
1032 char gridname[80]; /* Grid Name */
1033
1034
1035 /* Check for valid grid id */
1036 /* ----------------------- */
1037 status = GDchkgdid(gridID, "GDdefproj", &fid, &sdInterfaceID, &gdVgrpID);
1038
1039 if (status == 0)
1040 {
1041 /*
1042 * If projection not GEO, UTM, or State Code build projection
1043 * parameter string
1044 */
1045 if (projcode != GCTP_GEO &&
1046 projcode != GCTP_UTM &&
1047 projcode != GCTP_SPCS)
1048 {
1049
1050 /* Begin projection parameter list with "(" */
1051 strcpy(projparmbuf, "(");
1052
1053 for (i = 0; i < 13; i++)
1054 {
1055 /* If projparm[i] = 0 ... */
1056 if (projparm[i] == 0.0)
1057 {
1058 strcpy(utlbuf, "0,");
1059 }
1060 else
1061 {
1062 /* if projparm[i] is integer ... */
1063 if ((int32) projparm[i] == projparm[i])
1064 {
1065 sprintf(utlbuf, "%d%s",
1066 (int) projparm[i], ",");
1067 }
1068 /* else projparm[i] is non-zero floating point ... */
1069 else
1070 {
1071 CPLsprintf(utlbuf, "%f%s", projparm[i], ",");
1072 }
1073 }
1074 strcat(projparmbuf, utlbuf);
1075 }
1076 slen = strlen(projparmbuf);
1077
1078 /* Add trailing ")" */
1079 projparmbuf[slen - 1] = ')';
1080 }
1081
1082 for (projx = 0; Projections[projx].projcode != -1; projx++)
1083 {
1084 if (projcode == Projections[projx].projcode)
1085 {
1086 break;
1087 }
1088 }
1089
1090
1091 /* Build metadata string */
1092 /* --------------------- */
1093 if ((projcode == GCTP_GEO))
1094 {
1095 sprintf(utlbuf,
1096 "%s%s%s",
1097 "\t\tProjection=", Projections[projx].projname, "\n");
1098 }
1099 else if (projcode == GCTP_UTM || projcode == GCTP_SPCS)
1100 {
1101 sprintf(utlbuf,
1102 "%s%s%s%s%d%s%s%d%s",
1103 "\t\tProjection=", Projections[projx].projname, "\n",
1104 "\t\tZoneCode=", (int)zonecode, "\n",
1105 "\t\tSphereCode=", (int)spherecode, "\n");
1106 }
1107 else
1108 {
1109 sprintf(utlbuf,
1110 "%s%s%s%s%s%s%s%d%s",
1111 "\t\tProjection=", Projections[projx].projname, "\n",
1112 "\t\tProjParams=", projparmbuf, "\n",
1113 "\t\tSphereCode=", (int)spherecode, "\n");
1114 }
1115
1116
1117 /* Insert in structural metadata */
1118 /* ----------------------------- */
1119 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
1120 status = EHinsertmeta(sdInterfaceID, gridname, "g", 101L,
1121 utlbuf, NULL);
1122 }
1123
1124 return (status);
1125 }
1126
1127
1128
1129 /*----------------------------------------------------------------------------|
1130 | BEGIN_PROLOG |
1131 | |
1132 | FUNCTION: GDblkSOMoffset |
1133 | |
1134 | DESCRIPTION: Writes Block SOM offset values |
1135 | |
1136 | |
1137 | Return Value Type Units Description |
1138 | ============ ====== ========= ===================================== |
1139 | status intn return status (0) SUCCEED, (-1) FAIL |
1140 | |
1141 | INPUTS: |
1142 | gridID int32 Grid structure ID |
1143 | offset float32 Offset values |
1144 | count int32 Number of offset values |
1145 | code char w/r code (w/r) |
1146 | |
1147 | OUTPUTS: |
1148 | None |
1149 | |
1150 | NOTES: |
1151 | |
1152 | |
1153 | Date Programmer Description |
1154 | ====== ============ ================================================= |
1155 | Sep 96 Joel Gales Original Programmer |
1156 | Mar 99 David Wynne Changed data type of offset array from int32 to |
1157 | float32, NCR 21197 |
1158 | |
1159 | END_PROLOG |
1160 -----------------------------------------------------------------------------*/
1161 intn
GDblkSOMoffset(int32 gridID,float32 offset[],int32 count,char * code)1162 GDblkSOMoffset(int32 gridID, float32 offset[], int32 count, char *code)
1163 {
1164 intn status = 0; /* routine return status variable */
1165
1166 int32 fid; /* HDF-EOS file ID */
1167 int32 sdInterfaceID; /* HDF SDS interface ID */
1168 int32 gdVgrpID; /* Grid root Vgroup ID */
1169 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1170 int32 projcode; /* GCTP projection code */
1171
1172 float64 projparm[13]; /* Projection parameters */
1173
1174 char utlbuf[128];/* Utility Buffer */
1175 char gridname[80]; /* Grid Name */
1176
1177 /* Check for valid grid id */
1178 status = GDchkgdid(gridID, "GDblkSOMoffset",
1179 &fid, &sdInterfaceID, &gdVgrpID);
1180
1181 if (status == 0)
1182 {
1183 /* Get projection parameters */
1184 status = GDprojinfo(gridID, &projcode, NULL, NULL, projparm);
1185
1186 /* If SOM projection with projparm[11] non-zero ... */
1187 if (projcode == GCTP_SOM && projparm[11] != 0)
1188 {
1189 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
1190 sprintf(utlbuf, "%s%s", "_BLKSOM:", gridname);
1191
1192 /* Write offset values as attribute */
1193 if (strcmp(code, "w") == 0)
1194 {
1195 status = GDwriteattr(gridID, utlbuf, DFNT_FLOAT32,
1196 count, offset);
1197 }
1198 /* Read offset values from attribute */
1199 else if (strcmp(code, "r") == 0)
1200 {
1201 status = GDreadattr(gridID, utlbuf, offset);
1202 }
1203 }
1204 }
1205 return (status);
1206 }
1207
1208
1209 /*----------------------------------------------------------------------------|
1210 | BEGIN_PROLOG |
1211 | |
1212 | FUNCTION: GDdefcomp |
1213 | |
1214 | DESCRIPTION: Defines compression type and parameters |
1215 | |
1216 | |
1217 | Return Value Type Units Description |
1218 | ============ ====== ========= ===================================== |
1219 | status intn return status (0) SUCCEED, (-1) FAIL |
1220 | |
1221 | INPUTS: |
1222 | gridID int32 grid structure ID |
1223 | compcode int32 compression code |
1224 | compparm intn compression parameters |
1225 | |
1226 | OUTPUTS: |
1227 | None |
1228 | |
1229 | NOTES: |
1230 | |
1231 | |
1232 | Date Programmer Description |
1233 | ====== ============ ================================================= |
1234 | Sep 96 Joel Gales Original Programmer |
1235 | |
1236 | END_PROLOG |
1237 -----------------------------------------------------------------------------*/
1238 intn
GDdefcomp(int32 gridID,int32 compcode,intn compparm[])1239 GDdefcomp(int32 gridID, int32 compcode, intn compparm[])
1240 {
1241 intn status = 0; /* routine return status variable */
1242
1243 int32 fid; /* HDF-EOS file id */
1244 int32 sdInterfaceID; /* HDF SDS interface ID */
1245 int32 gdVgrpID; /* Grid root Vgroup ID */
1246 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1247 int32 gID; /* gridID - offset */
1248
1249 /* Check for valid grid id */
1250 status = GDchkgdid(gridID, "GDdefcomp", &fid, &sdInterfaceID, &gdVgrpID);
1251
1252 if (status == 0)
1253 {
1254 gID = gridID % idOffset;
1255
1256 /* Set compression code in compression exteral array */
1257 GDXGrid[gID].compcode = compcode;
1258
1259 switch (compcode)
1260 {
1261 /* Set NBIT compression parameters in compression external array */
1262 case HDFE_COMP_NBIT:
1263
1264 GDXGrid[gID].compparm[0] = compparm[0];
1265 GDXGrid[gID].compparm[1] = compparm[1];
1266 GDXGrid[gID].compparm[2] = compparm[2];
1267 GDXGrid[gID].compparm[3] = compparm[3];
1268
1269 break;
1270
1271 /* Set GZIP compression parameter in compression external array */
1272 case HDFE_COMP_DEFLATE:
1273
1274 GDXGrid[gID].compparm[0] = compparm[0];
1275
1276 break;
1277
1278 }
1279 }
1280
1281 return (status);
1282 }
1283
1284
1285
1286
1287 /*----------------------------------------------------------------------------|
1288 | BEGIN_PROLOG |
1289 | |
1290 | FUNCTION: GDdeftile |
1291 | |
1292 | DESCRIPTION: Defines tiling parameters |
1293 | |
1294 | |
1295 | Return Value Type Units Description |
1296 | ============ ====== ========= ===================================== |
1297 | status intn return status (0) SUCCEED, (-1) FAIL |
1298 | |
1299 | INPUTS: |
1300 | gridID int32 grid structure ID |
1301 | tilecode int32 tile code |
1302 | tilerank int32 number of tiling dimensions |
1303 | tiledims int32 tiling dimensions |
1304 | |
1305 | OUTPUTS: |
1306 | None |
1307 | |
1308 | NOTES: |
1309 | |
1310 | |
1311 | Date Programmer Description |
1312 | ====== ============ ================================================= |
1313 | Jan 97 Joel Gales Original Programmer |
1314 | |
1315 | END_PROLOG |
1316 -----------------------------------------------------------------------------*/
1317 intn
GDdeftile(int32 gridID,int32 tilecode,int32 tilerank,int32 tiledims[])1318 GDdeftile(int32 gridID, int32 tilecode, int32 tilerank, int32 tiledims[])
1319 {
1320 intn i; /* Loop index */
1321 intn status = 0; /* routine return status variable */
1322
1323 int32 fid; /* HDF-EOS file id */
1324 int32 sdInterfaceID; /* HDF SDS interface ID */
1325 int32 gdVgrpID; /* Grid root Vgroup ID */
1326 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1327 int32 gID; /* gridID - offset */
1328
1329 /* Check for valid grid id */
1330 /* ----------------------- */
1331 status = GDchkgdid(gridID, "GDdeftile", &fid, &sdInterfaceID, &gdVgrpID);
1332
1333
1334 if (status == 0)
1335 {
1336 gID = gridID % idOffset;
1337
1338 for (i = 0; i < 8; i++)
1339 {
1340 GDXGrid[gID].tiledims[i] = 0;
1341 }
1342
1343 GDXGrid[gID].tilecode = tilecode;
1344
1345 switch (tilecode)
1346 {
1347 case HDFE_NOTILE:
1348
1349 GDXGrid[gID].tilerank = 0;
1350
1351 break;
1352
1353
1354 case HDFE_TILE:
1355
1356 GDXGrid[gID].tilerank = tilerank;
1357
1358 for (i = 0; i < tilerank; i++)
1359 {
1360 GDXGrid[gID].tiledims[i] = tiledims[i];
1361
1362 if (GDXGrid[gID].tiledims[i] == 0)
1363 {
1364 GDXGrid[gID].tiledims[i] = 1;
1365 }
1366 }
1367
1368 break;
1369
1370 }
1371 }
1372
1373 return (status);
1374 }
1375
1376
1377
1378
1379 /*----------------------------------------------------------------------------|
1380 | BEGIN_PROLOG |
1381 | |
1382 | FUNCTION: GDdeforigin |
1383 | |
1384 | DESCRIPTION: Defines the origin of the grid data. |
1385 | |
1386 | |
1387 | Return Value Type Units Description |
1388 | ============ ====== ========= ===================================== |
1389 | status intn return status (0) SUCCEED, (-1) FAIL |
1390 | |
1391 | INPUTS: |
1392 | gridID int32 grid structure ID |
1393 | origincode int32 origin code |
1394 | HDFE_GD_UL (0) |
1395 | HDFE_GD_UR (1) |
1396 | HDFE_GD_LL (2) |
1397 | HDFE_GD_LR (3) |
1398 | |
1399 | |
1400 | OUTPUTS: |
1401 | None |
1402 | |
1403 | NOTES: |
1404 | |
1405 | |
1406 | Date Programmer Description |
1407 | ====== ============ ================================================= |
1408 | Jun 96 Joel Gales Original Programmer |
1409 | |
1410 | END_PROLOG |
1411 -----------------------------------------------------------------------------*/
1412 intn
GDdeforigin(int32 gridID,int32 origincode)1413 GDdeforigin(int32 gridID, int32 origincode)
1414 {
1415 intn status = 0; /* routine return status variable */
1416
1417 int32 fid; /* HDF-EOS file ID */
1418 int32 gdVgrpID; /* Grid root Vgroup ID */
1419 int32 sdInterfaceID; /* HDF SDS interface ID */
1420 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1421
1422 char utlbuf[64]; /* Utility buffer */
1423 char gridname[80]; /* Grid name */
1424
1425
1426 /* Check for valid grid id */
1427 status = GDchkgdid(gridID, "GDdeforigin",
1428 &fid, &sdInterfaceID, &gdVgrpID);
1429
1430 if (status == 0)
1431 {
1432 /* If proper origin code then write to structural metadata */
1433 /* ------------------------------------------------------- */
1434 if (origincode >= 0 && origincode < sizeof(originNames))
1435 {
1436 sprintf(utlbuf, "%s%s%s",
1437 "\t\tGridOrigin=", originNames[origincode], "\n");
1438
1439 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
1440 status = EHinsertmeta(sdInterfaceID, gridname, "g", 101L,
1441 utlbuf, NULL);
1442 }
1443 else
1444 {
1445 status = -1;
1446 HEpush(DFE_GENAPP, "GDdeforigin", __FILE__, __LINE__);
1447 HEreport("Improper Grid Origin code: %d\n", origincode);
1448 }
1449 }
1450
1451 return (status);
1452 }
1453
1454 /*----------------------------------------------------------------------------|
1455 | BEGIN_PROLOG |
1456 | |
1457 | FUNCTION: GDdefpixreg |
1458 | |
1459 | DESCRIPTION: Defines pixel registration within grid cell. |
1460 | |
1461 | |
1462 | Return Value Type Units Description |
1463 | ============ ====== ========= ===================================== |
1464 | status intn return status (0) SUCCEED, (-1) FAIL |
1465 | |
1466 | INPUTS: |
1467 | gridID int32 grid structure ID |
1468 | pixregcode int32 Pixel registration code |
1469 | HDFE_CENTER (0) |
1470 | HDFE_CORNER (1) |
1471 | |
1472 | |
1473 | OUTPUTS: |
1474 | None |
1475 | |
1476 | NOTES: |
1477 | |
1478 | |
1479 | Date Programmer Description |
1480 | ====== ============ ================================================= |
1481 | Jun 96 Joel Gales Original Programmer |
1482 | |
1483 | END_PROLOG |
1484 -----------------------------------------------------------------------------*/
1485 intn
GDdefpixreg(int32 gridID,int32 pixregcode)1486 GDdefpixreg(int32 gridID, int32 pixregcode)
1487 {
1488 intn status = 0; /* routine return status variable */
1489
1490 int32 fid; /* HDF-EOS file ID */
1491 int32 gdVgrpID; /* Grid root Vgroup ID */
1492 int32 sdInterfaceID; /* HDF SDS interface ID */
1493 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1494
1495 char utlbuf[64]; /* Utility buffer */
1496 char gridname[80]; /* Grid name */
1497
1498 /* Check for valid grid id */
1499 status = GDchkgdid(gridID, "GDdefpixreg",
1500 &fid, &sdInterfaceID, &gdVgrpID);
1501
1502 if (status == 0)
1503 {
1504 /* If proper pix reg code then write to structural metadata */
1505 /* -------------------------------------------------------- */
1506 if (pixregcode >= 0 && pixregcode < sizeof(pixregNames))
1507 {
1508 sprintf(utlbuf, "%s%s%s",
1509 "\t\tPixelRegistration=", pixregNames[pixregcode], "\n");
1510
1511 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
1512 status = EHinsertmeta(sdInterfaceID, gridname, "g", 101L,
1513 utlbuf, NULL);
1514 }
1515 else
1516 {
1517 status = -1;
1518 HEpush(DFE_GENAPP, "GDdefpixreg", __FILE__, __LINE__);
1519 HEreport("Improper Pixel Registration code: %d\n", pixregcode);
1520 }
1521 }
1522
1523 return (status);
1524
1525 }
1526
1527
1528
1529
1530
1531 /*----------------------------------------------------------------------------|
1532 | BEGIN_PROLOG |
1533 | |
1534 | FUNCTION: GDdiminfo |
1535 | |
1536 | DESCRIPTION: Retrieve size of specified dimension. |
1537 | |
1538 | |
1539 | Return Value Type Units Description |
1540 | ============ ====== ========= ===================================== |
1541 | size int32 Size of dimension |
1542 | |
1543 | INPUTS: |
1544 | gridID int32 grid structure id |
1545 | dimname char Dimension name |
1546 | |
1547 | |
1548 | OUTPUTS: |
1549 | None |
1550 | |
1551 | NOTES: |
1552 | |
1553 | |
1554 | Date Programmer Description |
1555 | ====== ============ ================================================= |
1556 | Jun 96 Joel Gales Original Programmer |
1557 | Aug 96 Joel Gales Make metadata ODL compliant |
1558 | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
1559 | |
1560 | END_PROLOG |
1561 -----------------------------------------------------------------------------*/
1562 int32
GDdiminfo(int32 gridID,char * dimname)1563 GDdiminfo(int32 gridID, char *dimname)
1564
1565 {
1566 intn status; /* routine return status variable */
1567
1568 int32 fid; /* HDF-EOS file ID */
1569 int32 sdInterfaceID; /* HDF SDS interface ID */
1570 int32 gdVgrpID; /* Grid root Vgroup ID */
1571 int32 size; /* Dimension size */
1572 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1573
1574
1575 char *metabuf; /* Pointer to structural metadata (SM) */
1576 char *metaptrs[2];/* Pointers to begin and end of SM section */
1577 char gridname[80]; /* Grid Name */
1578 char *utlstr; /* Utility string */
1579
1580 /* Allocate space for utility string */
1581 /* --------------------------------- */
1582 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
1583 if(utlstr == NULL)
1584 {
1585 HEpush(DFE_NOSPACE,"GDdiminfo", __FILE__, __LINE__);
1586 return(-1);
1587 }
1588 /* Initialize return value */
1589 /* ----------------------- */
1590 size = -1;
1591
1592
1593 /* Check Grid ID */
1594 /* ------------- */
1595 status = GDchkgdid(gridID, "GDdiminfo", &fid, &sdInterfaceID, &gdVgrpID);
1596
1597
1598 if (status == 0)
1599 {
1600 /* Get grid name */
1601 /* ------------- */
1602 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
1603
1604
1605 /* Get pointers to "Dimension" section within SM */
1606 /* --------------------------------------------- */
1607 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
1608 "Dimension", metaptrs);
1609
1610 if(metabuf == NULL)
1611 {
1612 free(utlstr);
1613 return(-1);
1614 }
1615
1616 /* Search for dimension name (surrounded by quotes) */
1617 /* ------------------------------------------------ */
1618 sprintf(utlstr, "%s%s%s", "\"", dimname, "\"\n");
1619 metaptrs[0] = strstr(metaptrs[0], utlstr);
1620
1621 /*
1622 * If dimension found within grid structure then get dimension value
1623 */
1624 if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
1625 {
1626 /* Set endptr at end of dimension definition entry */
1627 /* ----------------------------------------------- */
1628 metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");
1629
1630 status = EHgetmetavalue(metaptrs, "Size", utlstr);
1631
1632 if (status == 0)
1633 {
1634 size = atol(utlstr);
1635 }
1636 else
1637 {
1638 HEpush(DFE_GENAPP, "GDdiminfo", __FILE__, __LINE__);
1639 HEreport("\"Size\" string not found in metadata.\n");
1640 }
1641 }
1642 else
1643 {
1644 HEpush(DFE_GENAPP, "GDdiminfo", __FILE__, __LINE__);
1645 HEreport("Dimension \"%s\" not found.\n", dimname);
1646 }
1647
1648 free(metabuf);
1649 }
1650 free(utlstr);
1651 return (size);
1652 }
1653
1654
1655
1656
1657
1658 /*----------------------------------------------------------------------------|
1659 | BEGIN_PROLOG |
1660 | |
1661 | FUNCTION: GDgridinfo |
1662 | |
1663 | DESCRIPTION: Returns xdim, ydim and location of upper left and lower |
1664 | right corners, in meters. |
1665 | |
1666 | |
1667 | Return Value Type Units Description |
1668 | ============ ====== ========= ===================================== |
1669 | status intn return status (0) SUCCEED, (-1) FAIL |
1670 | |
1671 | INPUTS: |
1672 | fid int32 File ID |
1673 | gridname char Grid structure name |
1674 | |
1675 | OUTPUTS: |
1676 | xdimsize int32 Number of columns in grid |
1677 | ydimsize int32 Number of rows in grid |
1678 | upleftpt float64 Location (m/deg) of upper left corner |
1679 | lowrightpt float64 Location (m/deg) of lower right corner |
1680 | |
1681 | NOTES: |
1682 | |
1683 | |
1684 | Date Programmer Description |
1685 | ====== ============ ================================================= |
1686 | Jun 96 Joel Gales Original Programmer |
1687 | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
1688 | |
1689 | END_PROLOG |
1690 -----------------------------------------------------------------------------*/
1691 intn
GDgridinfo(int32 gridID,int32 * xdimsize,int32 * ydimsize,float64 upleftpt[],float64 lowrightpt[])1692 GDgridinfo(int32 gridID, int32 * xdimsize, int32 * ydimsize,
1693 float64 upleftpt[], float64 lowrightpt[])
1694
1695 {
1696 intn status = 0; /* routine return status variable */
1697 intn statmeta = 0; /* EHgetmetavalue return status */
1698
1699 int32 fid; /* HDF-EOS file ID */
1700 int32 sdInterfaceID; /* HDF SDS interface ID */
1701 int32 gdVgrpID; /* Grid root Vgroup ID */
1702 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1703
1704
1705 char *metabuf; /* Pointer to structural metadata (SM) */
1706 char *metaptrs[2];/* Pointers to begin and end of SM section */
1707 char gridname[80]; /* Grid Name */
1708 char *utlstr; /* Utility string */
1709
1710 /* Allocate space for utility string */
1711 /* --------------------------------- */
1712 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
1713 if(utlstr == NULL)
1714 {
1715 HEpush(DFE_NOSPACE,"GDgridinfo", __FILE__, __LINE__);
1716 return(-1);
1717 }
1718 /* Check Grid ID */
1719 /* ------------- */
1720 status = GDchkgdid(gridID, "GDgridinfo", &fid, &sdInterfaceID, &gdVgrpID);
1721
1722 if (status == 0)
1723 {
1724 /* Get grid name */
1725 /* ------------- */
1726 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
1727
1728
1729 /* Get pointers to grid structure section within SM */
1730 /* ------------------------------------------------ */
1731 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
1732 NULL, metaptrs);
1733
1734 if(metabuf == NULL)
1735 {
1736 free(utlstr);
1737 return(-1);
1738 }
1739
1740
1741 /* Get xdimsize if requested */
1742 /* ------------------------- */
1743 if (xdimsize != NULL)
1744 {
1745 statmeta = EHgetmetavalue(metaptrs, "XDim", utlstr);
1746 if (statmeta == 0)
1747 {
1748 *xdimsize = atol(utlstr);
1749 }
1750 else
1751 {
1752 status = -1;
1753 HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
1754 HEreport("\"XDim\" string not found in metadata.\n");
1755 }
1756 }
1757
1758
1759 /* Get ydimsize if requested */
1760 /* ------------------------- */
1761 if (ydimsize != NULL)
1762 {
1763 statmeta = EHgetmetavalue(metaptrs, "YDim", utlstr);
1764 if (statmeta == 0)
1765 {
1766 *ydimsize = atol(utlstr);
1767 }
1768 else
1769 {
1770 status = -1;
1771 HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
1772 HEreport("\"YDim\" string not found in metadata.\n");
1773 }
1774 }
1775
1776
1777 /* Get upleftpt if requested */
1778 /* ------------------------- */
1779 if (upleftpt != NULL)
1780 {
1781 statmeta = EHgetmetavalue(metaptrs, "UpperLeftPointMtrs", utlstr);
1782 if (statmeta == 0)
1783 {
1784 /* If value is "DEFAULT" then return zeros */
1785 /* --------------------------------------- */
1786 if (strcmp(utlstr, "DEFAULT") == 0)
1787 {
1788 upleftpt[0] = 0;
1789 upleftpt[1] = 0;
1790 }
1791 else
1792 {
1793 sscanf(utlstr, "(%lf,%lf)",
1794 &upleftpt[0], &upleftpt[1]);
1795 }
1796 }
1797 else
1798 {
1799 status = -1;
1800 HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
1801 HEreport(
1802 "\"UpperLeftPointMtrs\" string not found in metadata.\n");
1803 }
1804
1805 }
1806
1807 /* Get lowrightpt if requested */
1808 /* --------------------------- */
1809 if (lowrightpt != NULL)
1810 {
1811 statmeta = EHgetmetavalue(metaptrs, "LowerRightMtrs", utlstr);
1812 if (statmeta == 0)
1813 {
1814 /* If value is "DEFAULT" then return zeros */
1815 if (strcmp(utlstr, "DEFAULT") == 0)
1816 {
1817 lowrightpt[0] = 0;
1818 lowrightpt[1] = 0;
1819 }
1820 else
1821 {
1822 sscanf(utlstr, "(%lf,%lf)",
1823 &lowrightpt[0], &lowrightpt[1]);
1824 }
1825 }
1826 else
1827 {
1828 status = -1;
1829 HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
1830 HEreport(
1831 "\"LowerRightMtrs\" string not found in metadata.\n");
1832 }
1833 }
1834
1835 free(metabuf);
1836 }
1837 free(utlstr);
1838 return (status);
1839 }
1840
1841
1842
1843
1844
1845
1846
1847 /*----------------------------------------------------------------------------|
1848 | BEGIN_PROLOG |
1849 | |
1850 | FUNCTION: GDprojinfo |
1851 | |
1852 | DESCRIPTION: Returns GCTP projection code, zone code, spheroid code |
1853 | and projection parameters. |
1854 | |
1855 | |
1856 | Return Value Type Units Description |
1857 | ============ ====== ========= ===================================== |
1858 | status intn return status (0) SUCCEED, (-1) FAIL |
1859 | |
1860 | INPUTS: |
1861 | gridID int32 Grid structure ID |
1862 | |
1863 | OUTPUTS: |
1864 | projcode int32 GCTP projection code |
1865 | zonecode int32 UTM zone code |
1866 | spherecode int32 GCTP spheriod code |
1867 | projparm float64 Projection parameters |
1868 | |
1869 | NOTES: |
1870 | |
1871 | |
1872 | Date Programmer Description |
1873 | ====== ============ ================================================= |
1874 | Jun 96 Joel Gales Original Programmer |
1875 | Oct 96 Joel Gales Add check for no projection code |
1876 | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
1877 | Jun 00 Abe Taaheri Added support for EASE grid |
1878 | |
1879 | END_PROLOG |
1880 -----------------------------------------------------------------------------*/
1881 intn
GDprojinfo(int32 gridID,int32 * projcode,int32 * zonecode,int32 * spherecode,float64 projparm[])1882 GDprojinfo(int32 gridID, int32 * projcode, int32 * zonecode,
1883 int32 * spherecode, float64 projparm[])
1884
1885 {
1886 intn i; /* Loop index */
1887 intn projx; /* Loop index */
1888 intn status = 0; /* routine return status variable */
1889 intn statmeta = 0; /* EHgetmetavalue return status */
1890
1891 int32 fid; /* HDF-EOS file ID */
1892 int32 sdInterfaceID; /* HDF SDS interface ID */
1893 int32 gdVgrpID; /* Grid root Vgroup ID */
1894 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1895
1896
1897 char *metabuf; /* Pointer to structural metadata (SM) */
1898 char *metaptrs[2];/* Pointers to begin and end of SM section */
1899 char gridname[80]; /* Grid Name */
1900 char *utlstr; /* Utility string */
1901 char fmt[96]; /* Format String */
1902
1903 /* Allocate space for utility string */
1904 /* --------------------------------- */
1905 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
1906 if(utlstr == NULL)
1907 {
1908 HEpush(DFE_NOSPACE,"GDprojinfo", __FILE__, __LINE__);
1909 return(-1);
1910 }
1911
1912 /* Check Grid ID */
1913 /* ------------- */
1914 status = GDchkgdid(gridID, "GDprojinfo", &fid, &sdInterfaceID, &gdVgrpID);
1915
1916 if (status == 0)
1917 {
1918 /* Get grid name */
1919 /* ------------- */
1920 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
1921
1922
1923 /* Get pointers to grid structure section within SM */
1924 /* ------------------------------------------------ */
1925 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
1926 NULL, metaptrs);
1927
1928 if(metabuf == NULL)
1929 {
1930 free(utlstr);
1931 return(-1);
1932 }
1933
1934
1935 /* Get projcode if requested */
1936 /* ------------------------- */
1937 if (projcode != NULL)
1938 {
1939 *projcode = -1;
1940
1941 statmeta = EHgetmetavalue(metaptrs, "Projection", utlstr);
1942 if (statmeta == 0)
1943 {
1944 /* Loop through projection codes until found */
1945 /* ----------------------------------------- */
1946 for (projx = 0; Projections[projx].projcode != -1; projx++)
1947 if (strcmp(utlstr, Projections[projx].projname) == 0)
1948 break;
1949 if (Projections[projx].projname != NULL)
1950 *projcode = Projections[projx].projcode;
1951 }
1952 else
1953 {
1954 status = -1;
1955 HEpush(DFE_GENAPP, "GDprojinfo", __FILE__, __LINE__);
1956 HEreport("Projection Code not defined for \"%s\".\n",
1957 gridname);
1958
1959 if (projparm != NULL)
1960 {
1961 for (i = 0; i < 13; i++)
1962 {
1963 projparm[i] = -1;
1964 }
1965 }
1966 }
1967 }
1968
1969
1970 /* Get zonecode if requested */
1971 /* ------------------------- */
1972 if (zonecode != NULL)
1973 {
1974 *zonecode = -1;
1975
1976
1977 /* Zone code only relevant for UTM and State Code projections */
1978 /* ---------------------------------------------------------- */
1979 if (*projcode == GCTP_UTM || *projcode == GCTP_SPCS)
1980 {
1981 statmeta = EHgetmetavalue(metaptrs, "ZoneCode", utlstr);
1982 if (statmeta == 0)
1983 {
1984 *zonecode = atol(utlstr);
1985 }
1986 else
1987 {
1988 status = -1;
1989 HEpush(DFE_GENAPP, "GDprojinfo", __FILE__, __LINE__);
1990 HEreport("Zone Code not defined for \"%s\".\n",
1991 gridname);
1992 }
1993 }
1994 }
1995
1996
1997 /* Get projection parameters if requested */
1998 /* -------------------------------------- */
1999 if (projparm != NULL)
2000 {
2001
2002 /*
2003 * Note: No projection parameters for GEO, UTM, and State Code
2004 * projections
2005 */
2006 if (*projcode == GCTP_GEO || *projcode == GCTP_UTM ||
2007 *projcode == GCTP_SPCS)
2008 {
2009 for (i = 0; i < 13; i++)
2010 {
2011 projparm[i] = 0.0;
2012 }
2013
2014 }
2015 else
2016 {
2017 statmeta = EHgetmetavalue(metaptrs, "ProjParams", utlstr);
2018
2019 if (statmeta == 0)
2020 {
2021
2022 /* Build format string to read projection parameters */
2023 /* ------------------------------------------------- */
2024 strcpy(fmt, "%lf,");
2025 for (i = 1; i <= 11; i++)
2026 strcat(fmt, "%lf,");
2027 strcat(fmt, "%lf");
2028
2029
2030 /* Read parameters from numeric list */
2031 /* --------------------------------- */
2032 sscanf(&utlstr[1], fmt,
2033 &projparm[0], &projparm[1],
2034 &projparm[2], &projparm[3],
2035 &projparm[4], &projparm[5],
2036 &projparm[6], &projparm[7],
2037 &projparm[8], &projparm[9],
2038 &projparm[10], &projparm[11],
2039 &projparm[12]);
2040 }
2041 else
2042 {
2043 status = -1;
2044 HEpush(DFE_GENAPP, "GDprojinfo", __FILE__, __LINE__);
2045 HEreport("Projection parameters not defined for \"%s\".\n",
2046 gridname);
2047
2048 }
2049 }
2050 }
2051
2052
2053 /* Get spherecode if requested */
2054 /* --------------------------- */
2055 if (spherecode != NULL)
2056 {
2057 *spherecode = 0;
2058
2059 /* Note: Spherecode not defined for GEO projection */
2060 /* ----------------------------------------------- */
2061 if ((*projcode != GCTP_GEO))
2062 {
2063 EHgetmetavalue(metaptrs, "SphereCode", utlstr);
2064 if (statmeta == 0)
2065 {
2066 *spherecode = atol(utlstr);
2067 }
2068 }
2069 }
2070 free(metabuf);
2071
2072 }
2073 free(utlstr);
2074 return (status);
2075 }
2076
2077
2078
2079 /*----------------------------------------------------------------------------|
2080 | BEGIN_PROLOG |
2081 | |
2082 | FUNCTION: GDorigininfo |
2083 | |
2084 | DESCRIPTION: Returns origin code |
2085 | |
2086 | |
2087 | Return Value Type Units Description |
2088 | ============ ====== ========= ===================================== |
2089 | status intn return status (0) SUCCEED, (-1) FAIL |
2090 | |
2091 | INPUTS: |
2092 | gridID int32 Grid structure ID |
2093 | |
2094 | |
2095 | OUTPUTS: |
2096 | origincode int32 grid origin code |
2097 | |
2098 | NOTES: |
2099 | |
2100 | |
2101 | Date Programmer Description |
2102 | ====== ============ ================================================= |
2103 | Jun 96 Joel Gales Original Programmer |
2104 | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
2105 | |
2106 | END_PROLOG |
2107 -----------------------------------------------------------------------------*/
2108 intn
GDorigininfo(int32 gridID,int32 * origincode)2109 GDorigininfo(int32 gridID, int32 * origincode)
2110 {
2111 intn i; /* Loop index */
2112 intn status = 0; /* routine return status variable */
2113 intn statmeta = 0; /* EHgetmetavalue return status */
2114
2115 int32 fid; /* HDF-EOS file ID */
2116 int32 sdInterfaceID; /* HDF SDS interface ID */
2117 int32 gdVgrpID; /* Grid root Vgroup ID */
2118 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2119
2120
2121 char *metabuf; /* Pointer to structural metadata (SM) */
2122 char *metaptrs[2];/* Pointers to begin and end of SM section */
2123 char gridname[80]; /* Grid Name */
2124 char *utlstr; /* Utility string */
2125
2126 /* Allocate space for utility string */
2127 /* --------------------------------- */
2128 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
2129 if(utlstr == NULL)
2130 {
2131 HEpush(DFE_NOSPACE,"GDorigininfo", __FILE__, __LINE__);
2132 return(-1);
2133 }
2134 /* Check Grid ID */
2135 /* ------------- */
2136 status = GDchkgdid(gridID, "GDorigininfo",
2137 &fid, &sdInterfaceID, &gdVgrpID);
2138
2139
2140 /* Initialize pixreg code to -1 (in case of error) */
2141 /* ----------------------------------------------- */
2142 *origincode = -1;
2143
2144 if (status == 0)
2145 {
2146 /* Set default origin code */
2147 /* ----------------------- */
2148 *origincode = 0;
2149
2150
2151 /* Get grid name */
2152 /* ------------- */
2153 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
2154
2155
2156 /* Get pointers to grid structure section within SM */
2157 /* ------------------------------------------------ */
2158 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
2159 NULL, metaptrs);
2160
2161 if(metabuf == NULL)
2162 {
2163 free(utlstr);
2164 return(-1);
2165 }
2166
2167
2168 statmeta = EHgetmetavalue(metaptrs, "GridOrigin", utlstr);
2169
2170 if (statmeta == 0)
2171 {
2172 /*
2173 * If "GridOrigin" string found in metadata then convert to
2174 * numeric origin code (fixed added: Jan 97)
2175 */
2176 for (i = 0; i < sizeof(originNames); i++)
2177 {
2178 if (strcmp(utlstr, originNames[i]) == 0)
2179 {
2180 *origincode = i;
2181 break;
2182 }
2183 }
2184 }
2185
2186 free(metabuf);
2187 }
2188 free(utlstr);
2189 return (status);
2190 }
2191
2192
2193
2194
2195
2196
2197 /*----------------------------------------------------------------------------|
2198 | BEGIN_PROLOG |
2199 | |
2200 | FUNCTION: GDpixreginfo |
2201 | |
2202 | DESCRIPTION: |
2203 | |
2204 | |
2205 | Return Value Type Units Description |
2206 | ============ ====== ========= ===================================== |
2207 | status intn return status (0) SUCCEED, (-1) FAIL |
2208 | |
2209 | INPUTS: |
2210 | gridID int32 Grid structure ID |
2211 | |
2212 | |
2213 | OUTPUTS: |
2214 | pixregcode int32 Pixel registration code |
2215 | |
2216 | |
2217 | OUTPUTS: |
2218 | None |
2219 | |
2220 | NOTES: |
2221 | |
2222 | |
2223 | Date Programmer Description |
2224 | ====== ============ ================================================= |
2225 | Jun 96 Joel Gales Original Programmer |
2226 | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
2227 | |
2228 | END_PROLOG |
2229 -----------------------------------------------------------------------------*/
2230 intn
GDpixreginfo(int32 gridID,int32 * pixregcode)2231 GDpixreginfo(int32 gridID, int32 * pixregcode)
2232 {
2233 intn i; /* Loop index */
2234 intn status = 0; /* routine return status variable */
2235 intn statmeta = 0; /* EHgetmetavalue return status */
2236
2237 int32 fid; /* HDF-EOS file ID */
2238 int32 sdInterfaceID; /* HDF SDS interface ID */
2239 int32 gdVgrpID; /* Grid root Vgroup ID */
2240 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2241
2242
2243 char *metabuf; /* Pointer to structural metadata (SM) */
2244 char *metaptrs[2];/* Pointers to begin and end of SM section */
2245 char gridname[80]; /* Grid Name */
2246 char *utlstr; /* Utility string */
2247
2248 /* Allocate space for utility string */
2249 /* --------------------------------- */
2250 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
2251 if(utlstr == NULL)
2252 {
2253 HEpush(DFE_NOSPACE,"GDpixreginfo", __FILE__, __LINE__);
2254 return(-1);
2255 }
2256 /* Check Grid ID */
2257 status = GDchkgdid(gridID, "GDpixreginfo",
2258 &fid, &sdInterfaceID, &gdVgrpID);
2259
2260 /* Initialize pixreg code to -1 (in case of error) */
2261 *pixregcode = -1;
2262
2263 if (status == 0)
2264 {
2265 /* Set default pixreg code */
2266 *pixregcode = 0;
2267
2268 /* Get grid name */
2269 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
2270
2271 /* Get pointers to grid structure section within SM */
2272 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
2273 NULL, metaptrs);
2274
2275 if(metabuf == NULL)
2276 {
2277 free(utlstr);
2278 return(-1);
2279 }
2280
2281
2282 statmeta = EHgetmetavalue(metaptrs, "PixelRegistration", utlstr);
2283
2284 if (statmeta == 0)
2285 {
2286 /*
2287 * If "PixelRegistration" string found in metadata then convert
2288 * to numeric origin code (fixed added: Jan 97)
2289 */
2290
2291 for (i = 0; i < sizeof(pixregNames); i++)
2292 {
2293 if (strcmp(utlstr, pixregNames[i]) == 0)
2294 {
2295 *pixregcode = i;
2296 break;
2297 }
2298 }
2299 }
2300 free(metabuf);
2301 }
2302 free(utlstr);
2303 return (status);
2304 }
2305
2306
2307
2308 /*----------------------------------------------------------------------------|
2309 | BEGIN_PROLOG |
2310 | |
2311 | FUNCTION: GDcompinfo |
2312 | |
2313 | DESCRIPTION: |
2314 | |
2315 | |
2316 | Return Value Type Units Description |
2317 | ============ ====== ========= ===================================== |
2318 | status intn |
2319 | |
2320 | INPUTS: |
2321 | gridID int32 |
2322 | compcode int32 |
2323 | compparm intn |
2324 | |
2325 | |
2326 | OUTPUTS: |
2327 | None |
2328 | |
2329 | NOTES: |
2330 | |
2331 | |
2332 | Date Programmer Description |
2333 | ====== ============ ================================================= |
2334 | Oct 96 Joel Gales Original Programmer |
2335 | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
2336 | |
2337 | END_PROLOG |
2338 -----------------------------------------------------------------------------*/
2339 intn
GDcompinfo(int32 gridID,char * fieldname,int32 * compcode,intn compparm[])2340 GDcompinfo(int32 gridID, char *fieldname, int32 * compcode, intn compparm[])
2341 {
2342 intn i; /* Loop index */
2343 intn status = 0; /* routine return status variable */
2344 intn statmeta = 0; /* EHgetmetavalue return status */
2345
2346 int32 fid; /* HDF-EOS file ID */
2347 int32 sdInterfaceID; /* HDF SDS interface ID */
2348 int32 gdVgrpID; /* Grid root Vgroup ID */
2349 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2350
2351
2352 char *metabuf; /* Pointer to structural metadata (SM) */
2353 char *metaptrs[2];/* Pointers to begin and end of SM section */
2354 char gridname[80]; /* Grid Name */
2355 char *utlstr;/* Utility string */
2356
2357 /* Allocate space for utility string */
2358 /* --------------------------------- */
2359 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
2360 if(utlstr == NULL)
2361 {
2362 HEpush(DFE_NOSPACE,"GDcompinfo", __FILE__, __LINE__);
2363 return(-1);
2364 }
2365 /* Check Grid ID */
2366 status = GDchkgdid(gridID, "GDcompinfo", &fid, &sdInterfaceID, &gdVgrpID);
2367
2368
2369 if (status == 0)
2370 {
2371 /* Get grid name */
2372 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
2373
2374 /* Get pointers to "DataField" section within SM */
2375 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
2376 "DataField", metaptrs);
2377 if(metabuf == NULL)
2378 {
2379 free(utlstr);
2380 return(-1);
2381 }
2382
2383
2384 /* Search for field */
2385 sprintf(utlstr, "%s%s%s", "\"", fieldname, "\"\n");
2386 metaptrs[0] = strstr(metaptrs[0], utlstr);
2387
2388
2389 /* If field found and user wants compression code ... */
2390 if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
2391 {
2392 if (compcode != NULL)
2393 {
2394 /* Set endptr at end of field's definition entry */
2395 metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");
2396
2397 /* Get compression type */
2398 statmeta = EHgetmetavalue(metaptrs, "CompressionType", utlstr);
2399
2400 /*
2401 * Default is no compression if "CompressionType" string not
2402 * in metadata
2403 */
2404 *compcode = HDFE_COMP_NONE;
2405
2406 /* If compression code is found ... */
2407 if (statmeta == 0)
2408 {
2409 /* Loop through compression types until match */
2410 for (i = 0; i < sizeof(HDFcomp); i++)
2411 {
2412 if (strcmp(utlstr, HDFcomp[i]) == 0)
2413 {
2414 *compcode = i;
2415 break;
2416 }
2417 }
2418 }
2419 }
2420
2421 /* If user wants compression parameters ... */
2422 if (compparm != NULL && compcode != NULL)
2423 {
2424 /* Initialize to zero */
2425 for (i = 0; i < 4; i++)
2426 {
2427 compparm[i] = 0.0;
2428 }
2429
2430 /*
2431 * Get compression parameters if NBIT or DEFLATE compression
2432 */
2433 if (*compcode == HDFE_COMP_NBIT)
2434 {
2435 statmeta =
2436 EHgetmetavalue(metaptrs, "CompressionParams", utlstr);
2437 if (statmeta == 0)
2438 {
2439 sscanf(utlstr, "(%d,%d,%d,%d)",
2440 &compparm[0], &compparm[1],
2441 &compparm[2], &compparm[3]);
2442 }
2443 else
2444 {
2445 status = -1;
2446 HEpush(DFE_GENAPP, "GDcompinfo", __FILE__, __LINE__);
2447 HEreport(
2448 "\"CompressionParams\" string not found in metadata.\n");
2449 }
2450 }
2451 else if (*compcode == HDFE_COMP_DEFLATE)
2452 {
2453 statmeta =
2454 EHgetmetavalue(metaptrs, "DeflateLevel", utlstr);
2455 if (statmeta == 0)
2456 {
2457 sscanf(utlstr, "%d", &compparm[0]);
2458 }
2459 else
2460 {
2461 status = -1;
2462 HEpush(DFE_GENAPP, "GDcompinfo", __FILE__, __LINE__);
2463 HEreport(
2464 "\"DeflateLevel\" string not found in metadata.\n");
2465 }
2466 }
2467 }
2468 }
2469 else
2470 {
2471 HEpush(DFE_GENAPP, "GDcompinfo", __FILE__, __LINE__);
2472 HEreport("Fieldname \"%s\" not found.\n", fieldname);
2473 }
2474
2475 free(metabuf);
2476
2477 }
2478 free(utlstr);
2479 return (status);
2480 }
2481
2482
2483
2484
2485
2486
2487 /*----------------------------------------------------------------------------|
2488 | BEGIN_PROLOG |
2489 | |
2490 | FUNCTION: GDfieldinfo |
2491 | |
2492 | DESCRIPTION: Retrieve information about a specific geolocation or data |
2493 | field in the grid. |
2494 | |
2495 | |
2496 | Return Value Type Units Description |
2497 | ============ ====== ========= ===================================== |
2498 | status intn return status (0) SUCCEED, (-1) FAIL |
2499 | |
2500 | INPUTS: |
2501 | gridID int32 grid structure id |
2502 | fieldname char name of field |
2503 | |
2504 | |
2505 | OUTPUTS: |
2506 | rank int32 rank of field (# of dims) |
2507 | dims int32 field dimensions |
2508 | numbertype int32 field number type |
2509 | dimlist char field dimension list |
2510 | |
2511 | |
2512 | OUTPUTS: |
2513 | None |
2514 | |
2515 | NOTES: |
2516 | |
2517 | |
2518 | Date Programmer Description |
2519 | ====== ============ ================================================= |
2520 | Jun 96 Joel Gales Original Programmer |
2521 | Aug 96 Joel Gales Make metadata ODL compliant |
2522 | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
2523 | Feb 99 Abe Taaheri Changed memcpy to memmove to avoid overlapping |
2524 | problem when copying strings |
2525 | |
2526 | END_PROLOG |
2527 -----------------------------------------------------------------------------*/
2528 intn
GDfieldinfo(int32 gridID,char * fieldname,int32 * rank,int32 dims[],int32 * numbertype,char * dimlist)2529 GDfieldinfo(int32 gridID, char *fieldname, int32 * rank, int32 dims[],
2530 int32 * numbertype, char *dimlist)
2531
2532 {
2533 intn i; /* Loop index */
2534 intn status; /* routine return status variable */
2535 intn statmeta = 0; /* EHgetmetavalue return status */
2536
2537 int32 fid; /* HDF-EOS file ID */
2538 int32 sdInterfaceID; /* HDF SDS interface ID */
2539 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2540 int32 ndims; /* Number of dimensions */
2541 int32 slen[8]; /* Length of each entry in parsed string */
2542 int32 dum; /* Dummy variable */
2543 int32 xdim; /* X dim size */
2544 int32 ydim; /* Y dim size */
2545 int32 sdid; /* SDS id */
2546
2547 char *metabuf; /* Pointer to structural metadata (SM) */
2548 char *metaptrs[2]; /* Pointers to begin and end of SM section */
2549 char gridname[80]; /* Grid Name */
2550 char *utlstr; /* Utility string */
2551 char *ptr[8]; /* String pointers for parsed string */
2552 char dimstr[64]; /* Individual dimension entry string */
2553
2554
2555 /* Allocate space for utility string */
2556 /* --------------------------------- */
2557 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
2558 if(utlstr == NULL)
2559 {
2560 HEpush(DFE_NOSPACE,"GDfieldinfo", __FILE__, __LINE__);
2561 return(-1);
2562 }
2563 *rank = -1;
2564 *numbertype = -1;
2565
2566 status = GDchkgdid(gridID, "GDfieldinfo", &fid, &sdInterfaceID, &dum);
2567
2568 if (status == 0)
2569 {
2570
2571 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
2572
2573 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
2574 "DataField", metaptrs);
2575 if(metabuf == NULL)
2576 {
2577 free(utlstr);
2578 return(-1);
2579 }
2580
2581
2582 /* Search for field */
2583 sprintf(utlstr, "%s%s%s", "\"", fieldname, "\"\n");
2584 metaptrs[0] = strstr(metaptrs[0], utlstr);
2585
2586 /* If field found ... */
2587 if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
2588 {
2589
2590 /* Set endptr at end of dimension definition entry */
2591 metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");
2592
2593 /* Get DataType string */
2594 statmeta = EHgetmetavalue(metaptrs, "DataType", utlstr);
2595
2596 /* Convert to numbertype code */
2597 if (statmeta == 0)
2598 *numbertype = EHnumstr(utlstr);
2599 else
2600 {
2601 status = -1;
2602 HEpush(DFE_GENAPP, "GDfieldinfo", __FILE__, __LINE__);
2603 HEreport("\"DataType\" string not found in metadata.\n");
2604 }
2605
2606 /*
2607 * Get DimList string and trim off leading and trailing parens
2608 * "()"
2609 */
2610 statmeta = EHgetmetavalue(metaptrs, "DimList", utlstr);
2611
2612 if (statmeta == 0)
2613 {
2614 memmove(utlstr, utlstr + 1, strlen(utlstr) - 2);
2615 utlstr[strlen(utlstr) - 2] = 0;
2616
2617 /* Parse trimmed DimList string and get rank */
2618 ndims = EHparsestr(utlstr, ',', ptr, slen);
2619 *rank = ndims;
2620 }
2621 else
2622 {
2623 status = -1;
2624 HEpush(DFE_GENAPP, "GDfieldinfo", __FILE__, __LINE__);
2625 HEreport("\"DimList\" string not found in metadata.\n");
2626 }
2627
2628
2629 if (status == 0)
2630 {
2631 status = GDgridinfo(gridID, &xdim, &ydim, NULL, NULL);
2632
2633 for (i = 0; i < ndims; i++)
2634 {
2635 memcpy(dimstr, ptr[i] + 1, slen[i] - 2);
2636 dimstr[slen[i] - 2] = 0;
2637
2638 if (strcmp(dimstr, "XDim") == 0)
2639 {
2640 dims[i] = xdim;
2641 }
2642 else if (strcmp(dimstr, "YDim") == 0)
2643 {
2644 dims[i] = ydim;
2645 }
2646 else
2647 {
2648 dims[i] = GDdiminfo(gridID, dimstr);
2649 }
2650
2651
2652 if (dimlist != NULL)
2653 {
2654 if (i == 0)
2655 {
2656 dimlist[0] = 0;
2657 }
2658
2659 if (i > 0)
2660 {
2661 strcat(dimlist, ",");
2662 }
2663 strcat(dimlist, dimstr);
2664 }
2665 }
2666
2667
2668 if (dims[0] == 0)
2669 {
2670 status = GDSDfldsrch(gridID, sdInterfaceID, fieldname,
2671 &sdid, &dum, &dum, &dum, dims,
2672 &dum);
2673 }
2674 }
2675 }
2676
2677 free(metabuf);
2678 }
2679
2680 if (*rank == -1)
2681 {
2682 status = -1;
2683
2684 HEpush(DFE_GENAPP, "GDfieldinfo", __FILE__, __LINE__);
2685 HEreport("Fieldname \"%s\" not found.\n", fieldname);
2686 }
2687 free(utlstr);
2688 return (status);
2689 }
2690
2691
2692
2693
2694
2695
2696 /*----------------------------------------------------------------------------|
2697 | BEGIN_PROLOG |
2698 | |
2699 | FUNCTION: GDdeffield |
2700 | |
2701 | DESCRIPTION: Defines a new data field within the grid. |
2702 | |
2703 | |
2704 | Return Value Type Units Description |
2705 | ============ ====== ========= ===================================== |
2706 | status intn return status (0) SUCCEED, (-1) FAIL |
2707 | |
2708 | INPUTS: |
2709 | gridID int32 grid structure ID |
2710 | fieldname char fieldname |
2711 | dimlist char Dimension list (comma-separated list) |
2712 | numbertype int32 field type |
2713 | merge int32 merge code |
2714 | |
2715 | |
2716 | OUTPUTS: |
2717 | None |
2718 | |
2719 | NOTES: |
2720 | |
2721 | |
2722 | Date Programmer Description |
2723 | ====== ============ ================================================= |
2724 | Jun 96 Joel Gales Original Programmer |
2725 | Aug 96 Joel Gales Check name for ODL compliance |
2726 | Sep 96 Joel Gales Make string array "dimbuf" dynamic |
2727 | Sep 96 Joel Gales Add support for Block SOM (MISR) |
2728 | Jan 97 Joel Gales Add support for tiling |
2729 | Feb 99 Abe Taaheri Changed strcpy to memmove to avoid overlapping |
2730 | problem when copying strings |
2731 | |
2732 | END_PROLOG |
2733 -----------------------------------------------------------------------------*/
2734 intn
GDdeffield(int32 gridID,char * fieldname,char * dimlist,int32 numbertype,int32 merge)2735 GDdeffield(int32 gridID, char *fieldname, char *dimlist,
2736 int32 numbertype, int32 merge)
2737
2738 {
2739 intn i; /* Loop index */
2740 intn status; /* routine return status variable */
2741 intn found; /* utility found flag */
2742 intn foundNT = 0;/* found number type flag */
2743 intn foundAllDim = 1; /* found all dimensions flag */
2744 intn first = 1; /* first entry flag */
2745
2746 int32 fid; /* HDF-EOS file ID */
2747 int32 vgid; /* Geo/Data field Vgroup ID */
2748 int32 sdInterfaceID; /* HDF SDS interface ID */
2749 int32 sdid; /* SDS object ID */
2750 int32 dimid; /* SDS dimension ID */
2751 int32 gdVgrpID; /* Grid root Vgroup ID */
2752 int32 dims[8]; /* Dimension size array */
2753 int32 dimsize; /* Dimension size */
2754 int32 rank = 0; /* Field rank */
2755 int32 slen[32]; /* String length array */
2756 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2757 int32 compcode; /* Compression code */
2758 int32 tilecode; /* Tiling code */
2759 int32 chunkFlag; /* Chunking (Tiling) flag */
2760 int32 gID; /* GridID - offset */
2761 int32 xdim; /* Grid X dimension */
2762 int32 ydim; /* Grid Y dimension */
2763 int32 projcode; /* Projection Code */
2764
2765 float64 projparm[13]; /* Projection Parameters */
2766
2767 char *dimbuf; /* Dimension buffer */
2768 char *dimlist0; /* Auxilliary dimension list */
2769 char *comma; /* Pointer to comma */
2770 char *dimcheck; /* Dimension check buffer */
2771 char utlbuf[512];/* Utility buffer */
2772 char utlbuf2[256]; /* Utility buffer 1 */
2773 char *ptr[32]; /* String pointer array */
2774 char gridname[80]; /* Grid name */
2775 char parmbuf[128]; /* Parameter string buffer */
2776 char errbuf1[128]; /* Error buffer 1 */
2777 char errbuf2[128]; /* Error buffer 2 */
2778 static const char errmsg1[] = "Dimension: %d (size: %d) not divisible by ";
2779 /* Tiling error message part 1 */
2780 static const char errmsg2[] = "tile dimension (size: %d).\n";
2781 /* Tiling error message part 2 */
2782 char errmsg[128];/* Tiling error message */
2783
2784 /* Valid number types */
2785 static const uint16 good_number[10] = {
2786 3, 4, 5, 6, 20, 21, 22, 23, 24, 25
2787 };
2788
2789 comp_info c_info; /* Compression parameter structure */
2790
2791 HDF_CHUNK_DEF chunkDef; /* Tiling structure */
2792
2793
2794
2795 /* Setup error message strings */
2796 /* --------------------------- */
2797 strcpy(errbuf1, "GDXSDname array too small.\nPlease increase ");
2798 strcat(errbuf1, "size of HDFE_NAMBUFSIZE in \"HdfEosDef.h\".\n");
2799 strcpy(errbuf2, "GDXSDdims array too small.\nPlease increase ");
2800 strcat(errbuf2, "size of HDFE_DIMBUFSIZE in \"HdfEosDef.h\".\n");
2801
2802
2803 /* Build tiling dimension error message */
2804 /* ------------------------------------ */
2805 strcpy(errmsg, errmsg1);
2806 strcat(errmsg, errmsg2);
2807
2808 /*
2809 * Check for proper grid ID and return HDF-EOS file ID, SDinterface ID,
2810 * and grid root Vgroup ID
2811 */
2812 status = GDchkgdid(gridID, "GDdefinefield",
2813 &fid, &sdInterfaceID, &gdVgrpID);
2814
2815
2816 if (status == 0)
2817 {
2818 /* Remove offset from grid ID & get gridname */
2819 gID = gridID % idOffset;
2820 Vgetname(GDXGrid[gID].IDTable, gridname);
2821
2822
2823 /* Allocate space for dimension buffer and auxilliary dimension list */
2824 /* ----------------------------------------------------------------- */
2825 dimbuf = (char *) calloc(strlen(dimlist) + 64, 1);
2826 if(dimbuf == NULL)
2827 {
2828 HEpush(DFE_NOSPACE,"GDdeffield", __FILE__, __LINE__);
2829 return(-1);
2830 }
2831 dimlist0 = (char *) calloc(strlen(dimlist) + 64, 1);
2832 if(dimlist0 == NULL)
2833 {
2834 HEpush(DFE_NOSPACE,"GDdeffield", __FILE__, __LINE__);
2835 free(dimbuf);
2836 return(-1);
2837 }
2838
2839
2840 /* Get Grid and Projection info */
2841 /* ---------------------------- */
2842 status = GDgridinfo(gridID, &xdim, &ydim, NULL, NULL);
2843 status = GDprojinfo(gridID, &projcode, NULL, NULL, projparm);
2844
2845
2846 /* Setup Block Dimension if "Blocked" SOM projection */
2847 /* ------------------------------------------------- */
2848 if (projcode == GCTP_SOM && (int32) projparm[11] != 0)
2849 {
2850 dimsize = GDdiminfo(gridID, "SOMBlockDim");
2851
2852 /* If "SOMBlockDim" not yet defined then do it */
2853 if (dimsize == -1)
2854 {
2855 GDdefdim(gridID, "SOMBlockDim", (int32) projparm[11]);
2856 }
2857
2858 /* If not 1D field then prepend to dimension list */
2859 if (strchr(dimlist, ',') != NULL)
2860 {
2861 strcpy(dimbuf, "SOMBlockDim,");
2862 strcat(dimbuf, dimlist);
2863 }
2864 else
2865 {
2866 strcpy(dimbuf, dimlist);
2867 }
2868 }
2869 else
2870 {
2871 /* If not "Blocked" SOM then just copy dim list to dim buffer */
2872 strcpy(dimbuf, dimlist);
2873 }
2874
2875 /*
2876 * Copy dimension buffer to auxilliary dimlist and Append comma to
2877 * end of dimension list
2878 */
2879 strcpy(dimlist0, dimbuf);
2880 strcat(dimbuf, ",");
2881
2882
2883 /* Find comma */
2884 /* ---------- */
2885 comma = strchr(dimbuf, ',');
2886
2887
2888 /*
2889 * Loop through entries in dimension list to make sure they are
2890 * defined in grid
2891 */
2892 while (comma != NULL)
2893 {
2894 /* Copy dimension list entry to dimcheck */
2895 /* ------------------------------------- */
2896 dimcheck = (char *) calloc(comma - dimbuf + 1, 1);
2897 if(dimcheck == NULL)
2898 {
2899 HEpush(DFE_NOSPACE,"GDdeffield", __FILE__, __LINE__);
2900 free(dimbuf);
2901 free(dimlist0);
2902 return(-1);
2903 }
2904 memcpy(dimcheck, dimbuf, comma - dimbuf);
2905
2906
2907 /* Get Dimension Size */
2908 /* ------------------ */
2909 if (strcmp(dimcheck, "XDim") == 0)
2910 {
2911 /* If "XDim" then use xdim value for grid definition */
2912 /* ------------------------------------------------- */
2913 dimsize = xdim;
2914 found = 1;
2915 dims[rank] = dimsize;
2916 rank++;
2917 }
2918 else if (strcmp(dimcheck, "YDim") == 0)
2919 {
2920 /* If "YDim" then use ydim value for grid definition */
2921 /* ------------------------------------------------- */
2922 dimsize = ydim;
2923 found = 1;
2924 dims[rank] = dimsize;
2925 rank++;
2926 }
2927 else
2928 {
2929 /* "Regular" Dimension */
2930 /* ------------------- */
2931 dimsize = GDdiminfo(gridID, dimcheck);
2932 if (dimsize != -1)
2933 {
2934 found = 1;
2935 dims[rank] = dimsize;
2936 rank++;
2937 }
2938 else
2939 {
2940 found = 0;
2941 }
2942 }
2943
2944
2945 /*
2946 * If dimension list entry not found - set error return status,
2947 * append name to utility buffer for error report
2948 */
2949 if (found == 0)
2950 {
2951 status = -1;
2952 foundAllDim = 0;
2953 if (first == 1)
2954 {
2955 strcpy(utlbuf, dimcheck);
2956 }
2957 else
2958 {
2959 strcat(utlbuf, ",");
2960 strcat(utlbuf, dimcheck);
2961 }
2962 first = 0;
2963 }
2964
2965 /*
2966 * Go to next dimension entry, find next comma, & free up
2967 * dimcheck buffer
2968 */
2969 memmove(dimbuf, comma + 1, strlen(comma)-1);
2970 dimbuf[strlen(comma)-1]= 0;
2971 comma = strchr(dimbuf, ',');
2972 free(dimcheck);
2973 }
2974 free(dimbuf);
2975
2976
2977
2978 /* Check fieldname length */
2979 /* ---------------------- */
2980 if (status == 0)
2981 {
2982 /* if ((intn) strlen(fieldname) > MAX_NC_NAME - 7)
2983 ** this was changed because HDF4.1r3 made a change in the
2984 ** hlimits.h file. We have notidfied NCSA and asked to have
2985 ** it made the same as in previous versions of HDF
2986 ** see ncr 26314. DaW Apr 2000
2987 */
2988 if((intn) strlen(fieldname) > (256 - 7))
2989 {
2990 status = -1;
2991 HEpush(DFE_GENAPP, "GDdefinefield", __FILE__, __LINE__);
2992 HEreport("Fieldname \"%s\" too long.\n", fieldname);
2993 }
2994 }
2995
2996
2997
2998 /* Check for valid numbertype */
2999 /* -------------------------- */
3000 if (status == 0)
3001 {
3002 for (i = 0; i < 10; i++)
3003 {
3004 if (numbertype == good_number[i])
3005 {
3006 foundNT = 1;
3007 break;
3008 }
3009 }
3010
3011 if (foundNT == 0)
3012 {
3013 HEpush(DFE_BADNUMTYPE, "GDdeffield", __FILE__, __LINE__);
3014 HEreport("Invalid number type: %d (%s).\n",
3015 numbertype, fieldname);
3016 status = -1;
3017 }
3018 }
3019
3020
3021 /* Define Field */
3022 /* ------------ */
3023 if (status == 0)
3024 {
3025 /* Get Field Vgroup id, compresion code, & tiling code */
3026 /* -------------------------------------------------- */
3027 vgid = GDXGrid[gID].VIDTable[0];
3028 compcode = GDXGrid[gID].compcode;
3029 tilecode = GDXGrid[gID].tilecode;
3030
3031
3032 /* SDS Interface (Multi-dim fields) */
3033 /* -------------------------------- */
3034
3035
3036 /*
3037 * If rank is less than or equal to 3 (and greater than 1) and
3038 * AUTOMERGE is set and the first dimension is not appendable and
3039 * the compression code is set to none then ...
3040 */
3041 if (rank >= 2 && rank <= 3 && merge == HDFE_AUTOMERGE &&
3042 dims[0] != 0 && compcode == HDFE_COMP_NONE &&
3043 tilecode == HDFE_NOTILE)
3044 {
3045
3046 /* Find first empty slot in external combination array */
3047 /* --------------------------------------------------- */
3048 i = 0;
3049 while (GDXSDcomb[5 * i] != 0)
3050 {
3051 i++;
3052 }
3053
3054 /*
3055 * Store dimensions, grid root Vgroup ID, and number type in
3056 * external combination array "GDXSDcomb"
3057 */
3058 if (rank == 2)
3059 {
3060 /* If 2-dim field then set lowest dimension to 1 */
3061 /* --------------------------------------------- */
3062 GDXSDcomb[5 * i] = 1;
3063 GDXSDcomb[5 * i + 1] = dims[0];
3064 GDXSDcomb[5 * i + 2] = dims[1];
3065 }
3066 else
3067 {
3068 GDXSDcomb[5 * i] = dims[0];
3069 GDXSDcomb[5 * i + 1] = dims[1];
3070 GDXSDcomb[5 * i + 2] = dims[2];
3071 }
3072
3073 GDXSDcomb[5 * i + 3] = gdVgrpID;
3074 GDXSDcomb[5 * i + 4] = numbertype;
3075
3076
3077 /* Concatanate fieldname with combined name string */
3078 /* ----------------------------------------------- */
3079 if ((intn) strlen(GDXSDname) +
3080 (intn) strlen(fieldname) + 2 < HDFE_NAMBUFSIZE)
3081 {
3082 strcat(GDXSDname, fieldname);
3083 strcat(GDXSDname, ",");
3084 }
3085 else
3086 {
3087 /* GDXSDname array too small! */
3088 /* -------------------------- */
3089 HEpush(DFE_GENAPP, "GDdefinefield",
3090 __FILE__, __LINE__);
3091 HEreport(errbuf1);
3092 status = -1;
3093 free(dimlist0);
3094 return (status);
3095 }
3096
3097
3098 /*
3099 * If 2-dim field then set lowest dimension (in 3-dim array)
3100 * to "ONE"
3101 */
3102 if (rank == 2)
3103 {
3104 if ((intn) strlen(GDXSDdims) + 5 < HDFE_DIMBUFSIZE)
3105 {
3106 strcat(GDXSDdims, "ONE,");
3107 }
3108 else
3109 {
3110 /* GDXSDdims array too small! */
3111 /* -------------------------- */
3112 HEpush(DFE_GENAPP, "GDdefinefield",
3113 __FILE__, __LINE__);
3114 HEreport(errbuf2);
3115 status = -1;
3116 free(dimlist0);
3117 return (status);
3118 }
3119 }
3120
3121
3122 /*
3123 * Concatanate field dimlist to merged dimlist and separate
3124 * fields with semi-colon
3125 */
3126 if ((intn) strlen(GDXSDdims) +
3127 (intn) strlen(dimlist0) + 2 < HDFE_DIMBUFSIZE)
3128 {
3129 strcat(GDXSDdims, dimlist0);
3130 strcat(GDXSDdims, ";");
3131 }
3132 else
3133 {
3134 /* GDXSDdims array too small! */
3135 /* -------------------------- */
3136 HEpush(DFE_GENAPP, "GDdefinefield",
3137 __FILE__, __LINE__);
3138 HEreport(errbuf2);
3139 status = -1;
3140 free(dimlist0);
3141 return (status);
3142 }
3143
3144 } /* End Multi-Dim Merge Section */
3145 else
3146 {
3147
3148 /* Multi-Dim No Merge Section */
3149 /* ========================== */
3150
3151
3152 /* Check that field dims are divisible by tile dims */
3153 /* ------------------------------------------------ */
3154 if (tilecode == HDFE_TILE)
3155 {
3156 for (i = 0; i < GDXGrid[gID].tilerank; i++)
3157 {
3158 if ((dims[i] % GDXGrid[gID].tiledims[i]) != 0)
3159 {
3160 HEpush(DFE_GENAPP, "GDdeffield",
3161 __FILE__, __LINE__);
3162 HEreport(errmsg,
3163 i, dims[i], GDXGrid[gID].tiledims[0]);
3164 status = -1;
3165 }
3166 }
3167
3168 if (status == -1)
3169 {
3170 free(dimlist0);
3171 return (status);
3172 }
3173 }
3174
3175
3176 /* Create SDS dataset */
3177 /* ------------------ */
3178 sdid = SDcreate(sdInterfaceID, fieldname,
3179 numbertype, rank, dims);
3180
3181
3182 /* Store Dimension Names in SDS */
3183 /* ---------------------------- */
3184 rank = EHparsestr(dimlist0, ',', ptr, slen);
3185 for (i = 0; i < rank; i++)
3186 {
3187 /* Dimension name = Swathname:Dimname */
3188 /* ---------------------------------- */
3189 memcpy(utlbuf, ptr[i], slen[i]);
3190 utlbuf[slen[i]] = 0;
3191 strcat(utlbuf, ":");
3192 strcat(utlbuf, gridname);
3193
3194 dimid = SDgetdimid(sdid, i);
3195 SDsetdimname(dimid, utlbuf);
3196 }
3197
3198
3199 /* Setup Compression */
3200 /* ----------------- */
3201 if (compcode == HDFE_COMP_NBIT)
3202 {
3203 c_info.nbit.nt = numbertype;
3204 c_info.nbit.sign_ext = GDXGrid[gID].compparm[0];
3205 c_info.nbit.fill_one = GDXGrid[gID].compparm[1];
3206 c_info.nbit.start_bit = GDXGrid[gID].compparm[2];
3207 c_info.nbit.bit_len = GDXGrid[gID].compparm[3];
3208 }
3209 else if (compcode == HDFE_COMP_SKPHUFF)
3210 {
3211 c_info.skphuff.skp_size = (intn) DFKNTsize(numbertype);
3212 }
3213 else if (compcode == HDFE_COMP_DEFLATE)
3214 {
3215 c_info.deflate.level = GDXGrid[gID].compparm[0];
3216 }
3217
3218
3219 /* If field is compressed w/o tiling then call SDsetcompress */
3220 /* --------------------------------------------------------- */
3221 if (compcode != HDFE_COMP_NONE && tilecode == HDFE_NOTILE)
3222 {
3223 status = SDsetcompress(sdid, (comp_coder_t) compcode, &c_info);
3224 }
3225
3226
3227 /* Setup Tiling */
3228 /* ------------ */
3229 if (tilecode == HDFE_TILE)
3230 {
3231 /* Tiling without Compression */
3232 /* -------------------------- */
3233 if (compcode == HDFE_COMP_NONE)
3234 {
3235
3236 /* Setup chunk lengths */
3237 /* ------------------- */
3238 for (i = 0; i < GDXGrid[gID].tilerank; i++)
3239 {
3240 chunkDef.chunk_lengths[i] =
3241 GDXGrid[gID].tiledims[i];
3242 }
3243
3244 chunkFlag = HDF_CHUNK;
3245 }
3246
3247 /* Tiling with Compression */
3248 /* ----------------------- */
3249 else
3250 {
3251 /* Setup chunk lengths */
3252 /* ------------------- */
3253 for (i = 0; i < GDXGrid[gID].tilerank; i++)
3254 {
3255 chunkDef.comp.chunk_lengths[i] =
3256 GDXGrid[gID].tiledims[i];
3257 }
3258
3259
3260 /* Setup chunk flag & chunk compression type */
3261 /* ----------------------------------------- */
3262 chunkFlag = HDF_CHUNK | HDF_COMP;
3263 chunkDef.comp.comp_type = compcode;
3264
3265
3266 /* Setup chunk compression parameters */
3267 /* ---------------------------------- */
3268 if (compcode == HDFE_COMP_SKPHUFF)
3269 {
3270 chunkDef.comp.cinfo.skphuff.skp_size =
3271 c_info.skphuff.skp_size;
3272 }
3273 else if (compcode == HDFE_COMP_DEFLATE)
3274 {
3275 chunkDef.comp.cinfo.deflate.level =
3276 c_info.deflate.level;
3277 }
3278 }
3279
3280 /* Call SDsetchunk routine */
3281 /* ----------------------- */
3282 status = SDsetchunk(sdid, chunkDef, chunkFlag);
3283 }
3284
3285
3286 /* Attach to Vgroup */
3287 /* ---------------- */
3288 Vaddtagref(vgid, DFTAG_NDG, SDidtoref(sdid));
3289
3290
3291 /* Store SDS dataset IDs */
3292 /* --------------------- */
3293
3294 /* Allocate space for the SDS ID array */
3295 /* ----------------------------------- */
3296 if (GDXGrid[gID].nSDS > 0)
3297 {
3298 /* Array already exists therefore reallocate */
3299 /* ----------------------------------------- */
3300 GDXGrid[gID].sdsID = (int32 *)
3301 realloc((void *) GDXGrid[gID].sdsID,
3302 (GDXGrid[gID].nSDS + 1) * 4);
3303 if(GDXGrid[gID].sdsID == NULL)
3304 {
3305 HEpush(DFE_NOSPACE,"GDdeffield", __FILE__, __LINE__);
3306 free(dimlist0);
3307 return(-1);
3308 }
3309 }
3310 else
3311 {
3312 /* Array does not exist */
3313 /* -------------------- */
3314 GDXGrid[gID].sdsID = (int32 *) calloc(1, 4);
3315 if(GDXGrid[gID].sdsID == NULL)
3316 {
3317 HEpush(DFE_NOSPACE,"GDdeffield", __FILE__, __LINE__);
3318 free(dimlist0);
3319 return(-1);
3320 }
3321 }
3322
3323 /* Store SDS ID in array & increment count */
3324 /* --------------------------------------- */
3325 GDXGrid[gID].sdsID[GDXGrid[gID].nSDS] = sdid;
3326 GDXGrid[gID].nSDS++;
3327
3328 }
3329
3330
3331 /* Setup metadata string */
3332 /* --------------------- */
3333 sprintf(utlbuf, "%s%s%s", fieldname, ":", dimlist0);
3334
3335
3336 /* Setup compression metadata */
3337 /* -------------------------- */
3338 if (compcode != HDFE_COMP_NONE)
3339 {
3340 sprintf(utlbuf2,
3341 "%s%s",
3342 ":\n\t\t\t\tCompressionType=", HDFcomp[compcode]);
3343
3344 switch (compcode)
3345 {
3346 case HDFE_COMP_NBIT:
3347
3348 sprintf(parmbuf,
3349 "%s%d,%d,%d,%d%s",
3350 "\n\t\t\t\tCompressionParams=(",
3351 GDXGrid[gID].compparm[0],
3352 GDXGrid[gID].compparm[1],
3353 GDXGrid[gID].compparm[2],
3354 GDXGrid[gID].compparm[3], ")");
3355 strcat(utlbuf2, parmbuf);
3356 break;
3357
3358
3359 case HDFE_COMP_DEFLATE:
3360
3361 sprintf(parmbuf,
3362 "%s%d",
3363 "\n\t\t\t\tDeflateLevel=",
3364 GDXGrid[gID].compparm[0]);
3365 strcat(utlbuf2, parmbuf);
3366 break;
3367 }
3368 strcat(utlbuf, utlbuf2);
3369 }
3370
3371
3372
3373
3374 /* Setup tiling metadata */
3375 /* --------------------- */
3376 if (tilecode == HDFE_TILE)
3377 {
3378 if (compcode == HDFE_COMP_NONE)
3379 {
3380 sprintf(utlbuf2, "%s%d",
3381 ":\n\t\t\t\tTilingDimensions=(",
3382 (int)GDXGrid[gID].tiledims[0]);
3383 }
3384 else
3385 {
3386 sprintf(utlbuf2, "%s%d",
3387 "\n\t\t\t\tTilingDimensions=(",
3388 (int)GDXGrid[gID].tiledims[0]);
3389 }
3390
3391 for (i = 1; i < GDXGrid[gID].tilerank; i++)
3392 {
3393 sprintf(parmbuf, ",%d", (int)GDXGrid[gID].tiledims[i]);
3394 strcat(utlbuf2, parmbuf);
3395 }
3396 strcat(utlbuf2, ")");
3397 strcat(utlbuf, utlbuf2);
3398 }
3399
3400
3401 /* Insert field metadata within File Structural Metadata */
3402 /* ----------------------------------------------------- */
3403 status = EHinsertmeta(sdInterfaceID, gridname, "g", 4L,
3404 utlbuf, &numbertype);
3405
3406 }
3407 free(dimlist0);
3408
3409 }
3410
3411 /* If all dimensions not found then report error */
3412 /* --------------------------------------------- */
3413 if (foundAllDim == 0)
3414 {
3415 HEpush(DFE_GENAPP, "GDdeffield", __FILE__, __LINE__);
3416 HEreport("Dimension(s): \"%s\" not found (%s).\n",
3417 utlbuf, fieldname);
3418 status = -1;
3419 }
3420
3421 return (status);
3422 }
3423
3424
3425
3426
3427 /*----------------------------------------------------------------------------|
3428 | BEGIN_PROLOG |
3429 | |
3430 | FUNCTION: GDwritefieldmeta |
3431 | |
3432 | DESCRIPTION: Writes field meta data for an existing grid field not |
3433 | defined within the grid API routine "GDdeffield". |
3434 | |
3435 | Return Value Type Units Description |
3436 | ============ ====== ========= ===================================== |
3437 | status intn return status (0) SUCCEED, (-1) FAIL |
3438 | |
3439 | INPUTS: |
3440 | gridID int32 grid structure ID |
3441 | fieldname char fieldname |
3442 | dimlist char Dimension list (comma-separated list) |
3443 | numbertype int32 field type |
3444 | |
3445 | |
3446 | OUTPUTS: |
3447 | None |
3448 | |
3449 | NOTES: |
3450 | |
3451 | |
3452 | Date Programmer Description |
3453 | ====== ============ ================================================= |
3454 | Jun 96 Joel Gales Original Programmer |
3455 | |
3456 | END_PROLOG |
3457 -----------------------------------------------------------------------------*/
3458 intn
GDwritefieldmeta(int32 gridID,char * fieldname,char * dimlist,int32 numbertype)3459 GDwritefieldmeta(int32 gridID, char *fieldname, char *dimlist,
3460 int32 numbertype)
3461 {
3462 intn status = 0; /* routine return status variable */
3463
3464 int32 sdInterfaceID; /* HDF SDS interface ID */
3465 int32 dum; /* dummy variable */
3466 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
3467
3468 char utlbuf[256];/* Utility buffer */
3469 char gridname[80]; /* Grid name */
3470
3471
3472 status = GDchkgdid(gridID, "GDwritefieldmeta", &dum, &sdInterfaceID,
3473 &dum);
3474
3475 if (status == 0)
3476 {
3477 sprintf(utlbuf, "%s%s%s", fieldname, ":", dimlist);
3478
3479 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
3480 status = EHinsertmeta(sdInterfaceID, gridname, "g", 4L,
3481 utlbuf, &numbertype);
3482 }
3483 return (status);
3484 }
3485
3486
3487
3488
3489 /*----------------------------------------------------------------------------|
3490 | BEGIN_PROLOG |
3491 | |
3492 | FUNCTION: GDSDfldsrch |
3493 | |
3494 | DESCRIPTION: Retrieves information from SDS fields |
3495 | |
3496 | |
3497 | Return Value Type Units Description |
3498 | ============ ====== ========= ===================================== |
3499 | status intn return status (0) SUCCEED, (-1) FAIL |
3500 | |
3501 | INPUTS: |
3502 | gridID int32 grid structure ID |
3503 | sdInterfaceID int32 SD interface ID |
3504 | fieldname char field name |
3505 | |
3506 | |
3507 | OUTPUTS: |
3508 | sdid int32 SD element ID |
3509 | rankSDS int32 Rank of SDS |
3510 | rankFld int32 True rank of field (merging) |
3511 | offset int32 Offset of field within merged field |
3512 | dims int32 Dimensions of field |
3513 | solo int32 Solo field flag |
3514 | |
3515 | NOTES: |
3516 | |
3517 | |
3518 | Date Programmer Description |
3519 | ====== ============ ================================================= |
3520 | Jun 96 Joel Gales Original Programmer |
3521 | Aug 96 Joel Gales Make metadata ODL compliant |
3522 | |
3523 | END_PROLOG |
3524 -----------------------------------------------------------------------------*/
3525 static intn
GDSDfldsrch(int32 gridID,int32 sdInterfaceID,const char * fieldname,int32 * sdid,int32 * rankSDS,int32 * rankFld,int32 * offset,int32 dims[],int32 * solo)3526 GDSDfldsrch(int32 gridID, int32 sdInterfaceID, const char *fieldname,
3527 int32 * sdid, int32 * rankSDS, int32 * rankFld, int32 * offset,
3528 int32 dims[], int32 * solo)
3529 {
3530 intn i; /* Loop index */
3531 intn status = -1;/* routine return status variable */
3532
3533 int32 gID; /* GridID - offset */
3534 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
3535 int32 dum; /* Dummy variable */
3536 int32 dums[128]; /* Dummy array */
3537 int32 attrIndex; /* Attribute index */
3538
3539 char name[2048]; /* Merged-Field Names */
3540 char gridname[80]; /* Grid Name */
3541 char *utlstr;/* Utility string */
3542 char *metabuf; /* Pointer to structural metadata (SM) */
3543 char *metaptrs[2];/* Pointers to begin and end of SM section */
3544 char *oldmetaptr; /* Pointer within SM section */
3545 char *metaptr; /* Pointer within SM section */
3546
3547
3548 /* Allocate space for utility string */
3549 /* --------------------------------- */
3550 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
3551 if(utlstr == NULL)
3552 {
3553 HEpush(DFE_NOSPACE,"GDSDfldsrch", __FILE__, __LINE__);
3554 return(-1);
3555 }
3556 /* Set solo flag to 0 (no) */
3557 /* ----------------------- */
3558 *solo = 0;
3559
3560
3561 /* Compute "reduced" grid ID */
3562 /* ------------------------- */
3563 gID = gridID % idOffset;
3564
3565
3566 /* Loop through all SDSs in grid */
3567 /* ----------------------------- */
3568 for (i = 0; i < GDXGrid[gID].nSDS; i++)
3569 {
3570 /* If active SDS ... */
3571 /* ----------------- */
3572 if (GDXGrid[gID].sdsID[i] != 0)
3573 {
3574 /* Get SDS ID, name, rankSDS, and dimensions */
3575 /* ----------------------------------------- */
3576 *sdid = GDXGrid[gID].sdsID[i];
3577 SDgetinfo(*sdid, name, rankSDS, dims, &dum, &dum);
3578 *rankFld = *rankSDS;
3579
3580
3581 /* If merged field ... */
3582 /* ------------------- */
3583 if (strstr(name, "MRGFLD_") == &name[0])
3584 {
3585 /* Get grid name */
3586 /* ------------- */
3587 Vgetname(GDXGrid[gID].IDTable, gridname);
3588
3589
3590 /* Get pointers to "MergedFields" section within SM */
3591 /* ------------------------------------------------ */
3592 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
3593 "MergedFields", metaptrs);
3594 if(metabuf == NULL)
3595 {
3596 free(utlstr);
3597 return(-1);
3598 }
3599
3600
3601 /* Initialize metaptr to beg. of section */
3602 /* ------------------------------------- */
3603 metaptr = metaptrs[0];
3604
3605
3606 /* Store metaptr in order to recover */
3607 /* --------------------------------- */
3608 oldmetaptr = metaptr;
3609
3610
3611 /* Search for Merged field name */
3612 /* ---------------------------- */
3613 sprintf(utlstr, "%s%s%s", "MergedFieldName=\"",
3614 name, "\"\n");
3615 metaptr = strstr(metaptr, utlstr);
3616
3617
3618 /* If not found check for old metadata */
3619 /* ----------------------------------- */
3620 if (metaptr == NULL)
3621 {
3622 sprintf(utlstr, "%s%s%s", "OBJECT=\"", name, "\"\n");
3623 metaptr = strstr(oldmetaptr, utlstr);
3624 }
3625
3626
3627 /* Get field list and strip off leading and trailing quotes */
3628 /* -------------------------------------------------------- */
3629 EHgetmetavalue(metaptrs, "FieldList", name);
3630 memmove(name, name + 1, strlen(name) - 2);
3631 name[strlen(name) - 2] = 0;
3632
3633
3634 /* Search for desired field within merged field list */
3635 /* ------------------------------------------------- */
3636 sprintf(utlstr, "%s%s%s", "\"", fieldname, "\"");
3637 dum = EHstrwithin(utlstr, name, ',');
3638
3639 free(metabuf);
3640 }
3641 else
3642 {
3643 /* If solo (unmerged) check if SDS name matches fieldname */
3644 /* ------------------------------------------------------ */
3645 dum = EHstrwithin(fieldname, name, ',');
3646 if (dum != -1)
3647 {
3648 *solo = 1;
3649 *offset = 0;
3650 }
3651 }
3652
3653
3654
3655 /* If field found ... */
3656 /* ------------------ */
3657 if (dum != -1)
3658 {
3659 status = 0;
3660
3661 /* If merged field ... */
3662 /* ------------------- */
3663 if (*solo == 0)
3664 {
3665 /* Get "Field Offsets" SDS attribute index */
3666 /* --------------------------------------- */
3667 attrIndex = SDfindattr(*sdid, "Field Offsets");
3668
3669 /*
3670 * If attribute exists then get offset of desired field
3671 * within merged field
3672 */
3673 if (attrIndex != -1)
3674 {
3675 SDreadattr(*sdid, attrIndex, (VOIDP) dums);
3676 *offset = dums[dum];
3677 }
3678
3679
3680 /* Get "Field Dims" SDS attribute index */
3681 /* ------------------------------------ */
3682 attrIndex = SDfindattr(*sdid, "Field Dims");
3683
3684 /*
3685 * If attribute exists then get 0th dimension of desired
3686 * field within merged field
3687 */
3688 if (attrIndex != -1)
3689 {
3690 SDreadattr(*sdid, attrIndex, (VOIDP) dums);
3691 dims[0] = dums[dum];
3692
3693 /* If this dimension = 1 then field is really 2 dim */
3694 /* ------------------------------------------------ */
3695 if (dums[dum] == 1)
3696 {
3697 *rankFld = 2;
3698 }
3699 }
3700 }
3701
3702
3703 /* Break out of SDS loop */
3704 /* --------------------- */
3705 break;
3706 } /* End of found field section */
3707 }
3708 else
3709 {
3710 /* First non-active SDS signifies no more, break out of SDS loop */
3711 /* ------------------------------------------------------------- */
3712 break;
3713 }
3714 }
3715 free(utlstr);
3716 return (status);
3717 }
3718
3719
3720
3721
3722 /*----------------------------------------------------------------------------|
3723 | BEGIN_PROLOG |
3724 | |
3725 | FUNCTION: GDwrrdfield |
3726 | |
3727 | DESCRIPTION: Writes/Reads fields |
3728 | |
3729 | |
3730 | Return Value Type Units Description |
3731 | ============ ====== ========= ===================================== |
3732 | status intn return status (0) SUCCEED, (-1) FAIL |
3733 | |
3734 | INPUTS: |
3735 | gridID int32 grid structure ID |
3736 | fieldname char fieldname |
3737 | code char Write/Read code (w/r) |
3738 | start int32 start array |
3739 | stride int32 stride array |
3740 | edge int32 edge array |
3741 | datbuf void data buffer for read |
3742 | |
3743 | |
3744 | OUTPUTS: |
3745 | datbuf void data buffer for write |
3746 | |
3747 | |
3748 | NOTES: |
3749 | |
3750 | |
3751 | Date Programmer Description |
3752 | ====== ============ ================================================= |
3753 | Jun 96 Joel Gales Original Programmer |
3754 | Feb 97 Joel Gales Stride = 1 HDF compression workaround |
3755 | |
3756 | END_PROLOG |
3757 -----------------------------------------------------------------------------*/
3758 static intn
GDwrrdfield(int32 gridID,char * fieldname,char * code,int32 start[],int32 stride[],int32 edge[],VOIDP datbuf)3759 GDwrrdfield(int32 gridID, char *fieldname, char *code,
3760 int32 start[], int32 stride[], int32 edge[], VOIDP datbuf)
3761
3762 {
3763 intn i; /* Loop index */
3764 intn status = 0; /* routine return status variable */
3765
3766 int32 fid; /* HDF-EOS file ID */
3767 int32 sdInterfaceID; /* HDF SDS interface ID */
3768 int32 sdid; /* SDS ID */
3769 int32 dum; /* Dummy variable */
3770 int32 rankSDS; /* Rank of SDS */
3771 int32 rankFld; /* Rank of field */
3772
3773 int32 offset[8]; /* I/O offset (start) */
3774 int32 incr[8]; /* I/O increment (stride) */
3775 int32 count[8]; /* I/O count (edge) */
3776 int32 dims[8]; /* Field/SDS dimensions */
3777 int32 mrgOffset; /* Merged field offset */
3778 int32 strideOne; /* Strides = 1 flag */
3779
3780
3781 /* Check for valid grid ID */
3782 /* ----------------------- */
3783 status = GDchkgdid(gridID, "GDwrrdfield", &fid, &sdInterfaceID, &dum);
3784
3785
3786 if (status == 0)
3787 {
3788 /* Check that field exists */
3789 /* ----------------------- */
3790 status = GDfieldinfo(gridID, fieldname, &rankSDS, dims, &dum, NULL);
3791
3792
3793 if (status != 0)
3794 {
3795 HEpush(DFE_GENAPP, "GDwrrdfield", __FILE__, __LINE__);
3796 HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
3797 status = -1;
3798
3799 }
3800
3801
3802 if (status == 0)
3803 {
3804 status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
3805 &rankSDS, &rankFld, &mrgOffset, dims, &dum);
3806
3807
3808 /* Set I/O offset Section */
3809 /* ---------------------- */
3810
3811 /*
3812 * If start == NULL (default) set I/O offset of 0th field to
3813 * offset within merged field (if any) and the rest to 0
3814 */
3815 if (start == NULL)
3816 {
3817 for (i = 0; i < rankSDS; i++)
3818 {
3819 offset[i] = 0;
3820 }
3821 offset[0] = mrgOffset;
3822 }
3823 else
3824 {
3825 /*
3826 * ... otherwise set I/O offset to user values, adjusting the
3827 * 0th field with the merged field offset (if any)
3828 */
3829 if (rankFld == rankSDS)
3830 {
3831 for (i = 0; i < rankSDS; i++)
3832 {
3833 offset[i] = start[i];
3834 }
3835 offset[0] += mrgOffset;
3836 }
3837 else
3838 {
3839 /*
3840 * If field really 2-dim merged in 3-dim field then set
3841 * 0th field offset to merge offset and then next two to
3842 * the user values
3843 */
3844 for (i = 0; i < rankFld; i++)
3845 {
3846 offset[i + 1] = start[i];
3847 }
3848 offset[0] = mrgOffset;
3849 }
3850 }
3851
3852
3853
3854 /* Set I/O stride Section */
3855 /* ---------------------- */
3856
3857 /*
3858 * If stride == NULL (default) set I/O stride to 1
3859 */
3860 if (stride == NULL)
3861 {
3862 for (i = 0; i < rankSDS; i++)
3863 {
3864 incr[i] = 1;
3865 }
3866 }
3867 else
3868 {
3869 /*
3870 * ... otherwise set I/O stride to user values
3871 */
3872 if (rankFld == rankSDS)
3873 {
3874 for (i = 0; i < rankSDS; i++)
3875 {
3876 incr[i] = stride[i];
3877 }
3878 }
3879 else
3880 {
3881 /*
3882 * If field really 2-dim merged in 3-dim field then set
3883 * 0th field stride to 1 and then next two to the user
3884 * values.
3885 */
3886 for (i = 0; i < rankFld; i++)
3887 {
3888 incr[i + 1] = stride[i];
3889 }
3890 incr[0] = 1;
3891 }
3892 }
3893
3894
3895
3896 /* Set I/O count Section */
3897 /* --------------------- */
3898
3899 /*
3900 * If edge == NULL (default) set I/O count to number of remaining
3901 * entries (dims - start) / increment. Note that 0th field
3902 * offset corrected for merged field offset (if any).
3903 */
3904 if (edge == NULL)
3905 {
3906 for (i = 1; i < rankSDS; i++)
3907 {
3908 count[i] = (dims[i] - offset[i]) / incr[i];
3909 }
3910 count[0] = (dims[0] - (offset[0] - mrgOffset)) / incr[0];
3911 }
3912 else
3913 {
3914 /*
3915 * ... otherwise set I/O count to user values
3916 */
3917 if (rankFld == rankSDS)
3918 {
3919 for (i = 0; i < rankSDS; i++)
3920 {
3921 count[i] = edge[i];
3922 }
3923 }
3924 else
3925 {
3926 /*
3927 * If field really 2-dim merged in 3-dim field then set
3928 * 0th field count to 1 and then next two to the user
3929 * values.
3930 */
3931 for (i = 0; i < rankFld; i++)
3932 {
3933 count[i + 1] = edge[i];
3934 }
3935 count[0] = 1;
3936 }
3937 }
3938
3939
3940 /* Perform I/O with relevant HDF I/O routine */
3941 /* ----------------------------------------- */
3942 if (strcmp(code, "w") == 0)
3943 {
3944 /* Set strideOne to true (1) */
3945 /* ------------------------- */
3946 strideOne = 1;
3947
3948
3949 /* If incr[i] != 1 set strideOne to false (0) */
3950 /* ------------------------------------------ */
3951 for (i = 0; i < rankSDS; i++)
3952 {
3953 if (incr[i] != 1)
3954 {
3955 strideOne = 0;
3956 break;
3957 }
3958 }
3959
3960
3961 /*
3962 * If strideOne is true use NULL parameter for stride. This
3963 * is a work-around to HDF compression problem
3964 */
3965 if (strideOne == 1)
3966 {
3967 status = SDwritedata(sdid, offset, NULL, count,
3968 (VOIDP) datbuf);
3969 }
3970 else
3971 {
3972 status = SDwritedata(sdid, offset, incr, count,
3973 (VOIDP) datbuf);
3974 }
3975 }
3976 else
3977 {
3978 status = SDreaddata(sdid, offset, incr, count,
3979 (VOIDP) datbuf);
3980 }
3981 }
3982 }
3983
3984 return (status);
3985 }
3986
3987
3988 /*----------------------------------------------------------------------------|
3989 | BEGIN_PROLOG |
3990 | |
3991 | FUNCTION: GDwritefield |
3992 | |
3993 | DESCRIPTION: Writes data to a grid field. |
3994 | |
3995 | |
3996 | Return Value Type Units Description |
3997 | ============ ====== ========= ===================================== |
3998 | status intn return status (0) SUCCEED, (-1) FAIL |
3999 | |
4000 | INPUTS: |
4001 | gridID int32 grid structure ID |
4002 | fieldname char fieldname |
4003 | start int32 start array |
4004 | stride int32 stride array |
4005 | edge int32 edge array |
4006 | |
4007 | |
4008 | OUTPUTS: |
4009 | data void data buffer for write |
4010 | |
4011 | NOTES: |
4012 | |
4013 | |
4014 | Date Programmer Description |
4015 | ====== ============ ================================================= |
4016 | Jun 96 Joel Gales Original Programmer |
4017 | |
4018 | END_PROLOG |
4019 -----------------------------------------------------------------------------*/
4020 intn
GDwritefield(int32 gridID,char * fieldname,int32 start[],int32 stride[],int32 edge[],VOIDP data)4021 GDwritefield(int32 gridID, char *fieldname,
4022 int32 start[], int32 stride[], int32 edge[], VOIDP data)
4023
4024 {
4025 intn status = 0; /* routine return status variable */
4026
4027 status = GDwrrdfield(gridID, fieldname, "w", start, stride, edge,
4028 data);
4029 return (status);
4030 }
4031
4032
4033
4034
4035
4036 /*----------------------------------------------------------------------------|
4037 | BEGIN_PROLOG |
4038 | |
4039 | FUNCTION: GDreadfield |
4040 | |
4041 | DESCRIPTION: Reads data from a grid field. |
4042 | |
4043 | |
4044 | Return Value Type Units Description |
4045 | ============ ====== ========= ===================================== |
4046 | status intn return status (0) SUCCEED, (-1) FAIL |
4047 | |
4048 | INPUTS: |
4049 | gridID int32 grid structure ID |
4050 | fieldname char fieldname |
4051 | start int32 start array |
4052 | stride int32 stride array |
4053 | edge int32 edge array |
4054 | buffer void data buffer for read |
4055 | |
4056 | |
4057 | OUTPUTS: |
4058 | None |
4059 | |
4060 | NOTES: |
4061 | |
4062 | |
4063 | Date Programmer Description |
4064 | ====== ============ ================================================= |
4065 | Jun 96 Joel Gales Original Programmer |
4066 | |
4067 | END_PROLOG |
4068 -----------------------------------------------------------------------------*/
4069 intn
GDreadfield(int32 gridID,char * fieldname,int32 start[],int32 stride[],int32 edge[],VOIDP buffer)4070 GDreadfield(int32 gridID, char *fieldname,
4071 int32 start[], int32 stride[], int32 edge[], VOIDP buffer)
4072
4073 {
4074 intn status = 0; /* routine return status variable */
4075
4076 status = GDwrrdfield(gridID, fieldname, "r", start, stride, edge,
4077 buffer);
4078 return (status);
4079 }
4080
4081
4082
4083
4084 /*----------------------------------------------------------------------------|
4085 | BEGIN_PROLOG |
4086 | |
4087 | FUNCTION: GDwrrdattr |
4088 | |
4089 | DESCRIPTION: |
4090 | |
4091 | |
4092 | Return Value Type Units Description |
4093 | ============ ====== ========= ===================================== |
4094 | status intn return status (0) SUCCEED, (-1) FAIL |
4095 | |
4096 | INPUTS: |
4097 | gridID int32 grid structure ID |
4098 | attrname char attribute name |
4099 | numbertype int32 attribute HDF numbertype |
4100 | count int32 Number of attribute elements |
4101 | wrcode char Read/Write Code "w/r" |
4102 | datbuf void I/O buffer |
4103 | |
4104 | OUTPUTS: |
4105 | datbuf |
4106 | |
4107 | NOTES: |
4108 | |
4109 | |
4110 | Date Programmer Description |
4111 | ====== ============ ================================================= |
4112 | Jun 96 Joel Gales Original Programmer |
4113 | Oct 96 Joel Gales Get Attribute Vgroup ID from external array |
4114 | |
4115 | END_PROLOG |
4116 -----------------------------------------------------------------------------*/
4117 static intn
GDwrrdattr(int32 gridID,char * attrname,int32 numbertype,int32 count,char * wrcode,VOIDP datbuf)4118 GDwrrdattr(int32 gridID, char *attrname, int32 numbertype, int32 count,
4119 char *wrcode, VOIDP datbuf)
4120
4121 {
4122 intn status; /* routine return status variable */
4123
4124 int32 fid; /* HDF-EOS file ID */
4125 int32 attrVgrpID; /* Grid attribute ID */
4126 int32 dum; /* dummy variable */
4127 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
4128
4129
4130 /* Check Grid id */
4131 status = GDchkgdid(gridID, "GDwrrdattr", &fid, &dum, &dum);
4132
4133 if (status == 0)
4134 {
4135 /* Perform Attribute I/O */
4136 /* --------------------- */
4137 attrVgrpID = GDXGrid[gridID % idOffset].VIDTable[1];
4138 status = EHattr(fid, attrVgrpID, attrname, numbertype, count,
4139 wrcode, datbuf);
4140 }
4141 return (status);
4142 }
4143
4144
4145
4146 /*----------------------------------------------------------------------------|
4147 | BEGIN_PROLOG |
4148 | |
4149 | FUNCTION: GDwriteattr |
4150 | |
4151 | DESCRIPTION: Writes/updates attribute in a grid. |
4152 | |
4153 | |
4154 | Return Value Type Units Description |
4155 | ============ ====== ========= ===================================== |
4156 | status intn return status (0) SUCCEED, (-1) FAIL |
4157 | |
4158 | INPUTS: |
4159 | gridID int32 grid structure ID |
4160 | attrname char attribute name |
4161 | numbertype int32 attribute HDF numbertype |
4162 | count int32 Number of attribute elements |
4163 | datbuf void I/O buffer |
4164 | |
4165 | OUTPUTS: |
4166 | None |
4167 | |
4168 | NOTES: |
4169 | |
4170 | |
4171 | Date Programmer Description |
4172 | ====== ============ ================================================= |
4173 | Jun 96 Joel Gales Original Programmer |
4174 | |
4175 | END_PROLOG |
4176 -----------------------------------------------------------------------------*/
4177 intn
GDwriteattr(int32 gridID,char * attrname,int32 numbertype,int32 count,VOIDP datbuf)4178 GDwriteattr(int32 gridID, char *attrname, int32 numbertype, int32 count,
4179 VOIDP datbuf)
4180 {
4181 intn status = 0; /* routine return status variable */
4182
4183 /* Call GDwrrdattr routine to write attribute */
4184 /* ------------------------------------------ */
4185 status = GDwrrdattr(gridID, attrname, numbertype, count, "w", datbuf);
4186
4187 return (status);
4188 }
4189
4190
4191
4192 /*----------------------------------------------------------------------------|
4193 | BEGIN_PROLOG |
4194 | |
4195 | FUNCTION: GDreadattr |
4196 | |
4197 | DESCRIPTION: Reads attribute from a grid. |
4198 | |
4199 | |
4200 | Return Value Type Units Description |
4201 | ============ ====== ========= ===================================== |
4202 | status intn return status (0) SUCCEED, (-1) FAIL |
4203 | |
4204 | INPUTS: |
4205 | gridID int32 grid structure ID |
4206 | attrname char attribute name |
4207 | |
4208 | OUTPUTS: |
4209 | datbuf void I/O buffer |
4210 | |
4211 | NOTES: |
4212 | |
4213 | |
4214 | Date Programmer Description |
4215 | ====== ============ ================================================= |
4216 | Jun 96 Joel Gales Original Programmer |
4217 | |
4218 | END_PROLOG |
4219 -----------------------------------------------------------------------------*/
4220 intn
GDreadattr(int32 gridID,char * attrname,VOIDP datbuf)4221 GDreadattr(int32 gridID, char *attrname, VOIDP datbuf)
4222 {
4223 intn status = 0; /* routine return status variable */
4224 int32 dum = 0; /* dummy variable */
4225
4226 /* Call GDwrrdattr routine to read attribute */
4227 /* ----------------------------------------- */
4228 status = GDwrrdattr(gridID, attrname, dum, dum, "r", datbuf);
4229
4230 return (status);
4231 }
4232
4233
4234
4235
4236
4237 /*----------------------------------------------------------------------------|
4238 | BEGIN_PROLOG |
4239 | |
4240 | FUNCTION: GDattrinfo |
4241 | |
4242 | DESCRIPTION: |
4243 | |
4244 | |
4245 | Return Value Type Units Description |
4246 | ============ ====== ========= ===================================== |
4247 | status intn return status (0) SUCCEED, (-1) FAIL |
4248 | |
4249 | INPUTS: |
4250 | gridID int32 grid structure ID |
4251 | attrname char attribute name |
4252 | |
4253 | OUTPUTS: |
4254 | numbertype int32 attribute HDF numbertype |
4255 | count int32 Number of attribute elements |
4256 | |
4257 | |
4258 | OUTPUTS: |
4259 | None |
4260 | |
4261 | NOTES: |
4262 | |
4263 | |
4264 | Date Programmer Description |
4265 | ====== ============ ================================================= |
4266 | Jun 96 Joel Gales Original Programmer |
4267 | Oct 96 Joel Gales Get Attribute Vgroup ID from external array |
4268 | |
4269 | END_PROLOG |
4270 -----------------------------------------------------------------------------*/
4271 intn
GDattrinfo(int32 gridID,char * attrname,int32 * numbertype,int32 * count)4272 GDattrinfo(int32 gridID, char *attrname, int32 * numbertype, int32 * count)
4273 {
4274 intn status = 0; /* routine return status variable */
4275
4276 int32 fid; /* HDF-EOS file ID */
4277 int32 attrVgrpID; /* Grid attribute ID */
4278 int32 dum; /* dummy variable */
4279 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
4280
4281 status = GDchkgdid(gridID, "GDattrinfo", &fid, &dum, &dum);
4282
4283 attrVgrpID = GDXGrid[gridID % idOffset].VIDTable[1];
4284
4285 status = EHattrinfo(fid, attrVgrpID, attrname, numbertype,
4286 count);
4287
4288 return (status);
4289 }
4290
4291
4292
4293
4294
4295
4296 /*----------------------------------------------------------------------------|
4297 | BEGIN_PROLOG |
4298 | |
4299 | FUNCTION: GDinqattrs |
4300 | |
4301 | DESCRIPTION: |
4302 | |
4303 | |
4304 | Return Value Type Units Description |
4305 | ============ ====== ========= ===================================== |
4306 | nattr int32 Number of attributes in swath struct |
4307 | |
4308 | INPUTS: |
4309 | grid ID int32 grid structure ID |
4310 | |
4311 | OUTPUTS: |
4312 | attrnames char Attribute names in swath struct |
4313 | (Comma-separated list) |
4314 | strbufsize int32 Attributes name list string length |
4315 | |
4316 | OUTPUTS: |
4317 | None |
4318 | |
4319 | NOTES: |
4320 | |
4321 | |
4322 | Date Programmer Description |
4323 | ====== ============ ================================================= |
4324 | Jun 96 Joel Gales Original Programmer |
4325 | Oct 96 Joel Gales Initialize nattr |
4326 | Oct 96 Joel Gales Get Attribute Vgroup ID from external array |
4327 | |
4328 | END_PROLOG |
4329 -----------------------------------------------------------------------------*/
4330 int32
GDinqattrs(int32 gridID,char * attrnames,int32 * strbufsize)4331 GDinqattrs(int32 gridID, char *attrnames, int32 * strbufsize)
4332 {
4333 intn status; /* routine return status variable */
4334
4335 int32 fid; /* HDF-EOS file ID */
4336 int32 attrVgrpID; /* Grid attribute ID */
4337 int32 dum; /* dummy variable */
4338 int32 nattr = 0; /* Number of attributes */
4339 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
4340
4341
4342 /* Check Grid id */
4343 status = GDchkgdid(gridID, "GDinqattrs", &fid, &dum, &dum);
4344
4345 if (status == 0)
4346 {
4347 attrVgrpID = GDXGrid[gridID % idOffset].VIDTable[1];
4348 nattr = EHattrcat(fid, attrVgrpID, attrnames, strbufsize);
4349 }
4350
4351 return (nattr);
4352 }
4353
4354
4355
4356
4357
4358
4359 #define REMQUOTE \
4360 \
4361 memmove(utlstr, utlstr + 1, strlen(utlstr) - 2); \
4362 utlstr[strlen(utlstr) - 2] = 0;
4363
4364
4365 /*----------------------------------------------------------------------------|
4366 | BEGIN_PROLOG |
4367 | |
4368 | FUNCTION: GDinqdims |
4369 | |
4370 | DESCRIPTION: Retrieve information about all dimensions defined in a grid. |
4371 | |
4372 | |
4373 | Return Value Type Units Description |
4374 | ============ ====== ========= ===================================== |
4375 | nDim int32 Number of defined dimensions |
4376 | |
4377 | INPUTS: |
4378 | gridID int32 grid structure ID |
4379 | |
4380 | OUTPUTS: |
4381 | dimnames char Dimension names (comma-separated) |
4382 | dims int32 Dimension values |
4383 | |
4384 | |
4385 | OUTPUTS: |
4386 | None |
4387 | |
4388 | NOTES: |
4389 | |
4390 | |
4391 | Date Programmer Description |
4392 | ====== ============ ================================================= |
4393 | Jun 96 Joel Gales Original Programmer |
4394 | Aug 96 Joel Gales Make metadata ODL compliant |
4395 | Feb 97 Joel Gales Set nDim to -1 if status = -1 |
4396 | |
4397 | END_PROLOG |
4398 -----------------------------------------------------------------------------*/
4399 int32
GDinqdims(int32 gridID,char * dimnames,int32 dims[])4400 GDinqdims(int32 gridID, char *dimnames, int32 dims[])
4401 {
4402 intn status; /* routine return status variable */
4403
4404 int32 fid; /* HDF-EOS file ID */
4405 int32 sdInterfaceID; /* HDF SDS interface ID */
4406 int32 gdVgrpID; /* Grid root Vgroup ID */
4407 int32 size; /* Dimension size */
4408 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
4409 int32 nDim = 0; /* Number of dimensions */
4410
4411 char *metabuf; /* Pointer to structural metadata (SM) */
4412 char *metaptrs[2];/* Pointers to begin and end of SM section */
4413 char gridname[80]; /* Grid Name */
4414 char *utlstr;/* Utility string */
4415
4416 /* Allocate space for utility string */
4417 /* --------------------------------- */
4418 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
4419 if(utlstr == NULL)
4420 {
4421 HEpush(DFE_NOSPACE,"GDinqdims", __FILE__, __LINE__);
4422 return(-1);
4423 }
4424 /* Check for valid grid id */
4425 /* ----------------------- */
4426 status = GDchkgdid(gridID, "GDinqdims", &fid, &sdInterfaceID, &gdVgrpID);
4427
4428 if (status == 0)
4429 {
4430 /* If dimension names or sizes are requested */
4431 /* ----------------------------------------- */
4432 if (dimnames != NULL || dims != NULL)
4433 {
4434 /* Get grid name */
4435 /* ------------- */
4436 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
4437
4438
4439 /* Get pointers to "Dimension" section within SM */
4440 /* --------------------------------------------- */
4441 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
4442 "Dimension", metaptrs);
4443 if(metabuf == NULL)
4444 {
4445 free(utlstr);
4446 return(-1);
4447 }
4448
4449
4450 /* If dimension names are requested then "clear" name buffer */
4451 /* --------------------------------------------------------- */
4452 if (dimnames != NULL)
4453 {
4454 dimnames[0] = 0;
4455 }
4456
4457 while (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
4458 {
4459 strcpy(utlstr, "\t\tOBJECT=");
4460 metaptrs[0] = strstr(metaptrs[0], utlstr);
4461 if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
4462 {
4463 /* Get Dimension Name */
4464 /* ------------------ */
4465 if (dimnames != NULL)
4466 {
4467 /* Check 1st for old meta data then new */
4468 /* ------------------------------------ */
4469 EHgetmetavalue(metaptrs, "OBJECT", utlstr);
4470 if (utlstr[0] != '"')
4471 {
4472 metaptrs[0] =
4473 strstr(metaptrs[0], "\t\t\t\tDimensionName=");
4474 EHgetmetavalue(metaptrs, "DimensionName", utlstr);
4475 }
4476
4477 /* Strip off double quotes */
4478 /* ----------------------- */
4479 memmove(utlstr, utlstr + 1, strlen(utlstr) - 2);
4480 utlstr[strlen(utlstr) - 2] = 0;
4481
4482 if (nDim > 0)
4483 {
4484 strcat(dimnames, ",");
4485 }
4486 strcat(dimnames, utlstr);
4487 }
4488
4489 /* Get Dimension Size */
4490 /* ------------------ */
4491 if (dims != NULL)
4492 {
4493 EHgetmetavalue(metaptrs, "Size", utlstr);
4494 size = atol(utlstr);
4495 dims[nDim] = size;
4496 }
4497 nDim++;
4498 }
4499 }
4500 free(metabuf);
4501
4502 }
4503 }
4504
4505
4506 /* Set nDim to -1 if error status exists */
4507 /* ------------------------------------- */
4508 if (status == -1)
4509 {
4510 nDim = -1;
4511 }
4512 free(utlstr);
4513 return (nDim);
4514 }
4515
4516
4517
4518
4519
4520
4521 /*----------------------------------------------------------------------------|
4522 | BEGIN_PROLOG |
4523 | |
4524 | FUNCTION: GDinqfields |
4525 | |
4526 | DESCRIPTION: Retrieve information about all data fields defined in a grid. |
4527 | |
4528 | |
4529 | Return Value Type Units Description |
4530 | ============ ====== ========= ===================================== |
4531 | nFld int32 Number of fields in swath |
4532 | |
4533 | INPUTS: |
4534 | gridID int32 grid structure ID |
4535 | |
4536 | |
4537 | OUTPUTS: |
4538 | fieldlist char Field names (comma-separated) |
4539 | rank int32 Array of ranks |
4540 | numbertype int32 Array of HDF number types |
4541 | |
4542 | NOTES: |
4543 | |
4544 | |
4545 | Date Programmer Description |
4546 | ====== ============ ================================================= |
4547 | Jun 96 Joel Gales Original Programmer |
4548 | Aug 96 Joel Gales Make metadata ODL compliant |
4549 | Feb 97 Joel Gales Set nFld to -1 if status = -1 |
4550 | |
4551 | END_PROLOG |
4552 -----------------------------------------------------------------------------*/
4553 int32
GDinqfields(int32 gridID,char * fieldlist,int32 rank[],int32 numbertype[])4554 GDinqfields(int32 gridID, char *fieldlist, int32 rank[],
4555 int32 numbertype[])
4556 {
4557 intn status; /* routine return status variable */
4558
4559 int32 fid; /* HDF-EOS file ID */
4560 int32 sdInterfaceID; /* HDF SDS interface ID */
4561 int32 gdVgrpID; /* Grid root Vgroup ID */
4562 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
4563 int32 nFld = 0; /* Number of mappings */
4564 int32 slen[8]; /* String length array */
4565
4566 char *metabuf; /* Pointer to structural metadata (SM) */
4567 char *metaptrs[2];/* Pointers to begin and end of SM section */
4568 char gridname[80]; /* Grid Name */
4569 char *utlstr;/* Utility string */
4570 char *ptr[8]; /* String pointer array */
4571
4572 /* Allocate space for utility string */
4573 /* --------------------------------- */
4574 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
4575 if(utlstr == NULL)
4576 {
4577 HEpush(DFE_NOSPACE,"GDinqfields", __FILE__, __LINE__);
4578 return(-1);
4579 }
4580 /* Check for valid grid id */
4581 /* ----------------------- */
4582 status = GDchkgdid(gridID, "GDinqfields", &fid, &sdInterfaceID, &gdVgrpID);
4583 if (status == 0)
4584 {
4585
4586 /* If field names, ranks, or number types desired ... */
4587 /* --------------------------------------------------- */
4588 if (fieldlist != NULL || rank != NULL || numbertype != NULL)
4589 {
4590 /* Get grid name */
4591 /* ------------- */
4592 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
4593
4594
4595 /* Get pointers to "DataField" section within SM */
4596 /* --------------------------------------------- */
4597 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
4598 "DataField", metaptrs);
4599 if(metabuf == NULL)
4600 {
4601 free(utlstr);
4602 return(-1);
4603 }
4604
4605
4606 /* If field names are desired then "clear" name buffer */
4607 /* --------------------------------------------------- */
4608 if (fieldlist != NULL)
4609 {
4610 fieldlist[0] = 0;
4611 }
4612
4613
4614 /* Begin loop through mapping entries in metadata */
4615 /* ---------------------------------------------- */
4616 while (1)
4617 {
4618 /* Search for OBJECT string */
4619 /* ------------------------ */
4620 metaptrs[0] = strstr(metaptrs[0], "\t\tOBJECT=");
4621
4622
4623 /* If found within "Data" Field metadata section .. */
4624 /* ------------------------------------------------ */
4625 if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
4626 {
4627 /* Get Fieldnames (if desired) */
4628 /* --------------------------- */
4629 if (fieldlist != NULL)
4630 {
4631 /* Check 1st for old meta data then new */
4632 /* ------------------------------------ */
4633 EHgetmetavalue(metaptrs, "OBJECT", utlstr);
4634
4635 /*
4636 * If OBJECT value begins with double quote then old
4637 * metadata, field name is OBJECT value. Otherwise
4638 * search for "DataFieldName" string
4639 */
4640
4641 if (utlstr[0] != '"')
4642 {
4643 strcpy(utlstr, "\t\t\t\t");
4644 strcat(utlstr, "DataFieldName");
4645 strcat(utlstr, "=");
4646 metaptrs[0] = strstr(metaptrs[0], utlstr);
4647 EHgetmetavalue(metaptrs, "DataFieldName", utlstr);
4648 }
4649
4650 /* Strip off double quotes */
4651 /* ----------------------- */
4652 REMQUOTE
4653
4654
4655 /* Add to fieldlist */
4656 /* ---------------- */
4657 if (nFld > 0)
4658 {
4659 strcat(fieldlist, ",");
4660 }
4661 strcat(fieldlist, utlstr);
4662
4663 }
4664 /* Get Numbertype */
4665 if (numbertype != NULL)
4666 {
4667 EHgetmetavalue(metaptrs, "DataType", utlstr);
4668 numbertype[nFld] = EHnumstr(utlstr);
4669 }
4670 /*
4671 * Get Rank (if desired) by counting # of dimensions in
4672 * "DimList" string
4673 */
4674 if (rank != NULL)
4675 {
4676 EHgetmetavalue(metaptrs, "DimList", utlstr);
4677 rank[nFld] = EHparsestr(utlstr, ',', ptr, slen);
4678 }
4679 /* Increment number of fields */
4680 nFld++;
4681 }
4682 else
4683 /* No more fields found */
4684 {
4685 break;
4686 }
4687 }
4688 free(metabuf);
4689 }
4690 }
4691
4692 /* Set nFld to -1 if error status exists */
4693 /* ------------------------------------- */
4694 if (status == -1)
4695 {
4696 nFld = -1;
4697 }
4698 free(utlstr);
4699 return (nFld);
4700 }
4701
4702
4703
4704
4705
4706 /*----------------------------------------------------------------------------|
4707 | BEGIN_PROLOG |
4708 | |
4709 | FUNCTION: GDnentries |
4710 | |
4711 | DESCRIPTION: Returns number of entries and descriptive string buffer |
4712 | size for a specified entity. |
4713 | |
4714 | |
4715 | Return Value Type Units Description |
4716 | ============ ====== ========= ===================================== |
4717 | nEntries int32 Number of entries |
4718 | |
4719 | INPUTS: |
4720 | gridID int32 grid structure ID |
4721 | entrycode int32 Entry code |
4722 | HDFE_NENTDIM (0) |
4723 | HDFE_NENTDFLD (4) |
4724 | |
4725 | |
4726 | OUTPUTS: |
4727 | strbufsize int32 Length of comma-separated list |
4728 | (Does not include null-terminator |
4729 | |
4730 | NOTES: |
4731 | |
4732 | |
4733 | Date Programmer Description |
4734 | ====== ============ ================================================= |
4735 | Jun 96 Joel Gales Original Programmer |
4736 | Aug 96 Joel Gales Make metadata ODL compliant |
4737 | Feb 97 Joel Gales Set nEntries to -1 if status = -1 |
4738 | |
4739 | END_PROLOG |
4740 -----------------------------------------------------------------------------*/
4741 int32
GDnentries(int32 gridID,int32 entrycode,int32 * strbufsize)4742 GDnentries(int32 gridID, int32 entrycode, int32 * strbufsize)
4743
4744 {
4745 intn status; /* routine return status variable */
4746 intn i; /* Loop index */
4747
4748 int32 fid; /* HDF-EOS file ID */
4749 int32 sdInterfaceID; /* HDF SDS interface ID */
4750 int32 gdVgrpID; /* Grid root Vgroup ID */
4751 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
4752 int32 nEntries = 0; /* Number of entries */
4753 int32 metaflag; /* Old (0), New (1) metadata flag) */
4754 int32 nVal = 0; /* Number of strings to search for */
4755
4756 char *metabuf = NULL; /* Pointer to structural metadata (SM) */
4757 char *metaptrs[2];/* Pointers to begin and end of SM section */
4758 char gridname[80]; /* Grid Name */
4759 char *utlstr;/* Utility string */
4760 char valName[2][32]; /* Strings to search for */
4761
4762 /* Allocate space for utility string */
4763 /* --------------------------------- */
4764 utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
4765 if(utlstr == NULL)
4766 {
4767 HEpush(DFE_NOSPACE,"GDnentries", __FILE__, __LINE__);
4768 return(-1);
4769 }
4770 status = GDchkgdid(gridID, "GDnentries", &fid, &sdInterfaceID, &gdVgrpID);
4771
4772 if (status == 0)
4773 {
4774 /* Get grid name */
4775 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
4776
4777 /* Zero out string buffer size */
4778 *strbufsize = 0;
4779
4780
4781 /*
4782 * Get pointer to relevant section within SM and Get names of
4783 * metadata strings to inquire about
4784 */
4785 switch (entrycode)
4786 {
4787 case HDFE_NENTDIM:
4788 {
4789 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
4790 "Dimension", metaptrs);
4791 if(metabuf == NULL)
4792 {
4793 free(utlstr);
4794 return(-1);
4795 }
4796
4797 nVal = 1;
4798 strcpy(&valName[0][0], "DimensionName");
4799 }
4800 break;
4801
4802 case HDFE_NENTDFLD:
4803 {
4804 metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
4805 "DataField", metaptrs);
4806 if(metabuf == NULL)
4807 {
4808 free(utlstr);
4809 return(-1);
4810 }
4811
4812 nVal = 1;
4813 strcpy(&valName[0][0], "DataFieldName");
4814 }
4815 break;
4816 }
4817
4818
4819 /*
4820 * Check for presence of 'GROUP="' string If found then old metadata,
4821 * search on OBJECT string
4822 */
4823 metaflag = (strstr(metabuf, "GROUP=\"") == NULL) ? 1 : 0;
4824 if (metaflag == 0)
4825 {
4826 nVal = 1;
4827 strcpy(&valName[0][0], "\t\tOBJECT");
4828 }
4829
4830
4831 /* Begin loop through entries in metadata */
4832 /* -------------------------------------- */
4833 while (1)
4834 {
4835 /* Search for first string */
4836 strcpy(utlstr, &valName[0][0]);
4837 strcat(utlstr, "=");
4838 metaptrs[0] = strstr(metaptrs[0], utlstr);
4839
4840 /* If found within relevant metadata section ... */
4841 if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
4842 {
4843 for (i = 0; i < nVal; i++)
4844 {
4845 /*
4846 * Get all string values Don't count quotes
4847 */
4848 EHgetmetavalue(metaptrs, &valName[i][0], utlstr);
4849 *strbufsize += strlen(utlstr) - 2;
4850 }
4851 /* Increment number of entries */
4852 nEntries++;
4853
4854 /* Go to end of OBJECT */
4855 metaptrs[0] = strstr(metaptrs[0], "END_OBJECT");
4856 }
4857 else
4858 /* No more entries found */
4859 {
4860 break;
4861 }
4862 }
4863 free(metabuf);
4864
4865
4866 /* Count comma separators & slashes (if mappings) */
4867 /* ---------------------------------------------- */
4868 if (nEntries > 0)
4869 {
4870 *strbufsize += nEntries - 1;
4871 *strbufsize += (nVal - 1) * nEntries;
4872 }
4873 }
4874
4875
4876 /* Set nEntries to -1 if error status exists */
4877 /* ----------------------------------------- */
4878 if (status == -1)
4879 {
4880 nEntries = -1;
4881 }
4882
4883 free(utlstr);
4884 return (nEntries);
4885 }
4886
4887
4888
4889
4890
4891 /*----------------------------------------------------------------------------|
4892 | BEGIN_PROLOG |
4893 | |
4894 | FUNCTION: GDinqgrid |
4895 | |
4896 | DESCRIPTION: Returns number and names of grid structures in file |
4897 | |
4898 | |
4899 | Return Value Type Units Description |
4900 | ============ ====== ========= ===================================== |
4901 | nGrid int32 Number of grid structures in file |
4902 | |
4903 | INPUTS: |
4904 | filename char HDF-EOS filename |
4905 | |
4906 | OUTPUTS: |
4907 | gridlist char List of grid names (comma-separated) |
4908 | strbufsize int32 Length of gridlist |
4909 | |
4910 | NOTES: |
4911 | |
4912 | |
4913 | Date Programmer Description |
4914 | ====== ============ ================================================= |
4915 | Jun 96 Joel Gales Original Programmer |
4916 | |
4917 | END_PROLOG |
4918 -----------------------------------------------------------------------------*/
4919 int32
GDinqgrid(char * filename,char * gridlist,int32 * strbufsize)4920 GDinqgrid(char *filename, char *gridlist, int32 * strbufsize)
4921 {
4922 int32 nGrid; /* Number of grid structures in file */
4923
4924 /* Call "EHinquire" routine */
4925 /* ------------------------ */
4926 nGrid = EHinquire(filename, "GRID", gridlist, strbufsize);
4927
4928 return (nGrid);
4929 }
4930
4931
4932 /*----------------------------------------------------------------------------|
4933 | BEGIN_PROLOG |
4934 | |
4935 | FUNCTION: GDsetfillvalue |
4936 | |
4937 | DESCRIPTION: Sets fill value for the specified field. |
4938 | |
4939 | |
4940 | Return Value Type Units Description |
4941 | ============ ====== ========= ===================================== |
4942 | status intn return status (0) SUCCEED, (-1) FAIL |
4943 | |
4944 | INPUTS: |
4945 | gridID int32 grid structure ID |
4946 | fieldname char field name |
4947 | fillval void fill value |
4948 | |
4949 | OUTPUTS: |
4950 | None |
4951 | |
4952 | NOTES: |
4953 | |
4954 | |
4955 | Date Programmer Description |
4956 | ====== ============ ================================================= |
4957 | Jun 96 Joel Gales Original Programmer |
4958 | |
4959 | END_PROLOG |
4960 -----------------------------------------------------------------------------*/
4961 intn
GDsetfillvalue(int32 gridID,char * fieldname,VOIDP fillval)4962 GDsetfillvalue(int32 gridID, char *fieldname, VOIDP fillval)
4963 {
4964 intn status; /* routine return status variable */
4965
4966 int32 fid; /* HDF-EOS file ID */
4967 int32 sdInterfaceID; /* HDF SDS interface ID */
4968 int32 gdVgrpID; /* Grid root Vgroup ID */
4969 int32 sdid; /* SDS id */
4970 int32 nt; /* Number type */
4971 int32 dims[8]; /* Dimensions array */
4972 int32 dum; /* Dummy variable */
4973 int32 solo; /* "Solo" (non-merged) field flag */
4974
4975 char name[80]; /* Fill value "attribute" name */
4976
4977 /* Check for valid grid ID and get SDS interface ID */
4978 status = GDchkgdid(gridID, "GDsetfillvalue",
4979 &fid, &sdInterfaceID, &gdVgrpID);
4980
4981 if (status == 0)
4982 {
4983 /* Get field info */
4984 status = GDfieldinfo(gridID, fieldname, &dum, dims, &nt, NULL);
4985
4986 if (status == 0)
4987 {
4988 /* Get SDS ID and solo flag */
4989 status = GDSDfldsrch(gridID, sdInterfaceID, fieldname,
4990 &sdid, &dum, &dum, &dum,
4991 dims, &solo);
4992
4993 /* If unmerged field then call HDF set field routine */
4994 if (solo == 1)
4995 {
4996 status = SDsetfillvalue(sdid, fillval);
4997 }
4998
4999 /*
5000 * Store fill value in attribute. Name is given by fieldname
5001 * prepended with "_FV_"
5002 */
5003 strcpy(name, "_FV_");
5004 strcat(name, fieldname);
5005 status = GDwriteattr(gridID, name, nt, 1, fillval);
5006
5007
5008 }
5009 else
5010 {
5011 HEpush(DFE_GENAPP, "GDsetfillvalue", __FILE__, __LINE__);
5012 HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
5013 }
5014 }
5015 return (status);
5016 }
5017
5018
5019
5020
5021
5022
5023
5024 /*----------------------------------------------------------------------------|
5025 | BEGIN_PROLOG |
5026 | |
5027 | FUNCTION: GDgetfillvalue |
5028 | |
5029 | DESCRIPTION: Retrieves fill value for a specified field. |
5030 | |
5031 | |
5032 | Return Value Type Units Description |
5033 | ============ ====== ========= ===================================== |
5034 | status intn return status (0) SUCCEED, (-1) FAIL |
5035 | |
5036 | INPUTS: |
5037 | gridID int32 grid structure ID |
5038 | fieldname char field name |
5039 | |
5040 | OUTPUTS: |
5041 | fillval void fill value |
5042 | |
5043 | NOTES: |
5044 | |
5045 | |
5046 | Date Programmer Description |
5047 | ====== ============ ================================================= |
5048 | Jun 96 Joel Gales Original Programmer |
5049 | |
5050 | END_PROLOG |
5051 -----------------------------------------------------------------------------*/
5052 intn
GDgetfillvalue(int32 gridID,char * fieldname,VOIDP fillval)5053 GDgetfillvalue(int32 gridID, char *fieldname, VOIDP fillval)
5054 {
5055 intn status; /* routine return status variable */
5056
5057 int32 nt; /* Number type */
5058 int32 dims[8]; /* Dimensions array */
5059 int32 dum; /* Dummy variable */
5060
5061 char name[80]; /* Fill value "attribute" name */
5062
5063 status = GDchkgdid(gridID, "GDgetfillvalue", &dum, &dum, &dum);
5064
5065 /* Check for valid grid ID */
5066 if (status == 0)
5067 {
5068 /* Get field info */
5069 status = GDfieldinfo(gridID, fieldname, &dum, dims, &nt, NULL);
5070
5071 if (status == 0)
5072 {
5073 /* Read fill value attribute */
5074 strcpy(name, "_FV_");
5075 strcat(name, fieldname);
5076 status = GDreadattr(gridID, name, fillval);
5077 }
5078 else
5079 {
5080 HEpush(DFE_GENAPP, "GDgetfillvalue", __FILE__, __LINE__);
5081 HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
5082 }
5083
5084 }
5085 return (status);
5086 }
5087
5088
5089
5090
5091
5092 /*----------------------------------------------------------------------------|
5093 | BEGIN_PROLOG |
5094 | |
5095 | FUNCTION: GDdetach |
5096 | |
5097 | DESCRIPTION: Detaches from grid interface and performs file housekeeping. |
5098 | |
5099 | |
5100 | Return Value Type Units Description |
5101 | ============ ====== ========= ===================================== |
5102 | status intn return status (0) SUCCEED, (-1) FAIL |
5103 | |
5104 | INPUTS: |
5105 | gridID int32 grid structure ID |
5106 | |
5107 | |
5108 | OUTPUTS: |
5109 | None |
5110 | |
5111 | NOTES: |
5112 | |
5113 | |
5114 | Date Programmer Description |
5115 | ====== ============ ================================================= |
5116 | Jun 96 Joel Gales Original Programmer |
5117 | Sep 96 Joel Gales Setup dim names for SDsetdimname in dimbuf1 rather |
5118 | that utlstr |
5119 | Oct 96 Joel Gales Detach Grid Vgroups |
5120 | Oct 96 Joel Gales "Detach" from SDS |
5121 | Nov 96 Joel Gales Call GDchkgdid to check for proper grid ID |
5122 | Dec 96 Joel Gales Add multiple vertical subsetting garbage collection |
5123 | Oct 98 Abe Taaheri Added GDXRegion[k]->DimNamePtr[i] =0; after freeing |
5124 | memory |
5125 | Sep 99 Abe Taaheri Changed memcpy to memmove because of overlapping |
5126 | source and destination for GDXSDcomb, nameptr, and |
5127 | dimptr. memcpy may cause unexpected results. |
5128 | |
5129 | END_PROLOG |
5130 -----------------------------------------------------------------------------*/
5131 intn
GDdetach(int32 gridID)5132 GDdetach(int32 gridID)
5133
5134 {
5135 intn i; /* Loop index */
5136 intn j; /* Loop index */
5137 intn k; /* Loop index */
5138 intn status = 0; /* routine return status variable */
5139 intn statusFill = 0; /* return status from GDgetfillvalue */
5140
5141 int32 *namelen; /* Pointer to name string length array */
5142 int32 *dimlen; /* Pointer to dim string length array */
5143 int32 slen1[3]; /* String length array 1 */
5144 int32 slen2[3]; /* String length array 2 */
5145 int32 nflds; /* Number of fields */
5146 int32 match[5]; /* Merged field match array */
5147 int32 cmbfldcnt; /* Number of fields combined */
5148 int32 sdid; /* SDS ID */
5149 int32 vgid; /* Vgroup ID */
5150 int32 dims[3]; /* Dimension array */
5151 int32 *offset; /* Pointer to merged field offset array */
5152 int32 *indvdims; /* Pointer to merged field size array */
5153 int32 sdInterfaceID; /* SDS interface ID */
5154 int32 gID; /* Grid ID - offset */
5155 int32 nflds0; /* Number of fields */
5156 int32 *namelen0; /* Pointer to name string length array */
5157 int32 rank; /* Rank of merged field */
5158 int32 truerank; /* True rank of merged field */
5159 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
5160 int32 dum; /* Dummy variable */
5161
5162 char *nambuf; /* Pointer to name buffer */
5163 char **nameptr; /* Pointer to name string pointer array */
5164 char **dimptr; /* Pointer to dim string pointer array */
5165 char **nameptr0; /* Pointer to name string pointer array */
5166 char *ptr1[3]; /* String pointer array */
5167 char *ptr2[3]; /* String pointer array */
5168 char dimbuf1[128]; /* Dimension buffer 1 */
5169 char dimbuf2[128]; /* Dimension buffer 2 */
5170 char gridname[VGNAMELENMAX + 1]; /* Grid name */
5171 char *utlbuf; /* Utility buffer */
5172 char fillval[32];/* Fill value buffer */
5173
5174
5175
5176 status = GDchkgdid(gridID, "GDdetach", &dum, &sdInterfaceID, &dum);
5177
5178 if (status == 0)
5179 {
5180 gID = gridID % idOffset;
5181 Vgetname(GDXGrid[gID].IDTable, gridname);
5182
5183 /* SDS combined fields */
5184 /* ------------------- */
5185 if (strlen(GDXSDname) == 0)
5186 {
5187 nflds = 0;
5188
5189 /* Allocate "dummy" arrays so free() doesn't bomb later */
5190 /* ---------------------------------------------------- */
5191 nameptr = (char **) calloc(1, sizeof(char *));
5192 if(nameptr == NULL)
5193 {
5194 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5195 return(-1);
5196 }
5197 namelen = (int32 *) calloc(1, sizeof(int32));
5198 if(namelen == NULL)
5199 {
5200 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5201 free(nameptr);
5202 return(-1);
5203 }
5204 nameptr0 = (char **) calloc(1, sizeof(char *));
5205 if(nameptr0 == NULL)
5206 {
5207 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5208 free(nameptr);
5209 free(namelen);
5210 return(-1);
5211 }
5212 namelen0 = (int32 *) calloc(1, sizeof(int32));
5213 if(namelen0 == NULL)
5214 {
5215 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5216 free(nameptr);
5217 free(namelen);
5218 free(nameptr0);
5219 return(-1);
5220 }
5221 dimptr = (char **) calloc(1, sizeof(char *));
5222 if(dimptr == NULL)
5223 {
5224 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5225 free(nameptr);
5226 free(namelen);
5227 free(nameptr0);
5228 free(namelen0);
5229 return(-1);
5230 }
5231 dimlen = (int32 *) calloc(1, sizeof(int32));
5232 if(dimlen == NULL)
5233 {
5234 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5235 free(nameptr);
5236 free(namelen);
5237 free(nameptr0);
5238 free(namelen0);
5239 free(dimptr);
5240 return(-1);
5241 }
5242 offset = (int32 *) calloc(1, sizeof(int32));
5243 if(offset == NULL)
5244 {
5245 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5246 free(nameptr);
5247 free(namelen);
5248 free(nameptr0);
5249 free(namelen0);
5250 free(dimptr);
5251 free(dimlen);
5252 return(-1);
5253 }
5254 indvdims = (int32 *) calloc(1, sizeof(int32));
5255 if(indvdims == NULL)
5256 {
5257 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5258 free(nameptr);
5259 free(namelen);
5260 free(nameptr0);
5261 free(namelen0);
5262 free(dimptr);
5263 free(dimlen);
5264 free(offset);
5265 return(-1);
5266 }
5267 }
5268 else
5269 {
5270 /*
5271 * "Trim Off" trailing "," and ";" in GDXSDname & GDXSDdims
5272 * respectively
5273 */
5274 GDXSDname[strlen(GDXSDname) - 1] = 0;
5275 GDXSDdims[strlen(GDXSDdims) - 1] = 0;
5276
5277
5278 /* Get number of fields from GDXSDname string */
5279 /* ------------------------------------------ */
5280 nflds = EHparsestr(GDXSDname, ',', NULL, NULL);
5281
5282 /* Allocate space for various dynamic arrays */
5283 /* ----------------------------------------- */
5284 nameptr = (char **) calloc(nflds, sizeof(char *));
5285 if(nameptr == NULL)
5286 {
5287 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5288 return(-1);
5289 }
5290 namelen = (int32 *) calloc(nflds, sizeof(int32));
5291 if(namelen == NULL)
5292 {
5293 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5294 free(nameptr);
5295 return(-1);
5296 }
5297 nameptr0 = (char **) calloc(nflds, sizeof(char *));
5298 if(nameptr0 == NULL)
5299 {
5300 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5301 free(nameptr);
5302 free(namelen);
5303 return(-1);
5304 }
5305 namelen0 = (int32 *) calloc(nflds, sizeof(int32));
5306 if(namelen0 == NULL)
5307 {
5308 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5309 free(nameptr);
5310 free(namelen);
5311 free(nameptr0);
5312 return(-1);
5313 }
5314 dimptr = (char **) calloc(nflds, sizeof(char *));
5315 if(dimptr == NULL)
5316 {
5317 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5318 free(nameptr);
5319 free(namelen);
5320 free(nameptr0);
5321 free(namelen0);
5322 return(-1);
5323 }
5324 dimlen = (int32 *) calloc(nflds, sizeof(int32));
5325 if(dimlen == NULL)
5326 {
5327 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5328 free(nameptr);
5329 free(namelen);
5330 free(nameptr0);
5331 free(namelen0);
5332 free(dimptr);
5333 return(-1);
5334 }
5335 offset = (int32 *) calloc(nflds, sizeof(int32));
5336 if(offset == NULL)
5337 {
5338 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5339 free(nameptr);
5340 free(namelen);
5341 free(nameptr0);
5342 free(namelen0);
5343 free(dimptr);
5344 free(dimlen);
5345 return(-1);
5346 }
5347 indvdims = (int32 *) calloc(nflds, sizeof(int32));
5348 if(indvdims == NULL)
5349 {
5350 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5351 free(nameptr);
5352 free(namelen);
5353 free(nameptr0);
5354 free(namelen0);
5355 free(dimptr);
5356 free(dimlen);
5357 free(offset);
5358 return(-1);
5359 }
5360
5361 /* Parse GDXSDname and GDXSDdims strings */
5362 /* ------------------------------------- */
5363 nflds = EHparsestr(GDXSDname, ',', nameptr, namelen);
5364 nflds = EHparsestr(GDXSDdims, ';', dimptr, dimlen);
5365 }
5366
5367
5368 for (i = 0; i < nflds; i++)
5369 {
5370 if (GDXSDcomb[5 * i] != 0 &&
5371 GDXSDcomb[5 * i + 3] == GDXGrid[gID].IDTable)
5372 {
5373 nambuf = (char *) calloc(strlen(GDXSDname) + 1, 1);
5374 if(nambuf == NULL)
5375 {
5376 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5377 free(nameptr);
5378 free(namelen);
5379 free(nameptr0);
5380 free(namelen0);
5381 free(dimptr);
5382 free(dimlen);
5383 free(offset);
5384 return(-1);
5385 }
5386 utlbuf = (char *) calloc(strlen(GDXSDname) * 2 + 7, 1);
5387 if(utlbuf == NULL)
5388 {
5389 HEpush(DFE_NOSPACE,"GDdetach", __FILE__, __LINE__);
5390 free(nambuf);
5391 free(nameptr);
5392 free(namelen);
5393 free(nameptr0);
5394 free(namelen0);
5395 free(dimptr);
5396 free(dimlen);
5397 free(offset);
5398 return(-1);
5399 }
5400
5401 for (k = 0; k < sizeof(dimbuf1); k++)
5402 dimbuf1[k] = 0;
5403
5404
5405 /* Load array to match, name & parse dims */
5406 /* -------------------------------------- */
5407 memcpy(match, &GDXSDcomb[5 * i], 20);
5408 memcpy(nambuf, nameptr[i], namelen[i]);
5409
5410 memcpy(dimbuf1, dimptr[i], dimlen[i]);
5411 dum = EHparsestr(dimbuf1, ',', ptr1, slen1);
5412
5413
5414 /* Separate combined dimension from others */
5415 /* --------------------------------------- */
5416 dimbuf1[slen1[0]] = 0;
5417
5418 offset[0] = 0;
5419 indvdims[0] = abs(match[0]);
5420
5421 for (j = i + 1, cmbfldcnt = 0; j < nflds; j++)
5422 {
5423 for (k = 0; k < sizeof(dimbuf2); k++)
5424 dimbuf2[k] = 0;
5425 memcpy(dimbuf2, dimptr[j], dimlen[j]);
5426 dum = EHparsestr(dimbuf2, ',', ptr2, slen2);
5427 dimbuf2[slen2[0]] = 0;
5428
5429
5430 if (GDXSDcomb[5 * j] != 0 &&
5431 strcmp(dimbuf1 + slen1[0],
5432 dimbuf2 + slen2[0]) == 0 &&
5433 match[1] == GDXSDcomb[5 * j + 1] &&
5434 match[2] == GDXSDcomb[5 * j + 2] &&
5435 match[3] == GDXSDcomb[5 * j + 3] &&
5436 match[4] == GDXSDcomb[5 * j + 4])
5437 {
5438 /* Add to combined dimension size */
5439 match[0] += GDXSDcomb[5 * j];
5440
5441 /* Concatanate name */
5442 strcat(nambuf, ",");
5443 memcpy(nambuf + strlen(nambuf),
5444 nameptr[j], namelen[j]);
5445
5446 /* Store individual dims and dim offsets */
5447 cmbfldcnt++;
5448 indvdims[cmbfldcnt] = abs(GDXSDcomb[5 * j]);
5449 offset[cmbfldcnt] =
5450 offset[cmbfldcnt - 1] + indvdims[cmbfldcnt - 1];
5451
5452 GDXSDcomb[5 * j] = 0;
5453 }
5454 }
5455
5456
5457 /* Create SDS */
5458 /* ---------- */
5459 nflds0 = EHparsestr(nambuf, ',', nameptr0, namelen0);
5460
5461 if (abs(match[0]) == 1)
5462 {
5463 for (k = 0; k < 2; k++)
5464 dims[k] = abs(match[k + 1]);
5465
5466 rank = 2;
5467
5468 sdid = SDcreate(sdInterfaceID, nambuf,
5469 GDXSDcomb[5 * i + 4], 2, dims);
5470 }
5471 else
5472 {
5473 for (k = 0; k < 3; k++)
5474 dims[k] = abs(match[k]);
5475
5476 rank = 3;
5477
5478 if (cmbfldcnt > 0)
5479 {
5480 strcpy(utlbuf, "MRGFLD_");
5481 memcpy(utlbuf + 7, nameptr0[0], namelen0[0]);
5482 utlbuf[7 + namelen0[0]] = 0;
5483 strcat(utlbuf, ":");
5484 strcat(utlbuf, nambuf);
5485
5486 status = EHinsertmeta(sdInterfaceID, gridname, "g",
5487 6L, utlbuf, NULL);
5488 }
5489 else
5490 {
5491 strcpy(utlbuf, nambuf);
5492 }
5493
5494 sdid = SDcreate(sdInterfaceID, utlbuf,
5495 GDXSDcomb[5 * i + 4], 3, dims);
5496
5497
5498 if (cmbfldcnt > 0)
5499 {
5500 SDsetattr(sdid, "Field Dims", DFNT_INT32,
5501 cmbfldcnt + 1, (VOIDP) indvdims);
5502
5503 SDsetattr(sdid, "Field Offsets", DFNT_INT32,
5504 cmbfldcnt + 1, (VOIDP) offset);
5505 }
5506
5507 }
5508
5509
5510
5511 /* Register Dimensions in SDS */
5512 /* -------------------------- */
5513 for (k = 0; k < rank; k++)
5514 {
5515 if (rank == 2)
5516 {
5517 memcpy(dimbuf2, ptr1[k + 1], slen1[k + 1]);
5518 dimbuf2[slen1[k + 1]] = 0;
5519 }
5520 else
5521 {
5522 memcpy(dimbuf2, ptr1[k], slen1[k]);
5523 dimbuf2[slen1[k]] = 0;
5524 }
5525
5526
5527 if (k == 0 && rank > 2 && cmbfldcnt > 0)
5528 {
5529 sprintf(dimbuf2, "%s%s_%d", "MRGDIM:",
5530 gridname, (int)dims[0]);
5531 }
5532 else
5533 {
5534 strcat(dimbuf2, ":");
5535 strcat(dimbuf2, gridname);
5536 }
5537 SDsetdimname(SDgetdimid(sdid, k), (char *) dimbuf2);
5538 }
5539
5540
5541
5542 /* Write Fill Value */
5543 /* ---------------- */
5544 for (k = 0; k < nflds0; k++)
5545 {
5546 memcpy(utlbuf, nameptr0[k], namelen0[k]);
5547 utlbuf[namelen[k]] = 0;
5548 statusFill = GDgetfillvalue(gridID, utlbuf, fillval);
5549
5550 if (statusFill == 0)
5551 {
5552 if (cmbfldcnt > 0)
5553 {
5554 dims[0] = indvdims[k];
5555 truerank = (dims[0] == 1) ? 2 : 3;
5556 EHfillfld(sdid, rank, truerank,
5557 DFKNTsize(match[4]), offset[k],
5558 dims, fillval);
5559 }
5560 else
5561 {
5562 status = SDsetfillvalue(sdid, fillval);
5563 }
5564 }
5565 }
5566
5567
5568 vgid = GDXGrid[gID].VIDTable[0];
5569 Vaddtagref(vgid, DFTAG_NDG, SDidtoref(sdid));
5570 SDendaccess(sdid);
5571
5572 free(nambuf);
5573 free(utlbuf);
5574
5575 }
5576 }
5577
5578
5579 for (i = 0; i < nflds; i++)
5580 {
5581 if (GDXSDcomb[5 * i + 3] == GDXGrid[gID].IDTable)
5582 {
5583 if (i == (nflds - 1))
5584 {
5585 GDXSDcomb[5 * i] = 0;
5586 *(nameptr[i] - (nflds != 1)) = 0;
5587 *(dimptr[i] - (nflds != 1)) = 0;
5588 }
5589 else
5590 {
5591 /* memcpy(&GDXSDcomb[5 * i],
5592 &GDXSDcomb[5 * (i + 1)],
5593 (512 - i - 1) * 5 * 4);*/
5594 memmove(&GDXSDcomb[5 * i],
5595 &GDXSDcomb[5 * (i + 1)],
5596 (512 - i - 1) * 5 * 4);
5597 /* memcpy(nameptr[i],
5598 nameptr[i + 1],
5599 nameptr[0] + 2048 - nameptr[i + 1] - 1);*/
5600 memmove(nameptr[i],
5601 nameptr[i + 1],
5602 nameptr[0] + 2048 - nameptr[i + 1] - 1);
5603 /* memcpy(dimptr[i],
5604 dimptr[i + 1],
5605 dimptr[0] + 2048 * 2 - dimptr[i + 1] - 1);*/
5606 memmove(dimptr[i],
5607 dimptr[i + 1],
5608 dimptr[0] + 2048 * 2 - dimptr[i + 1] - 1);
5609 }
5610
5611 i--;
5612 nflds = EHparsestr(GDXSDname, ',', nameptr, namelen);
5613 nflds = EHparsestr(GDXSDdims, ';', dimptr, dimlen);
5614 }
5615 }
5616
5617 if (nflds != 0)
5618 {
5619 strcat(GDXSDname, ",");
5620 strcat(GDXSDdims, ";");
5621 }
5622
5623
5624
5625 /* Free up a bunch of dynamically allocated arrays */
5626 /* ----------------------------------------------- */
5627 free(nameptr);
5628 free(namelen);
5629 free(nameptr0);
5630 free(namelen0);
5631 free(dimptr);
5632 free(dimlen);
5633 free(offset);
5634 free(indvdims);
5635
5636
5637
5638 /* "Detach" from previously attached SDSs */
5639 /* -------------------------------------- */
5640 for (k = 0; k < GDXGrid[gID].nSDS; k++)
5641 {
5642 SDendaccess(GDXGrid[gID].sdsID[k]);
5643 }
5644 free(GDXGrid[gID].sdsID);
5645 GDXGrid[gID].sdsID = 0;
5646 GDXGrid[gID].nSDS = 0;
5647
5648
5649
5650 /* Detach Grid Vgroups */
5651 /* ------------------- */
5652 Vdetach(GDXGrid[gID].VIDTable[0]);
5653 Vdetach(GDXGrid[gID].VIDTable[1]);
5654 Vdetach(GDXGrid[gID].IDTable);
5655
5656 GDXGrid[gID].active = 0;
5657 GDXGrid[gID].VIDTable[0] = 0;
5658 GDXGrid[gID].VIDTable[1] = 0;
5659 GDXGrid[gID].IDTable = 0;
5660 GDXGrid[gID].fid = 0;
5661
5662
5663
5664
5665 /* Free Region Pointers */
5666 /* -------------------- */
5667 for (k = 0; k < NGRIDREGN; k++)
5668 {
5669 if (GDXRegion[k] != 0 &&
5670 GDXRegion[k]->gridID == gridID)
5671 {
5672 for (i = 0; i < 8; i++)
5673 {
5674 if (GDXRegion[k]->DimNamePtr[i] != 0)
5675 {
5676 free(GDXRegion[k]->DimNamePtr[i]);
5677 GDXRegion[k]->DimNamePtr[i] = 0;
5678 }
5679 }
5680
5681 free(GDXRegion[k]);
5682 GDXRegion[k] = 0;
5683 }
5684 }
5685 }
5686 return (status);
5687 }
5688
5689
5690 /*----------------------------------------------------------------------------|
5691 | BEGIN_PROLOG |
5692 | |
5693 | FUNCTION: GDclose |
5694 | |
5695 | DESCRIPTION: Closes file. |
5696 | |
5697 | |
5698 | Return Value Type Units Description |
5699 | ============ ====== ========= ===================================== |
5700 | status intn return status (0) SUCCEED, (-1) FAIL |
5701 | |
5702 | INPUTS: |
5703 | fid int32 File ID |
5704 | |
5705 | |
5706 | OUTPUTS: |
5707 | None |
5708 | |
5709 | NOTES: |
5710 | |
5711 | |
5712 | Date Programmer Description |
5713 | ====== ============ ================================================= |
5714 | Jun 96 Joel Gales Original Programmer |
5715 | |
5716 | END_PROLOG |
5717 -----------------------------------------------------------------------------*/
5718 intn
GDclose(int32 fid)5719 GDclose(int32 fid)
5720
5721 {
5722 intn status = 0; /* routine return status variable */
5723
5724 /* Call EHclose to perform file close */
5725 /* ---------------------------------- */
5726 status = EHclose(fid);
5727
5728 return (status);
5729 }
5730
5731
5732 /*----------------------------------------------------------------------------|
5733 | BEGIN_PROLOG |
5734 | |
5735 | FUNCTION: GDgetdefaults |
5736 | |
5737 | DESCRIPTION: |
5738 | |
5739 | |
5740 | Return Value Type Units Description |
5741 | ============ ====== ========= ===================================== |
5742 | status intn return status (0) SUCCEED, (-1) FAIL |
5743 | |
5744 | INPUTS: |
5745 | projcode int32 GCTP projection code |
5746 | zonecode int32 UTM zone code |
5747 | projparm float64 Projection parameters |
5748 | spherecode int32 GCTP spheriod code |
5749 | upleftpt float64 upper left corner coordinates |
5750 | lowrightpt float64 lower right corner coordinates |
5751 | |
5752 | |
5753 | OUTPUTS: |
5754 | upleftpt float64 upper left corner coordinates |
5755 | lowrightpt float64 lower right corner coordinates |
5756 | |
5757 | NOTES: |
5758 | |
5759 | |
5760 | Date Programmer Description |
5761 | ====== ============ ================================================= |
5762 | Aug 96 Joel Gales Original Programmer |
5763 | Sep 96 Raj Gejjaga Fixed bugs in Polar Stereographic and Goode | | Homolosine default calculations. |
5764 | Sep 96 Raj Gejjaga Added code to compute default boundary points |
5765 | for Lambert Azimuthal Polar and Equitorial |
5766 | projections. |
5767 | Feb 97 Raj Gejjaga Added code to compute default boundary points |
5768 | for Integerized Sinusoidal Grid. Added error |
5769 | handling code. |
5770 | Jun 00 Abe Taaheri Added support for EASE grid |
5771 | |
5772 | END_PROLOG |
5773 -----------------------------------------------------------------------------*/
5774 static intn
GDgetdefaults(int32 projcode,int32 zonecode,float64 projparm[],int32 spherecode,float64 upleftpt[],float64 lowrightpt[])5775 GDgetdefaults(int32 projcode, int32 zonecode, float64 projparm[],
5776 int32 spherecode, float64 upleftpt[], float64 lowrightpt[])
5777 {
5778 int32 errorcode = 0, status = 0;
5779 int32(*for_trans[100]) ();
5780
5781 float64 lon, lat, plat, x, y;
5782 float64 plon, tlon, llon, rlon, pplon, LLon, LLat, RLon, RLat;
5783
5784
5785 /* invoke GCTP initialization routine */
5786 /* ---------------------------------- */
5787 for_init(projcode, zonecode, projparm, spherecode, NULL, NULL,
5788 &errorcode, for_trans);
5789
5790 /* Report error if any */
5791 /* ------------------- */
5792 if (errorcode != 0)
5793 {
5794 status = -1;
5795 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
5796 HEreport("GCTP Error: %d\n", errorcode);
5797 return (status);
5798 }
5799
5800 /* Compute Default Boundary Points for EASE Grid */
5801 /* Use Global coverage */
5802 /* ------------------------------------------------------ */
5803 if (projcode == GCTP_BCEA &&
5804 upleftpt[0] == 0 && upleftpt[1] == 0 &&
5805 lowrightpt[0] == 0 && lowrightpt[1] == 0)
5806 {
5807 upleftpt[0] = EHconvAng(EASE_GRID_DEFAULT_UPLEFT_LON, HDFE_DEG_DMS);
5808 upleftpt[1] = EHconvAng(EASE_GRID_DEFAULT_UPLEFT_LAT, HDFE_DEG_DMS);
5809 lowrightpt[0] = EHconvAng(EASE_GRID_DEFAULT_LOWRGT_LON, HDFE_DEG_DMS);
5810 lowrightpt[1] = EHconvAng(EASE_GRID_DEFAULT_LOWRGT_LAT, HDFE_DEG_DMS);
5811 }
5812
5813 /* Compute Default Boundary Points for CEA */
5814 /* --------------------------------------------*/
5815 if (projcode == GCTP_CEA &&
5816 upleftpt[0] == 0 && upleftpt[1] == 0 &&
5817 lowrightpt[0] == 0 && lowrightpt[1] == 0)
5818 {
5819 LLon = EHconvAng(EASE_GRID_DEFAULT_UPLEFT_LON, HDFE_DEG_RAD);
5820 LLat = EHconvAng(EASE_GRID_DEFAULT_UPLEFT_LAT, HDFE_DEG_RAD);
5821 RLon = EHconvAng(EASE_GRID_DEFAULT_LOWRGT_LON, HDFE_DEG_RAD);
5822 RLat = EHconvAng(EASE_GRID_DEFAULT_LOWRGT_LAT, HDFE_DEG_RAD);
5823
5824 errorcode = for_trans[projcode] (LLon, LLat, &x, &y);
5825 if (errorcode != 0)
5826 {
5827 status = -1;
5828 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
5829 HEreport("GCTP Error: %d\n", errorcode);
5830 return (status);
5831 }
5832 upleftpt[0] = x;
5833 upleftpt[1] = y;
5834
5835 errorcode = for_trans[projcode] (RLon, RLat, &x, &y);
5836 if (errorcode != 0)
5837 {
5838 status = -1;
5839 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
5840 HEreport("GCTP Error: %d\n", errorcode);
5841 return (status);
5842 }
5843 lowrightpt[0] = x;
5844 lowrightpt[1] = y;
5845
5846 }
5847
5848
5849 /* Compute Default Boundary Points for Polar Sterographic */
5850 /* ------------------------------------------------------ */
5851 if (projcode == GCTP_PS &&
5852 upleftpt[0] == 0 && upleftpt[1] == 0 &&
5853 lowrightpt[0] == 0 && lowrightpt[1] == 0)
5854 {
5855 /*
5856 * Convert the longitude and latitude from the DMS to decimal degree
5857 * format.
5858 */
5859 plon = EHconvAng(projparm[4], HDFE_DMS_DEG);
5860 plat = EHconvAng(projparm[5], HDFE_DMS_DEG);
5861
5862 /*
5863 * Compute the longitudes at 90, 180 and 270 degrees from the central
5864 * longitude.
5865 */
5866
5867 if (plon <= 0.0)
5868 {
5869 tlon = 180.0 + plon;
5870 pplon = plon + 360.0;
5871 }
5872 else
5873 {
5874 tlon = plon - 180.0;
5875 pplon = plon;
5876 }
5877
5878 rlon = pplon + 90.0;
5879 if (rlon > 360.0)
5880 rlon = rlon - 360;
5881
5882 if (rlon > 180.0)
5883 rlon = rlon - 360.0;
5884
5885 if (rlon <= 0.0)
5886 llon = 180.0 + rlon;
5887 else
5888 llon = rlon - 180.0;
5889
5890
5891 /* Convert all four longitudes from decimal degrees to radians */
5892 plon = EHconvAng(plon, HDFE_DEG_RAD);
5893 tlon = EHconvAng(tlon, HDFE_DEG_RAD);
5894 llon = EHconvAng(llon, HDFE_DEG_RAD);
5895 rlon = EHconvAng(rlon, HDFE_DEG_RAD);
5896
5897 errorcode = for_trans[projcode] (llon, 0.0, &x, &y);
5898 if (errorcode != 0)
5899 {
5900 status = -1;
5901 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
5902 HEreport("GCTP Error: %d\n", errorcode);
5903 return (status);
5904 }
5905
5906 upleftpt[0] = x;
5907
5908 errorcode = for_trans[projcode] (rlon, 0.0, &x, &y);
5909 if (errorcode != 0)
5910 {
5911 status = -1;
5912 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
5913 HEreport("GCTP Error: %d\n", errorcode);
5914 return (status);
5915 }
5916
5917 lowrightpt[0] = x;
5918
5919 /*
5920 * Compute the upperleft and lowright y values based on the south or
5921 * north polar projection
5922 */
5923
5924 if (plat < 0.0)
5925 {
5926 errorcode = for_trans[projcode] (plon, 0.0, &x, &y);
5927 if (errorcode != 0)
5928 {
5929 status = -1;
5930 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
5931 HEreport("GCTP Error: %d\n", errorcode);
5932 return (status);
5933 }
5934
5935 upleftpt[1] = y;
5936
5937 errorcode = for_trans[projcode] (tlon, 0.0, &x, &y);
5938 if (errorcode != 0)
5939 {
5940 status = -1;
5941 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
5942 HEreport("GCTP Error: %d\n", errorcode);
5943 return (status);
5944 }
5945
5946 lowrightpt[1] = y;
5947
5948 }
5949 else
5950 {
5951 errorcode = for_trans[projcode] (tlon, 0.0, &x, &y);
5952 if (errorcode != 0)
5953 {
5954 status = -1;
5955 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
5956 HEreport("GCTP Error: %d\n", errorcode);
5957 return (status);
5958 }
5959
5960 upleftpt[1] = y;
5961
5962 errorcode = for_trans[projcode] (plon, 0.0, &x, &y);
5963 if (errorcode != 0)
5964 {
5965 status = -1;
5966 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
5967 HEreport("GCTP Error: %d\n", errorcode);
5968 return (status);
5969 }
5970
5971 lowrightpt[1] = y;
5972
5973 }
5974 }
5975
5976
5977 /* Compute Default Boundary Points for Goode Homolosine */
5978 /* ---------------------------------------------------- */
5979 if (projcode == GCTP_GOOD &&
5980 upleftpt[0] == 0 && upleftpt[1] == 0 &&
5981 lowrightpt[0] == 0 && lowrightpt[1] == 0)
5982 {
5983 lon = EHconvAng(-180, HDFE_DEG_RAD);
5984 lat = 0.0;
5985
5986 errorcode = for_trans[projcode] (lon, lat, &x, &y);
5987 if (errorcode != 0)
5988 {
5989 status = -1;
5990 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
5991 HEreport("GCTP Error: %d\n", errorcode);
5992 return (status);
5993 }
5994
5995 upleftpt[0] = -fabs(x);
5996 lowrightpt[0] = +fabs(x);
5997
5998 lat = EHconvAng(90, HDFE_DEG_RAD);
5999
6000 errorcode = for_trans[projcode] (lon, lat, &x, &y);
6001 if (errorcode != 0)
6002 {
6003 status = -1;
6004 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6005 HEreport("GCTP Error: %d\n", errorcode);
6006 return (status);
6007 }
6008
6009 upleftpt[1] = +fabs(y);
6010 lowrightpt[1] = -fabs(y);
6011 }
6012
6013 /* Compute Default Boundary Points for Lambert Azimuthal */
6014 /* ----------------------------------------------------- */
6015 if (projcode == GCTP_LAMAZ &&
6016 upleftpt[0] == 0 && upleftpt[1] == 0 &&
6017 lowrightpt[0] == 0 && lowrightpt[1] == 0)
6018 {
6019 /*
6020 * Convert the longitude and latitude from the DMS to decimal degree
6021 * format.
6022 */
6023 plon = EHconvAng(projparm[4], HDFE_DMS_DEG);
6024 plat = EHconvAng(projparm[5], HDFE_DMS_DEG);
6025
6026 /*
6027 * Compute the longitudes at 90, 180 and 270 degrees from the central
6028 * longitude.
6029 */
6030
6031 if (plon <= 0.0)
6032 {
6033 tlon = 180.0 + plon;
6034 pplon = plon + 360.0;
6035 }
6036 else
6037 {
6038 tlon = plon - 180.0;
6039 pplon = plon;
6040 }
6041
6042 rlon = pplon + 90.0;
6043 if (rlon > 360.0)
6044 rlon = rlon - 360;
6045
6046 if (rlon > 180.0)
6047 rlon = rlon - 360.0;
6048
6049 if (rlon <= 0.0)
6050 llon = 180.0 + rlon;
6051 else
6052 llon = rlon - 180.0;
6053
6054 /* Convert all four longitudes from decimal degrees to radians */
6055 plon = EHconvAng(plon, HDFE_DEG_RAD);
6056 tlon = EHconvAng(tlon, HDFE_DEG_RAD);
6057 llon = EHconvAng(llon, HDFE_DEG_RAD);
6058 rlon = EHconvAng(rlon, HDFE_DEG_RAD);
6059
6060 errorcode = for_trans[projcode] (llon, 0.0, &x, &y);
6061 if (errorcode != 0)
6062 {
6063 status = -1;
6064 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6065 HEreport("GCTP Error: %d\n", errorcode);
6066 return (status);
6067 }
6068
6069 upleftpt[0] = x;
6070
6071 errorcode = for_trans[projcode] (rlon, 0.0, &x, &y);
6072 if (errorcode != 0)
6073 {
6074 status = -1;
6075 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6076 HEreport("GCTP Error: %d\n", errorcode);
6077 return (status);
6078 }
6079
6080 lowrightpt[0] = x;
6081
6082 /*
6083 * Compute upperleft and lowerright values based on whether the
6084 * projection is south polar, north polar or equitorial
6085 */
6086
6087 if (plat == -90.0)
6088 {
6089 errorcode = for_trans[projcode] (plon, 0.0, &x, &y);
6090 if (errorcode != 0)
6091 {
6092 status = -1;
6093 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6094 HEreport("GCTP Error: %d\n", errorcode);
6095 return (status);
6096 }
6097
6098 upleftpt[1] = y;
6099
6100 errorcode = for_trans[projcode] (tlon, 0.0, &x, &y);
6101 if (errorcode != 0)
6102 {
6103 status = -1;
6104 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6105 HEreport("GCTP Error: %d\n", errorcode);
6106 return (status);
6107 }
6108
6109 lowrightpt[1] = y;
6110 }
6111 else if (plat == 90.0)
6112 {
6113 errorcode = for_trans[projcode] (tlon, 0.0, &x, &y);
6114 if (errorcode != 0)
6115 {
6116 status = -1;
6117 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6118 HEreport("GCTP Error: %d\n", errorcode);
6119 return (status);
6120 }
6121
6122 upleftpt[1] = y;
6123
6124 errorcode = for_trans[projcode] (plon, 0.0, &x, &y);
6125 if (errorcode != 0)
6126 {
6127 status = -1;
6128 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6129 HEreport("GCTP Error: %d\n", errorcode);
6130 return (status);
6131 }
6132
6133 lowrightpt[1] = y;
6134 }
6135 else
6136 {
6137 lat = EHconvAng(90, HDFE_DEG_RAD);
6138 errorcode = for_trans[projcode] (plon, lat, &x, &y);
6139 if (errorcode != 0)
6140 {
6141 status = -1;
6142 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6143 HEreport("GCTP Error: %d\n", errorcode);
6144 return (status);
6145 }
6146
6147 upleftpt[1] = y;
6148
6149 lat = EHconvAng(-90, HDFE_DEG_RAD);
6150 errorcode = for_trans[projcode] (plon, lat, &x, &y);
6151 if (errorcode != 0)
6152 {
6153 status = -1;
6154 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6155 HEreport("GCTP Error: %d\n", errorcode);
6156 return (status);
6157 }
6158
6159 lowrightpt[1] = y;
6160 }
6161 }
6162
6163 /* Compute Default Boundary Points for Integerized Sinusoidal Grid */
6164 /* --------------------------------------------------------------- */
6165 if (((projcode == GCTP_ISINUS) || (projcode == GCTP_ISINUS1)) &&
6166 upleftpt[0] == 0 && upleftpt[1] == 0 &&
6167 lowrightpt[0] == 0 && lowrightpt[1] == 0)
6168 {
6169 /*
6170 * Convert the longitude and latitude from the DMS to decimal degree
6171 * format.
6172 */
6173 plon = EHconvAng(projparm[4], HDFE_DMS_DEG);
6174 plat = EHconvAng(projparm[5], HDFE_DMS_DEG);
6175
6176 /*
6177 * Compute the longitudes at 90, 180 and 270 degrees from the central
6178 * longitude.
6179 */
6180
6181 if (plon <= 0.0)
6182 {
6183 tlon = 180.0 + plon;
6184 pplon = plon + 360.0;
6185 }
6186 else
6187 {
6188 tlon = plon - 180.0;
6189 pplon = plon;
6190 }
6191
6192 rlon = pplon + 90.0;
6193 if (rlon > 360.0)
6194 rlon = rlon - 360;
6195
6196 if (rlon > 180.0)
6197 rlon = rlon - 360.0;
6198
6199 if (rlon <= 0.0)
6200 llon = 180.0 + rlon;
6201 else
6202 llon = rlon - 180.0;
6203
6204 /* Convert all four longitudes from decimal degrees to radians */
6205 plon = EHconvAng(plon, HDFE_DEG_RAD);
6206 tlon = EHconvAng(tlon, HDFE_DEG_RAD);
6207 llon = EHconvAng(llon, HDFE_DEG_RAD);
6208 rlon = EHconvAng(rlon, HDFE_DEG_RAD);
6209
6210 errorcode = for_trans[projcode] (llon, 0.0, &x, &y);
6211 if (errorcode != 0)
6212 {
6213 status = -1;
6214 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6215 HEreport("GCTP Error: %d\n", errorcode);
6216 return (status);
6217 }
6218
6219 upleftpt[0] = x;
6220
6221 errorcode = for_trans[projcode] (rlon, 0.0, &x, &y);
6222 if (errorcode != 0)
6223 {
6224 status = -1;
6225 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6226 HEreport("GCTP Error: %d\n", errorcode);
6227 return (status);
6228 }
6229
6230 lowrightpt[0] = x;
6231
6232 lat = EHconvAng(90, HDFE_DEG_RAD);
6233 errorcode = for_trans[projcode] (plon, lat, &x, &y);
6234 if (errorcode != 0)
6235 {
6236 status = -1;
6237 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6238 HEreport("GCTP Error: %d\n", errorcode);
6239 return (status);
6240 }
6241
6242 upleftpt[1] = y;
6243
6244 lat = EHconvAng(-90, HDFE_DEG_RAD);
6245 errorcode = for_trans[projcode] (plon, lat, &x, &y);
6246 if (errorcode != 0)
6247 {
6248 status = -1;
6249 HEpush(DFE_GENAPP, "GDgetdefaults", __FILE__, __LINE__);
6250 HEreport("GCTP Error: %d\n", errorcode);
6251 return (status);
6252 }
6253
6254 lowrightpt[1] = y;
6255 }
6256 return (errorcode);
6257 }
6258
6259 /*----------------------------------------------------------------------------|
6260 | BEGIN_PROLOG |
6261 | |
6262 | FUNCTION: GDll2ij |
6263 | |
6264 | DESCRIPTION: |
6265 | |
6266 | |
6267 | Return Value Type Units Description |
6268 | ============ ====== ========= ===================================== |
6269 | status intn return status (0) SUCCEED, (-1) FAIL |
6270 | |
6271 | INPUTS: |
6272 | projcode int32 GCTP projection code |
6273 | zonecode int32 UTM zone code |
6274 | projparm float64 Projection parameters |
6275 | spherecode int32 GCTP spheriod code |
6276 | xdimsize int32 xdimsize from GDcreate |
6277 | ydimsize int32 ydimsize from GDcreate |
6278 | upleftpt float64 upper left corner coordinates |
6279 | lowrightpt float64 lower right corner coordinates |
6280 | npnts int32 number of lon-lat points |
6281 | longitude float64 longitude array (radians) |
6282 | latitude float64 latitude array (radians) |
6283 | |
6284 | OUTPUTS: |
6285 | row int32 Row array |
6286 | col int32 Column array |
6287 | xval float64 X value array |
6288 | yval float64 Y value array |
6289 | |
6290 | |
6291 | NOTES: |
6292 | |
6293 | |
6294 | Date Programmer Description |
6295 | ====== ============ ================================================= |
6296 | Jun 96 Joel Gales Original Programmer |
6297 | Aug 96 Joel Gales Return x and y values if requested |
6298 | Jun 00 Abe Taaheri Added support for EASE grid |
6299 | |
6300 | END_PROLOG |
6301 -----------------------------------------------------------------------------*/
6302 static intn
GDll2ij(int32 projcode,int32 zonecode,float64 projparm[],int32 spherecode,int32 xdimsize,int32 ydimsize,float64 upleftpt[],float64 lowrightpt[],int32 npnts,float64 longitude[],float64 latitude[],int32 row[],int32 col[],float64 xval[],float64 yval[])6303 GDll2ij(int32 projcode, int32 zonecode, float64 projparm[],
6304 int32 spherecode, int32 xdimsize, int32 ydimsize,
6305 float64 upleftpt[], float64 lowrightpt[],
6306 int32 npnts, float64 longitude[], float64 latitude[],
6307 int32 row[], int32 col[], float64 xval[], float64 yval[])
6308
6309
6310 {
6311 intn i; /* Loop index */
6312 intn status = 0; /* routine return status variable */
6313
6314 int32 errorcode = 0; /* GCTP error code */
6315 int32(*for_trans[100]) (); /* GCTP function pointer */
6316
6317 float64 xVal; /* Scaled x distance */
6318 float64 yVal; /* Scaled y distance */
6319 float64 xMtr; /* X value in meters from GCTP */
6320 float64 yMtr; /* Y value in meters from GCTP */
6321 float64 lonrad0; /* Longitude in radians of upleft point */
6322 float64 latrad0 = 0; /* Latitude in radians of upleft point */
6323 float64 lonrad; /* Longitude in radians of point */
6324 float64 latrad; /* Latitude in radians of point */
6325 float64 scaleX; /* X scale factor */
6326 float64 scaleY; /* Y scale factor */
6327 float64 EHconvAng();/* Angle conversion routine */
6328 float64 xMtr0, xMtr1, yMtr0, yMtr1;
6329 float64 lonrad1; /* Longitude in radians of lowright point */
6330
6331 /* If projection not GEO call GCTP initialization routine */
6332 /* ------------------------------------------------------ */
6333 if (projcode != GCTP_GEO)
6334 {
6335 for_init(projcode, zonecode, projparm, spherecode, NULL, NULL,
6336 &errorcode, for_trans);
6337
6338 /* Report error if any */
6339 /* ------------------- */
6340 if (errorcode != 0)
6341 {
6342 status = -1;
6343 HEpush(DFE_GENAPP, "GDll2ij", __FILE__, __LINE__);
6344 HEreport("GCTP Error: %d\n", errorcode);
6345 }
6346 }
6347
6348
6349 if (status == 0)
6350 {
6351 /* GEO projection */
6352 /* -------------- */
6353 if (projcode == GCTP_GEO)
6354 {
6355 /* Convert upleft and lowright X coords from DMS to radians */
6356 /* -------------------------------------------------------- */
6357 lonrad0 = EHconvAng(upleftpt[0], HDFE_DMS_RAD);
6358 lonrad = EHconvAng(lowrightpt[0], HDFE_DMS_RAD);
6359
6360 /* Compute x scale factor */
6361 /* ---------------------- */
6362 scaleX = (lonrad - lonrad0) / xdimsize;
6363
6364
6365 /* Convert upleft and lowright Y coords from DMS to radians */
6366 /* -------------------------------------------------------- */
6367 latrad0 = EHconvAng(upleftpt[1], HDFE_DMS_RAD);
6368 latrad = EHconvAng(lowrightpt[1], HDFE_DMS_RAD);
6369
6370
6371 /* Compute y scale factor */
6372 /* ---------------------- */
6373 scaleY = (latrad - latrad0) / ydimsize;
6374 }
6375
6376 /* BCEA projection */
6377 /* -------------- */
6378 else if ( projcode == GCTP_BCEA)
6379 {
6380 /* Convert upleft and lowright X coords from DMS to radians */
6381 /* -------------------------------------------------------- */
6382
6383 lonrad0 = EHconvAng(upleftpt[0], HDFE_DMS_RAD);
6384 lonrad = EHconvAng(lowrightpt[0], HDFE_DMS_RAD);
6385
6386 /* Convert upleft and lowright Y coords from DMS to radians */
6387 /* -------------------------------------------------------- */
6388 latrad0 = EHconvAng(upleftpt[1], HDFE_DMS_RAD);
6389 latrad = EHconvAng(lowrightpt[1], HDFE_DMS_RAD);
6390
6391 /* Convert from lon/lat to meters(or whatever unit is, i.e unit
6392 of r_major and r_minor) using GCTP */
6393 /* ----------------------------------------- */
6394 errorcode = for_trans[projcode] (lonrad0, latrad0, &xMtr0, &yMtr0);
6395
6396
6397 /* Report error if any */
6398 /* ------------------- */
6399 if (errorcode != 0)
6400 {
6401 status = -1;
6402 HEpush(DFE_GENAPP, "GDll2ij", __FILE__, __LINE__);
6403 HEreport("GCTP Error: %d\n", errorcode);
6404 return (status);
6405 }
6406
6407 /* Convert from lon/lat to meters(or whatever unit is, i.e unit
6408 of r_major and r_minor) using GCTP */
6409 /* ----------------------------------------- */
6410 errorcode = for_trans[projcode] (lonrad, latrad, &xMtr1, &yMtr1);
6411
6412
6413 /* Report error if any */
6414 /* ------------------- */
6415 if (errorcode != 0)
6416 {
6417 status = -1;
6418 HEpush(DFE_GENAPP, "GDll2ij", __FILE__, __LINE__);
6419 HEreport("GCTP Error: %d\n", errorcode);
6420 return (status);
6421 }
6422
6423 /* Compute x scale factor */
6424 /* ---------------------- */
6425 scaleX = (xMtr1 - xMtr0) / xdimsize;
6426
6427 /* Compute y scale factor */
6428 /* ---------------------- */
6429 scaleY = (yMtr1 - yMtr0) / ydimsize;
6430 }
6431 else
6432 {
6433 /* Non-GEO, Non_BCEA projections */
6434 /* ---------------------------- */
6435
6436 /* Compute x & y scale factors */
6437 /* --------------------------- */
6438 scaleX = (lowrightpt[0] - upleftpt[0]) / xdimsize;
6439 scaleY = (lowrightpt[1] - upleftpt[1]) / ydimsize;
6440 }
6441
6442
6443
6444 /* Loop through all points */
6445 /* ----------------------- */
6446 for (i = 0; i < npnts; i++)
6447 {
6448 /* Convert lon & lat from decimal degrees to radians */
6449 /* ------------------------------------------------- */
6450 lonrad = EHconvAng(longitude[i], HDFE_DEG_RAD);
6451 latrad = EHconvAng(latitude[i], HDFE_DEG_RAD);
6452
6453
6454 /* GEO projection */
6455 /* -------------- */
6456 if (projcode == GCTP_GEO)
6457 {
6458 /*allow map to span dateline */
6459 lonrad0 = EHconvAng(upleftpt[0], HDFE_DMS_RAD);
6460 lonrad1 = EHconvAng(lowrightpt[0], HDFE_DMS_RAD);
6461 /* if time-line is paased */
6462 if(lonrad < lonrad1)
6463 {
6464 if (lonrad < lonrad0) lonrad += 2.0 * M_PI1;
6465 if (lonrad > lonrad1) lonrad -= 2.0 * M_PI1;
6466 }
6467
6468 /* Compute scaled distance to point from origin */
6469 /* -------------------------------------------- */
6470 xVal = (lonrad - lonrad0) / scaleX;
6471 yVal = (latrad - latrad0) / scaleY;
6472 }
6473 else
6474 {
6475 /* Convert from lon/lat to meters using GCTP */
6476 /* ----------------------------------------- */
6477 errorcode = for_trans[projcode] (lonrad, latrad, &xMtr, &yMtr);
6478
6479
6480 /* Report error if any */
6481 /* ------------------- */
6482 if (errorcode != 0)
6483 {
6484 /*status = -1;
6485 HEpush(DFE_GENAPP, "GDll2ij", __FILE__, __LINE__);
6486 HEreport("GCTP Error: %d\n", errorcode);
6487 return (status); */ /* Bruce Beaumont */
6488 xVal = -2147483648.0; /* Bruce Beaumont */
6489 yVal = -2147483648.0; /* Bruce Beaumont */
6490 }/* (Note: MAXLONG is defined as 2147483647.0 in
6491 function cproj.c of GCTP) */
6492 else {
6493 /* if projection is BCEA normalize x and y by cell size and
6494 measure it from the uperleft corner of the grid */
6495
6496 /* Compute scaled distance to point from origin */
6497 /* -------------------------------------------- */
6498 if( projcode == GCTP_BCEA)
6499 {
6500 xVal = (xMtr - xMtr0) / scaleX;
6501 yVal = (yMtr - yMtr0) / scaleY;
6502 }
6503 else
6504 {
6505 xVal = (xMtr - upleftpt[0]) / scaleX;
6506 yVal = (yMtr - upleftpt[1]) / scaleY;
6507 }
6508 }
6509 }
6510
6511
6512 /* Compute row and col from scaled distance */
6513 /* ---------------------------------------- */
6514 col[i] = (int32) xVal;
6515 row[i] = (int32) yVal;
6516
6517 /* Store scaled distances if requested */
6518 /* ----------------------------------- */
6519 if (xval != NULL)
6520 {
6521 xval[i] = xVal;
6522 }
6523
6524 if (yval != NULL)
6525 {
6526 yval[i] = yVal;
6527 }
6528 }
6529 }
6530 return (status);
6531 }
6532
6533
6534
6535
6536 /*----------------------------------------------------------------------------|
6537 | BEGIN_PROLOG |
6538 | |
6539 | FUNCTION: GDrs2ll |
6540 | |
6541 | DESCRIPTION: Converts EASE grid's (r,s) coordinates to longitude and |
6542 | latritude (in decimal degrees). |
6543 | |
6544 | |
6545 | Return Value Type Units Description |
6546 | ============ ====== ========= ===================================== |
6547 | status intn return status (0) SUCCEED, (-1) FAIL |
6548 | |
6549 | INPUTS: |
6550 | projcode int32 GCTP projection code |
6551 | projparm float64 Projection parameters |
6552 | xdimsize int32 xdimsize from GDcreate |
6553 | ydimsize int32 ydimsize from GDcreate |
6554 | pixcen int32 pixel center code |
6555 | npnts int32 number of lon-lat points |
6556 | s int32 s coordinate |
6557 | r int32 r coordinate |
6558 | pixcen int32 Code from GDpixreginfo |
6559 | pixcnr int32 Code from GDorigininfo |
6560 | upleft float64 upper left corner coordinates (DMS) |
6561 | lowright float64 lower right corner coordinates (DMS) |
6562 | |
6563 | |
6564 | OUTPUTS: |
6565 | longitude float64 longitude array (decimal degrees) |
6566 | latitude float64 latitude array (decimal degrees) |
6567 | |
6568 | NOTES: |
6569 | |
6570 | |
6571 | Date Programmer Description |
6572 | ====== ============ ================================================= |
6573 | Jul 00 Abe Taaheri Original Programmer |
6574 | |
6575 | END_PROLOG |
6576 -----------------------------------------------------------------------------*/
6577 intn
GDrs2ll(int32 projcode,float64 projparm[],int32 xdimsize,int32 ydimsize,float64 upleft[],float64 lowright[],int32 npnts,float64 r[],float64 s[],float64 longitude[],float64 latitude[],int32 pixcen,int32 pixcnr)6578 GDrs2ll(int32 projcode, float64 projparm[],
6579 int32 xdimsize, int32 ydimsize,
6580 float64 upleft[], float64 lowright[],
6581 int32 npnts, float64 r[], float64 s[],
6582 float64 longitude[], float64 latitude[], int32 pixcen, int32 pixcnr)
6583 {
6584 intn i; /* Loop index */
6585 intn status = 0; /* routine return status variable */
6586
6587 int32 errorcode = 0; /* GCTP error code */
6588 int32(*inv_trans[100]) (); /* GCTP function pointer */
6589
6590 float64 pixadjX = 0.0; /* Pixel adjustment (x) */
6591 float64 pixadjY = 0.0; /* Pixel adjustment (y) */
6592 float64 lonrad; /* Longitude in radians of point */
6593 float64 latrad; /* Latitude in radians of point */
6594 float64 EHconvAng(); /* Angle conversion routine */
6595 float64 xMtr; /* X value in meters from GCTP */
6596 float64 yMtr; /* Y value in meters from GCTP */
6597 float64 epsilon;
6598 float64 beta;
6599 float64 qp_cea = 0;
6600 float64 kz_cea = 0;
6601 float64 eccen, eccen_sq;
6602 float64 phi1, sinphi1, cosphi1;
6603 float64 scaleX, scaleY;
6604
6605 int32 zonecode=0;
6606
6607 int32 spherecode=0;
6608 float64 lon[2],lat[2];
6609 float64 xcor[2], ycor[2];
6610 int32 nlatlon;
6611
6612 /* If projection is BCEA define scale, r0 and s0 */
6613 if (projcode == GCTP_BCEA)
6614 {
6615 eccen_sq = 1.0 - SQUARE(projparm[1]/projparm[0]);
6616 eccen = sqrt(eccen_sq);
6617 if(eccen < 0.00001)
6618 {
6619 qp_cea = 2.0;
6620 }
6621 else
6622 {
6623 qp_cea =
6624 (1.0 - eccen_sq)*((1.0/(1.0 - eccen_sq))-(1.0/(2.0*eccen))*
6625 log((1.0 - eccen)/(1.0 + eccen)));
6626 }
6627 phi1 = EHconvAng(projparm[5],HDFE_DMS_RAD);
6628 cosphi1 = cos(phi1);
6629 sinphi1 = sin(phi1);
6630 kz_cea = cosphi1/(sqrt(1.0 - (eccen_sq*sinphi1*sinphi1)));
6631 }
6632
6633
6634
6635
6636 /* Compute adjustment of position within pixel */
6637 /* ------------------------------------------- */
6638 if (pixcen == HDFE_CENTER)
6639 {
6640 /* Pixel defined at center */
6641 /* ----------------------- */
6642 pixadjX = 0.5;
6643 pixadjY = 0.5;
6644 }
6645 else
6646 {
6647 switch (pixcnr)
6648 {
6649 case HDFE_GD_UL:
6650 {
6651 /* Pixel defined at upper left corner */
6652 /* ---------------------------------- */
6653 pixadjX = 0.0;
6654 pixadjY = 0.0;
6655 break;
6656 }
6657
6658 case HDFE_GD_UR:
6659 {
6660 /* Pixel defined at upper right corner */
6661 /* ----------------------------------- */
6662 pixadjX = 1.0;
6663 pixadjY = 0.0;
6664 break;
6665 }
6666
6667 case HDFE_GD_LL:
6668 {
6669 /* Pixel defined at lower left corner */
6670 /* ---------------------------------- */
6671 pixadjX = 0.0;
6672 pixadjY = 1.0;
6673 break;
6674 }
6675
6676 case HDFE_GD_LR:
6677 {
6678 /* Pixel defined at lower right corner */
6679 /* ----------------------------------- */
6680 pixadjX = 1.0;
6681 pixadjY = 1.0;
6682 break;
6683 }
6684
6685 }
6686 }
6687
6688 /* If projection is BCEA call GCTP initialization routine */
6689 /* ------------------------------------------------------ */
6690 if (projcode == GCTP_BCEA)
6691 {
6692
6693 inv_init(projcode, 0, projparm, 0, NULL, NULL,
6694 &errorcode, inv_trans);
6695
6696 /* Report error if any */
6697 /* ------------------- */
6698 if (errorcode != 0)
6699 {
6700 status = -1;
6701 HEpush(DFE_GENAPP, "GDrs2ll", __FILE__, __LINE__);
6702 HEreport("GCTP Error: %d\n", errorcode);
6703 }
6704 else
6705 {
6706 /* For each point ... */
6707 /* ------------------ */
6708 for (i = 0; i < npnts; i++)
6709 {
6710 /* Convert from EASE grid's (r,s) to lon/lat (radians)
6711 using GCTP */
6712 /* --------------------------------------------------- */
6713 nlatlon = 2;
6714 lon[0] = upleft[0];
6715 lon[1] = lowright[0];
6716 lat[0] = upleft[1];
6717 lat[1] = lowright[1];
6718 status =
6719 GDll2mm_cea(projcode,zonecode,spherecode,projparm,
6720 xdimsize, ydimsize,
6721 upleft, lowright, nlatlon,
6722 lon, lat,
6723 xcor, ycor, &scaleX, &scaleY);
6724
6725 if (status == -1)
6726 {
6727 HEpush(DFE_GENAPP, "GDrs2ll", __FILE__, __LINE__);
6728 return (status);
6729 }
6730
6731 xMtr = (r[i]/ scaleX + pixadjX - 0.5)* scaleX;
6732 yMtr = - (s[i]/fabs(scaleY) + pixadjY - 0.5)* fabs(scaleY);
6733
6734
6735 /* allow .5 cell tolerance in arcsin function
6736 (used in bceainv function) so that grid
6737 coordinates which are less than .5 cells
6738 above 90.00N or below 90.00S are given lat of 90.00
6739 */
6740
6741 epsilon = 1 + 0.5 * (fabs(scaleY)/projparm[0]);
6742 beta = 2.0 * (yMtr - projparm[7]) * kz_cea/(projparm[0] * qp_cea);
6743
6744 if( fabs (beta) > epsilon)
6745 {
6746 status = -1;
6747 HEpush(DFE_GENAPP, "GDrs2ll", __FILE__, __LINE__);
6748 HEreport("GCTP Error: %s %s %s\n", "grid coordinates",
6749 "are more than .5 cells",
6750 "above 90.00N or below 90.00S. ");
6751 return (status);
6752 }
6753 else if( beta <= -1)
6754 {
6755 errorcode = inv_trans[projcode] (xMtr, 0.0,
6756 &lonrad, &latrad);
6757 latrad = - M_PI1/2;
6758 }
6759 else if( beta >= 1)
6760 {
6761 errorcode = inv_trans[projcode] (xMtr, 0.0,
6762 &lonrad, &latrad);
6763 latrad = M_PI1/2;
6764 }
6765 else
6766 {
6767 errorcode = inv_trans[projcode] (xMtr, yMtr,
6768 &lonrad, &latrad);
6769 }
6770
6771 /* Report error if any */
6772 /* ------------------- */
6773 if (errorcode != 0)
6774 {
6775 status = -1;
6776 HEpush(DFE_GENAPP, "GDrs2ll", __FILE__, __LINE__);
6777 HEreport("GCTP Error: %d\n", errorcode);
6778 return (status);
6779 }
6780
6781 /* Convert from radians to decimal degrees */
6782 /* --------------------------------------- */
6783 longitude[i] = EHconvAng(lonrad, HDFE_RAD_DEG);
6784 latitude[i] = EHconvAng(latrad, HDFE_RAD_DEG);
6785 }
6786 }
6787 }
6788
6789
6790
6791
6792 return (status);
6793 }
6794
6795
6796
6797 /*----------------------------------------------------------------------------|
6798 | BEGIN_PROLOG |
6799 | |
6800 | FUNCTION: lamaxDxDtheta |
6801 | |
6802 | DESCRIPTION: Partial derivative along longitude line for Lambert Azimuthal |
6803 | |
6804 | |
6805 | Return Value Type Units Description |
6806 | ============ ====== ========= ===================================== |
6807 | float64 Dx/D(theta) for LAMAZ projection |
6808 | |
6809 | INPUTS: |
6810 | parms float64 Parameters defining partial derivative |
6811 | |
6812 | OUTPUTS: |
6813 | None |
6814 | |
6815 | NOTES: |
6816 | |
6817 | |
6818 | Date Programmer Description |
6819 | ====== ============ ================================================= |
6820 | Nov 96 Joel Gales Original Programmer |
6821 | |
6822 | END_PROLOG |
6823 -----------------------------------------------------------------------------*/
6824 float64
lamazDxDtheta(float64 parms[])6825 lamazDxDtheta(float64 parms[])
6826 {
6827 float64 snTheta, sn2Theta, snTheta1, csTheta1, csLamda;
6828
6829 snTheta = sin(EHconvAng(parms[0], HDFE_DEG_RAD));
6830 sn2Theta = sin(2 * EHconvAng(parms[0], HDFE_DEG_RAD));
6831 snTheta1 = sin(EHconvAng(parms[1], HDFE_DEG_RAD));
6832 csTheta1 = cos(EHconvAng(parms[1], HDFE_DEG_RAD));
6833 csLamda = cos(EHconvAng(parms[2], HDFE_DEG_RAD) -
6834 EHconvAng(parms[3], HDFE_DEG_RAD));
6835
6836 return (4 * snTheta +
6837 (csTheta1 * csLamda * sn2Theta) +
6838 (2 * snTheta1 * (1 + (snTheta * snTheta))));
6839 }
6840
6841
6842
6843
6844 /*----------------------------------------------------------------------------|
6845 | BEGIN_PROLOG |
6846 | |
6847 | FUNCTION: lamaxDxDlamda |
6848 | |
6849 | DESCRIPTION: Partial derivative along latitude line for Lambert Azimuthal |
6850 | |
6851 | |
6852 | Return Value Type Units Description |
6853 | ============ ====== ========= ===================================== |
6854 | float64 Dx/D(lamda) for LAMAZ projection |
6855 | |
6856 | INPUTS: |
6857 | parms float64 Parameters defining partial derivative |
6858 | |
6859 | OUTPUTS: |
6860 | None |
6861 | |
6862 | NOTES: |
6863 | |
6864 | |
6865 | Date Programmer Description |
6866 | ====== ============ ================================================= |
6867 | Nov 96 Joel Gales Original Programmer |
6868 | |
6869 | END_PROLOG |
6870 -----------------------------------------------------------------------------*/
6871 float64
lamazDxDlamda(float64 parms[])6872 lamazDxDlamda(float64 parms[])
6873 {
6874 float64 snTheta, csTheta, snTheta1, csTheta1, csLamda;
6875 float64 cs, sn;
6876
6877 snTheta = sin(EHconvAng(parms[2], HDFE_DEG_RAD));
6878 csTheta = cos(EHconvAng(parms[2], HDFE_DEG_RAD));
6879 snTheta1 = sin(EHconvAng(parms[1], HDFE_DEG_RAD));
6880 csTheta1 = cos(EHconvAng(parms[1], HDFE_DEG_RAD));
6881 csLamda = cos(EHconvAng(parms[0], HDFE_DEG_RAD) -
6882 EHconvAng(parms[3], HDFE_DEG_RAD));
6883
6884 cs = csTheta * csTheta1;
6885 sn = snTheta * snTheta1;
6886
6887 return (cs + (2 * (1 + sn) + (cs * csLamda)) * csLamda);
6888 }
6889
6890
6891
6892 /*----------------------------------------------------------------------------|
6893 | BEGIN_PROLOG |
6894 | |
6895 | FUNCTION: lamaxDyDtheta |
6896 | |
6897 | DESCRIPTION: Partial derivative along longitude line for Lambert Azimuthal |
6898 | |
6899 | |
6900 | Return Value Type Units Description |
6901 | ============ ====== ========= ===================================== |
6902 | float64 Dy/D(theta) for LAMAZ projection |
6903 | |
6904 | INPUTS: |
6905 | parms float64 Parameters defining partial derivative |
6906 | |
6907 | OUTPUTS: |
6908 | None |
6909 | |
6910 | NOTES: |
6911 | |
6912 | |
6913 | Date Programmer Description |
6914 | ====== ============ ================================================= |
6915 | Nov 96 Joel Gales Original Programmer |
6916 | |
6917 | END_PROLOG |
6918 -----------------------------------------------------------------------------*/
6919 float64
lamazDyDtheta(float64 parms[])6920 lamazDyDtheta(float64 parms[])
6921 {
6922 float64 snTheta, csTheta, snTheta1, csTheta1, csLamda;
6923 float64 sn2, cs2, sndiff;
6924
6925 snTheta = sin(EHconvAng(parms[0], HDFE_DEG_RAD));
6926 csTheta = cos(EHconvAng(parms[0], HDFE_DEG_RAD));
6927 snTheta1 = sin(EHconvAng(parms[1], HDFE_DEG_RAD));
6928 csTheta1 = cos(EHconvAng(parms[1], HDFE_DEG_RAD));
6929 csLamda = cos(EHconvAng(parms[2], HDFE_DEG_RAD) -
6930 EHconvAng(parms[3], HDFE_DEG_RAD));
6931
6932 sn2 = snTheta1 * snTheta;
6933 cs2 = csTheta1 * csTheta;
6934 sndiff = snTheta1 - snTheta;
6935
6936 return (cs2 * (sn2 * (1 + (csLamda * csLamda)) + 2) +
6937 csLamda * (2 * (1 + sn2 * sn2) - (sndiff * sndiff)));
6938 }
6939
6940
6941
6942 /*----------------------------------------------------------------------------|
6943 | BEGIN_PROLOG |
6944 | |
6945 | FUNCTION: homDyDtheta |
6946 | |
6947 | DESCRIPTION: Partial derivative along longitude line for Oblique Mercator |
6948 | |
6949 | |
6950 | Return Value Type Units Description |
6951 | ============ ====== ========= ===================================== |
6952 | float64 Dx/D(theta) for HOM projection |
6953 | |
6954 | INPUTS: |
6955 | parms float64 Parameters defining partial derivative |
6956 | |
6957 | OUTPUTS: |
6958 | None |
6959 | |
6960 | NOTES: |
6961 | |
6962 | |
6963 | Date Programmer Description |
6964 | ====== ============ ================================================= |
6965 | Mar 97 Joel Gales Original Programmer |
6966 | |
6967 | END_PROLOG |
6968 -----------------------------------------------------------------------------*/
6969 float64
homDyDtheta(float64 parms[])6970 homDyDtheta(float64 parms[])
6971 {
6972 float64 tnTheta, tnTheta1, snLamda;
6973
6974 tnTheta = tan(EHconvAng(parms[0], HDFE_DEG_RAD));
6975 tnTheta1 = tan(EHconvAng(parms[1], HDFE_DEG_RAD));
6976 snLamda = cos(EHconvAng(parms[2], HDFE_DEG_RAD) -
6977 EHconvAng(parms[3], HDFE_DEG_RAD));
6978
6979 return (tnTheta * snLamda + tnTheta1);
6980 }
6981
6982
6983
6984
6985 /*----------------------------------------------------------------------------|
6986 | BEGIN_PROLOG |
6987 | |
6988 | FUNCTION: GDtangentpnts |
6989 | |
6990 | DESCRIPTION: Finds tangent points along lon/lat lines |
6991 | |
6992 | |
6993 | Return Value Type Units Description |
6994 | ============ ====== ========= ===================================== |
6995 | status intn return status (0) SUCCEED, (-1) FAIL |
6996 | |
6997 | INPUTS: |
6998 | projcode int32 Projection code |
6999 | projparm float64 Projection parameters |
7000 | cornerlon float64 dec deg Longitude of opposite corners of box |
7001 | cornerlat float64 dec deg Latitude of opposite corners of box |
7002 | longitude float64 dec deg Longitude of points to check |
7003 | latitude float64 dec deg Latitude of points to check |
7004 | |
7005 | |
7006 | OUTPUTS: |
7007 | npnts int32 Number of points to check in subset |
7008 | |
7009 | NOTES: |
7010 | |
7011 | |
7012 | Date Programmer Description |
7013 | ====== ============ ================================================= |
7014 | Nov 96 Joel Gales Original Programmer |
7015 | Mar 97 Joel Gales Add support for LAMCC, POLYC, TM |
7016 | Aug 99 Abe Taaheri Add support for ALBERS, and MERCAT projections. |
7017 | Also changed misstyped bisectParm[2] to |
7018 | bisectParm[3] for HOM projection. |
7019 | Jun 00 Abe Taaheri Added support for EASE grid |
7020 | |
7021 | END_PROLOG |
7022 -----------------------------------------------------------------------------*/
7023 static intn
GDtangentpnts(int32 projcode,float64 projparm[],float64 cornerlon[],float64 cornerlat[],float64 longitude[],float64 latitude[],int32 * npnts)7024 GDtangentpnts(int32 projcode, float64 projparm[], float64 cornerlon[],
7025 float64 cornerlat[], float64 longitude[], float64 latitude[],
7026 int32 * npnts)
7027 {
7028 intn i; /* Loop index */
7029 intn status = 0; /* routine return status variable */
7030
7031 float64 lonrad; /* Longitude (radians) */
7032 float64 latrad; /* Latitude (radians) */
7033 float64 cs[4]; /* Cosine array */
7034 float64 sn[4]; /* Sine array */
7035 float64 csTest; /* Cosine test value */
7036 float64 snTest; /* Sine test value */
7037 float64 crs01; /* Cross product */
7038 float64 crsTest[2]; /* Cross product array */
7039 float64 longPol; /* Longitude beneath pole */
7040 float64 minLat; /* Minimum latitude */
7041 float64 bisectParm[4]; /* Bisection parameters */
7042 float64 tanLat; /* Tangent latitude */
7043 float64 tanLon; /* Tangent lontitude */
7044 float64 dotPrd; /* Dot product */
7045 float64 centMerd; /* Central Meridian */
7046 float64 orgLat; /* Latitude of origin */
7047 float64 dpi; /* Double precision pi */
7048
7049 float64 lamazDxDtheta(); /* Lambert Azimuthal Dx/Dtheta */
7050 float64 lamazDxDlamda(); /* Lambert Azimuthal Dx/Dlamda */
7051 float64 lamazDyDtheta(); /* Lambert Azimuthal Dy/Dtheta */
7052 float64 homDyDtheta(); /* Oblique Mercator Dy/Dtheta */
7053
7054
7055 /* Conpute pi (double precsion) */
7056 /* ---------------------------- */
7057 dpi = atan(1.0) * 4;
7058
7059
7060 switch (projcode)
7061 {
7062 case GCTP_MERCAT:
7063 {
7064 /* No need for tangent points, since MERCAT projection
7065 is rectangular */
7066 }
7067 break;
7068 case GCTP_BCEA:
7069 {
7070 /* No need for tangent points, since BCEA projection
7071 is rectangular */
7072 }
7073 break;
7074 case GCTP_CEA:
7075 {
7076 /* No need for tangent points, since CEA projection
7077 is rectangular */
7078 }
7079 break;
7080
7081 case GCTP_PS:
7082 {
7083 /* Add "xy axis" points for Polar Stereographic if necessary */
7084 /* --------------------------------------------------------- */
7085
7086
7087 /* Get minimum of corner latitudes */
7088 /* ------------------------------- */
7089 minLat = (fabs(cornerlat[0]) <= fabs(cornerlat[1]))
7090 ? cornerlat[0] : cornerlat[1];
7091
7092
7093 /* Compute sine and cosine of corner longitudes */
7094 /* -------------------------------------------- */
7095 for (i = 0; i < 2; i++)
7096 {
7097 lonrad = EHconvAng(cornerlon[i], HDFE_DEG_RAD);
7098 cs[i] = cos(lonrad);
7099 sn[i] = sin(lonrad);
7100 }
7101
7102
7103 /* Compute cross product */
7104 /* --------------------- */
7105 crs01 = cs[0] * sn[1] - cs[1] * sn[0];
7106
7107
7108 /* Convert longitude beneath pole from DMS to DEG */
7109 /* ---------------------------------------------- */
7110 longPol = EHconvAng(projparm[4], HDFE_DMS_RAD);
7111
7112
7113
7114 for (i = 0; i < 4; i++)
7115 {
7116 csTest = cos(longPol);
7117 snTest = sin(longPol);
7118
7119 crsTest[0] = cs[0] * snTest - csTest * sn[0];
7120 crsTest[1] = cs[1] * snTest - csTest * sn[1];
7121
7122 if ((crs01 > 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
7123 (crs01 < 0 && crsTest[0] < 0 && crsTest[1] < 0) ||
7124 (crs01 < 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
7125 (crs01 < 0 && crsTest[0] > 0 && crsTest[1] > 0))
7126 {
7127 longitude[*npnts] = EHconvAng(longPol, HDFE_RAD_DEG);
7128 latitude[*npnts] = minLat;
7129 (*npnts)++;
7130 }
7131 longPol += 0.5 * dpi;
7132 }
7133 }
7134 break;
7135
7136
7137 case GCTP_LAMAZ:
7138 {
7139 if ((int32) projparm[5] == +90000000 ||
7140 (int32) projparm[5] == -90000000)
7141 {
7142 /* Add "xy axis" points for Polar Lambert Azimuthal */
7143 /* ------------------------------------------------ */
7144 minLat = (fabs(cornerlat[0]) <= fabs(cornerlat[1]))
7145 ? cornerlat[0] : cornerlat[1];
7146
7147 for (i = 0; i < 2; i++)
7148 {
7149 lonrad = EHconvAng(cornerlon[i], HDFE_DEG_RAD);
7150 cs[i] = cos(lonrad);
7151 sn[i] = sin(lonrad);
7152 }
7153 crs01 = cs[0] * sn[1] - cs[1] * sn[0];
7154
7155 longPol = EHconvAng(projparm[4], HDFE_DMS_RAD);
7156 for (i = 0; i < 4; i++)
7157 {
7158 csTest = cos(longPol);
7159 snTest = sin(longPol);
7160
7161 crsTest[0] = cs[0] * snTest - csTest * sn[0];
7162 crsTest[1] = cs[1] * snTest - csTest * sn[1];
7163
7164 if ((crs01 > 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
7165 (crs01 < 0 && crsTest[0] < 0 && crsTest[1] < 0) ||
7166 (crs01 < 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
7167 (crs01 < 0 && crsTest[0] > 0 && crsTest[1] > 0))
7168 {
7169 longitude[*npnts] = EHconvAng(longPol, HDFE_RAD_DEG);
7170 latitude[*npnts] = minLat;
7171 (*npnts)++;
7172 }
7173 longPol += 0.5 * dpi;
7174 }
7175 }
7176 else if ((int32) projparm[5] == 0)
7177 {
7178 /* Add "Equator" points for Equatorial Lambert Azimuthal */
7179 /* ----------------------------------------------------- */
7180 if (cornerlat[0] * cornerlat[1] < 0)
7181 {
7182 longitude[4] = cornerlon[0];
7183 latitude[4] = 0;
7184
7185 longitude[5] = cornerlon[1];
7186 latitude[5] = 0;
7187
7188 *npnts = 6;
7189 }
7190 }
7191 else
7192 {
7193 /* Add tangent points for Oblique Lambert Azimuthal */
7194 /* ------------------------------------------------ */
7195 bisectParm[0] = EHconvAng(projparm[5], HDFE_DMS_DEG);
7196 bisectParm[2] = EHconvAng(projparm[4], HDFE_DMS_DEG);
7197
7198
7199 /* Tangent to y-axis along longitude */
7200 /* --------------------------------- */
7201 for (i = 0; i < 2; i++)
7202 {
7203 bisectParm[1] = cornerlon[i];
7204
7205 if (EHbisect(lamazDxDtheta, bisectParm, 3,
7206 cornerlat[0], cornerlat[1],
7207 0.0001, &tanLat) == 0)
7208 {
7209 longitude[*npnts] = cornerlon[i];
7210 latitude[*npnts] = tanLat;
7211 (*npnts)++;
7212 }
7213 }
7214
7215 /* Tangent to y-axis along latitude */
7216 /* -------------------------------- */
7217 for (i = 0; i < 2; i++)
7218 {
7219 bisectParm[1] = cornerlat[i];
7220
7221 if (EHbisect(lamazDxDlamda, bisectParm, 3,
7222 cornerlon[0], cornerlon[1],
7223 0.0001, &tanLon) == 0)
7224 {
7225 longitude[*npnts] = tanLon;
7226 latitude[*npnts] = cornerlat[i];
7227 (*npnts)++;
7228 }
7229 }
7230
7231
7232 /* Tangent to x-axis along longitude */
7233 /* --------------------------------- */
7234 for (i = 0; i < 2; i++)
7235 {
7236 bisectParm[1] = cornerlon[i];
7237
7238 if (EHbisect(lamazDyDtheta, bisectParm, 3,
7239 cornerlat[0], cornerlat[1],
7240 0.0001, &tanLat) == 0)
7241 {
7242 longitude[*npnts] = cornerlon[i];
7243 latitude[*npnts] = tanLat;
7244 (*npnts)++;
7245 }
7246 }
7247
7248 /* Tangent to x-axis along latitude */
7249 /* -------------------------------- */
7250 for (i = 0; i < 2; i++)
7251 {
7252 lonrad = EHconvAng(cornerlon[i], HDFE_DEG_RAD);
7253 cs[i] = cos(lonrad);
7254 sn[i] = sin(lonrad);
7255 }
7256 crs01 = cs[0] * sn[1] - cs[1] * sn[0];
7257
7258 longPol = EHconvAng(projparm[4], HDFE_DMS_RAD);
7259 for (i = 0; i < 2; i++)
7260 {
7261 csTest = cos(longPol);
7262 snTest = sin(longPol);
7263
7264 crsTest[0] = cs[0] * snTest - csTest * sn[0];
7265 crsTest[1] = cs[1] * snTest - csTest * sn[1];
7266
7267 if ((crs01 > 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
7268 (crs01 < 0 && crsTest[0] < 0 && crsTest[1] < 0) ||
7269 (crs01 < 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
7270 (crs01 < 0 && crsTest[0] > 0 && crsTest[1] > 0))
7271 {
7272 longitude[*npnts] = EHconvAng(longPol, HDFE_RAD_DEG);
7273 latitude[*npnts] = cornerlat[0];
7274 (*npnts)++;
7275 longitude[*npnts] = EHconvAng(longPol, HDFE_RAD_DEG);
7276 latitude[*npnts] = cornerlat[1];
7277 (*npnts)++;
7278 }
7279 longPol += dpi;
7280 }
7281 }
7282 }
7283 break;
7284
7285
7286 case GCTP_GOOD:
7287 {
7288 /* Add "Equator" points for Goode Homolosine if necessary */
7289 /* ------------------------------------------------------ */
7290 if (cornerlat[0] * cornerlat[1] < 0)
7291 {
7292 longitude[4] = cornerlon[0];
7293 latitude[4] = 0;
7294
7295 longitude[5] = cornerlon[1];
7296 latitude[5] = 0;
7297
7298 *npnts = 6;
7299 }
7300 }
7301 break;
7302
7303
7304 case GCTP_LAMCC:
7305 {
7306 /* Compute sine and cosine of corner longitudes */
7307 /* -------------------------------------------- */
7308 for (i = 0; i < 2; i++)
7309 {
7310 lonrad = EHconvAng(cornerlon[i], HDFE_DEG_RAD);
7311 cs[i] = cos(lonrad);
7312 sn[i] = sin(lonrad);
7313 }
7314
7315
7316 /* Compute dot product */
7317 /* ------------------- */
7318 dotPrd = cs[0] * cs[1] + sn[0] * sn[1];
7319
7320
7321 /* Convert central meridian (DMS to DEG) & compute sin & cos */
7322 /* --------------------------------------------------------- */
7323 centMerd = EHconvAng(projparm[4], HDFE_DMS_DEG);
7324 lonrad = EHconvAng(centMerd, HDFE_DEG_RAD);
7325 cs[1] = cos(lonrad);
7326 sn[1] = sin(lonrad);
7327
7328
7329 /* If box brackets central meridian ... */
7330 /* ------------------------------------ */
7331 if (cs[0] * cs[1] + sn[0] * sn[1] > dotPrd)
7332 {
7333 latitude[4] = cornerlat[0];
7334 longitude[4] = centMerd;
7335
7336 latitude[5] = cornerlat[1];
7337 longitude[5] = centMerd;
7338
7339 *npnts = 6;
7340 }
7341 }
7342 break;
7343
7344
7345 case GCTP_ALBERS:
7346 {
7347 /* Compute sine and cosine of corner longitudes */
7348 /* -------------------------------------------- */
7349 for (i = 0; i < 2; i++)
7350 {
7351 lonrad = EHconvAng(cornerlon[i], HDFE_DEG_RAD);
7352 cs[i] = cos(lonrad);
7353 sn[i] = sin(lonrad);
7354 }
7355
7356
7357 /* Compute dot product */
7358 /* ------------------- */
7359 dotPrd = cs[0] * cs[1] + sn[0] * sn[1];
7360
7361
7362 /* Convert central meridian (DMS to DEG) & compute sin & cos */
7363 /* --------------------------------------------------------- */
7364 centMerd = EHconvAng(projparm[4], HDFE_DMS_DEG);
7365 lonrad = EHconvAng(centMerd, HDFE_DEG_RAD);
7366 cs[1] = cos(lonrad);
7367 sn[1] = sin(lonrad);
7368
7369
7370 /* If box brackets central meridian ... */
7371 /* ------------------------------------ */
7372 if (cs[0] * cs[1] + sn[0] * sn[1] > dotPrd)
7373 {
7374 latitude[4] = cornerlat[0];
7375 longitude[4] = centMerd;
7376
7377 latitude[5] = cornerlat[1];
7378 longitude[5] = centMerd;
7379
7380 *npnts = 6;
7381 }
7382 }
7383 break;
7384
7385
7386 case GCTP_POLYC:
7387 {
7388 /* Compute sine and cosine of corner longitudes */
7389 /* -------------------------------------------- */
7390 for (i = 0; i < 2; i++)
7391 {
7392 lonrad = EHconvAng(cornerlon[i], HDFE_DEG_RAD);
7393 cs[i] = cos(lonrad);
7394 sn[i] = sin(lonrad);
7395 }
7396
7397
7398 /* Compute dot product */
7399 /* ------------------- */
7400 dotPrd = cs[0] * cs[1] + sn[0] * sn[1];
7401
7402
7403 /* Convert central meridian (DMS to DEG) & compute sin & cos */
7404 /* --------------------------------------------------------- */
7405 centMerd = EHconvAng(projparm[4], HDFE_DMS_DEG);
7406 lonrad = EHconvAng(centMerd, HDFE_DEG_RAD);
7407 cs[1] = cos(lonrad);
7408 sn[1] = sin(lonrad);
7409
7410
7411 /* If box brackets central meridian ... */
7412 /* ------------------------------------ */
7413 if (cs[0] * cs[1] + sn[0] * sn[1] > dotPrd)
7414 {
7415 latitude[4] = cornerlat[0];
7416 longitude[4] = centMerd;
7417
7418 latitude[5] = cornerlat[1];
7419 longitude[5] = centMerd;
7420
7421 *npnts = 6;
7422 }
7423 }
7424 break;
7425
7426
7427 case GCTP_TM:
7428 {
7429 /* Compute sine and cosine of corner longitudes */
7430 /* -------------------------------------------- */
7431 for (i = 0; i < 2; i++)
7432 {
7433 lonrad = EHconvAng(cornerlon[i], HDFE_DEG_RAD);
7434 cs[i] = cos(lonrad);
7435 sn[i] = sin(lonrad);
7436 }
7437
7438
7439 /* Compute dot product */
7440 /* ------------------- */
7441 dotPrd = cs[0] * cs[1] + sn[0] * sn[1];
7442
7443
7444 for (i = -1; i <= 1; i++)
7445 {
7446 centMerd = EHconvAng(projparm[4], HDFE_DMS_DEG);
7447 lonrad = EHconvAng(centMerd + 90 * i, HDFE_DEG_RAD);
7448 csTest = cos(lonrad);
7449 snTest = sin(lonrad);
7450
7451
7452 /* If box brackets meridian ... */
7453 /* ---------------------------- */
7454 if (csTest * cs[1] + snTest * sn[1] > dotPrd)
7455 {
7456 latitude[*npnts] = cornerlat[0];
7457 longitude[*npnts] = centMerd;
7458 (*npnts)++;
7459
7460 latitude[*npnts] = cornerlat[1];
7461 longitude[*npnts] = centMerd;
7462 (*npnts)++;
7463 }
7464 }
7465
7466
7467
7468 /* Compute sine and cosine of corner latitudes */
7469 /* ------------------------------------------- */
7470 for (i = 0; i < 2; i++)
7471 {
7472 latrad = EHconvAng(cornerlat[i], HDFE_DEG_RAD);
7473 cs[i] = cos(latrad);
7474 sn[i] = sin(latrad);
7475 }
7476
7477
7478 /* Compute dot product */
7479 /* ------------------- */
7480 dotPrd = cs[0] * cs[1] + sn[0] * sn[1];
7481
7482
7483 /* Convert origin latitude (DMS to DEG) & compute sin & cos */
7484 /* -------------------------------------------------------- */
7485 orgLat = EHconvAng(projparm[5], HDFE_DMS_DEG);
7486 latrad = EHconvAng(orgLat, HDFE_DEG_RAD);
7487 cs[1] = cos(latrad);
7488 sn[1] = sin(latrad);
7489
7490
7491 /* If box brackets origin latitude ... */
7492 /* ----------------------------------- */
7493 if (cs[0] * cs[1] + sn[0] * sn[1] > dotPrd)
7494 {
7495 latitude[*npnts] = orgLat;
7496 longitude[*npnts] = cornerlon[0];
7497 (*npnts)++;
7498
7499 latitude[*npnts] = orgLat;
7500 longitude[*npnts] = cornerlon[1];
7501 (*npnts)++;
7502 }
7503 }
7504 break;
7505
7506
7507 case GCTP_HOM:
7508 {
7509 /* Tangent to y-axis along longitude */
7510 /* --------------------------------- */
7511 if (projparm[12] == 0)
7512 {
7513 cs[0] = cos(EHconvAng(projparm[8], HDFE_DMS_RAD));
7514 sn[0] = sin(EHconvAng(projparm[8], HDFE_DMS_RAD));
7515 cs[1] = cos(EHconvAng(projparm[9], HDFE_DMS_RAD));
7516 sn[1] = sin(EHconvAng(projparm[9], HDFE_DMS_RAD));
7517 cs[2] = cos(EHconvAng(projparm[10], HDFE_DMS_RAD));
7518 sn[2] = sin(EHconvAng(projparm[10], HDFE_DMS_RAD));
7519 cs[3] = cos(EHconvAng(projparm[11], HDFE_DMS_RAD));
7520 sn[3] = sin(EHconvAng(projparm[11], HDFE_DMS_RAD));
7521
7522 bisectParm[3] = atan2(
7523 (cs[1] * sn[3] * cs[0] - sn[1] * cs[3] * cs[2]),
7524 (sn[1] * cs[3] * sn[2] - cs[1] * sn[3] * sn[0]));
7525 bisectParm[0] = atan(
7526 (sin(bisectParm[3]) * sn[0] - cos(bisectParm[3]) * cs[0]) /
7527 (sn[1] / cs[1]));
7528 bisectParm[2] = bisectParm[3] + 0.5 * dpi;
7529 }
7530 else
7531 {
7532 cs[0] = cos(EHconvAng(projparm[3], HDFE_DMS_RAD));
7533 sn[0] = sin(EHconvAng(projparm[3], HDFE_DMS_RAD));
7534 cs[1] = cos(EHconvAng(projparm[4], HDFE_DMS_RAD));
7535 sn[1] = sin(EHconvAng(projparm[4], HDFE_DMS_RAD));
7536
7537 bisectParm[0] = asin(cs[1] * sn[0]);
7538 bisectParm[2] = atan2(-cs[0], (-sn[1] * sn[0])) + 0.5 * dpi;
7539 }
7540
7541 for (i = 0; i < 2; i++)
7542 {
7543 bisectParm[1] = cornerlon[i];
7544
7545 if (EHbisect(homDyDtheta, bisectParm, 3,
7546 cornerlat[0], cornerlat[1],
7547 0.0001, &tanLat) == 0)
7548 {
7549 longitude[*npnts] = cornerlon[i];
7550 latitude[*npnts] = tanLat;
7551 (*npnts)++;
7552 }
7553 }
7554
7555 }
7556 break;
7557 }
7558
7559
7560 return (status);
7561 }
7562
7563
7564
7565 /*----------------------------------------------------------------------------|
7566 | BEGIN_PROLOG |
7567 | |
7568 | FUNCTION: GDdefboxregion |
7569 | |
7570 | DESCRIPTION: Defines region for subsetting in a grid. |
7571 | |
7572 | |
7573 | Return Value Type Units Description |
7574 | ============ ====== ========= ===================================== |
7575 | regionID int32 Region ID |
7576 | |
7577 | INPUTS: |
7578 | gridID int32 Grid structure ID |
7579 | cornerlon float64 dec deg Longitude of opposite corners of box |
7580 | cornerlat float64 dec deg Latitude of opposite corners of box |
7581 | |
7582 | |
7583 | OUTPUTS: |
7584 | None |
7585 | |
7586 | NOTES: |
7587 | |
7588 | |
7589 | Date Programmer Description |
7590 | ====== ============ ================================================= |
7591 | Jun 96 Joel Gales Original Programmer |
7592 | Oct 96 Joel Gales "Clamp" subset region around grid |
7593 | Oct 96 Joel Gales Fix "outside region" check |
7594 | Nov 96 Joel Gales Add check for "tangent" points (GDtangentpnts) |
7595 | Dec 96 Joel Gales Trap if no projection code defined |
7596 | Dec 96 Joel Gales Add multiple vertical subsetting capability |
7597 | Mar 99 David Wynne Fix for NCR 21195, allow subsetting of MISR SOM |
7598 | data sets |
7599 | Jun 00 Abe Taaheri Added support for EASE grid |
7600 | |
7601 | END_PROLOG |
7602 -----------------------------------------------------------------------------*/
7603 int32
GDdefboxregion(int32 gridID,float64 cornerlon[],float64 cornerlat[])7604 GDdefboxregion(int32 gridID, float64 cornerlon[], float64 cornerlat[])
7605 {
7606 intn i; /* Loop index */
7607 intn j; /* Loop index */
7608 intn k; /* Loop index */
7609 intn n; /* Loop index */
7610 intn status = 0; /* routine return status variable */
7611
7612 int32 fid; /* HDF-EOS file ID */
7613 int32 sdInterfaceID; /* HDF SDS interface ID */
7614 int32 gdVgrpID; /* Grid root Vgroup ID */
7615 int32 regionID = -1; /* Region ID */
7616 int32 xdimsize; /* XDim size */
7617 int32 ydimsize; /* YDim size */
7618 int32 projcode; /* Projection code */
7619 int32 zonecode; /* Zone code */
7620 int32 spherecode; /* Sphere code */
7621 int32 row[32]; /* Row array */
7622 int32 col[32]; /* Column array */
7623 int32 minCol = 0; /* Minimun column value */
7624 int32 minRow = 0; /* Minimun row value */
7625 int32 maxCol = 0; /* Maximun column value */
7626 int32 maxRow = 0; /* Maximun row value */
7627 int32 npnts; /* Number of boundary
7628 (edge & tangent) pnts */
7629
7630 float64 longitude[32]; /* Longitude array */
7631 float64 latitude[32]; /* Latitude array */
7632 float64 upleftpt[2]; /* Upper left pt coordinates */
7633 float64 lowrightpt[2]; /* Lower right pt coordinates */
7634 float64 somupleftpt[2]; /* temporary Upper left pt coordinates
7635 for SOM projection */
7636 float64 somlowrightpt[2]; /* temporary Lower right pt
7637 coordinates for SOM projection */
7638 float64 projparm[16]; /* Projection parameters */
7639 float64 xscale; /* X scale */
7640 float64 yscale; /* Y scale */
7641 float64 lonrad0; /* Longitude of upper left point
7642 (radians) */
7643 float64 latrad0; /* Latitude of upper left point (radians) */
7644 float64 lonrad2; /* Longitude of point (radians) */
7645 float64 latrad2; /* Latitude of point (radians) */
7646
7647 /* Used for SOM projection */
7648 char *utlbuf;
7649 char *gridname;
7650 int32 blockindexstart = -1;
7651 int32 blockindexstop = -1;
7652 float32 offset[180];
7653 float64 templeftpt[2];
7654 float64 temprightpt[2];
7655 int32 idOffset = GDIDOFFSET; /* Grid ID offset */
7656 float64 xmtr[2], ymtr[2];
7657 float64 lon[2],lat[2];
7658 float64 xcor[2], ycor[2];
7659 int32 nlatlon;
7660 float64 upleftpt_m[2];
7661
7662
7663 utlbuf = (char *)calloc(128, sizeof(char));
7664 if(utlbuf == NULL)
7665 {
7666 HEpush(DFE_NOSPACE,"GDdefboxregion", __FILE__, __LINE__);
7667 return(-1);
7668 }
7669 gridname = (char *)calloc(128, sizeof(char));
7670 if(gridname == NULL)
7671 {
7672 HEpush(DFE_NOSPACE,"GDdefboxregion", __FILE__, __LINE__);
7673 free(utlbuf);
7674 return(-1);
7675 }
7676
7677 /* Check for valid grid ID */
7678 /* ----------------------- */
7679 status = GDchkgdid(gridID, "GDdefboxregion",
7680 &fid, &sdInterfaceID, &gdVgrpID);
7681
7682
7683 if (status == 0)
7684 {
7685 /* Get grid info */
7686 /* ------------- */
7687 status = GDgridinfo(gridID, &xdimsize, &ydimsize,
7688 upleftpt, lowrightpt);
7689
7690
7691 /* If error then bail */
7692 /* ------------------ */
7693 if (status != 0)
7694 {
7695 regionID = -1;
7696 free(utlbuf);
7697 free(gridname);
7698 return (regionID);
7699 }
7700
7701
7702 /* Get proj info */
7703 /* ------------- */
7704 status = GDprojinfo(gridID, &projcode, &zonecode,
7705 &spherecode, projparm);
7706
7707
7708 /* If no projection code defined then bail */
7709 /* --------------------------------------- */
7710 if (projcode == -1)
7711 {
7712 regionID = -1;
7713 free(utlbuf);
7714 free(gridname);
7715 return (regionID);
7716 }
7717
7718
7719 /* Get default values for upleft and lowright if necessary */
7720 /* ------------------------------------------------------- */
7721 if (upleftpt[0] == 0 && upleftpt[1] == 0 &&
7722 lowrightpt[0] == 0 && lowrightpt[1] == 0)
7723 {
7724 status = GDgetdefaults(projcode, zonecode, projparm, spherecode,
7725 upleftpt, lowrightpt);
7726
7727 /* If error then bail */
7728 /* ------------------ */
7729 if (status != 0)
7730 {
7731 regionID = -1;
7732 free(utlbuf);
7733 free(gridname);
7734 return (regionID);
7735 }
7736 }
7737
7738
7739
7740 /* Fill-up longitude and latitude arrays */
7741 /* ------------------------------------- */
7742 longitude[0] = cornerlon[0];
7743 latitude[0] = cornerlat[0];
7744
7745 longitude[1] = cornerlon[0];
7746 latitude[1] = cornerlat[1];
7747
7748 longitude[2] = cornerlon[1];
7749 latitude[2] = cornerlat[0];
7750
7751 longitude[3] = cornerlon[1];
7752 latitude[3] = cornerlat[1];
7753
7754 npnts = 4;
7755
7756
7757 /* Find additional tangent points from GDtangentpnts */
7758 /* ------------------------------------------------- */
7759 status = GDtangentpnts(projcode, projparm, cornerlon, cornerlat,
7760 longitude, latitude, &npnts);
7761
7762 /* If SOM projection with projparm[11] non-zero ... */
7763 if (projcode == GCTP_SOM && projparm[11] != 0)
7764 {
7765 Vgetname(GDXGrid[gridID % idOffset].IDTable, gridname);
7766 sprintf(utlbuf, "%s%s", "_BLKSOM:", gridname);
7767 status = GDreadattr(gridID, utlbuf, offset);
7768
7769 somupleftpt[0] = upleftpt[0];
7770 somupleftpt[1] = upleftpt[1];
7771 somlowrightpt[0]= lowrightpt[0];
7772 somlowrightpt[1] = lowrightpt[1];
7773
7774 k = 0;
7775 n = 2;
7776
7777 for (j = 0; j <= projparm[11] - 1; j++)
7778 {
7779
7780 /* Convert from lon/lat to row/col */
7781 /* ------------------------------- */
7782 status = GDll2ij(projcode, zonecode, projparm, spherecode,
7783 xdimsize, ydimsize, somupleftpt, somlowrightpt,
7784 npnts, longitude, latitude, row, col, NULL, NULL);
7785
7786
7787 /* Find min/max values for row & col */
7788 /* --------------------------------- */
7789 minCol = col[0];
7790 minRow = row[0];
7791 maxCol = col[0];
7792 maxRow = row[0];
7793 for (i = 1; i < npnts; i++)
7794 {
7795 if (col[i] < minCol)
7796 {
7797 minCol = col[i];
7798 }
7799
7800 if (col[i] > maxCol)
7801 {
7802 maxCol = col[i];
7803 }
7804
7805 if (row[i] < minRow)
7806 {
7807 minRow = row[i];
7808 }
7809
7810 if (row[i] > maxRow)
7811 {
7812 maxRow = row[i];
7813 }
7814 }
7815
7816
7817
7818 /* "Clamp" if outside Grid */
7819 /* ----------------------- */
7820 minCol = (minCol < 0) ? 0 : minCol;
7821 minRow = (minRow < 0) ? 0 : minRow;
7822
7823 maxCol = (maxCol >= xdimsize) ? xdimsize - 1 : maxCol;
7824 maxRow = (maxRow >= ydimsize) ? ydimsize - 1 : maxRow;
7825
7826
7827 /* Check whether subset region is outside grid region */
7828 /* -------------------------------------------------- */
7829 if (minCol >= xdimsize || minRow >= ydimsize ||
7830 maxCol < 0 || maxRow < 0)
7831 {
7832 if ( blockindexstart == -1 && (projparm[11]) == j)
7833 {
7834 status = -1;
7835 HEpush(DFE_GENAPP, "GDdefboxregion", __FILE__, __LINE__);
7836 HEreport("Subset Region outside of Grid Region\n");
7837 regionID = -1;
7838 }
7839 }
7840 else
7841 {
7842 if (k == 0)
7843 {
7844 blockindexstart = j;
7845 blockindexstop = j;
7846 k = 1;
7847 }
7848 else
7849 {
7850 blockindexstop = j;
7851 }
7852 }
7853 templeftpt[0] = upleftpt[0] + ((offset[j]/xdimsize)*abs(upleftpt[0] - lowrightpt[0])) + abs((upleftpt[0] - lowrightpt[0]))*(n-1);
7854 templeftpt[1] = upleftpt[1] + ((lowrightpt[1] - upleftpt[1]))*(n-1);
7855
7856 temprightpt[0] = lowrightpt[0] + ((offset[j]/xdimsize)*abs(lowrightpt[0] - upleftpt[0])) + abs((lowrightpt[0] - upleftpt[0]))*(n-1);
7857 temprightpt[1] = lowrightpt[1] + ((upleftpt[1] - lowrightpt[1]))*(n-1);
7858
7859 somupleftpt[0] = templeftpt[0];
7860 somupleftpt[1] = templeftpt[1];
7861
7862 somlowrightpt[0] = temprightpt[0];
7863 somlowrightpt[1] = temprightpt[1];
7864 n++;
7865 }
7866 }
7867 else
7868 {
7869
7870 /* Convert from lon/lat to row/col */
7871 /* ------------------------------- */
7872
7873 status = GDll2ij(projcode, zonecode, projparm, spherecode,
7874 xdimsize, ydimsize, upleftpt, lowrightpt,
7875 npnts, longitude, latitude, row, col, NULL, NULL);
7876
7877 /* Find min/max values for row & col */
7878 /* --------------------------------- */
7879 minCol = col[0];
7880 minRow = row[0];
7881 maxCol = col[0];
7882 maxRow = row[0];
7883 for (i = 1; i < npnts; i++)
7884 {
7885 if (col[i] < minCol)
7886 {
7887 minCol = col[i];
7888 }
7889
7890 if (col[i] > maxCol)
7891 {
7892 maxCol = col[i];
7893 }
7894
7895 if (row[i] < minRow)
7896 {
7897 minRow = row[i];
7898 }
7899
7900 if (row[i] > maxRow)
7901 {
7902 maxRow = row[i];
7903 }
7904 }
7905
7906
7907
7908 /* "Clamp" if outside Grid */
7909 /* ----------------------- */
7910 minCol = (minCol < 0) ? 0 : minCol;
7911 minRow = (minRow < 0) ? 0 : minRow;
7912
7913 maxCol = (maxCol >= xdimsize) ? xdimsize - 1 : maxCol;
7914 maxRow = (maxRow >= ydimsize) ? ydimsize - 1 : maxRow;
7915
7916
7917 /* Check whether subset region is outside grid region */
7918 /* -------------------------------------------------- */
7919 if (minCol >= xdimsize || minRow >= ydimsize || maxCol < 0 || maxRow < 0)
7920 {
7921 status = -1;
7922 HEpush(DFE_GENAPP, "GDdefboxregion", __FILE__, __LINE__);
7923 HEreport("Subset Region outside of Grid Region\n");
7924 regionID = -1;
7925
7926 }
7927 }
7928 if (status == 0)
7929 {
7930 /* Store grid region info */
7931 /* ---------------------- */
7932 for (i = 0; i < NGRIDREGN; i++)
7933 {
7934 /* Find first empty grid region */
7935 /* ---------------------------- */
7936 if (GDXRegion[i] == 0)
7937 {
7938 /* Allocate space for grid region entry */
7939 /* ------------------------------------ */
7940 GDXRegion[i] = (struct gridRegion *)
7941 calloc(1, sizeof(struct gridRegion));
7942 if(GDXRegion[i] == NULL)
7943 {
7944 HEpush(DFE_NOSPACE,"GDdefboxregion", __FILE__, __LINE__);
7945 free(utlbuf);
7946 free(gridname);
7947 return(-1);
7948 }
7949
7950
7951 /* Store file and grid ID */
7952 /* ---------------------- */
7953 GDXRegion[i]->fid = fid;
7954 GDXRegion[i]->gridID = gridID;
7955
7956
7957 /* Initialize vertical subset entries to -1 */
7958 /* ---------------------------------------- */
7959 for (j = 0; j < 8; j++)
7960 {
7961 GDXRegion[i]->StartVertical[j] = -1;
7962 GDXRegion[i]->StopVertical[j] = -1;
7963 }
7964
7965
7966 /* Store start & count along x & y */
7967 /* ------------------------------- */
7968 GDXRegion[i]->xStart = minCol;
7969 GDXRegion[i]->xCount = maxCol - minCol + 1;
7970 GDXRegion[i]->yStart = minRow;
7971 GDXRegion[i]->yCount = maxRow - minRow + 1;
7972
7973
7974 /* Store upleft and lowright points of subset region */
7975 /* ------------------------------------------------- */
7976 if (projcode == GCTP_GEO )
7977 {
7978 /* GEO projection */
7979 /* ------------------------ */
7980
7981 /* Convert upleft & lowright lon from DMS to radians */
7982 /* ------------------------------------------------- */
7983 lonrad0 = EHconvAng(upleftpt[0], HDFE_DMS_RAD);
7984 lonrad2 = EHconvAng(lowrightpt[0], HDFE_DMS_RAD);
7985
7986 /* Compute X scale */
7987 /* --------------- */
7988 xscale = (lonrad2 - lonrad0) / xdimsize;
7989
7990 /* Convert upleft & lowright lat from DMS to radians */
7991 /* ------------------------------------------------- */
7992 latrad0 = EHconvAng(upleftpt[1], HDFE_DMS_RAD);
7993 latrad2 = EHconvAng(lowrightpt[1], HDFE_DMS_RAD);
7994
7995 /* Compute Y scale */
7996 /* --------------- */
7997 yscale = (latrad2 - latrad0) / ydimsize;
7998
7999
8000 /* MinCol -> radians -> DMS -> upleftpt[0] */
8001 /* --------------------------------------- */
8002 GDXRegion[i]->upleftpt[0] =
8003 EHconvAng(lonrad0 + xscale * minCol,
8004 HDFE_RAD_DMS);
8005
8006
8007 /* MinRow -> radians -> DMS -> upleftpt[1] */
8008 /* --------------------------------------- */
8009 GDXRegion[i]->upleftpt[1] =
8010 EHconvAng(latrad0 + yscale * minRow,
8011 HDFE_RAD_DMS);
8012
8013
8014 /* MinCol + 1 -> radians -> DMS -> lowrightpt[0] */
8015 /* --------------------------------------------- */
8016 GDXRegion[i]->lowrightpt[0] =
8017 EHconvAng(lonrad0 + xscale * (maxCol + 1),
8018 HDFE_RAD_DMS);
8019
8020
8021 /* MinRow + 1 -> radians -> DMS -> lowrightpt[1] */
8022 /* --------------------------------------------- */
8023 GDXRegion[i]->lowrightpt[1] =
8024 EHconvAng(latrad0 + yscale * (maxRow + 1),
8025 HDFE_RAD_DMS);
8026 }
8027 else if (projcode == GCTP_BCEA)
8028 {
8029 /* BCEA projection */
8030 /* -------------- */
8031 nlatlon = 2;
8032 lon[0] = upleftpt[0];
8033 lon[1] = lowrightpt[0];
8034 lat[0] = upleftpt[1];
8035 lat[1] = lowrightpt[1];
8036 status =
8037 GDll2mm_cea(projcode,zonecode,spherecode,projparm,
8038 xdimsize, ydimsize,
8039 upleftpt, lowrightpt,nlatlon,
8040 lon, lat,
8041 xcor, ycor, &xscale, &yscale);
8042 upleftpt_m[0] = xcor[0];
8043 upleftpt_m[1] = ycor[0];
8044
8045
8046 if (status == -1)
8047 {
8048 HEpush(DFE_GENAPP, "GDdefboxregion", __FILE__, __LINE__);
8049 free(utlbuf);
8050 free(gridname);
8051 return (status);
8052 }
8053
8054 /* MinCol -> meters -> upleftpt[0] */
8055 /* ------------------------------- */
8056 xmtr[0] = upleftpt_m[0] + xscale * minCol;
8057
8058 /* MinRow -> meters -> upleftpt[1] */
8059 /* ------------------------------- */
8060 ymtr[0] = upleftpt_m[1] + yscale * minRow;
8061
8062 /* MinCol + 1 -> meters -> lowrightpt[0] */
8063 /* ------------------------------------- */
8064 xmtr[1] = upleftpt_m[0] + xscale * (maxCol + 1);
8065
8066 /* MinRow + 1 -> meters -> lowrightpt[1] */
8067 /* ------------------------------------- */
8068 ymtr[1] = upleftpt_m[1] + yscale * (maxRow + 1);
8069
8070 /* Convert upleft & lowright lon from DMS to radians */
8071 /* ------------------------------------------------- */
8072 npnts = 2;
8073 status = GDmm2ll_cea(projcode, zonecode, spherecode,
8074 projparm, xdimsize, ydimsize,
8075 upleftpt, lowrightpt, npnts,
8076 xmtr, ymtr,
8077 longitude, latitude);
8078 if (status == -1)
8079 {
8080 HEpush(DFE_GENAPP, "GDdefboxregion", __FILE__, __LINE__);
8081 free(utlbuf);
8082 free(gridname);
8083 return (status);
8084 }
8085 GDXRegion[i]->upleftpt[0] = longitude[0];
8086
8087 GDXRegion[i]->upleftpt[1] = latitude[0];
8088
8089 GDXRegion[i]->lowrightpt[0] = longitude[1];
8090
8091 GDXRegion[i]->lowrightpt[1] = latitude[1];
8092 }
8093 else if (projcode == GCTP_SOM)
8094 {
8095 /* Store start & count along x & y */
8096 /* ------------------------------- */
8097 GDXRegion[i]->xStart = 0;
8098 GDXRegion[i]->xCount = xdimsize;
8099 GDXRegion[i]->yStart = 0;
8100 GDXRegion[i]->yCount = ydimsize;
8101
8102 GDXRegion[i]->somStart = blockindexstart;
8103 GDXRegion[i]->somCount = blockindexstop - blockindexstart + 1;
8104
8105 /* Store upleft and lowright points of subset region */
8106 /* ------------------------------------------------- */
8107 if (blockindexstart == 0)
8108 {
8109 GDXRegion[i]->upleftpt[0] = upleftpt[0];
8110 GDXRegion[i]->upleftpt[1] = upleftpt[1];
8111 GDXRegion[i]->lowrightpt[0] = lowrightpt[0];
8112 GDXRegion[i]->lowrightpt[1] = lowrightpt[1];
8113 }
8114 else
8115 {
8116 GDXRegion[i]->upleftpt[0] =
8117 (lowrightpt[0] - upleftpt[0])*
8118 (offset[blockindexstart-1]/xdimsize) + upleftpt[0];
8119 GDXRegion[i]->upleftpt[1] =
8120 (lowrightpt[1] - upleftpt[1])*
8121 (blockindexstart+1-1) + upleftpt[1];
8122
8123 GDXRegion[i]->lowrightpt[0] =
8124 (lowrightpt[0] - upleftpt[0])*
8125 (offset[blockindexstart-1]/xdimsize) + lowrightpt[0];
8126 GDXRegion[i]->lowrightpt[1] =
8127 (lowrightpt[1] - upleftpt[1])*
8128 (blockindexstart+1-1) + lowrightpt[1];
8129
8130 }
8131 }
8132 else
8133 {
8134 /* Non-GEO, Non-BCEA projections */
8135 /* ---------------------------- */
8136
8137 /* Compute X & Y scale */
8138 /* ------------------- */
8139 xscale = (lowrightpt[0] - upleftpt[0]) / xdimsize;
8140 yscale = (lowrightpt[1] - upleftpt[1]) / ydimsize;
8141
8142
8143 /* MinCol -> meters -> upleftpt[0] */
8144 /* ------------------------------- */
8145 GDXRegion[i]->upleftpt[0] = upleftpt[0] +
8146 xscale * minCol;
8147
8148
8149 /* MinRow -> meters -> upleftpt[1] */
8150 /* ------------------------------- */
8151 GDXRegion[i]->upleftpt[1] = upleftpt[1] +
8152 yscale * minRow;
8153
8154
8155 /* MinCol + 1 -> meters -> lowrightpt[0] */
8156 /* ------------------------------------- */
8157 GDXRegion[i]->lowrightpt[0] = upleftpt[0] +
8158 xscale * (maxCol + 1);
8159
8160
8161 /* MinRow + 1 -> meters -> lowrightpt[1] */
8162 /* ------------------------------------- */
8163 GDXRegion[i]->lowrightpt[1] = upleftpt[1] +
8164 yscale * (maxRow + 1);
8165 }
8166
8167 /* Store region ID */
8168 /* --------------- */
8169 regionID = i;
8170 break;
8171 }
8172
8173 }
8174 }
8175
8176 }
8177 free(utlbuf);
8178 free(gridname);
8179 return (regionID);
8180 }
8181
8182
8183
8184
8185
8186 /*----------------------------------------------------------------------------|
8187 | BEGIN_PROLOG |
8188 | |
8189 | FUNCTION: GDregioninfo |
8190 | |
8191 | DESCRIPTION: Retrieves size of region in bytes. |
8192 | |
8193 | |
8194 | Return Value Type Units Description |
8195 | ============ ====== ========= ===================================== |
8196 | status intn return status (0) SUCCEED, (-1) FAIL |
8197 | |
8198 | INPUTS: |
8199 | gridID int32 Grid structure ID |
8200 | regionID int32 Region ID |
8201 | fieldname char Fieldname |
8202 | |
8203 | |
8204 | OUTPUTS: |
8205 | ntype int32 field number type |
8206 | rank int32 field rank |
8207 | dims int32 dimensions of field region |
8208 | size int32 size in bytes of field region |
8209 | upleftpt float64 Upper left corner coord for region |
8210 | lowrightpt float64 Lower right corner coord for region |
8211 | |
8212 | NOTES: |
8213 | |
8214 | |
8215 | Date Programmer Description |
8216 | ====== ============ ================================================= |
8217 | Jun 96 Joel Gales Original Programmer |
8218 | Aug 96 Joel Gales Add vertical subsetting |
8219 | Dec 96 Joel Gales Add multiple vertical subsetting capability |
8220 | Apr 99 David Wynne Added support for MISR SOM projection, NCR 21195 |
8221 | |
8222 | END_PROLOG |
8223 -----------------------------------------------------------------------------*/
8224 intn
GDregioninfo(int32 gridID,int32 regionID,char * fieldname,int32 * ntype,int32 * rank,int32 dims[],int32 * size,float64 upleftpt[],float64 lowrightpt[])8225 GDregioninfo(int32 gridID, int32 regionID, char *fieldname,
8226 int32 * ntype, int32 * rank, int32 dims[], int32 * size,
8227 float64 upleftpt[], float64 lowrightpt[])
8228 {
8229 intn j; /* Loop index */
8230 intn status = 0; /* routine return status variable */
8231
8232 int32 fid; /* HDF-EOS file ID */
8233 int32 sdInterfaceID; /* HDF SDS interface ID */
8234 int32 gdVgrpID; /* Grid root Vgroup ID */
8235 int32 index; /* Dimension index */
8236
8237 char dimlist[256]; /* Dimension list */
8238 char *errMesg = "Vertical Dimension Not Found: \"%s\".\n";
8239 char *errM1 = "Both \"XDim\" and \"YDim\" must be present ";
8240 char *errM2 = "in the dimension list for \"%s\".\n";
8241 char errbuf[256];/* Error buffer */
8242
8243
8244 /* Check for valid grid ID */
8245 /* ----------------------- */
8246 status = GDchkgdid(gridID, "GDregioninfo", &fid, &sdInterfaceID,
8247 &gdVgrpID);
8248
8249
8250 /* Check for valid region ID */
8251 /* ------------------------- */
8252 if (status == 0)
8253 {
8254 if (regionID < 0 || regionID >= NGRIDREGN)
8255 {
8256 status = -1;
8257 HEpush(DFE_RANGE, "GDregioninfo", __FILE__, __LINE__);
8258 HEreport("Invalid Region id: %d.\n", regionID);
8259 }
8260 }
8261
8262
8263 /* Check for active region ID */
8264 /* -------------------------- */
8265 if (status == 0)
8266 {
8267 if (GDXRegion[regionID] == 0)
8268 {
8269 status = -1;
8270 HEpush(DFE_GENAPP, "GDregioninfo", __FILE__, __LINE__);
8271 HEreport("Inactive Region ID: %d.\n", regionID);
8272 }
8273 }
8274
8275
8276
8277 /* Check that region defined for this file */
8278 /* --------------------------------------- */
8279 if (status == 0)
8280 {
8281 if (GDXRegion[regionID]->fid != fid)
8282 {
8283 status = -1;
8284 HEpush(DFE_GENAPP, "GDregioninfo", __FILE__, __LINE__);
8285 HEreport("Region is not defined for this file.\n");
8286 }
8287 }
8288
8289
8290 /* Check that region defined for this grid */
8291 /* --------------------------------------- */
8292 if (status == 0)
8293 {
8294 if (GDXRegion[regionID]->gridID != gridID)
8295 {
8296 status = -1;
8297 HEpush(DFE_GENAPP, "GDregioninfo", __FILE__, __LINE__);
8298 HEreport("Region is not defined for this Grid.\n");
8299 }
8300 }
8301
8302
8303
8304 /* Check for valid fieldname */
8305 /* ------------------------- */
8306 if (status == 0)
8307 {
8308 status = GDfieldinfo(gridID, fieldname, rank, dims, ntype, dimlist);
8309
8310 if (status != 0)
8311 {
8312 /* Fieldname not found in grid */
8313 /* --------------------------- */
8314 status = -1;
8315 HEpush(DFE_GENAPP, "GDregioninfo", __FILE__, __LINE__);
8316 HEreport("Fieldname \"%s\" not found.\n",
8317 fieldname);
8318 }
8319 else if (*rank == 1)
8320 {
8321 /* Field is 1 dimensional */
8322 /* ---------------------- */
8323 status = -1;
8324 HEpush(DFE_GENAPP, "GDregioninfo", __FILE__, __LINE__);
8325 HEreport(
8326 "One-Dimesional fields \"%s\" may not be subsetted.\n",
8327 fieldname);
8328 }
8329 else
8330 {
8331 /* "XDim" and/or "YDim" not found */
8332 /* ------------------------------ */
8333 if (EHstrwithin("XDim", dimlist, ',') == -1 ||
8334 EHstrwithin("YDim", dimlist, ',') == -1)
8335 {
8336 status = -1;
8337 HEpush(DFE_GENAPP, "GDregioninfo", __FILE__, __LINE__);
8338 sprintf(errbuf, "%s%s", errM1, errM2);
8339 HEreport(errbuf, fieldname);
8340 }
8341 }
8342 }
8343
8344
8345
8346 /* If no problems ... */
8347 /* ------------------ */
8348 if (status == 0)
8349 {
8350 /* Check if SOM projection */
8351 /* ----------------------- */
8352 if (EHstrwithin("SOMBlockDim", dimlist, ',') == 0)
8353 {
8354 dims[EHstrwithin("SOMBlockDim", dimlist, ',')] =
8355 GDXRegion[regionID]->somCount;
8356 }
8357
8358 /* Load XDim dimension from region entry */
8359 /* ------------------------------------- */
8360 if (GDXRegion[regionID]->xCount != 0)
8361 {
8362 dims[EHstrwithin("XDim", dimlist, ',')] =
8363 GDXRegion[regionID]->xCount;
8364 }
8365
8366 /* Load YDim dimension from region entry */
8367 /* ------------------------------------- */
8368 if (GDXRegion[regionID]->yCount != 0)
8369 {
8370 dims[EHstrwithin("YDim", dimlist, ',')] =
8371 GDXRegion[regionID]->yCount;
8372 }
8373
8374
8375 /* Vertical Subset */
8376 /* --------------- */
8377 for (j = 0; j < 8; j++)
8378 {
8379
8380 /* If active vertical subset ... */
8381 /* ----------------------------- */
8382 if (GDXRegion[regionID]->StartVertical[j] != -1)
8383 {
8384 /* Find vertical dimension within dimlist */
8385 /* -------------------------------------- */
8386 index = EHstrwithin(GDXRegion[regionID]->DimNamePtr[j],
8387 dimlist, ',');
8388
8389 /* If dimension found ... */
8390 /* ---------------------- */
8391 if (index != -1)
8392 {
8393 /* Compute dimension size */
8394 /* ---------------------- */
8395 dims[index] =
8396 GDXRegion[regionID]->StopVertical[j] -
8397 GDXRegion[regionID]->StartVertical[j] + 1;
8398 }
8399 else
8400 {
8401 /* Vertical dimension not found */
8402 /* ---------------------------- */
8403 status = -1;
8404 *size = -1;
8405 HEpush(DFE_GENAPP, "GDregioninfo",
8406 __FILE__, __LINE__);
8407 HEreport(errMesg,
8408 GDXRegion[regionID]->DimNamePtr[j]);
8409 }
8410 }
8411 }
8412
8413
8414 if (status == 0)
8415 {
8416 /* Compute number of total elements */
8417 /* -------------------------------- */
8418 *size = dims[0];
8419 for (j = 1; j < *rank; j++)
8420 {
8421 *size *= dims[j];
8422 }
8423
8424 /* Multiply by size in bytes of numbertype */
8425 /* --------------------------------------- */
8426 *size *= DFKNTsize(*ntype);
8427
8428
8429 /* Return upper left and lower right subset values */
8430 /* ----------------------------------------------- */
8431 upleftpt[0] = GDXRegion[regionID]->upleftpt[0];
8432 upleftpt[1] = GDXRegion[regionID]->upleftpt[1];
8433 lowrightpt[0] = GDXRegion[regionID]->lowrightpt[0];
8434 lowrightpt[1] = GDXRegion[regionID]->lowrightpt[1];
8435 }
8436 }
8437 return (status);
8438 }
8439
8440
8441
8442
8443
8444 /*----------------------------------------------------------------------------|
8445 | BEGIN_PROLOG |
8446 | |
8447 | FUNCTION: GDextractregion |
8448 | |
8449 | DESCRIPTION: Retrieves data from specified region. |
8450 | |
8451 | |
8452 | Return Value Type Units Description |
8453 | ============ ====== ========= ===================================== |
8454 | status intn return status (0) SUCCEED, (-1) FAIL |
8455 | |
8456 | INPUTS: |
8457 | gridID int32 Grid structure ID |
8458 | regionID int32 Region ID |
8459 | fieldname char Fieldname |
8460 | |
8461 | OUTPUTS: |
8462 | buffer void Data buffer containing subsetted region |
8463 | |
8464 | |
8465 | NOTES: |
8466 | |
8467 | |
8468 | Date Programmer Description |
8469 | ====== ============ ================================================= |
8470 | Jun 96 Joel Gales Original Programmer |
8471 | Aug 96 Joel Gales Add vertical subsetting |
8472 | Dec 96 Joel Gales Add multiple vertical subsetting capability |
8473 | Apr 99 David Wynne Add support for MISR SOM projection, NCR 21195 |
8474 | |
8475 | END_PROLOG |
8476 -----------------------------------------------------------------------------*/
8477 intn
GDextractregion(int32 gridID,int32 regionID,char * fieldname,VOIDP buffer)8478 GDextractregion(int32 gridID, int32 regionID, char *fieldname,
8479 VOIDP buffer)
8480 {
8481 intn i; /* Loop index */
8482 intn j; /* Loop index */
8483 intn status = 0; /* routine return status variable */
8484
8485 int32 fid; /* HDF-EOS file ID */
8486 int32 sdInterfaceID; /* HDF SDS interface ID */
8487 int32 gdVgrpID; /* Grid root Vgroup ID */
8488 int32 index; /* Dimension index */
8489 int32 start[8]; /* Start array for data read */
8490 int32 edge[8]; /* Edge array for data read */
8491 int32 dims[8]; /* Dimensions */
8492 int32 rank; /* Field rank */
8493 int32 ntype; /* Field number type */
8494 int32 origincode; /* Pixel origin code */
8495
8496 char dimlist[256]; /* Dimension list */
8497 char *errMesg = "Vertical Dimension Not Found: \"%s\".\n";
8498 char *errM1 = "Both \"XDim\" and \"YDim\" must be present ";
8499 char *errM2 = "in the dimension list for \"%s\".\n";
8500 char errbuf[256];/* Error buffer */
8501
8502
8503 /* Check for valid grid ID */
8504 /* ----------------------- */
8505 status = GDchkgdid(gridID, "GDextractregion", &fid, &sdInterfaceID,
8506 &gdVgrpID);
8507
8508
8509 /* Check for valid region ID */
8510 /* ------------------------- */
8511 if (status == 0)
8512 {
8513 if (regionID < 0 || regionID >= NGRIDREGN)
8514 {
8515 status = -1;
8516 HEpush(DFE_RANGE, "GDextractregion", __FILE__, __LINE__);
8517 HEreport("Invalid Region id: %d.\n", regionID);
8518 }
8519 }
8520
8521
8522 /* Check for active region ID */
8523 /* -------------------------- */
8524 if (status == 0)
8525 {
8526 if (GDXRegion[regionID] == 0)
8527 {
8528 status = -1;
8529 HEpush(DFE_GENAPP, "GDextractregion", __FILE__, __LINE__);
8530 HEreport("Inactive Region ID: %d.\n", regionID);
8531 }
8532 }
8533
8534
8535
8536 /* Check that region defined for this file */
8537 /* --------------------------------------- */
8538 if (status == 0)
8539 {
8540 if (GDXRegion[regionID]->fid != fid)
8541 {
8542 status = -1;
8543 HEpush(DFE_GENAPP, "GDextractregion", __FILE__, __LINE__);
8544 HEreport("Region is not defined for this file.\n");
8545 }
8546 }
8547
8548
8549 /* Check that region defined for this grid */
8550 /* --------------------------------------- */
8551 if (status == 0)
8552 {
8553 if (GDXRegion[regionID]->gridID != gridID)
8554 {
8555 status = -1;
8556 HEpush(DFE_GENAPP, "GDextractregion", __FILE__, __LINE__);
8557 HEreport("Region is not defined for this Grid.\n");
8558 }
8559 }
8560
8561
8562
8563 /* Check for valid fieldname */
8564 /* ------------------------- */
8565 if (status == 0)
8566 {
8567 status = GDfieldinfo(gridID, fieldname, &rank, dims, &ntype, dimlist);
8568
8569 if (status != 0)
8570 {
8571 /* Fieldname not found in grid */
8572 /* --------------------------- */
8573 status = -1;
8574 HEpush(DFE_GENAPP, "GDextractregion", __FILE__, __LINE__);
8575 HEreport("Fieldname \"%s\" not found.\n",
8576 fieldname);
8577 }
8578 else if (rank == 1)
8579 {
8580 /* Field is 1 dimensional */
8581 /* ---------------------- */
8582 status = -1;
8583 HEpush(DFE_GENAPP, "GDextractregion", __FILE__, __LINE__);
8584 HEreport(
8585 "One-Dimesional fields \"%s\" may not be subsetted.\n",
8586 fieldname);
8587 }
8588 else
8589 {
8590 /* "XDim" and/or "YDim" not found */
8591 /* ------------------------------ */
8592 if (EHstrwithin("XDim", dimlist, ',') == -1 ||
8593 EHstrwithin("YDim", dimlist, ',') == -1)
8594 {
8595 status = -1;
8596 HEpush(DFE_GENAPP, "GDextractregion", __FILE__, __LINE__);
8597 sprintf(errbuf, "%s%s", errM1, errM2);
8598 HEreport(errbuf, fieldname);
8599 }
8600 }
8601 }
8602
8603
8604
8605 if (status == 0)
8606 {
8607
8608 /* Get origin order info */
8609 /* --------------------- */
8610 status = GDorigininfo(gridID, &origincode);
8611
8612
8613 /* Initialize start & edge arrays */
8614 /* ------------------------------ */
8615 for (i = 0; i < rank; i++)
8616 {
8617 start[i] = 0;
8618 edge[i] = dims[i];
8619 }
8620
8621
8622 /* if MISR SOM projection, set start */
8623 /* & edge arrays for SOMBlockDim */
8624 /* --------------------------------- */
8625 if (EHstrwithin("SOMBlockDim", dimlist, ',') == 0)
8626 {
8627 index = EHstrwithin("SOMBlockDim", dimlist, ',');
8628 edge[index] = GDXRegion[regionID]->somCount;
8629 start[index] = GDXRegion[regionID]->somStart;
8630 }
8631
8632
8633 /* Set start & edge arrays for XDim */
8634 /* -------------------------------- */
8635 index = EHstrwithin("XDim", dimlist, ',');
8636 if (GDXRegion[regionID]->xCount != 0)
8637 {
8638 edge[index] = GDXRegion[regionID]->xCount;
8639 start[index] = GDXRegion[regionID]->xStart;
8640 }
8641
8642 /* Adjust X-dim start if origin on right edge */
8643 /* ------------------------------------------ */
8644 if ((origincode & 1) == 1)
8645 {
8646 start[index] = dims[index] - (start[index] + edge[index]);
8647 }
8648
8649
8650 /* Set start & edge arrays for YDim */
8651 /* -------------------------------- */
8652 index = EHstrwithin("YDim", dimlist, ',');
8653 if (GDXRegion[regionID]->yCount != 0)
8654 {
8655 start[index] = GDXRegion[regionID]->yStart;
8656 edge[index] = GDXRegion[regionID]->yCount;
8657 }
8658
8659 /* Adjust Y-dim start if origin on lower edge */
8660 /* ------------------------------------------ */
8661 if ((origincode & 2) == 2)
8662 {
8663 start[index] = dims[index] - (start[index] + edge[index]);
8664 }
8665
8666
8667
8668 /* Vertical Subset */
8669 /* --------------- */
8670 for (j = 0; j < 8; j++)
8671 {
8672 /* If active vertical subset ... */
8673 /* ----------------------------- */
8674 if (GDXRegion[regionID]->StartVertical[j] != -1)
8675 {
8676
8677 /* Find vertical dimension within dimlist */
8678 /* -------------------------------------- */
8679 index = EHstrwithin(GDXRegion[regionID]->DimNamePtr[j],
8680 dimlist, ',');
8681
8682 /* If dimension found ... */
8683 /* ---------------------- */
8684 if (index != -1)
8685 {
8686 /* Compute start and edge for vertical dimension */
8687 /* --------------------------------------------- */
8688 start[index] = GDXRegion[regionID]->StartVertical[j];
8689 edge[index] = GDXRegion[regionID]->StopVertical[j] -
8690 GDXRegion[regionID]->StartVertical[j] + 1;
8691 }
8692 else
8693 {
8694 /* Vertical dimension not found */
8695 /* ---------------------------- */
8696 status = -1;
8697 HEpush(DFE_GENAPP, "GDextractregion", __FILE__, __LINE__);
8698 HEreport(errMesg,
8699 GDXRegion[regionID]->DimNamePtr[j]);
8700 }
8701 }
8702 }
8703
8704
8705 /* Read into data buffer */
8706 /* --------------------- */
8707 if (status == 0)
8708 {
8709 status = GDreadfield(gridID, fieldname, start, NULL, edge, buffer);
8710 }
8711 }
8712 return (status);
8713 }
8714
8715
8716
8717
8718 /*----------------------------------------------------------------------------|
8719 | BEGIN_PROLOG |
8720 | |
8721 | FUNCTION: GDdupregion |
8722 | |
8723 | DESCRIPTION: Duplicates a region |
8724 | |
8725 | |
8726 | Return Value Type Units Description |
8727 | ============ ====== ========= ===================================== |
8728 | newregionID int32 New region ID |
8729 | |
8730 | INPUTS: |
8731 | oldregionID int32 Old region ID |
8732 | |
8733 | OUTPUTS: |
8734 | None |
8735 | |
8736 | NOTES: |
8737 | |
8738 | |
8739 | Date Programmer Description |
8740 | ====== ============ ================================================= |
8741 | Jan 97 Joel Gales Original Programmer |
8742 | Oct 98 Abe Taaheri changed *GDXRegion[i] = *GDXRegion[oldregionID]; |
8743 | to copy elements of structure one by one to avoid |
8744 | copying pointer for DimNamePtr to another place that|
8745 | causes "Freeing Unallocated Memory" in purify when |
8746 | using GDdetach |
8747 | |
8748 | END_PROLOG |
8749 -----------------------------------------------------------------------------*/
8750 int32
GDdupregion(int32 oldregionID)8751 GDdupregion(int32 oldregionID)
8752 {
8753 intn i; /* Loop index */
8754 intn j; /* Loop index */
8755 int32 slendupregion;
8756 int32 newregionID = -1; /* New region ID */
8757
8758
8759 /* Find first empty (inactive) region */
8760 /* ---------------------------------- */
8761 for (i = 0; i < NGRIDREGN; i++)
8762 {
8763 if (GDXRegion[i] == 0)
8764 {
8765 /* Allocate space for new grid region entry */
8766 /* ---------------------------------------- */
8767 GDXRegion[i] = (struct gridRegion *)
8768 calloc(1, sizeof(struct gridRegion));
8769 if(GDXRegion[i] == NULL)
8770 {
8771 HEpush(DFE_NOSPACE,"GDdupregion", __FILE__, __LINE__);
8772 return(-1);
8773 }
8774
8775
8776 /* Copy old region structure data to new region */
8777 /* -------------------------------------------- */
8778
8779 GDXRegion[i]->fid = GDXRegion[oldregionID]->fid;
8780 GDXRegion[i]->gridID = GDXRegion[oldregionID]->gridID;
8781 GDXRegion[i]->xStart = GDXRegion[oldregionID]->xStart;
8782 GDXRegion[i]->xCount = GDXRegion[oldregionID]->xCount;
8783 GDXRegion[i]->yStart = GDXRegion[oldregionID]->yStart;
8784 GDXRegion[i]->yCount = GDXRegion[oldregionID]->yCount;
8785 GDXRegion[i]->upleftpt[0] = GDXRegion[oldregionID]->upleftpt[0];
8786 GDXRegion[i]->upleftpt[1] = GDXRegion[oldregionID]->upleftpt[1];
8787 GDXRegion[i]->lowrightpt[0] = GDXRegion[oldregionID]->lowrightpt[0];
8788 GDXRegion[i]->lowrightpt[1] = GDXRegion[oldregionID]->lowrightpt[1];
8789 for (j = 0; j < 8; j++)
8790 {
8791 GDXRegion[i]->StartVertical[j] = GDXRegion[oldregionID]->StartVertical[j];
8792 GDXRegion[i]->StopVertical[j] = GDXRegion[oldregionID]->StopVertical[j];
8793 }
8794
8795 for (j=0; j<8; j++)
8796 {
8797 if(GDXRegion[oldregionID]->DimNamePtr[j] != NULL)
8798 {
8799 slendupregion = strlen(GDXRegion[oldregionID]->DimNamePtr[j]);
8800 GDXRegion[i]->DimNamePtr[j] = (char *) malloc(slendupregion + 1);
8801 strcpy(GDXRegion[i]->DimNamePtr[j],GDXRegion[oldregionID]->DimNamePtr[j]);
8802 }
8803 }
8804
8805
8806 /* Define new region ID */
8807 /* -------------------- */
8808 newregionID = i;
8809
8810 break;
8811 }
8812 }
8813 return (newregionID);
8814 }
8815
8816
8817 /*----------------------------------------------------------------------------|
8818 | BEGIN_PROLOG |
8819 | |
8820 | FUNCTION: GDdefvrtregion |
8821 | |
8822 | DESCRIPTION: Finds elements of a monotonic field within a vertical subset |
8823 | region. |
8824 | |
8825 | |
8826 | Return Value Type Units Description |
8827 | ============ ====== ========= ===================================== |
8828 | regionID int32 Region ID |
8829 | |
8830 | INPUTS: |
8831 | gridID int32 Grid structure ID |
8832 | regionID int32 Region ID |
8833 | vertObj char Vertical object to subset |
8834 | range float64 Vertical subsetting range |
8835 | |
8836 | OUTPUTS: |
8837 | None |
8838 | |
8839 | NOTES: |
8840 | |
8841 | |
8842 | Date Programmer Description |
8843 | ====== ============ ================================================= |
8844 | Aug 96 Joel Gales Original Programmer |
8845 | Dec 96 Joel Gales Add multiple vertical subsetting capability |
8846 | Feb 97 Joel Gales Store XDim, YDim, upleftpt, lowrightpt in GDXRegion |
8847 | |
8848 | END_PROLOG |
8849 -----------------------------------------------------------------------------*/
8850 #define SETGRIDREG \
8851 \
8852 status = GDgridinfo(gridID, &xdimsize, &ydimsize, upleftpt, lowrightpt); \
8853 for (k = 0; k < NGRIDREGN; k++) \
8854 { \
8855 if (GDXRegion[k] == 0) \
8856 { \
8857 GDXRegion[k] = (struct gridRegion *) \
8858 calloc(1, sizeof(struct gridRegion)); \
8859 GDXRegion[k]->fid = fid; \
8860 GDXRegion[k]->gridID = gridID; \
8861 GDXRegion[k]->xStart = 0; \
8862 GDXRegion[k]->xCount = xdimsize; \
8863 GDXRegion[k]->yStart = 0; \
8864 GDXRegion[k]->yCount = ydimsize; \
8865 GDXRegion[k]->upleftpt[0] = upleftpt[0]; \
8866 GDXRegion[k]->upleftpt[1] = upleftpt[1]; \
8867 GDXRegion[k]->lowrightpt[0] = lowrightpt[0]; \
8868 GDXRegion[k]->lowrightpt[1] = lowrightpt[1]; \
8869 regionID = k; \
8870 for (j=0; j<8; j++) \
8871 { \
8872 GDXRegion[k]->StartVertical[j] = -1; \
8873 GDXRegion[k]->StopVertical[j] = -1; \
8874 } \
8875 break; \
8876 } \
8877 }
8878
8879 #define FILLVERTREG \
8880 for (j=0; j<8; j++) \
8881 { \
8882 if (GDXRegion[regionID]->StartVertical[j] == -1) \
8883 { \
8884 GDXRegion[regionID]->StartVertical[j] = i; \
8885 GDXRegion[regionID]->DimNamePtr[j] = \
8886 (char *) malloc(slen + 1); \
8887 memcpy(GDXRegion[regionID]->DimNamePtr[j], \
8888 dimlist, slen + 1); \
8889 break; \
8890 } \
8891 } \
8892
8893
8894
8895 int32
GDdefvrtregion(int32 gridID,int32 regionID,char * vertObj,float64 range[])8896 GDdefvrtregion(int32 gridID, int32 regionID, char *vertObj, float64 range[])
8897 {
8898 intn i, j, k, status;
8899 uint8 found = 0;
8900
8901 int16 vertINT16;
8902
8903 int32 fid, sdInterfaceID, slen;
8904 int32 gdVgrpID, rank, nt, dims[8], size;
8905 int32 vertINT32;
8906 int32 xdimsize;
8907 int32 ydimsize;
8908
8909 float32 vertFLT32;
8910 float64 vertFLT64;
8911 float64 upleftpt[2];
8912 float64 lowrightpt[2];
8913
8914 char *vertArr;
8915 char *dimlist;
8916
8917 /* Allocate space for dimlist */
8918 /* --------------------------------- */
8919 dimlist = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
8920 if(dimlist == NULL)
8921 {
8922 HEpush(DFE_NOSPACE,"GDdefvrtregion", __FILE__, __LINE__);
8923 return(-1);
8924 }
8925 /* Check for valid grid ID */
8926 /* ----------------------- */
8927 status = GDchkgdid(gridID, "GDdefvrtregion",
8928 &fid, &sdInterfaceID, &gdVgrpID);
8929
8930 if (status == 0)
8931 {
8932 memcpy(dimlist, vertObj, 4);
8933 dimlist[4] = 0;
8934
8935 if (strcmp(dimlist, "DIM:") == 0)
8936 {
8937 slen = strlen(vertObj) - 4;
8938 if (regionID == -1)
8939 {
8940 SETGRIDREG;
8941 }
8942 for (j = 0; j < 8; j++)
8943 {
8944 if (GDXRegion[regionID]->StartVertical[j] == -1)
8945 {
8946 GDXRegion[regionID]->StartVertical[j] = (int32) range[0];
8947 GDXRegion[regionID]->StopVertical[j] = (int32) range[1];
8948 GDXRegion[regionID]->DimNamePtr[j] =
8949 (char *) malloc(slen + 1);
8950 if(GDXRegion[regionID]->DimNamePtr[j] == NULL)
8951 {
8952 HEpush(DFE_NOSPACE,"GDdefvrtregion", __FILE__, __LINE__);
8953 free(dimlist);
8954 return(-1);
8955 }
8956 memcpy(GDXRegion[regionID]->DimNamePtr[j],
8957 vertObj + 4, slen + 1);
8958 break;
8959 }
8960 }
8961 }
8962 else
8963 {
8964 status = GDfieldinfo(gridID, vertObj, &rank, dims, &nt, dimlist);
8965 if (status != 0)
8966 {
8967 status = -1;
8968 HEpush(DFE_GENAPP, "GDdefvrtregion", __FILE__, __LINE__);
8969 HEreport("Vertical Field: \"%s\" not found.\n", vertObj);
8970 }
8971 else
8972 {
8973 if (rank != 1)
8974 {
8975 status = -1;
8976 HEpush(DFE_GENAPP, "GDdefvrtregion", __FILE__, __LINE__);
8977 HEreport("Vertical Field: \"%s\" must be 1-dim.\n",
8978 vertObj);
8979 }
8980 else
8981 {
8982 slen = strlen(dimlist);
8983 size = DFKNTsize(nt);
8984 vertArr = (char *) calloc(dims[0], size);
8985 if(vertArr == NULL)
8986 {
8987 HEpush(DFE_NOSPACE,"GDdefvrtregion", __FILE__, __LINE__);
8988 free(dimlist);
8989 return(-1);
8990 }
8991
8992 status = GDreadfield(gridID, vertObj,
8993 NULL, NULL, NULL, vertArr);
8994
8995 switch (nt)
8996 {
8997 case DFNT_INT16:
8998
8999 for (i = 0; i < dims[0]; i++)
9000 {
9001 memcpy(&vertINT16, vertArr + i * size, size);
9002
9003 if (vertINT16 >= range[0] &&
9004 vertINT16 <= range[1])
9005 {
9006 found = 1;
9007 if (regionID == -1)
9008 {
9009 SETGRIDREG;
9010 }
9011 FILLVERTREG;
9012
9013 break;
9014 }
9015 }
9016
9017 if (found == 1)
9018 {
9019 for (i = dims[0] - 1; i >= 0; i--)
9020 {
9021 memcpy(&vertINT16, vertArr + i * size, size);
9022
9023 if (vertINT16 >= range[0] &&
9024 vertINT16 <= range[1])
9025 {
9026 GDXRegion[regionID]->StopVertical[j] = i;
9027 break;
9028 }
9029 }
9030 }
9031 else
9032 {
9033 status = -1;
9034 }
9035 break;
9036
9037
9038 case DFNT_INT32:
9039
9040 for (i = 0; i < dims[0]; i++)
9041 {
9042 memcpy(&vertINT32, vertArr + i * size, size);
9043
9044 if (vertINT32 >= range[0] &&
9045 vertINT32 <= range[1])
9046 {
9047 found = 1;
9048 if (regionID == -1)
9049 {
9050 SETGRIDREG;
9051 }
9052 FILLVERTREG;
9053
9054 break;
9055 }
9056 }
9057
9058 if (found == 1)
9059 {
9060 for (i = dims[0] - 1; i >= 0; i--)
9061 {
9062 memcpy(&vertINT32, vertArr + i * size, size);
9063
9064 if (vertINT32 >= range[0] &&
9065 vertINT32 <= range[1])
9066 {
9067 GDXRegion[regionID]->StopVertical[j] = i;
9068 break;
9069 }
9070 }
9071 }
9072 else
9073 {
9074 status = -1;
9075 }
9076 break;
9077
9078
9079 case DFNT_FLOAT32:
9080
9081 for (i = 0; i < dims[0]; i++)
9082 {
9083 memcpy(&vertFLT32, vertArr + i * size, size);
9084
9085 if (vertFLT32 >= range[0] &&
9086 vertFLT32 <= range[1])
9087 {
9088 found = 1;
9089 if (regionID == -1)
9090 {
9091 SETGRIDREG;
9092 }
9093 FILLVERTREG;
9094
9095 break;
9096 }
9097 }
9098
9099 if (found == 1)
9100 {
9101 for (i = dims[0] - 1; i >= 0; i--)
9102 {
9103 memcpy(&vertFLT32, vertArr + i * size, size);
9104
9105 if (vertFLT32 >= range[0] &&
9106 vertFLT32 <= range[1])
9107 {
9108 GDXRegion[regionID]->StopVertical[j] = i;
9109 break;
9110 }
9111 }
9112 }
9113 else
9114 {
9115 status = -1;
9116 }
9117 break;
9118
9119
9120 case DFNT_FLOAT64:
9121
9122 for (i = 0; i < dims[0]; i++)
9123 {
9124 memcpy(&vertFLT64, vertArr + i * size, size);
9125
9126 if (vertFLT64 >= range[0] &&
9127 vertFLT64 <= range[1])
9128 {
9129 found = 1;
9130 if (regionID == -1)
9131 {
9132 SETGRIDREG;
9133 }
9134 FILLVERTREG;
9135
9136 break;
9137 }
9138 }
9139
9140 if (found == 1)
9141 {
9142 for (i = dims[0] - 1; i >= 0; i--)
9143 {
9144 memcpy(&vertFLT64, vertArr + i * size, size);
9145
9146 if (vertFLT64 >= range[0] &&
9147 vertFLT64 <= range[1])
9148 {
9149 GDXRegion[regionID]->StopVertical[j] = i;
9150 break;
9151 }
9152 }
9153 }
9154 else
9155 {
9156 status = -1;
9157 }
9158 break;
9159
9160 }
9161 free(vertArr);
9162 }
9163 }
9164 }
9165 }
9166 if (status == -1)
9167 {
9168 regionID = -1;
9169 }
9170 free(dimlist);
9171 return (regionID);
9172 }
9173
9174
9175
9176
9177
9178 /*----------------------------------------------------------------------------|
9179 | BEGIN_PROLOG |
9180 | |
9181 | FUNCTION: GDdeftimeperiod |
9182 | |
9183 | DESCRIPTION: Finds elements of the "Time" field within a given time |
9184 | period. |
9185 | |
9186 | |
9187 | Return Value Type Units Description |
9188 | ============ ====== ========= ===================================== |
9189 | periodID int32 Period ID |
9190 | |
9191 | INPUTS: |
9192 | gridID int32 Grid structure ID |
9193 | periodID int32 Period ID |
9194 | starttime float64 TAI sec Start of time period |
9195 | stoptime float64 TAI sec Stop of time period |
9196 | |
9197 | OUTPUTS: |
9198 | None |
9199 | |
9200 | NOTES: |
9201 | |
9202 | |
9203 | Date Programmer Description |
9204 | ====== ============ ================================================= |
9205 | Aug 96 Joel Gales Original Programmer |
9206 | |
9207 | END_PROLOG |
9208 -----------------------------------------------------------------------------*/
9209 int32
GDdeftimeperiod(int32 gridID,int32 periodID,float64 starttime,float64 stoptime)9210 GDdeftimeperiod(int32 gridID, int32 periodID, float64 starttime,
9211 float64 stoptime)
9212 {
9213 float64 timerange[2];
9214
9215 timerange[0] = starttime;
9216 timerange[1] = stoptime;
9217
9218 periodID = GDdefvrtregion(gridID, periodID, "Time", timerange);
9219
9220 return (periodID);
9221 }
9222
9223
9224
9225 /*----------------------------------------------------------------------------|
9226 | BEGIN_PROLOG |
9227 | |
9228 | FUNCTION: GDgetpixels |
9229 | |
9230 | DESCRIPTION: Finds row and columns for specified lon/lat values |
9231 | |
9232 | |
9233 | Return Value Type Units Description |
9234 | ============ ====== ========= ===================================== |
9235 | status intn return status (0) SUCCEED, (-1) FAIL |
9236 | |
9237 | INPUTS: |
9238 | gridID int32 Grid structure ID |
9239 | nLonLat int32 Number of lonlat values |
9240 | lonVal float64 dec deg Longitude values |
9241 | latVal float64 dec deg Latitude values |
9242 | |
9243 | |
9244 | OUTPUTS: |
9245 | pixRow int32 Pixel rows |
9246 | pixCol int32 Pixel columns |
9247 | |
9248 | NOTES: |
9249 | |
9250 | |
9251 | Date Programmer Description |
9252 | ====== ============ ================================================= |
9253 | Aug 96 Joel Gales Original Programmer |
9254 | Oct 96 Joel Gales Set row/col to -1 if outside boundary |
9255 | Mar 97 Joel Gales Adjust row/col for CORNER pixel registration |
9256 | |
9257 | END_PROLOG |
9258 -----------------------------------------------------------------------------*/
9259 intn
GDgetpixels(int32 gridID,int32 nLonLat,float64 lonVal[],float64 latVal[],int32 pixRow[],int32 pixCol[])9260 GDgetpixels(int32 gridID, int32 nLonLat, float64 lonVal[], float64 latVal[],
9261 int32 pixRow[], int32 pixCol[])
9262 {
9263 intn i; /* Loop index */
9264 intn status = 0; /* routine return status variable */
9265
9266 int32 fid; /* HDF-EOS file ID */
9267 int32 sdInterfaceID; /* HDF SDS interface ID */
9268 int32 gdVgrpID; /* Grid root Vgroup ID */
9269
9270 int32 xdimsize; /* Size of "XDim" */
9271 int32 ydimsize; /* Size of "YDim" */
9272 int32 projcode; /* GCTP projection code */
9273 int32 zonecode; /* Zone code */
9274 int32 spherecode; /* Sphere code */
9275 int32 origincode; /* Origin code */
9276 int32 pixregcode; /* Pixel registration code */
9277
9278 float64 upleftpt[2];/* Upper left point */
9279 float64 lowrightpt[2]; /* Lower right point */
9280 float64 projparm[16]; /* Projection parameters */
9281 float64 *xVal; /* Pointer to point x location values */
9282 float64 *yVal; /* Pointer to point y location values */
9283
9284
9285 /* Check for valid grid ID */
9286 /* ----------------------- */
9287 status = GDchkgdid(gridID, "GDgetpixels", &fid, &sdInterfaceID, &gdVgrpID);
9288
9289 if (status == 0)
9290 {
9291 /* Get grid info */
9292 /* ------------- */
9293 status = GDgridinfo(gridID, &xdimsize, &ydimsize,
9294 upleftpt, lowrightpt);
9295
9296
9297 /* Get projection info */
9298 /* ------------------- */
9299 status = GDprojinfo(gridID, &projcode, &zonecode,
9300 &spherecode, projparm);
9301
9302
9303 /* Get explicit upleftpt & lowrightpt if defaults are used */
9304 /* ------------------------------------------------------- */
9305 status = GDgetdefaults(projcode, zonecode, projparm, spherecode,
9306 upleftpt, lowrightpt);
9307
9308
9309 /* Get pixel registration and origin info */
9310 /* -------------------------------------- */
9311 status = GDorigininfo(gridID, &origincode);
9312 status = GDpixreginfo(gridID, &pixregcode);
9313
9314
9315 /* Allocate space for x & y locations */
9316 /* ---------------------------------- */
9317 xVal = (float64 *) calloc(nLonLat, sizeof(float64));
9318 if(xVal == NULL)
9319 {
9320 HEpush(DFE_NOSPACE,"GDgetpixels", __FILE__, __LINE__);
9321 return(-1);
9322 }
9323 yVal = (float64 *) calloc(nLonLat, sizeof(float64));
9324 if(yVal == NULL)
9325 {
9326 HEpush(DFE_NOSPACE,"GDgetpixels", __FILE__, __LINE__);
9327 free(xVal);
9328 return(-1);
9329 }
9330
9331
9332 /* Get pixRow, pixCol, xVal, & yVal */
9333 /* -------------------------------- */
9334 status = GDll2ij(projcode, zonecode, projparm, spherecode,
9335 xdimsize, ydimsize, upleftpt, lowrightpt,
9336 nLonLat, lonVal, latVal, pixRow, pixCol,
9337 xVal, yVal);
9338
9339
9340
9341 /* Loop through all lon/lat values */
9342 /* ------------------------------- */
9343 for (i = 0; i < nLonLat; i++)
9344 {
9345 /* Adjust columns & rows for "corner" registered grids */
9346 /* --------------------------------------------------- */
9347 if (pixregcode == HDFE_CORNER)
9348 {
9349 if (origincode == HDFE_GD_UL)
9350 {
9351 if (xVal[i] - pixCol[i] > 0.5)
9352 {
9353 ++pixCol[i];
9354 }
9355
9356 if (yVal[i] - pixRow[i] > 0.5)
9357 {
9358 ++pixRow[i];
9359 }
9360 }
9361 else if (origincode == HDFE_GD_UR)
9362 {
9363 if (xVal[i] - pixCol[i] <= 0.5)
9364 {
9365 --pixCol[i];
9366 }
9367
9368 if (yVal[i] - pixRow[i] > 0.5)
9369 {
9370 ++pixRow[i];
9371 }
9372 }
9373 else if (origincode == HDFE_GD_LL)
9374 {
9375 if (xVal[i] - pixCol[i] > 0.5)
9376 {
9377 ++pixCol[i];
9378 }
9379
9380 if (yVal[i] - pixRow[i] <= 0.5)
9381 {
9382 --pixRow[i];
9383 }
9384 }
9385 else if (origincode == HDFE_GD_LR)
9386 {
9387 if (xVal[i] - pixCol[i] <= 0.5)
9388 {
9389 --pixCol[i];
9390 }
9391
9392 if (yVal[i] - pixRow[i] <= 0.5)
9393 {
9394 --pixRow[i];
9395 }
9396 }
9397 }
9398
9399
9400 /* If outside grid boundaries then set to -1 */
9401 /* ----------------------------------------- */
9402 if (pixCol[i] < 0 || pixCol[i] >= xdimsize ||
9403 pixRow[i] < 0 || pixRow[i] >= ydimsize)
9404 {
9405 pixCol[i] = -1;
9406 pixRow[i] = -1;
9407 }
9408 }
9409 free(xVal);
9410 free(yVal);
9411 }
9412 return (status);
9413 }
9414
9415
9416
9417
9418
9419 /*----------------------------------------------------------------------------|
9420 | BEGIN_PROLOG |
9421 | |
9422 | FUNCTION: GDgetpixvalues |
9423 | |
9424 | DESCRIPTION: Retrieves data from specified pixels. |
9425 | |
9426 | |
9427 | Return Value Type Units Description |
9428 | ============ ====== ========= ===================================== |
9429 | size*nPixels int32 Size of data buffer |
9430 | |
9431 | INPUTS: |
9432 | gridID int32 Grid structure ID |
9433 | nPixels int32 Number of pixels |
9434 | pixRow int32 Pixel row numbers |
9435 | pixCol int32 Pixel column numbers |
9436 | fieldname char Fieldname |
9437 | |
9438 | OUTPUTS: |
9439 | buffer void Data buffer |
9440 | |
9441 | |
9442 | NOTES: |
9443 | |
9444 | |
9445 | Date Programmer Description |
9446 | ====== ============ ================================================= |
9447 | Aug 96 Joel Gales Original Programmer |
9448 | Oct 96 Joel Gales Check for pixels outside boundaries (-1) |
9449 | Mar 98 Abe Taaheri revised to reduce overhead for rechecking |
9450 | for gridid, fieldname, etc in GDreadfield. |
9451 | June 98 AT fixed bug with 2-dim field merged in 3-dim field |
9452 | (for offset and count) |
9453 | END_PROLOG |
9454 -----------------------------------------------------------------------------*/
9455 int32
GDgetpixvalues(int32 gridID,int32 nPixels,int32 pixRow[],int32 pixCol[],char * fieldname,VOIDP buffer)9456 GDgetpixvalues(int32 gridID, int32 nPixels, int32 pixRow[], int32 pixCol[],
9457 char *fieldname, VOIDP buffer)
9458 {
9459 intn i; /* Loop index */
9460 intn j; /* Loop index */
9461 intn status = 0; /* routine return status variable */
9462
9463 int32 fid; /* HDF-EOS file ID */
9464 int32 sdInterfaceID; /* HDF SDS interface ID */
9465 int32 gdVgrpID; /* Grid root Vgroup ID */
9466
9467 int32 start[8]; /* GDreadfield start array */
9468 int32 edge[8]; /* GDreadfield edge array */
9469 int32 dims[8]; /* Field dimensions */
9470 int32 rank; /* Field rank */
9471 int32 xdum; /* Location of "XDim" within field list */
9472 int32 ydum; /* Location of "YDim" within field list */
9473 int32 ntype; /* Field number type */
9474 int32 origincode; /* Origin code */
9475 int32 bufOffset; /* Data buffer offset */
9476 int32 size; /* Size of returned data buffer for each
9477 * value in bytes */
9478 int32 offset[8]; /* I/O offset (start) */
9479 int32 incr[8]; /* I/O increment (stride) */
9480 int32 count[8]; /* I/O count (edge) */
9481 int32 sdid; /* SDS ID */
9482 int32 rankSDS; /* Rank of SDS */
9483 int32 rankFld; /* Rank of field */
9484 int32 dum; /* Dummy variable */
9485 int32 mrgOffset; /* Merged field offset */
9486
9487 char *dimlist; /* Dimension list */
9488
9489
9490
9491 /* Allocate space for dimlist */
9492 /* --------------------------------- */
9493 dimlist = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
9494 if(dimlist == NULL)
9495 {
9496 HEpush(DFE_NOSPACE,"GDgetpixvalues", __FILE__, __LINE__);
9497 return(-1);
9498 }
9499 /* Check for valid grid ID */
9500 /* ----------------------- */
9501 status = GDchkgdid(gridID, "GDgetpixvalues",
9502 &fid, &sdInterfaceID, &gdVgrpID);
9503
9504
9505 if (status == 0)
9506 {
9507 /* Get field list */
9508 /* -------------- */
9509 status = GDfieldinfo(gridID, fieldname, &rank, dims, &ntype, dimlist);
9510
9511
9512 /* Check for "XDim" & "YDim" in dimension list */
9513 /* ------------------------------------------- */
9514 if (status == 0)
9515 {
9516 xdum = EHstrwithin("XDim", dimlist, ',');
9517 ydum = EHstrwithin("YDim", dimlist, ',');
9518
9519 if (xdum == -1)
9520 {
9521 status = -1;
9522 HEpush(DFE_GENAPP, "GDgetpixvalues", __FILE__, __LINE__);
9523 HEreport(
9524 "\"XDim\" not present in dimlist for field: \"%s\".\n",
9525 fieldname);
9526 }
9527
9528
9529 if (ydum == -1)
9530 {
9531 status = -1;
9532 HEpush(DFE_GENAPP, "GDgetpixvalues", __FILE__, __LINE__);
9533 HEreport(
9534 "\"YDim\" not present in dimlist for field: \"%s\".\n",
9535 fieldname);
9536 }
9537 }
9538 else
9539 {
9540 status = -1;
9541 HEpush(DFE_GENAPP, "GDgetpixvalues", __FILE__, __LINE__);
9542 HEreport("Fieldname \"%s\" not found.\n", fieldname);
9543 }
9544
9545
9546 if (status == 0)
9547 {
9548
9549 /* Get origin order info */
9550 /* --------------------- */
9551 status = GDorigininfo(gridID, &origincode);
9552
9553
9554 /* Initialize start & edge arrays */
9555 /* ------------------------------ */
9556 for (i = 0; i < rank; i++)
9557 {
9558 start[i] = 0;
9559 edge[i] = dims[i];
9560 }
9561
9562
9563 /* Compute size of data buffer for each pixel */
9564 /* ------------------------------------------ */
9565 edge[xdum] = 1;
9566 edge[ydum] = 1;
9567 size = edge[0];
9568 for (j = 1; j < rank; j++)
9569 {
9570 size *= edge[j];
9571 }
9572 size *= DFKNTsize(ntype);
9573
9574
9575
9576 /* If data values are requested ... */
9577 /* -------------------------------- */
9578 if (buffer != NULL)
9579 {
9580 /* get sdid */
9581 status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
9582 &rankSDS, &rankFld, &mrgOffset, dims, &dum);
9583
9584 /* Loop through all pixels */
9585 /* ----------------------- */
9586 for (i = 0; i < nPixels; i++)
9587 {
9588 /* Conmpute offset within returned data buffer */
9589 /* ------------------------------------------- */
9590 bufOffset = size * i;
9591
9592
9593 /* If pixel row & column OK ... */
9594 /* ---------------------------- */
9595 if (pixCol[i] != -1 && pixRow[i] != -1)
9596 {
9597 start[xdum] = pixCol[i];
9598 start[ydum] = pixRow[i];
9599
9600
9601 /* Adjust X-dim start if origin on right edge */
9602 /* ------------------------------------------ */
9603 if ((origincode & 1) == 1)
9604 {
9605 start[xdum] = dims[xdum] - (start[xdum] + 1);
9606 }
9607
9608
9609 /* Adjust Y-dim start if origin on lower edge */
9610 /* ------------------------------------------ */
9611 if ((origincode & 2) == 2)
9612 {
9613 start[ydum] = dims[ydum] - (start[ydum] + 1);
9614 }
9615
9616 /* Set I/O offset and count Section */
9617 /* ---------------------- */
9618
9619 /*
9620 * start and edge != NULL, set I/O offset and count to
9621 * user values, adjusting the
9622 * 0th field with the merged field offset (if any)
9623 */
9624 if (rankFld == rankSDS)
9625 {
9626 for (j = 0; j < rankSDS; j++)
9627 {
9628 offset[j] = start[j];
9629 count[j] = edge[j];
9630 }
9631 offset[0] += mrgOffset;
9632 }
9633 else
9634 {
9635 /*
9636 * If field really 2-dim merged in 3-dim field then set
9637 * 0th field offset to merge offset and then next two to
9638 * the user values
9639 */
9640 for (j = 0; j < rankFld; j++)
9641 {
9642 offset[j + 1] = start[j];
9643 count[j + 1] = edge[j];
9644 }
9645 offset[0] = mrgOffset;
9646 count[0] = 1;
9647 }
9648
9649
9650
9651 /* Set I/O stride Section */
9652 /* ---------------------- */
9653
9654 /* In original code stride enetred as NULL.
9655 Abe Taaheri June 12, 1998 */
9656 /*
9657 * If stride == NULL (default) set I/O stride to 1
9658 */
9659 for (j = 0; j < rankSDS; j++)
9660 {
9661 incr[j] = 1;
9662 }
9663
9664
9665 /* Read into data buffer */
9666 /* --------------------- */
9667 status = SDreaddata(sdid,
9668 offset, incr, count,
9669 (VOIDP) ((uint8 *) buffer + bufOffset));
9670 }
9671 }
9672 }
9673 }
9674 }
9675
9676
9677 /* If successful return size of returned data in bytes */
9678 /* --------------------------------------------------- */
9679 if (status == 0)
9680 {
9681 free(dimlist);
9682 return (size * nPixels);
9683 }
9684 else
9685 {
9686 free(dimlist);
9687 return ((int32) status);
9688 }
9689 }
9690
9691
9692 /*----------------------------------------------------------------------------|
9693 | BEGIN_PROLOG |
9694 | |
9695 | FUNCTION: GDinterpolate |
9696 | |
9697 | DESCRIPTION: Performs bilinear interpolate on a set of xy values |
9698 | |
9699 | |
9700 | Return Value Type Units Description |
9701 | ============ ====== ========= ===================================== |
9702 | nRetn*nValues* int32 Size of data buffer |
9703 | sizeof(float64) |
9704 | |
9705 | INPUTS: |
9706 | gridID int32 Grid structure ID |
9707 | nValues int32 Number of lon/lat points to interpolate |
9708 | xyValues float64 XY values of points to interpolate |
9709 | fieldname char Fieldname |
9710 | |
9711 | OUTPUTS: |
9712 | interpVal float64 Interpolated Data Values |
9713 | |
9714 | |
9715 | NOTES: |
9716 | |
9717 | |
9718 | Date Programmer Description |
9719 | ====== ============ ================================================= |
9720 | Aug 96 Joel Gales Original Programmer |
9721 | Oct 96 Joel Gales Fix array index problem with interpVal write |
9722 | Apr 97 Joel Gales Trap interpolation boundary out of bounds error |
9723 | Jun 98 Abe Taaheri changed the return value so that the Return Value |
9724 | is size in bytes for the data buffer which is |
9725 | float64.
9726 | |
9727 | END_PROLOG |
9728 -----------------------------------------------------------------------------*/
9729 int32
GDinterpolate(int32 gridID,int32 nValues,float64 lonVal[],float64 latVal[],char * fieldname,float64 interpVal[])9730 GDinterpolate(int32 gridID, int32 nValues, float64 lonVal[], float64 latVal[],
9731 char *fieldname, float64 interpVal[])
9732 {
9733 intn i; /* Loop index */
9734 intn j; /* Loop index */
9735 intn k; /* Loop index */
9736 intn status = 0; /* routine return status variable */
9737
9738 int32 fid; /* HDF-EOS file ID */
9739 int32 sdInterfaceID; /* HDF SDS interface ID */
9740 int32 gdVgrpID; /* Grid root Vgroup ID */
9741 int32 xdimsize; /* XDim size */
9742 int32 ydimsize; /* YDim size */
9743 int32 projcode; /* Projection code */
9744 int32 zonecode; /* Zone code */
9745 int32 spherecode; /* Sphere code */
9746 int32 pixregcode; /* Pixel registration code */
9747 int32 origincode; /* Origin code */
9748 int32 dims[8]; /* Field dimensions */
9749 int32 numsize; /* Size in bytes of number type */
9750 int32 rank; /* Field rank */
9751 int32 xdum; /* Location of "XDim" within field list */
9752 int32 ydum; /* Location of "YDim" within field list */
9753 int32 ntype; /* Number type */
9754 int32 dum; /* Dummy variable */
9755 int32 size; /* Size of returned data buffer for each
9756 * value in bytes */
9757 int32 pixCol[4]; /* Pixel columns for 4 nearest neighbors */
9758 int32 pixRow[4]; /* Pixel rows for 4 nearest neighbors */
9759 int32 tDen; /* Interpolation denominator value 1 */
9760 int32 uDen; /* Interpolation denominator value 2 */
9761 int32 nRetn; /* Number of data values returned */
9762
9763 float64 upleftpt[2];/* Upper left pt coordinates */
9764 float64 lowrightpt[2]; /* Lower right pt coordinates */
9765 float64 projparm[16]; /* Projection parameters */
9766 float64 xVal; /* "Exact" x location of interpolated point */
9767 float64 yVal; /* "Exact" y location of interpolated point */
9768 float64 tNum = 0.0; /* Interpolation numerator value 1 */
9769 float64 uNum = 0.0; /* Interpolation numerator value 2 */
9770
9771 int16 i16[4]; /* Working buffer (int16) */
9772 int32 i32[4]; /* Working buffer (int132) */
9773 float32 f32[4]; /* Working buffer (float32) */
9774 float64 f64[4]; /* Working buffer (float64) */
9775
9776 char *pixVal; /* Nearest neighbor values */
9777 char *dimlist; /* Dimension list */
9778
9779 /* Allocate space for dimlist */
9780 /* --------------------------------- */
9781 dimlist = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
9782 if(dimlist == NULL)
9783 {
9784 HEpush(DFE_NOSPACE,"GDinterpolate", __FILE__, __LINE__);
9785 return(-1);
9786 }
9787 /* Check for valid grid ID */
9788 /* ----------------------- */
9789 status = GDchkgdid(gridID, "GDinterpolate",
9790 &fid, &sdInterfaceID, &gdVgrpID);
9791
9792
9793 /* If no problems ... */
9794 /* ------------------ */
9795 if (status == 0)
9796 {
9797 /* Get field information */
9798 /* --------------------- */
9799 status = GDfieldinfo(gridID, fieldname, &rank, dims, &ntype, dimlist);
9800
9801
9802 /* Check for "XDim" & "YDim" in dimension list */
9803 /* ------------------------------------------- */
9804 if (status == 0)
9805 {
9806 xdum = EHstrwithin("XDim", dimlist, ',');
9807 ydum = EHstrwithin("YDim", dimlist, ',');
9808
9809 if (xdum == -1)
9810 {
9811 status = -1;
9812 HEpush(DFE_GENAPP, "GDinterpolate", __FILE__, __LINE__);
9813 HEreport(
9814 "\"XDim\" not present in dimlist for field: \"%s\".\n",
9815 fieldname);
9816 }
9817
9818
9819 if (ydum == -1)
9820 {
9821 status = -1;
9822 HEpush(DFE_GENAPP, "GDinterpolate", __FILE__, __LINE__);
9823 HEreport(
9824 "\"YDim\" not present in dimlist for field: \"%s\".\n",
9825 fieldname);
9826 }
9827 }
9828 else
9829 {
9830 /* Fieldname not found in grid */
9831 /* --------------------------- */
9832 status = -1;
9833 HEpush(DFE_GENAPP, "GDinterpolate", __FILE__, __LINE__);
9834 HEreport("Fieldname \"%s\" not found.\n", fieldname);
9835 }
9836
9837
9838 /* If no problems ... */
9839 /* ------------------ */
9840 if (status == 0)
9841 {
9842 /* Compute size of data buffer for each interpolated value */
9843 /* ------------------------------------------------------- */
9844 dims[xdum] = 1;
9845 dims[ydum] = 1;
9846 size = dims[0];
9847 for (i = 1; i < rank; i++)
9848 {
9849 size *= dims[i];
9850 }
9851 numsize = DFKNTsize(ntype);
9852 size *= numsize;
9853
9854 nRetn = size / numsize;
9855
9856
9857
9858 /* If interpolated values are requested ... */
9859 /* ---------------------------------------- */
9860 if (interpVal != NULL)
9861 {
9862 /* Get grid info */
9863 /* ------------- */
9864 status = GDgridinfo(gridID, &xdimsize, &ydimsize,
9865 upleftpt, lowrightpt);
9866
9867
9868 /* Get projection info */
9869 /* ------------------- */
9870 status = GDprojinfo(gridID, &projcode, &zonecode,
9871 &spherecode, projparm);
9872
9873
9874 /* Get explicit upleftpt & lowrightpt if defaults are used */
9875 /* ------------------------------------------------------- */
9876 status = GDgetdefaults(projcode, zonecode, projparm,
9877 spherecode, upleftpt, lowrightpt);
9878
9879
9880 /* Get pixel registration and origin info */
9881 /* -------------------------------------- */
9882 status = GDpixreginfo(gridID, &pixregcode);
9883 status = GDorigininfo(gridID, &origincode);
9884
9885
9886
9887 /* Loop through all interpolated points */
9888 /* ------------------------------------ */
9889 for (i = 0; i < nValues; i++)
9890 {
9891 /* Get row & column of point pixel */
9892 /* ------------------------------- */
9893 status = GDll2ij(projcode, zonecode, projparm, spherecode,
9894 xdimsize, ydimsize, upleftpt, lowrightpt,
9895 1, &lonVal[i], &latVal[i],
9896 pixRow, pixCol, &xVal, &yVal);
9897
9898
9899 /* Get diff of interp. point from pixel location */
9900 /* --------------------------------------------- */
9901 if (pixregcode == HDFE_CENTER)
9902 {
9903 tNum = xVal - (pixCol[0] + 0.5);
9904 uNum = yVal - (pixRow[0] + 0.5);
9905 }
9906 else if (origincode == HDFE_GD_UL)
9907 {
9908 tNum = xVal - pixCol[0];
9909 uNum = yVal - pixRow[0];
9910 }
9911 else if (origincode == HDFE_GD_UR)
9912 {
9913 tNum = xVal - (pixCol[0] + 1);
9914 uNum = yVal - pixRow[0];
9915 }
9916 else if (origincode == HDFE_GD_LL)
9917 {
9918 tNum = xVal - pixCol[0];
9919 uNum = yVal - (pixRow[0] + 1);
9920 }
9921 else if (origincode == HDFE_GD_LR)
9922 {
9923 tNum = xVal - (pixCol[0] + 1);
9924 uNum = yVal - (pixRow[0] + 1);
9925 }
9926
9927
9928 /* Get rows and columns of other nearest neighbor pixels */
9929 /* ----------------------------------------------------- */
9930 pixCol[1] = pixCol[0];
9931 pixRow[3] = pixRow[0];
9932
9933 if (tNum >= 0)
9934 {
9935 pixCol[2] = pixCol[0] + 1;
9936 pixCol[3] = pixCol[0] + 1;
9937 }
9938
9939 if (tNum < 0)
9940 {
9941 pixCol[2] = pixCol[0] - 1;
9942 pixCol[3] = pixCol[0] - 1;
9943 }
9944
9945 if (uNum >= 0)
9946 {
9947 pixRow[2] = pixRow[0] + 1;
9948 pixRow[1] = pixRow[0] + 1;
9949 }
9950
9951 if (uNum < 0)
9952 {
9953 pixRow[2] = pixRow[0] - 1;
9954 pixRow[1] = pixRow[0] - 1;
9955 }
9956
9957
9958 /* Get values of nearest neighbors */
9959 /* -------------------------------- */
9960 pixVal = (char *) malloc(4 * size);
9961 if(pixVal == NULL)
9962 {
9963 HEpush(DFE_NOSPACE,"GDinterpolate", __FILE__, __LINE__);
9964 free(dimlist);
9965 return(-1);
9966 }
9967 dum = GDgetpixvalues(gridID, 4, pixRow, pixCol,
9968 fieldname, pixVal);
9969
9970
9971 /* Trap interpolation boundary out of range error */
9972 /* ---------------------------------------------- */
9973 if (dum == -1)
9974 {
9975 status = -1;
9976 HEpush(DFE_GENAPP, "GDinterpolate", __FILE__, __LINE__);
9977 HEreport("Interpolation boundary outside of grid.\n");
9978 }
9979 else
9980 {
9981
9982 /*
9983 * Algorithm taken for Numerical Recipies in C, 2nd
9984 * edition, Section 3.6
9985 */
9986
9987 /* Perform bilinear interpolation */
9988 /* ------------------------------ */
9989 tDen = pixCol[3] - pixCol[0];
9990 uDen = pixRow[1] - pixRow[0];
9991
9992 switch (ntype)
9993 {
9994 case DFNT_INT16:
9995
9996
9997 /* Loop through all returned data values */
9998 /* ------------------------------------- */
9999 for (j = 0; j < nRetn; j++)
10000 {
10001 /* Copy 4 NN values into working array */
10002 /* ----------------------------------- */
10003 for (k = 0; k < 4; k++)
10004 {
10005 memcpy(&i16[k],
10006 pixVal + j * numsize + k * size,
10007 sizeof(int16));
10008 }
10009
10010 /* Compute interpolated value */
10011 /* -------------------------- */
10012 interpVal[i * nRetn + j] =
10013 (1 - tNum / tDen) * (1 - uNum / uDen) *
10014 i16[0] +
10015 (tNum / tDen) * (1 - uNum / uDen) *
10016 i16[3] +
10017 (tNum / tDen) * (uNum / uDen) *
10018 i16[2] +
10019 (1 - tNum / tDen) * (uNum / uDen) *
10020 i16[1];
10021 }
10022 break;
10023
10024
10025 case DFNT_INT32:
10026
10027 for (j = 0; j < nRetn; j++)
10028 {
10029 for (k = 0; k < 4; k++)
10030 {
10031 memcpy(&i32[k],
10032 pixVal + j * numsize + k * size,
10033 sizeof(int32));
10034 }
10035
10036 interpVal[i * nRetn + j] =
10037 (1 - tNum / tDen) * (1 - uNum / uDen) *
10038 i32[0] +
10039 (tNum / tDen) * (1 - uNum / uDen) *
10040 i32[3] +
10041 (tNum / tDen) * (uNum / uDen) *
10042 i32[2] +
10043 (1 - tNum / tDen) * (uNum / uDen) *
10044 i32[1];
10045 }
10046 break;
10047
10048
10049 case DFNT_FLOAT32:
10050
10051 for (j = 0; j < nRetn; j++)
10052 {
10053 for (k = 0; k < 4; k++)
10054 {
10055 memcpy(&f32[k],
10056 pixVal + j * numsize + k * size,
10057 sizeof(float32));
10058 }
10059
10060 interpVal[i * nRetn + j] =
10061 (1 - tNum / tDen) * (1 - uNum / uDen) *
10062 f32[0] +
10063 (tNum / tDen) * (1 - uNum / uDen) *
10064 f32[3] +
10065 (tNum / tDen) * (uNum / uDen) *
10066 f32[2] +
10067 (1 - tNum / tDen) * (uNum / uDen) *
10068 f32[1];
10069 }
10070 break;
10071
10072
10073 case DFNT_FLOAT64:
10074
10075 for (j = 0; j < nRetn; j++)
10076 {
10077 for (k = 0; k < 4; k++)
10078 {
10079 memcpy(&f64[k],
10080 pixVal + j * numsize + k * size,
10081 sizeof(float64));
10082 }
10083
10084 interpVal[i * nRetn + j] =
10085 (1 - tNum / tDen) * (1 - uNum / uDen) *
10086 f64[0] +
10087 (tNum / tDen) * (1 - uNum / uDen) *
10088 f64[3] +
10089 (tNum / tDen) * (uNum / uDen) *
10090 f64[2] +
10091 (1 - tNum / tDen) * (uNum / uDen) *
10092 f64[1];
10093 }
10094 break;
10095 }
10096 }
10097 free(pixVal);
10098 }
10099 }
10100 }
10101 }
10102
10103
10104 /* If successful return size of returned data in bytes */
10105 /* --------------------------------------------------- */
10106 if (status == 0)
10107 {
10108 /*always return size of float64 buffer */
10109 free(dimlist);
10110 return (nRetn * nValues * sizeof(float64));
10111 }
10112 else
10113 {
10114 free(dimlist);
10115 return ((int32) status);
10116 }
10117
10118 }
10119 /***********************************************
10120 GDwrrdtile --
10121 This function is the underlying function below GDwritetile and
10122 GDreadtile.
10123
10124
10125 Author--
10126 Alexis Zubrow
10127
10128 ********************************************************/
10129
10130 static intn
GDwrrdtile(int32 gridID,char * fieldname,char * code,int32 start[],VOIDP datbuf)10131 GDwrrdtile(int32 gridID, char *fieldname, char *code, int32 start[],
10132 VOIDP datbuf)
10133 {
10134 intn i; /* Loop index */
10135 intn status = 0; /* routine return status variable */
10136
10137 int32 fid; /* HDF-EOS file ID */
10138 int32 sdInterfaceID; /* HDF SDS interface ID */
10139 int32 sdid; /* SDS ID */
10140
10141 int32 dum; /* Dummy variable */
10142 int32 rankSDS; /* Rank of SDS/Field */
10143
10144 int32 dims[8]; /* Field/SDS dimensions */
10145 int32 tileFlags; /* flag to determine if field is tiled */
10146 int32 numTileDims;/* number of tiles spanning a dimension */
10147 HDF_CHUNK_DEF tileDef; /* union holding tiling info. */
10148
10149
10150 /* Get gridID */
10151 status = GDchkgdid(gridID, "GDwrrdtile", &fid, &sdInterfaceID, &dum);
10152 if (status == 0)
10153 {
10154
10155 /* Get field info */
10156 status = GDfieldinfo(gridID, fieldname, &rankSDS, dims, &dum, NULL);
10157
10158 if (status == 0)
10159 {
10160
10161 /* Check whether fieldname is in SDS (multi-dim field) */
10162 /* --------------------------------------------------- */
10163 status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
10164 &rankSDS, &dum, &dum, dims, &dum);
10165
10166
10167
10168 /*
10169 * Check for errors in parameters passed to GDwritetile or
10170 * GDreadtile
10171 */
10172
10173 /* Check if untiled field */
10174 status = SDgetchunkinfo(sdid, &tileDef, &tileFlags);
10175 if (tileFlags == HDF_NONE)
10176 {
10177 HEpush(DFE_GENAPP, "GDwrrdtile", __FILE__, __LINE__);
10178 HEreport("Field \"%s\" is not tiled.\n", fieldname);
10179 status = -1;
10180 return (status);
10181
10182 }
10183
10184 /*
10185 * Check if rd/wr tilecoords are within the extent of the field
10186 */
10187 for (i = 0; i < rankSDS; i++)
10188 {
10189 /*
10190 * Calculate the number of tiles which span a dimension of
10191 * the field
10192 */
10193 numTileDims = dims[i] / tileDef.chunk_lengths[i];
10194 if ((start[i] >= numTileDims) || (start[i] < 0))
10195 {
10196 /*
10197 * ERROR INDICATING BEYOND EXTENT OF THAT DIMENSION OR
10198 * NEGATIVE TILECOORDS
10199 */
10200 HEpush(DFE_GENAPP, "GDwrrdtile", __FILE__, __LINE__);
10201 HEreport("Tilecoords for dimension \"%d\" ...\n", i);
10202 HEreport("is beyond the extent of dimension length\n");
10203 status = -1;
10204
10205 }
10206 }
10207
10208 if (status == -1)
10209 {
10210 return (status);
10211 }
10212
10213
10214 /* Actually write/read to the field */
10215
10216 if (strcmp(code, "w") == 0) /* write tile */
10217 {
10218 status = SDwritechunk(sdid, start, (VOIDP) datbuf);
10219 }
10220 else if (strcmp(code, "r") == 0) /* read tile */
10221 {
10222 status = SDreadchunk(sdid, start, (VOIDP) datbuf);
10223 }
10224
10225
10226 }
10227
10228 /* Non-existent fieldname */
10229 else
10230 {
10231 HEpush(DFE_GENAPP, "GDwrrdtile", __FILE__, __LINE__);
10232 HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
10233 status = -1;
10234 }
10235
10236 }
10237
10238 return (status);
10239 }
10240
10241
10242 /***********************************************
10243 GDtileinfo --
10244 This function queries the field to determine if it is tiled. If it is
10245 tile, one can retrieve some of the characteristics of the tiles.
10246
10247 Author-- Alexis Zubrow
10248
10249 ********************************************************/
10250
10251
10252 intn
GDtileinfo(int32 gridID,char * fieldname,int32 * tilecode,int32 * tilerank,int32 tiledims[])10253 GDtileinfo(int32 gridID, char *fieldname, int32 * tilecode, int32 * tilerank,
10254 int32 tiledims[])
10255
10256 {
10257 intn i; /* Loop index */
10258 intn status = 0; /* routine return status variable */
10259
10260 int32 fid; /* HDF-EOS file ID */
10261 int32 sdInterfaceID; /* HDF SDS interface ID */
10262 int32 sdid; /* SDS ID */
10263
10264 int32 dum; /* Dummy variable */
10265 int32 rankSDS; /* Rank of SDS/Field/tile */
10266
10267 int32 dims[8]; /* Field/SDS dimensions */
10268 int32 tileFlags; /* flag to determine if field is tiled */
10269 HDF_CHUNK_DEF tileDef; /* union holding tiling info. */
10270
10271
10272 /* Check if improper gridID */
10273 status = GDchkgdid(gridID, "GDtileinfo", &fid, &sdInterfaceID, &dum);
10274 if (status == 0)
10275 {
10276
10277 /* Get field info */
10278 status = GDfieldinfo(gridID, fieldname, &rankSDS, dims, &dum, NULL);
10279
10280 if (status == 0)
10281 {
10282
10283 /* Check whether fieldname is in SDS (multi-dim field) */
10284 /* --------------------------------------------------- */
10285 status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
10286 &rankSDS, &dum, &dum, dims, &dum);
10287
10288
10289
10290 /* Query field for tiling information */
10291 status = SDgetchunkinfo(sdid, &tileDef, &tileFlags);
10292
10293 /* If field is untiled, return untiled flag */
10294 if (tileFlags == HDF_NONE)
10295 {
10296 *tilecode = HDFE_NOTILE;
10297 return (status);
10298 }
10299
10300 /* IF field is tiled or tiled with compression */
10301 else if ((tileFlags == HDF_CHUNK) ||
10302 (tileFlags == (HDF_CHUNK | HDF_COMP)))
10303 {
10304 if (tilecode != NULL)
10305 {
10306 *tilecode = HDFE_TILE;
10307 }
10308 if (tilerank != NULL)
10309 {
10310 *tilerank = rankSDS;
10311 }
10312 if (tiledims != NULL)
10313 {
10314 /* Assign size of tile dimensions */
10315 for (i = 0; i < rankSDS; i++)
10316 {
10317 tiledims[i] = tileDef.chunk_lengths[i];
10318 }
10319 }
10320 }
10321 }
10322
10323 /* Non-existent fieldname */
10324 else
10325 {
10326 HEpush(DFE_GENAPP, "GDtileinfo", __FILE__, __LINE__);
10327 HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
10328 status = -1;
10329 }
10330
10331 }
10332 return (status);
10333 }
10334 /***********************************************
10335 GDwritetile --
10336 This function writes one tile to a particular field.
10337
10338
10339 Author--
10340 Alexis Zubrow
10341
10342 ********************************************************/
10343
10344 intn
GDwritetile(int32 gridID,char * fieldname,int32 tilecoords[],VOIDP tileData)10345 GDwritetile(int32 gridID, char *fieldname, int32 tilecoords[],
10346 VOIDP tileData)
10347 {
10348 char code[] = "w"; /* write tile code */
10349 intn status = 0; /* routine return status variable */
10350
10351 status = GDwrrdtile(gridID, fieldname, code, tilecoords, tileData);
10352
10353 return (status);
10354 }
10355 /***********************************************
10356 GDreadtile --
10357 This function reads one tile from a particular field.
10358
10359
10360 Author--
10361 Alexis Zubrow
10362
10363 ********************************************************/
10364
10365 intn
GDreadtile(int32 gridID,char * fieldname,int32 tilecoords[],VOIDP tileData)10366 GDreadtile(int32 gridID, char *fieldname, int32 tilecoords[],
10367 VOIDP tileData)
10368 {
10369 char code[] = "r"; /* read tile code */
10370 intn status = 0; /* routine return status variable */
10371
10372 status = GDwrrdtile(gridID, fieldname, code, tilecoords, tileData);
10373
10374 return (status);
10375 }
10376 /***********************************************
10377 GDsettilecache --
10378 This function sets the cache size for a tiled field.
10379
10380
10381 Author--
10382 Alexis Zubrow
10383
10384 ********************************************************/
10385
10386 intn
GDsettilecache(int32 gridID,char * fieldname,int32 maxcache,int32 cachecode)10387 GDsettilecache(int32 gridID, char *fieldname, int32 maxcache, int32 cachecode)
10388 {
10389
10390 intn status = 0; /* routine return status variable */
10391
10392 int32 fid; /* HDF-EOS file ID */
10393 int32 sdInterfaceID; /* HDF SDS interface ID */
10394 int32 sdid; /* SDS ID */
10395
10396 int32 dum; /* Dummy variable */
10397
10398 int32 dims[8]; /* Field/SDS dimensions */
10399
10400
10401 /* Check gridID */
10402 status = GDchkgdid(gridID, "GDwrrdtile", &fid, &sdInterfaceID, &dum);
10403 if (status == 0)
10404 {
10405
10406 /* Get field info */
10407 status = GDfieldinfo(gridID, fieldname, &dum, dims, &dum, NULL);
10408
10409 if (status == 0)
10410 {
10411
10412 /* Check whether fieldname is in SDS (multi-dim field) */
10413 /* --------------------------------------------------- */
10414 status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
10415 &dum, &dum, &dum, dims, &dum);
10416
10417
10418 /* Check if maxcache is less than or equal to zero */
10419 if (maxcache <= 0)
10420 {
10421 HEpush(DFE_GENAPP, "GDsettilecache", __FILE__, __LINE__);
10422 HEreport("Improper maxcache \"%d\"... \n", maxcache);
10423 HEreport("maxcache must be greater than zero.\n");
10424 status = -1;
10425 return (status);
10426 }
10427
10428
10429 /* Set the number of tiles to cache */
10430 /* Presently, the only cache flag allowed is 0 */
10431 status = SDsetchunkcache(sdid, maxcache, 0);
10432
10433
10434 }
10435
10436 /* Non-existent fieldname */
10437 else
10438 {
10439 HEpush(DFE_GENAPP, "GDwrrdtile", __FILE__, __LINE__);
10440 HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
10441 status = -1;
10442 }
10443
10444 }
10445
10446 return (status);
10447 }
10448
10449 /*----------------------------------------------------------------------------|
10450 | BEGIN_PROLOG |
10451 | |
10452 | FUNCTION: GDsettilecomp |
10453 | |
10454 | DESCRIPTION: Sets the tiling/compression parameters for the specified |
10455 | field. This can be called after GDsetfillvalue and assumes |
10456 | that the field was defined with no compression/tiling set |
10457 | by GDdeftile or GDdefcomp. |
10458 | |
10459 | This function replaces the following sequence: |
10460 | GDdefcomp |
10461 | GDdeftile |
10462 | GDdeffield |
10463 | GDsetfillvalue |
10464 | with: |
10465 | GDdeffield |
10466 | GDsetfillvalue |
10467 | GDsettilecomp |
10468 | so that fill values will work correctly. |
10469 | |
10470 | Return Value Type Units Description |
10471 | ============ ====== ========= ===================================== |
10472 | status intn return status (0) SUCCEED, (-1) FAIL |
10473 | |
10474 | INPUTS: |
10475 | gridID int32 grid structure ID |
10476 | fieldname char field name |
10477 | tilerank int32 number of tiling dimensions |
10478 | tiledims int32 tiling dimensions |
10479 | compcode int32 compression code |
10480 | compparm intn compression parameters |
10481 | |
10482 | OUTPUTS: |
10483 | None |
10484 | |
10485 | NOTES: |
10486 | |
10487 | |
10488 | Date Programmer Description |
10489 | ====== ============ ================================================= |
10490 | Jun 98 MISR Used GDsetfillvalue as a template and copied |
10491 | tiling/comp portions of GDdeffield.(NCR15866). |
10492 | |
10493 | END_PROLOG |
10494 -----------------------------------------------------------------------------*/
10495 intn
GDsettilecomp(int32 gridID,char * fieldname,int32 tilerank,int32 * tiledims,int32 compcode,intn * compparm)10496 GDsettilecomp(int32 gridID, char *fieldname, int32 tilerank, int32*
10497 tiledims, int32 compcode, intn* compparm)
10498 {
10499 intn status; /* routine return status variable */
10500
10501 int32 fid; /* HDF-EOS file ID */
10502 int32 sdInterfaceID; /* HDF SDS interface ID */
10503 int32 gdVgrpID; /* Grid root Vgroup ID */
10504 int i; /* Looping variable. */
10505 int32 sdid; /* SDS id */
10506 int32 nt; /* Number type */
10507 int32 dims[8]; /* Dimensions array */
10508 int32 dum; /* Dummy variable */
10509 int32 solo; /* "Solo" (non-merged) field flag */
10510 comp_info c_info; /* Compression parameter structure */
10511 HDF_CHUNK_DEF chunkDef; /* Tiling structure */
10512 int32 chunkFlag; /* Chunking (Tiling) flag */
10513
10514 /* Check for valid grid ID and get SDS interface ID */
10515 status = GDchkgdid(gridID, "GDsetfillvalue",
10516 &fid, &sdInterfaceID, &gdVgrpID);
10517
10518 if (status == 0)
10519 {
10520 /* Get field info */
10521 status = GDfieldinfo(gridID, fieldname, &dum, dims, &nt, NULL);
10522
10523 if (status == 0)
10524 {
10525 /* Get SDS ID and solo flag */
10526 status = GDSDfldsrch(gridID, sdInterfaceID, fieldname,
10527 &sdid, &dum, &dum, &dum,
10528 dims, &solo);
10529 if (status !=0) {
10530 HEpush(DFE_GENAPP, "GDsettilecomp", __FILE__, __LINE__);
10531 HEreport("GDSDfldsrch failed\n", fieldname);
10532 return FAIL;
10533 }
10534 /* Tiling with Compression */
10535 /* ----------------------- */
10536
10537
10538 /* Setup Compression */
10539 /* ----------------- */
10540 if (compcode == HDFE_COMP_NBIT)
10541 {
10542 c_info.nbit.nt = nt;
10543 c_info.nbit.sign_ext = compparm[0];
10544 c_info.nbit.fill_one = compparm[1];
10545 c_info.nbit.start_bit = compparm[2];
10546 c_info.nbit.bit_len = compparm[3];
10547 }
10548 else if (compcode == HDFE_COMP_SKPHUFF)
10549 {
10550 c_info.skphuff.skp_size = (intn) DFKNTsize(nt);
10551 }
10552 else if (compcode == HDFE_COMP_DEFLATE)
10553 {
10554 c_info.deflate.level = compparm[0];
10555 }
10556
10557 /* Setup chunk lengths */
10558 /* ------------------- */
10559 for (i = 0; i < tilerank; i++)
10560 {
10561 chunkDef.comp.chunk_lengths[i] = tiledims[i];
10562 }
10563
10564 /* Setup chunk flag & chunk compression type */
10565 /* ----------------------------------------- */
10566 chunkFlag = HDF_CHUNK | HDF_COMP;
10567 chunkDef.comp.comp_type = compcode;
10568
10569 /* Setup chunk compression parameters */
10570 /* ---------------------------------- */
10571 if (compcode == HDFE_COMP_SKPHUFF)
10572 {
10573 chunkDef.comp.cinfo.skphuff.skp_size =
10574 c_info.skphuff.skp_size;
10575 }
10576 else if (compcode == HDFE_COMP_DEFLATE)
10577 {
10578 chunkDef.comp.cinfo.deflate.level =
10579 c_info.deflate.level;
10580 }
10581 /* Call SDsetchunk routine */
10582 /* ----------------------- */
10583 status = SDsetchunk(sdid, chunkDef, chunkFlag);
10584 if (status ==FAIL) {
10585 HEpush(DFE_GENAPP, "GDsettilecomp", __FILE__, __LINE__);
10586 HEreport("Fieldname \"%s\" does not exist.\n",
10587 fieldname);
10588 return status;
10589 }
10590 }
10591 else
10592 {
10593 HEpush(DFE_GENAPP, "GDsettilecomp", __FILE__, __LINE__);
10594 HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
10595 }
10596 }
10597 return (status);
10598 }
10599
10600 /*----------------------------------------------------------------------------|
10601 | BEGIN_PROLOG |
10602 | |
10603 | FUNCTION: GDll2mm_cea |
10604 | |
10605 | DESCRIPTION: |
10606 | |
10607 | |
10608 | Return Value Type Units Description |
10609 | ============ ====== ========= ===================================== |
10610 | status intn return status (0) SUCCEED, (-1) FAIL |
10611 | |
10612 | INPUTS: |
10613 | projcode int32 GCTP projection code |
10614 | zonecode int32 UTM zone code |
10615 | projparm float64 Projection parameters |
10616 | spherecode int32 GCTP spheriod code |
10617 | xdimsize int32 xdimsize from GDcreate |
10618 | ydimsize int32 ydimsize from GDcreate |
10619 | upleftpt float64 upper left corner coordinates (DMS) |
10620 | lowrightpt float64 lower right corner coordinates (DMS) |
10621 | longitude float64 longitude array (DMS) |
10622 | latitude float64 latitude array (DMS) |
10623 | npnts int32 number of lon-lat points |
10624 | |
10625 | OUTPUTS: |
10626 | x float64 X value array |
10627 | y float64 Y value array |
10628 | scaleX float64 X grid size |
10629 | scaley float64 Y grid size |
10630 | |
10631 | NOTES: |
10632 | |
10633 | |
10634 | Date Programmer Description |
10635 | ====== ============ ================================================= |
10636 | Oct 02 Abe Taaheri Added support for EASE grid |
10637 | |
10638 | END_PROLOG |
10639 -----------------------------------------------------------------------------*/
GDll2mm_cea(int32 projcode,int32 zonecode,int32 spherecode,float64 projparm[],int32 xdimsize,int32 ydimsize,float64 upleftpt[],float64 lowrightpt[],int32 npnts,float64 lon[],float64 lat[],float64 x[],float64 y[],float64 * scaleX,float64 * scaleY)10640 static intn GDll2mm_cea(int32 projcode,int32 zonecode, int32 spherecode,
10641 float64 projparm[],
10642 int32 xdimsize, int32 ydimsize,
10643 float64 upleftpt[], float64 lowrightpt[], int32 npnts,
10644 float64 lon[],float64 lat[],
10645 float64 x[],float64 y[], float64 *scaleX,float64 *scaleY)
10646 {
10647 intn status = 0; /* routine return status variable */
10648 int32 errorcode = 0; /* GCTP error code */
10649 float64 xMtr0, xMtr1, yMtr0, yMtr1;
10650 float64 lonrad0; /* Longitude in radians of upleft point */
10651 float64 latrad0; /* Latitude in radians of upleft point */
10652 float64 lonrad; /* Longitude in radians of point */
10653 float64 latrad; /* Latitude in radians of point */
10654 int32(*for_trans[100]) (); /* GCTP function pointer */
10655
10656 if(npnts <= 0)
10657 {
10658 HEpush(DFE_GENAPP, " GDll2mm_cea", __FILE__, __LINE__);
10659 HEreport("Improper npnts value\"%d\"... \n", npnts);
10660 HEreport("npnts must be greater than zero.\n");
10661 status = -1;
10662 return (status);
10663 }
10664 if ( projcode == GCTP_BCEA)
10665 {
10666 for_init(projcode, zonecode, projparm, spherecode, NULL, NULL,
10667 &errorcode, for_trans);
10668 /* Convert upleft and lowright X coords from DMS to radians */
10669 /* -------------------------------------------------------- */
10670
10671 lonrad0 = EHconvAng(upleftpt[0], HDFE_DMS_RAD);
10672 lonrad = EHconvAng(lowrightpt[0], HDFE_DMS_RAD);
10673
10674 /* Convert upleft and lowright Y coords from DMS to radians */
10675 /* -------------------------------------------------------- */
10676 latrad0 = EHconvAng(upleftpt[1], HDFE_DMS_RAD);
10677 latrad = EHconvAng(lowrightpt[1], HDFE_DMS_RAD);
10678
10679 /* Convert from lon/lat to meters(or whatever unit is, i.e unit
10680 of r_major and r_minor) using GCTP */
10681 /* ----------------------------------------- */
10682 errorcode = for_trans[projcode] (lonrad0, latrad0, &xMtr0, &yMtr0);
10683 x[0] = xMtr0;
10684 y[0] = yMtr0;
10685
10686 /* Report error if any */
10687 /* ------------------- */
10688 if (errorcode != 0)
10689 {
10690 status = -1;
10691 HEpush(DFE_GENAPP, "GDll2mm_cea", __FILE__, __LINE__);
10692 HEreport("GCTP Error: %d\n", errorcode);
10693 return (status);
10694 }
10695
10696 /* Convert from lon/lat to meters(or whatever unit is, i.e unit
10697 of r_major and r_minor) using GCTP */
10698 /* ----------------------------------------- */
10699 errorcode = for_trans[projcode] (lonrad, latrad, &xMtr1, &yMtr1);
10700 x[1] = xMtr1;
10701 y[1] = yMtr1;
10702
10703 /* Report error if any */
10704 /* ------------------- */
10705 if (errorcode != 0)
10706 {
10707 status = -1;
10708 HEpush(DFE_GENAPP, "GDll2mm_cea", __FILE__, __LINE__);
10709 HEreport("GCTP Error: %d\n", errorcode);
10710 return (status);
10711 }
10712
10713 /* Compute x scale factor */
10714 /* ---------------------- */
10715 *scaleX = (xMtr1 - xMtr0) / xdimsize;
10716
10717 /* Compute y scale factor */
10718 /* ---------------------- */
10719 *scaleY = (yMtr1 - yMtr0) / ydimsize;
10720 }
10721 else
10722 {
10723 status = -1;
10724 HEpush(DFE_GENAPP, "GDll2mm_cea", __FILE__, __LINE__);
10725 HEreport("Wrong projection code; this function is only for EASE grid");
10726 return (status);
10727 }
10728 return (0);
10729 }
10730
10731
10732 /*----------------------------------------------------------------------------|
10733 | BEGIN_PROLOG |
10734 | |
10735 | FUNCTION: GDmm2ll_cea |
10736 | |
10737 | DESCRIPTION: |
10738 | |
10739 | |
10740 | Return Value Type Units Description |
10741 | ============ ====== ========= ===================================== |
10742 | status intn return status (0) SUCCEED, (-1) FAIL |
10743 | |
10744 | INPUTS: |
10745 | projcode int32 GCTP projection code |
10746 | zonecode int32 UTM zone code |
10747 | projparm float64 Projection parameters |
10748 | spherecode int32 GCTP spheriod code |
10749 | xdimsize int32 xdimsize from GDcreate |
10750 | ydimsize int32 ydimsize from GDcreate |
10751 | upleftpt float64 upper left corner coordinates (DMS) |
10752 | lowrightpt float64 lower right corner coordinates (DMS) |
10753 | x float64 X value array |
10754 | y float64 Y value array |
10755 | npnts int32 number of x-y points |
10756 | |
10757 | OUTPUTS: |
10758 | longitude float64 longitude array (DMS) |
10759 | latitude float64 latitude array (DMS) |
10760 | |
10761 | NOTES: |
10762 | |
10763 | |
10764 | Date Programmer Description |
10765 | ====== ============ ================================================= |
10766 | Oct 02 Abe Taaheri Added support for EASE grid |
10767 | |
10768 | END_PROLOG |
10769 -----------------------------------------------------------------------------*/
GDmm2ll_cea(int32 projcode,int32 zonecode,int32 spherecode,float64 projparm[],int32 xdimsize,int32 ydimsize,float64 upleftpt[],float64 lowrightpt[],int32 npnts,float64 x[],float64 y[],float64 longitude[],float64 latitude[])10770 static intn GDmm2ll_cea(int32 projcode,int32 zonecode, int32 spherecode,
10771 float64 projparm[],
10772 int32 xdimsize, int32 ydimsize,
10773 float64 upleftpt[], float64 lowrightpt[], int32 npnts,
10774 float64 x[], float64 y[],
10775 float64 longitude[], float64 latitude[])
10776 {
10777 intn status = 0; /* routine return status variable */
10778 int32 errorcode = 0; /* GCTP error code */
10779 int32(*inv_trans[100]) (); /* GCTP function pointer */
10780 int32 i;
10781
10782 if(npnts <= 0)
10783 {
10784 HEpush(DFE_GENAPP, " GDmm2ll_cea", __FILE__, __LINE__);
10785 HEreport("Improper npnts value\"%d\"... \n", npnts);
10786 HEreport("npnts must be greater than zero.\n");
10787 status = -1;
10788 return (status);
10789 }
10790 if ( projcode == GCTP_BCEA)
10791 {
10792 inv_init(projcode, zonecode, projparm, spherecode, NULL, NULL,
10793 &errorcode, inv_trans);
10794
10795 /* Convert from meters(or whatever unit is, i.e unit
10796 of r_major and r_minor) to lat/lon using GCTP */
10797 /* ----------------------------------------- */
10798 for(i=0; i<npnts; i++)
10799 {
10800 errorcode =
10801 inv_trans[projcode] (x[i], y[i],&longitude[i], &latitude[i]);
10802 /* Report error if any */
10803 /* ------------------- */
10804 if (errorcode != 0)
10805 {
10806 status = -1;
10807 HEpush(DFE_GENAPP, "GDmm2ll_cea", __FILE__, __LINE__);
10808 HEreport("GCTP Error: %d\n", errorcode);
10809 return (status);
10810 }
10811 longitude[i] = EHconvAng(longitude[i], HDFE_RAD_DMS);
10812 latitude[i] = EHconvAng(latitude[i], HDFE_RAD_DMS);
10813 }
10814 }
10815 else
10816 {
10817 /* Wrong projection code; this function is only for EASE grid */
10818 }
10819 return(status);
10820 }
10821
10822 /*----------------------------------------------------------------------------|
10823 | BEGIN_PROLOG |
10824 | |
10825 | FUNCTION: GDsdid |
10826 | |
10827 | DESCRIPTION: Returns SD element ID for grid field |
10828 | |
10829 | |
10830 | Return Value Type Units Description |
10831 | ============ ====== ========= ===================================== |
10832 | status intn return status (0) SUCCEED, (-1) FAIL |
10833 | |
10834 | INPUTS: |
10835 | gridID int32 grid structure ID |
10836 | fieldname const char field name |
10837 | |
10838 | |
10839 | OUTPUTS: |
10840 | sdid int32 SD element ID |
10841 | |
10842 | NOTES: |
10843 | |
10844 | |
10845 | Date Programmer Description |
10846 | ====== ============ ================================================= |
10847 | Oct 07 Andrey Kiselev Original Programmer |
10848 | |
10849 | END_PROLOG |
10850 -----------------------------------------------------------------------------*/
10851 intn
GDsdid(int32 gridID,const char * fieldname,int32 * sdid)10852 GDsdid(int32 gridID, const char *fieldname, int32 *sdid)
10853 {
10854 intn status; /* routine return status variable */
10855 int32 fid; /* HDF-EOS file ID */
10856 int32 sdInterfaceID; /* HDF SDS interface ID */
10857 int32 dum; /* Dummy variable */
10858 int32 dims[H4_MAX_VAR_DIMS]; /* Field/SDS dimensions */
10859
10860 status = GDchkgdid(gridID, "GDsdid", &fid, &sdInterfaceID, &dum);
10861 if (status != -1)
10862 {
10863 status = GDSDfldsrch(gridID, sdInterfaceID, fieldname,
10864 sdid, &dum, &dum, &dum, dims, &dum);
10865 }
10866
10867 return (status);
10868 }
10869
10870