7 #define htonl(x) swap_byte4(x)
9 #include <netinet/in.h>
11 #include "dprints.h" /* for dprints */
12 #include "gribfuncs.h" /* prototypes */
16 ************************************************************************
17 * A. FUNCTION gribputgds
18 * used to decode Grib's Grid Defn Section. It returns with both
19 * internal structures GDS_HEAD_INPUT and VOID* projblock filled,
20 * and also with true GDS already appended to GribHeader's Entire_Msg;
23 * int gribputgds (Geom_In, pGDS_Head_Input, ppvGDS_Proj_Input,
26 * ARGUMENTS (I=input, O=output, I&O=input and output):
28 * Geometry information used as input;
29 * (O) GDS_HEAD_INPUT *pGDS_Head_Input
30 * this is the internal GDS structure. Attributes (uslength,
31 * usData_type, chData_type, usNum_v and usPl_Pv) gets updated;
32 * (O) void **ppvGDS_Proj_Input;
33 * This is a pre-alloced storage of type Void and has length of
34 * MAX_INP_PROJ_SIZE bytes long. How this block is filled depends
35 * on the type of Projection it is. Projections currently supported
36 * are Spherical, Lambert, and Polar Stereographic.
37 * (I&O) GRIB_HDR **ppgrib_hdr
38 * may already have one or more of the other Grib Sections
39 * (IDS, PDS, BMS, BDS, or EDS). Upon successful exit, will
40 * also contain a GDS section.
42 * empty array, returned filled if error occurred;
45 * 0> no errors; GDS appended to GRIB_HDR's entire_msg, its info
46 * stored in bds_len & bds_ptr; msg_length updated too;
47 * 1> error, grib hdr is null; errmsg filled;
48 ************************************************************************
52 NCAR AIX does not have lrint, make one up.
55 #define lrint(dbl) ((long)rint(dbl))
59 int gribputgds ( GEOM_IN Geom_In
, GDS_HEAD_INPUT
*pGDS_Head_Input
,
60 void **ppvGDS_Proj_Input
, GRIB_HDR
**ppgrib_hdr
,
63 int gribputgds ( Geom_In
, pGDS_Head_Input
, ppvGDS_Proj_Input
,
66 GDS_HEAD_INPUT
*pGDS_Head_Input
;
67 void **ppvGDS_Proj_Input
;
68 GRIB_HDR
**ppgrib_hdr
;
73 * A.0 DEFAULT to err stat 1
75 char *func
= "gribputgds";
76 char *pgds
=0; /* true grib, GDS_HEAD + Proj block */
77 GDS_HEAD
*pGDS_Head
=0; /* first 6 bytes of PGDS */
78 void *pvGDS_Proj
=0; /* projection info, PGDS 7th byte and on... */
79 long lProj_sz
; /* size of True-Grib projection block */
80 long new_msgsz
; /* size after adding GDS */
81 GRIB_HDR
*gh
=0; /* temp ptr to struct */
88 DPRINT0 ("\nEntering gribputgds .....\n");
91 * A.1 IF (Grib Hdr is null) THEN
92 * RETURN error Stat !null ptrs msg in errmsg
96 if (!gh
|| !gh
->entire_msg
) {
97 DPRINT1("%s: grib header is null\n", func
);
98 sprintf(errmsg
,"%s: grib header is null\n", func
);
104 * A.3 ALLOCATE space for True Grib Structs GDS_HEAD & VOID *proj;
106 * RETURN with bad Stat !errmsg filled
112 if (! (pgds
= (char *) malloc(sizeof (GDS_HEAD
) + MAX_PROJ_SIZE
))) {
113 DPRINT1 ("%s: MALloced true Grib struct failed\n",func
);
114 sprintf(errmsg
,"%s: MALloced true Grib struct failed\n",func
);
117 else memset ((void *)pgds
, '\0', sizeof(GDS_HEAD
) + MAX_PROJ_SIZE
);
121 * A.4 ASSIGN (GDS_HEAD *pGDS_Head) to be beginning of local PGDS block
122 * ASSIGN (void *pvGDS_Proj) to byte #7 of local PGDS block
124 pGDS_Head
= (GDS_HEAD
*) pgds
;
125 pvGDS_Proj
= (void *) (pgds
+ sizeof(GDS_HEAD
));
129 * A.5 INIT some fields of GDS_HEAD & GDS_HEAD_INPUT structs
131 pGDS_Head
->chNV
= ( unsigned char ) 0;
132 pGDS_Head
->chPV
= ( unsigned char ) 255;
133 pGDS_Head_Input
->usNum_v
= 0; /* INPUT NOT USED AT THIS TIME */
134 pGDS_Head_Input
->usPl_Pv
= 255;
139 * !now fill true GRIB Grid Defn Sect depending on Projection type
140 * A.6.a IF (projection is Spherical) THEN
142 if ((strcmp(Geom_In
.prjn_name
,"spherical")==0) ||
143 (strcmp(Geom_In
.prjn_name
,"gaussian") == 0)){
145 * A.6.a.1 FUNCTION create_inpLatlon !create internal Latlon struct
146 * !using GEOM_IN & USER_INPUT
147 * A.6.a.2 FUNCTION inp2grib_Latlon !use internal Latlon struct to
148 * !make true Latlon Grib Gds
149 * A.6.a.3 IF (either failed) THEN
150 * FUNCTION upd_child_errmsg !tack funcname to errmsg
151 * RETURN with error !errmsg filled
155 if ( create_inpLatlon(Geom_In
, ppvGDS_Proj_Input
,errmsg
)
156 || inp2grib_Latlon (ppvGDS_Proj_Input
,
157 (LATLON
*)(pgds
+sizeof(GDS_HEAD
)),&lProj_sz
, errmsg
))
159 upd_child_errmsg (func
, errmsg
); goto BYE
;
163 * A.6.a.4 STORE Gds len, DataType=0 into internal GDS struct
165 pGDS_Head_Input
->uslength
= sizeof(GDS_HEAD
) + lProj_sz
;
166 if (strcmp(Geom_In
.prjn_name
,"spherical")==0) {
167 pGDS_Head_Input
->usData_type
= LATLON_PRJ
;
168 pGDS_Head
->chData_type
= 0;
170 pGDS_Head_Input
->usData_type
= GAUSS_PRJ
;
171 pGDS_Head
->chData_type
= 4;
176 * A.6.b ELSE IF (projection is Lambert) THEN
178 else if (strcmp(Geom_In
.prjn_name
,"lambert")==0)
181 * A.6.b.1 FUNCTION create_inpLambert !create internal Lambert struct
182 * !using GEOM_IN & USER_INPUT
183 * A.6.b.2 FUNCTION inp2grib_Lambert !use internal Lambert struct to
184 * !make true Lambert Grib Gds
185 * A.6.b.3 IF (either failed) THEN
186 * FUNCTION upd_child_errmsg !tack funcname to errmsg
187 * RETURN with error !errmsg filled
190 if ( create_inpLambert(Geom_In
,ppvGDS_Proj_Input
,errmsg
)
191 || inp2grib_Lambert( ppvGDS_Proj_Input
,
192 (LAMBERT
*)(pgds
+sizeof(GDS_HEAD
)), &lProj_sz
, errmsg
))
194 upd_child_errmsg (func
, errmsg
); goto BYE
;
198 * A.6.b.4 STORE Gds len, DataType=3 into internal GDS struct
200 pGDS_Head_Input
->uslength
= sizeof(GDS_HEAD
) + lProj_sz
;
201 pGDS_Head_Input
->usData_type
= LAMB_PRJ
;
202 pGDS_Head
->chData_type
= 3;
206 * A.6.c ELSE if (projection is Polar_Stereo) THEN
208 else if (strcmp(Geom_In
.prjn_name
,"polar_stereo")==0)
211 * A.6.c.1 FUNCTION create_inpPolar
212 * !create internal Polar struct using GEOM_IN & USER_INPUT
213 * A.6.c.2 FUNCTION inp2grib_PolarSt
214 * !use internal PolarSt struct to make true PolarSt Grib Gds
215 * A.6.c.3 IF (either failed) THEN
216 * FUNCTION upd_child_errmsg !tack funcname to errmsg
217 * RETURN with error !errmsg filled
220 /* make True Grib PPVGDS_PROJ & SIZE using internal ppvGds_proj_input : */
222 if (create_inpPolar(Geom_In
, ppvGDS_Proj_Input
,errmsg
)
223 || inp2grib_PolarSt(ppvGDS_Proj_Input
,
224 (void *)(pgds
+sizeof(GDS_HEAD
)),&lProj_sz
, errmsg
) )
226 upd_child_errmsg (func
, errmsg
); goto BYE
;
230 * A.6.c.4 STORE Gds len, DataType=5 into internal GDS struct
232 pGDS_Head_Input
->uslength
= sizeof(GDS_HEAD
) + lProj_sz
;
233 pGDS_Head_Input
->usData_type
= POLAR_PRJ
;
234 pGDS_Head
->chData_type
= 5;
238 * A.6.c ELSE if (projection is Mercator) THEN
240 else if (strcmp(Geom_In
.prjn_name
,"mercator")==0)
243 * A.6.c.1 FUNCTION create_inpMercator
244 * !create internal Mercator struct using GEOM_IN & USER_INPUT
245 * A.6.c.2 FUNCTION inp2grib_Mercator
246 * !use internal Mercator struct to make true PolarSt Grib Gds
247 * A.6.c.3 IF (either failed) THEN
248 * FUNCTION upd_child_errmsg !tack funcname to errmsg
249 * RETURN with error !errmsg filled
252 /* make True Grib PPVGDS_PROJ & SIZE using internal ppvGds_proj_input : */
254 if (create_inpMercator(Geom_In
, ppvGDS_Proj_Input
,errmsg
)
255 || inp2grib_Mercator(ppvGDS_Proj_Input
,
256 (void *)(pgds
+sizeof(GDS_HEAD
)),&lProj_sz
, errmsg
) )
258 upd_child_errmsg (func
, errmsg
); goto BYE
;
262 * A.6.c.4 STORE Gds len, DataType=5 into internal GDS struct
264 pGDS_Head_Input
->uslength
= sizeof(GDS_HEAD
) + lProj_sz
;
265 pGDS_Head_Input
->usData_type
= MERC_PRJ
;
266 pGDS_Head
->chData_type
= 1;
270 * A.6.d ELSE ! Projection unknown
274 * RETURN with error !errmsg filled
276 DPRINT2 ("%s: Projection '%s' unknown\n",func
,Geom_In
.prjn_name
);
277 sprintf (errmsg
,"%s: Projection '%s' unknown\n",func
,Geom_In
.prjn_name
);
286 * A.7 STORE ptr to Gds and its Length in Grib hdr
288 gh
->gds_ptr
= gh
->entire_msg
+ gh
->msg_length
;
289 gh
->gds_len
= sizeof(GDS_HEAD
) + lProj_sz
;
290 DPRINT3 ("Gds length= (%ld + %ld)= %ld \n",
291 sizeof(GDS_HEAD
), lProj_sz
, gh
->gds_len
);
295 * A.8 STORE Gds length in the True Grib GDS block too
297 set_bytes(gh
->gds_len
, 3, pGDS_Head
->achGDS_length
);
301 * A.9 IF gribhdr's buffer is too small AND
302 * FUCTION Expand_gribhdr failed
304 * RETURN with error !errmsg filled
307 new_msgsz
= gh
->msg_length
+ gh
->gds_len
;
309 if (new_msgsz
> gh
->abs_size
310 && Expand_gribhdr (gh
, new_msgsz
, errmsg
) !=0)
312 upd_child_errmsg (func
, errmsg
);
318 * A.10 UPDATE Grib Header Struct
319 * !copy true BDS block into Grib Header's Entire_Msg array;
320 * !add gds length to Message length
322 memcpy ((void *)gh
->gds_ptr
, (void *)pgds
, gh
->gds_len
);
323 gh
->msg_length
+= gh
->gds_len
;
324 DPRINT1 ("copying %ld bytes from PGDS to gh->GDS_PTR \n", gh
->gds_len
);
327 * A.11 CHANGE return Status to no errors
334 * A.12 FREE up storage
338 if (pgds
) free (pgds
);
339 DPRINT3 ("Leaving %s, stat=%d, errmsg='%s'\n", func
,stat
,errmsg
);
351 *********************************************************************
352 * B. FUNCTION: create_inpLambert
353 * Fills Lambert Projection structure.
356 * int create_inpLambert ( geom_in, ppvGDS_Proj_Input, errmsg)
358 * ARGUMENTS (I=input, O=output, I&O=input and output):
359 * (I) GEOM_IN geom_in Holds info to fill local Lambert block
360 * (O) void **ppvGDS_Proj_Input pre-allocated block to be filled;
361 * (O) char *errmsg returns filled if error occurred
364 * 0> success, ppvGDS_Proj_Input holds Lambert projection information;
365 * 1> the input pre-MAlloced projection block is null; errmsg filled;
366 **********************************************************************/
369 int create_inpLambert (GEOM_IN geom_in
, void **ppvGDS_Proj_Input
, char *errmsg
)
371 int create_inpLambert (geom_in
, ppvGDS_Proj_Input
, errmsg
)
372 GEOM_IN geom_in
; void **ppvGDS_Proj_Input
; char *errmsg
;
375 char *func
= "create_inpLambert";
378 * B.1 DEFAULT status of 0
381 double cut1
, cut2
, tmp
;
382 GDS_LAM_INPUT
*pGDS_Lam_Input
;
384 DPRINT1 ( " Entering %s.....\n", func
);
387 * B.2 IF (incoming projection block is Null)
390 * SET return status to error
392 if (!(pGDS_Lam_Input
= (GDS_LAM_INPUT
*) *ppvGDS_Proj_Input
) )
394 DPRINT1 ( "%s: ppvGDS_Proj_Input is null\n", func
);
395 sprintf(errmsg
, "%s: ppvGDS_Proj_Input is null\n", func
);
400 * USE info from GEOM_IN to fill the Lambert GDS struct
404 pGDS_Lam_Input
->usData_type
= LAMB_PRJ
; /* data type flag (Tbl ) */
405 pGDS_Lam_Input
->iNx
= (int) geom_in
.nx
; /* #pts along x-axis */
406 pGDS_Lam_Input
->iNy
= (int) geom_in
.ny
;/* #pts along y-axis */
407 /* latitude & lon of 1st grid point */
408 pGDS_Lam_Input
->lLat1
= lrint(geom_in
.first_lat
*1000.);
409 pGDS_Lam_Input
->lLon1
= lrint((geom_in
.first_lon
) *1000.);
410 pGDS_Lam_Input
->usRes_flag
= geom_in
.usRes_flag
;/*Resolution flags Tbl7*/
411 pGDS_Lam_Input
->lLon_orient
=lrint(geom_in
.parm_3
*1000.);/*grid orient */
412 pGDS_Lam_Input
->ulDx
=(unsigned long)lrint(geom_in
.x_int_dis
*1000.);/*Xdir gridlen*/
413 pGDS_Lam_Input
->ulDy
=(unsigned long)lrint(geom_in
.y_int_dis
*1000.);/*Ydir gridlen*/
414 if ((geom_in
.y_int_dis
!= 0) && (geom_in
.x_int_dis
!= 0))
415 pGDS_Lam_Input
->usRes_flag
= pGDS_Lam_Input
->usRes_flag
+ 0x80;
416 if (geom_in
.parm_1
> 0)
417 pGDS_Lam_Input
->usProj_flag
= 0; /* projection flag */
419 pGDS_Lam_Input
->usProj_flag
= 1<<7; /* projection flag */
420 pGDS_Lam_Input
->usScan_mode
= geom_in
.scan
; /* order of grid points (Tbl8)*/
421 /* Make sure CUT1 is closest to Pole */
422 cut1
= geom_in
.parm_1
;
423 cut2
= geom_in
.parm_2
;
425 if (cut2
> cut1
) { tmp
= cut1
; cut1
= cut2
; cut2
= tmp
; }
428 if (cut2
< cut1
) { tmp
= cut1
; cut1
= cut2
; cut2
= tmp
; }
431 pGDS_Lam_Input
->lLat_cut1
=lrint(cut1
*1000.);/* 1stlat fr pole secant cuts*/
432 pGDS_Lam_Input
->lLat_cut2
=lrint(cut2
*1000.);/* 2ndlat fr pole secant cuts*/
433 pGDS_Lam_Input
->lLat_southpole
= -90000; /* lat of southern pole (millidegrees) */
434 pGDS_Lam_Input
->lLon_southpole
= 0; /* lon of souther pole (millidegrees) */
435 pGDS_Lam_Input
->usZero
= 0; /* filler zeroes */
440 DPRINT3("\t%s: usData_type = %u (%s)\n",
441 func
,pGDS_Lam_Input
->usData_type
, prjn_name
[pGDS_Lam_Input
->usData_type
] );
442 DPRINT2("\t%s: iNx = %d\n", func
,pGDS_Lam_Input
->iNx
);
443 DPRINT2("\t%s: iNy = %d\n", func
,pGDS_Lam_Input
->iNy
);
444 DPRINT2("\t%s: lLat1 = %d\n", func
,pGDS_Lam_Input
->lLat1
);
445 DPRINT2("\t%s: lLon1 = %d\n", func
,pGDS_Lam_Input
->lLon1
);
446 DPRINT2("\t%s: lLon_orient = %d\n", func
,pGDS_Lam_Input
->lLon_orient
);
447 DPRINT2("\t%s: ulDx = %u\n", func
, pGDS_Lam_Input
->ulDx
);
448 DPRINT2("\t%s: ulDy = %u\n", func
, pGDS_Lam_Input
->ulDy
);
449 DPRINT2("\t%s: lLat_cut1 = %d\n", func
, pGDS_Lam_Input
->lLat_cut1
);
450 DPRINT2("\t%s: lLat_cut2 = %d\n", func
, pGDS_Lam_Input
->lLat_cut2
);
451 DPRINT2("\t%s: usRes_flag = %u\n", func
,pGDS_Lam_Input
->usRes_flag
);
452 DPRINT2("\t%s: usProj_flag = %u\n", func
,pGDS_Lam_Input
->usProj_flag
);
453 DPRINT2("\t%s: usScan_mode = %u\n", func
,pGDS_Lam_Input
->usScan_mode
);
459 DPRINT1(" Exiting %s.......\n" ,func
);
475 *********************************************************************
476 * C. FUNCTION: create_inpPolar
477 * Fills Polar Stereographic Projection structure.
480 * int create_inpPolar (geom_in, ppvGDS_Proj_Input, errmsg)
482 * ARGUMENTS (I=input, O=output, I&O=input and output):
483 * (I) GEOM_IN geom_in holds info to fill local Polar block
484 * (O) void **ppvGDS_Proj_Input block to filled with Polar Stereo info
485 * (O) char *errmsg empty array filled if error occurs
488 * 0> success, ppvGDS_Proj_Input holds Polar projection info;
489 * 1> the input pre-Malloced projection block is null; errmsg filled;
490 **********************************************************************/
493 int create_inpPolar (GEOM_IN geom_in
, void **ppvGDS_Proj_Input
, char *errmsg
)
495 int create_inpPolar (geom_in
, ppvGDS_Proj_Input
, errmsg
)
496 GEOM_IN geom_in
; void **ppvGDS_Proj_Input
; char *errmsg
;
499 char *func
="create_inpPolar";
502 * C.1 DEFAULT status of 0
504 GDS_PS_INPUT
*pGDS_PS_Input
;
507 DPRINT1 (" Entering %s.....\n",func
);
510 * C.2 IF (incoming projection block is Null)
513 * CHANGE return Status to error
515 if (!(pGDS_PS_Input
= (GDS_PS_INPUT
*) *ppvGDS_Proj_Input
) )
517 DPRINT1 ("%s: ppvGDS_Proj_Input is null\n", func
);
518 sprintf(errmsg
,"%s: ppvGDS_Proj_Input is null\n", func
);
525 * C.2.b.1 FILL elements of Polar Stereo structure
527 pGDS_PS_Input
->usData_type
= POLAR_PRJ
; /* data type flag (Tbl ) */
528 pGDS_PS_Input
->usNx
= (unsigned short) geom_in
.nx
;/* #pts along x-axis*/
529 pGDS_PS_Input
->usNy
= (unsigned short) geom_in
.ny
;/* #pts along y-axiz*/
530 pGDS_PS_Input
->lLat1
= lrint(geom_in
.first_lat
*1000.);/*lat of 1st gridpt*/
531 pGDS_PS_Input
->lLon1
= lrint(geom_in
.first_lon
*1000.);/*lon of 1st gridpt*/
532 pGDS_PS_Input
->usRes_flag
= geom_in
.usRes_flag
;/* resolution flags Tbl7 */
533 pGDS_PS_Input
->lLon_orient
= lrint(geom_in
.parm_2
*1000.);/*grid orient*/
534 pGDS_PS_Input
->ulDx
=(unsigned long)lrint(geom_in
.x_int_dis
*1000.);/*Xdir gridlen*/
535 pGDS_PS_Input
->ulDy
=(unsigned long)lrint(geom_in
.y_int_dis
*1000.);/*Ydir gridlen*/
536 if ((geom_in
.y_int_dis
!= 0) && (geom_in
.x_int_dis
!= 0))
537 pGDS_PS_Input
->usRes_flag
= pGDS_PS_Input
->usRes_flag
+ 0x80;
538 if (geom_in
.first_lat
> 0)
539 pGDS_PS_Input
->usProj_flag
= 0; /* projection flag */
541 pGDS_PS_Input
->usProj_flag
= 1<<7; /* projection flag */
543 pGDS_PS_Input
->usScan_mode
= geom_in
.scan
; /* order of grid points (Tbl 8) */
544 pGDS_PS_Input
->usZero
= 0; /* filler zeroes */
547 * C.2.b.2 DEBUG print
549 DPRINT3 ("\t%s: usData_type = %u (%s)\n",func
,pGDS_PS_Input
->usData_type
,
550 prjn_name
[pGDS_PS_Input
->usData_type
] );
551 DPRINT2("\t%s: usNx = %u\n", func
,pGDS_PS_Input
->usNx
);
552 DPRINT2("\t%s: usNy = %u\n", func
,pGDS_PS_Input
->usNy
);
553 DPRINT2("\t%s: lLat1 = %d\n", func
,pGDS_PS_Input
->lLat1
);
554 DPRINT2("\t%s: lLon1 = %d\n", func
,pGDS_PS_Input
->lLon1
);
555 DPRINT2("\t%s: lLon_orient = %d\n", func
,pGDS_PS_Input
->lLon_orient
);
556 DPRINT2("\t%s: ulDx = %u\n", func
,pGDS_PS_Input
->ulDx
);
557 DPRINT2("\t%s: ulDy = %u\n", func
,pGDS_PS_Input
->ulDy
);
558 DPRINT2("\t%s: usRes_flag = %u\n", func
,pGDS_PS_Input
->usRes_flag
);
559 DPRINT2("\t%s: usProj_flag = %u\n", func
,pGDS_PS_Input
->usProj_flag
);
560 DPRINT2("\t%s: usScan_mode = %u\n", func
,pGDS_PS_Input
->usScan_mode
);
566 DPRINT1(" Exiting %s.......\n" ,func
);
583 *********************************************************************
584 * D. FUNCTION: create_inpLatlon
585 * Fills Latitude Longitude Projection structure.
588 * int create_inpLatlon ( geom_in, ppvGDS_Proj_Input, errmsg)
590 * ARGUMENTS (I=input, O=output, I&O=input and output):
591 * (I) GEOM_IN geom_in holds geom info to fill local Lat/Lon block
592 * (O) void **ppvGDS_Proj_Input to be filled with LatLon projection info
593 * (O) char *errmsg empty array, filled if error occurred
596 * 0> success, ppGDS_Proj_Input filled with Lat/Lon projection info
597 * 1> pre-Malloced Projection block is null; errmsg filled;
598 **********************************************************************/
601 int create_inpLatlon (GEOM_IN geom_in
, void **ppvGDS_Proj_Input
, char *errmsg
)
603 int create_inpLatlon (geom_in
, ppvGDS_Proj_Input
, errmsg
)
604 GEOM_IN geom_in
; void **ppvGDS_Proj_Input
; char *errmsg
;
607 char *func
= "Create_InpLatLon";
610 * D.0 DEFAULT to return status of 0
612 GDS_LATLON_INPUT
*pGDS_Latlon_Input
;
615 DPRINT1 (" Entering %s......\n" ,func
);
618 * D.2 IF (incoming projection block is Null)
623 if (!(pGDS_Latlon_Input
= (GDS_LATLON_INPUT
*) *ppvGDS_Proj_Input
) )
625 DPRINT1 (" %s: ppvGDS_Proj_Input is null\n", func
);
626 sprintf(errmsg
," %s: ppvGDS_Proj_Input is null\n", func
);
631 * D.2.b.1 FILL elements of the Lat/Lon GDS block
636 pGDS_Latlon_Input
->usData_type
= LATLON_PRJ
; /* data type flag (Tbl )*/
637 pGDS_Latlon_Input
->usNi
=(unsigned short)geom_in
.nx
;/*#pts along x-axis 109*/
638 pGDS_Latlon_Input
->usNj
=(unsigned short)geom_in
.ny
;/* #pts along y-axiz 82*/
639 pGDS_Latlon_Input
->lLat1
=lrint(geom_in
.first_lat
*1000.);/*lat of 1stgridpt*/
640 pGDS_Latlon_Input
->lLon1
=lrint(geom_in
.first_lon
*1000.);/*lon of 1stgridpt*/
641 pGDS_Latlon_Input
->usRes_flag
=geom_in
.usRes_flag
;/*resolution flags Tbl7*/
642 pGDS_Latlon_Input
->lLat2
=lrint(geom_in
.last_lat
*1000.);/*lat of 2ndgridpt*/
643 pGDS_Latlon_Input
->lLon2
=lrint(geom_in
.last_lon
*1000.);/*lon of 2ndgridpt*/
644 pGDS_Latlon_Input
->iDi
= lrint(geom_in
.parm_2
*1000.);/* i-dir incr*/
645 pGDS_Latlon_Input
->iDj
= lrint(geom_in
.parm_1
*1000.);/* j-dir incr*/
646 if ((geom_in
.parm_1
!= 0) && (geom_in
.parm_2
!= 0))
647 pGDS_Latlon_Input
->usRes_flag
= pGDS_Latlon_Input
->usRes_flag
+ 0x80;
648 pGDS_Latlon_Input
->usScan_mode
= geom_in
.scan
; /* order ofgridpts (Tbl 8)*/
649 pGDS_Latlon_Input
->usZero
= 0; /* filler zeroes*/
650 pGDS_Latlon_Input
->lLat_southpole
= -90000;/* lat of southern pole (millidegrees)*/
651 pGDS_Latlon_Input
->lLon_southpole
= 0;/* lon of southern pole (millidegrees)*/
652 pGDS_Latlon_Input
->lRotate
= 0;/* angle of rotation*/
653 pGDS_Latlon_Input
->lPole_lat
= 0;/* lat of pole of stretching (mdeg)*/
654 pGDS_Latlon_Input
->lPole_lon
= 0; /* lon of pole of stretching*/
655 pGDS_Latlon_Input
->lStretch
= 0;/* stretching factor*/
658 * D.2.b.2 DEBUG print
660 DPRINT3("\t%s: usData_type = %u (%s)\n", func
,pGDS_Latlon_Input
->usData_type
,
661 prjn_name
[pGDS_Latlon_Input
->usData_type
] );
662 DPRINT2("\t%s: usNi = %u\n",func
,pGDS_Latlon_Input
->usNi
);
663 DPRINT2("\t%s: usNj = %u\n",func
,pGDS_Latlon_Input
->usNj
);
664 DPRINT2("\t%s: lLat1 = %d\n",func
,pGDS_Latlon_Input
->lLat1
);
665 DPRINT2("\t%s: lLon1 = %d\n",func
,pGDS_Latlon_Input
->lLon1
);
666 DPRINT2("\t%s: lLat2 = %d\n",func
,pGDS_Latlon_Input
->lLat2
);
667 DPRINT2("\t%s: lLon2 = %d\n",func
,pGDS_Latlon_Input
->lLon2
);
668 DPRINT2("\t%s: iDi = %u\n",func
,pGDS_Latlon_Input
->iDi
);
669 DPRINT2("\t%s: iDj = %u\n",func
,pGDS_Latlon_Input
->iDj
);
670 DPRINT2("\t%s: usRes_flag = %u\n",func
,pGDS_Latlon_Input
->usRes_flag
);
671 DPRINT2("\t%s: usScan_mode = %u\n",func
,pGDS_Latlon_Input
->usScan_mode
);
672 DPRINT2("\t%s: lLat_southpole = %ld\n",func
,pGDS_Latlon_Input
->lLat_southpole
);
673 DPRINT2("\t%s: lLon_southpole = %ld\n",func
,pGDS_Latlon_Input
->lLon_southpole
);
674 DPRINT2("\t%s: lRotate = %ld\n",func
,pGDS_Latlon_Input
->lRotate
);
675 DPRINT2("\t%s: lPole_lat = %ld\n",func
,pGDS_Latlon_Input
->lPole_lat
);
676 DPRINT2("\t%s: lPole_lon = %ld\n",func
,pGDS_Latlon_Input
->lPole_lon
);
677 DPRINT2("\t%s: lStretch = %ld\n",func
,pGDS_Latlon_Input
->lStretch
);
686 DPRINT1(" Exiting %s.......\n" ,func
);
696 *********************************************************************
697 * FUNCTION: create_inpMercator
698 * Fills Mercator Projection structure.
701 * int create_inpMercator (geom_in, ppvGDS_Proj_Input, errmsg)
703 * ARGUMENTS (I=input, O=output, I&O=input and output):
704 * (I) GEOM_IN geom_in holds info to fill local Mercator block
705 * (O) void **ppvGDS_Proj_Input block to filled with Mercator info
706 * (O) char *errmsg empty array filled if error occurs
709 * 0> success, ppvGDS_Proj_Input holds Mercator projection info;
710 * 1> the input pre-Malloced projection block is null; errmsg filled;
711 **********************************************************************/
714 int create_inpMercator (GEOM_IN geom_in
, void **ppvGDS_Proj_Input
, char *errmsg
)
716 int create_inpMercator (geom_in
, ppvGDS_Proj_Input
, errmsg
)
717 GEOM_IN geom_in
; void **ppvGDS_Proj_Input
; char *errmsg
;
720 char *func
="create_inpMercator";
723 * C.1 DEFAULT status of 0
725 mercator
*pGDS_mercator_Input
;
728 DPRINT1 (" Entering %s.....\n",func
);
731 * C.2 IF (incoming projection block is Null)
734 * CHANGE return Status to error
736 if (!(pGDS_mercator_Input
= (mercator
*) *ppvGDS_Proj_Input
) )
738 DPRINT1 ("%s: ppvGDS_Proj_Input is null\n", func
);
739 sprintf(errmsg
,"%s: ppvGDS_Proj_Input is null\n", func
);
746 * C.2.b.1 FILL elements of Polar Stereo structure
748 pGDS_mercator_Input
->usData_type
= MERC_PRJ
; /* data type flag (Tbl ) */
749 pGDS_mercator_Input
->cols
= (unsigned short) geom_in
.nx
;/* #pts along x-axis*/
750 pGDS_mercator_Input
->rows
= (unsigned short) geom_in
.ny
;/* #pts along y-axiz*/
751 pGDS_mercator_Input
->first_lat
= lrint(geom_in
.first_lat
*1000.);/*lat of 1st gridpt*/
752 pGDS_mercator_Input
->first_lon
= lrint(geom_in
.first_lon
*1000.);/*lon of 1st gridpt*/
753 pGDS_mercator_Input
->usRes_flag
= geom_in
.usRes_flag
;/* resolution flags Tbl7 */
754 pGDS_mercator_Input
->La2
= lrint(geom_in
.last_lat
*1000.);/*lat of last gridpt*/
755 pGDS_mercator_Input
->Lo2
= lrint(geom_in
.last_lon
*1000.);/*lon of last gridpt*/
756 pGDS_mercator_Input
->latin
= lrint(geom_in
.parm_1
*1000.);/*reference latitude*/
757 pGDS_mercator_Input
->usZero1
= 0; /* filler zeroes */
758 pGDS_mercator_Input
->usScan_mode
= geom_in
.scan
; /* order of grid points (Tbl 8) */
759 pGDS_mercator_Input
->lon_inc
= lrint(geom_in
.parm_2
*1000.);/*longitude increment*/
760 pGDS_mercator_Input
->lat_inc
= lrint(geom_in
.parm_3
*1000.);/*latitude increment*/
761 pGDS_mercator_Input
->usZero
= 0; /* filler zeroes */
764 * C.2.b.2 DEBUG print
766 DPRINT3 ("\t%s: usData_type = %u (%s)\n",func
,pGDS_mercator_Input
->usData_type
,
767 prjn_name
[pGDS_mercator_Input
->usData_type
] );
768 DPRINT2("\t%s: cols = %u\n", func
,pGDS_mercator_Input
->cols
);
769 DPRINT2("\t%s: rows = %u\n", func
,pGDS_mercator_Input
->rows
);
770 DPRINT2("\t%s: first_lat = %d\n", func
,pGDS_mercator_Input
->first_lat
);
771 DPRINT2("\t%s: first_lon = %d\n", func
,pGDS_mercator_Input
->first_lon
);
772 DPRINT2("\t%s: usRes_flag = %d\n", func
,pGDS_mercator_Input
->usRes_flag
);
773 DPRINT2("\t%s: La2 = %d\n", func
,pGDS_mercator_Input
->La2
);
774 DPRINT2("\t%s: Lo2 = %d\n", func
,pGDS_mercator_Input
->Lo2
);
775 DPRINT2("\t%s: latin = %d\n", func
,pGDS_mercator_Input
->latin
);
776 DPRINT2("\t%s: usZero1 = %d\n", func
,pGDS_mercator_Input
->usZero1
);
777 DPRINT2("\t%s: usScan_mode = %d\n", func
,pGDS_mercator_Input
->usScan_mode
);
778 DPRINT2("\t%s: lon_inc = %f\n", func
,pGDS_mercator_Input
->lon_inc
);
779 DPRINT2("\t%s: lat_inc = %f\n", func
,pGDS_mercator_Input
->lat_inc
);
785 DPRINT1(" Exiting %s.......\n" ,func
);
808 ****************************************************************************
809 * E. FUNCTION: inp2gribLambert
810 * This routine fills the special Lambert Projection structure for
814 * int inp2grib_Lambert (ppvGDS_Proj_Input, pLambert, lProj_size, errmsg)
816 * ARGUMENTS (I=input, O=output, I&O=input and output):
817 * (I) void **ppvGDS_Proj_Input;
818 * pointer to struct holds Input Projection data
819 * (O) LAMBERT *pLambert;
820 * block to be filled with Lambert Projection information
821 * (O) long *lProj_size;
822 * to be filled with size of LAMBERT struct;
824 * empty array, filled if error occurred;
827 * 0> success, pLambert and lProj_size filled;
828 * 1> got null pointers; errmsg filled;
829 ****************************************************************************/
832 int inp2grib_Lambert (void **ppvGDS_Proj_Input
, LAMBERT
*pLambert
,
833 long *lProj_size
, char *errmsg
)
835 int inp2grib_Lambert (ppvGDS_Proj_Input
, pLambert
, lProj_size
, errmsg
)
836 void **ppvGDS_Proj_Input
; LAMBERT
*pLambert
;
837 long *lProj_size
; char *errmsg
;
841 * E.1 INIT status to success
845 GDS_LAM_INPUT
*vProjInp
= 0;
848 char *func
= "inp2grib_Lambert";
850 DPRINT1 (" Entering %s.....\n",func
);
854 * E.3 MAKE local ptr vProjInp point to Input Projection data block arg
856 vProjInp
= ( GDS_LAM_INPUT
* ) *ppvGDS_Proj_Input
; /* read fr this */
860 * E.4 IF (either of the user's struct pointers are NUL) THEN
865 if (!vProjInp
|| !pLambert
) {
866 DPRINT1 ("%s: the VOID *ppvGDS_Proj_Input block is null\n",func
);
867 sprintf(errmsg
, "%s: the VOID *ppvGDS_Proj_Input block is null\n",func
);
873 * E.5 FILL local block type LAMBERT
876 set_bytes(vProjInp
->iNx
, 2, pLambert
->achNx
);
878 set_bytes(vProjInp
->iNy
, 2, pLambert
->achNy
);
880 /* convert lLat1 to 3chars */
881 set_bytes(vProjInp
->lLat1
, 3, pLambert
->achLat1
);
883 /* convert lLon1 to 3chars */
884 set_bytes(vProjInp
->lLon1
, 3, pLambert
->achLon1
);
886 pLambert
->chRes_flag
= ( unsigned char ) vProjInp
->usRes_flag
;
888 /* convert lLon_orient to 3 bytes */
889 set_bytes(vProjInp
->lLon_orient
, 3, pLambert
->achLon_orient
);
891 /* convert ulDx to 3 bytes */
892 set_bytes(vProjInp
->ulDx
, 3, pLambert
->achDx
);
894 /* convert ulDy to 3 bytes */
895 set_bytes(vProjInp
->ulDy
, 3, pLambert
->achDy
);
897 pLambert
->chProj_flag
= ( unsigned char ) vProjInp
->usProj_flag
;
898 pLambert
->chScan_mode
= ( unsigned char ) vProjInp
->usScan_mode
;
900 /* convert lLat_cut1 to 3 chars */
901 set_bytes(vProjInp
->lLat_cut1
, 3, pLambert
->achLat_cut1
);
903 /* convert lLat_cut2 to 3 chars */
904 set_bytes(vProjInp
->lLat_cut2
, 3, pLambert
->achLat_cut2
);
906 /* convert lLat_southpole to 3chars */
907 set_bytes(vProjInp
->lLat_southpole
, 3, pLambert
->achLat_southpole
);
909 /* convert lLon_southpole to 3 chars */
910 set_bytes(vProjInp
->lLon_southpole
, 3, pLambert
->achLon_southpole
);
912 set_bytes(vProjInp
->usZero
, 2, pLambert
->achZero
);
916 * E.6 DEBUG print Grib LAMBERT block
918 DPRINT3("\t%s: achNx [%02d,%02d]\n", func
,
919 pLambert
->achNx
[0],pLambert
->achNx
[1]);
920 DPRINT3("\t%s: achNy [%02d,%02d]\n", func
,
921 pLambert
->achNy
[0],pLambert
->achNy
[1]);
922 DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n", func
,
923 pLambert
->achLat1
[0], pLambert
->achLat1
[1], pLambert
->achLat1
[2]);
924 DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n", func
,
925 pLambert
->achLon1
[0], pLambert
->achLon1
[1], pLambert
->achLon1
[2]);
926 DPRINT2("\t%s: chRes_flag [%02d]\n", func
, pLambert
->chRes_flag
);
927 DPRINT4("\t%s: achLon_orient [%02d,%02d,%02d]\n", func
,
928 pLambert
->achLon_orient
[0], pLambert
->achLon_orient
[1],
929 pLambert
->achLon_orient
[2]);
930 DPRINT4("\t%s: achDx [%02d,%02d,%02d]\n", func
,
931 pLambert
->achDx
[0], pLambert
->achDx
[1], pLambert
->achDx
[2]);
932 DPRINT4("\t%s: achDy [%02d,%02d,%02d]\n", func
,
933 pLambert
->achDy
[0], pLambert
->achDy
[1], pLambert
->achDy
[2]);
934 DPRINT2("\t%s: chProj_flag [%02d]\n", func
, pLambert
->chProj_flag
);
935 DPRINT2("\t%s: chScan_mode [%02d]\n", func
, pLambert
->chScan_mode
);
936 DPRINT4("\t%s: achLat_cut1 [%02d,%02d,%02d]\n", func
,
937 pLambert
->achLat_cut1
[0],
938 pLambert
->achLat_cut1
[1], pLambert
->achLat_cut1
[2]);
939 DPRINT4("\t%s: achLat_cut2 [%02d,%02d,%02d]\n", func
,
940 pLambert
->achLat_cut2
[0],
941 pLambert
->achLat_cut2
[1], pLambert
->achLat_cut2
[2]);
942 DPRINT4("\t%s: achLat_southpole [%02d,%02d,%02d]\n",func
,
943 pLambert
->achLat_southpole
[0],
944 pLambert
->achLat_southpole
[1], pLambert
->achLat_southpole
[2] );
945 DPRINT4("\t%s: achLon_southpole [%02d,%02d,%02d]\n",func
,
946 pLambert
->achLon_southpole
[0],
947 pLambert
->achLon_southpole
[1], pLambert
->achLon_southpole
[2] );
948 DPRINT3("\t%s: achZero [%02d,%02d]\n", func
,
949 pLambert
->achZero
[0], pLambert
->achZero
[1]);
954 * E.7 STORE proj size of LAMBERT struct in lProj_size
957 *lProj_size
= sizeof (LAMBERT
);
960 DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func
,
961 *lProj_size
, nStatus
);
975 ****************************************************************************
976 * F. FUNCTION: inp2grib_PolarSt
977 * This routine fills the special Polar Stereo Projection structure for
981 * int inp2grib_PolarSt ( ppvGDS_Proj_Input, Polar, lProj_size ,errmsg)
983 * ARGUMENTS (I=input, O=output, I&O=input and output):
984 * (I) void **ppvGDS_Proj_Input;
985 * holds input projection data
987 * to be filled with Polar Stereographic projection info
988 * (O) long *lProj_size;
989 * to be filled with size of structure POLAR
991 * empty array, filled if error occurred
994 * 0> success, Polar and lProj_size filled;
995 * 1> pointers are null, errmsg filled;
996 ****************************************************************************/
999 int inp2grib_PolarSt (void **ppvGDS_Proj_Input
, POLAR
*Polar
,
1000 long *lProj_size
, char *errmsg
)
1002 int inp2grib_PolarSt (ppvGDS_Proj_Input
, Polar
, lProj_size
, errmsg
)
1003 void **ppvGDS_Proj_Input
; POLAR
*Polar
;
1004 long *lProj_size
; char *errmsg
;
1009 * F.1 INIT variables !default stat=good
1011 GDS_PS_INPUT
*pProjInp
= 0;
1014 char *func
="inp2grib_PolarSt";
1016 DPRINT1 ("\t Entering %s.....\n", func
);
1019 * F.2 POINT local pProjInp to incoming ppvGDS_Proj_Input
1021 pProjInp
= ( GDS_PS_INPUT
*) *ppvGDS_Proj_Input
;
1025 * F.3 IF (true grib Polar proj block OR input Polar block is null) THEN
1030 if (!Polar
|| !pProjInp
)
1032 DPRINT1 ( "%s: Polar or pProjInp is null\n", func
);
1033 sprintf(errmsg
,"%s: Polar or pProjInp is null\n", func
);
1034 nStatus
= 1; goto BYE
;
1039 * F.4 FILL local struct from pProjInp
1041 /* convert usNx to 2 chars */
1042 set_bytes(pProjInp
->usNx
, 2, Polar
->achNx
);
1044 /* convert usNy to 2 chars */
1045 set_bytes(pProjInp
->usNy
, 2, Polar
->achNy
);
1047 /* convert lLat1 to 3 chars */
1048 set_bytes(pProjInp
->lLat1
, 3, Polar
->achLat1
);
1050 /* convert lLon1 to 3 chars */
1051 set_bytes(pProjInp
->lLon1
, 3, Polar
->achLon1
);
1053 Polar
->chRes_flag
= ( unsigned char ) pProjInp
->usRes_flag
;
1055 /* convert lLon_orient to 3 chars */
1056 set_bytes(pProjInp
->lLon_orient
, 3, Polar
->achLon_orient
);
1058 /* convert ulDx to 3 char */
1059 set_bytes(pProjInp
->ulDx
, 3, Polar
->achDx
);
1061 /* convert ulDy to 3chars */
1062 set_bytes(pProjInp
->ulDy
, 3, Polar
->achDy
);
1064 Polar
->chProj_flag
= ( unsigned char ) pProjInp
->usProj_flag
;
1065 Polar
->chScan_mode
= ( unsigned char ) pProjInp
->usScan_mode
;
1067 /* 4 bytes of zero */
1068 memset((void*) Polar
->achZero
, '\0', 4);
1072 * F.5 DEBUG print GRIB Projection block
1074 DPRINT3("\t%s: achNx [%02d,%02d]\n",func
, Polar
->achNx
[0],Polar
->achNx
[1]);
1075 DPRINT3("\t%s: achNy [%02d,%02d]\n",func
, Polar
->achNy
[0],Polar
->achNy
[1]);
1076 DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n",func
, Polar
->achLat1
[0],
1077 Polar
->achLat1
[1], Polar
->achLat1
[2]);
1078 DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n",func
, Polar
->achLon1
[0],
1079 Polar
->achLon1
[1] , Polar
->achLon1
[2]);
1080 DPRINT2("\t%s: chRes_flag [%02d]\n",func
, Polar
->chRes_flag
);
1081 DPRINT4("\t%s: achLon_orient [%02d,%02d,%02d]\n",func
,
1082 Polar
->achLon_orient
[0], Polar
->achLon_orient
[1], Polar
->achLon_orient
[2]);
1083 DPRINT4("\t%s: achDx [%02d,%02d,%02d]\n",func
, Polar
->achDx
[0],
1084 Polar
->achDx
[1], Polar
->achDx
[2]);
1085 DPRINT4("\t%s: achDy [%02d,%02d,%02d]\n",func
, Polar
->achDy
[0],
1086 Polar
->achDy
[1], Polar
->achDy
[2]);
1087 DPRINT2("\t%s: chProj_flag [%02d]\n",func
, Polar
->chProj_flag
);
1088 DPRINT2("\t%s: chScan_mode [%02d]\n",func
, Polar
->chScan_mode
);
1089 DPRINT5("\t%s: achZero [%02d,%02d,%02d,%02d]\n",func
, Polar
->achZero
[0],
1090 Polar
->achZero
[1], Polar
->achZero
[2], Polar
->achZero
[3]);
1095 * F.7 STORE size of POLAR struct in lProj_size
1097 *lProj_size
= sizeof (POLAR
);
1100 DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func
,
1101 *lProj_size
, nStatus
);
1104 * F.8 RETURN Stat ! 0 or 1
1117 ****************************************************************************
1118 * G. FUNCTION: inp2grib_Latlon
1119 * This routine fills the Latitude Longitude Projection structure for
1123 * int inp2grib_Latlon ( ppvGDS_Proj_Input, pLatlon, lProj_size ,errmsg)
1125 * ARGUMENTS (I=input, O=output, I&O=input and output):
1126 * (I) void **ppvGDS_Proj_Input;
1127 * holds input projection data
1128 * (O) LATLON *pLatlon;
1129 * to be filled with Lat/Lon projection info
1130 * (O) long *lProj_size;
1131 * to be filled with size of structure LATLON
1133 * empty array, filled if error occurred
1136 * 0> success, pLatlon and lProj_size filled;
1137 * 1> got null pointers, errmsg filled;
1138 ****************************************************************************/
1139 #if PROTOTYPE_NEEDED
1140 int inp2grib_Latlon (void **ppvGDS_Proj_Input
, LATLON
*pLatlon
,
1141 long *lProj_size
, char *errmsg
)
1143 int inp2grib_Latlon (ppvGDS_Proj_Input
, pLatlon
, lProj_size
, errmsg
)
1144 void **ppvGDS_Proj_Input
; LATLON
*pLatlon
;
1145 long *lProj_size
; char *errmsg
;
1148 GDS_LATLON_INPUT
*Inp
= 0;
1150 char *func
= "inp2grib_Latlon";
1153 * G.1 INIT status to success
1156 DPRINT1 ( " Entering %s.....\n", func
);
1159 * G.2 ASSIGN arguments to local pointers
1161 Inp
= (GDS_LATLON_INPUT
*) *ppvGDS_Proj_Input
;
1163 DPRINT3("\n%s: usData_type = %u (%s)\n", func, Inp->usData_type,
1164 prjn_name[Inp->usData_type] );
1165 DPRINT2("\t%s: usNi = %u\n",func, Inp->usNi );
1166 DPRINT2("\t%s: usNj = %u\n",func, Inp->usNj );
1167 DPRINT2("\t%s: lLat1 = %d\n",func, Inp->lLat1 );
1168 DPRINT2("\t%s: lLon1 = %d\n",func, Inp->lLon1 );
1169 DPRINT2("\t%s: lLat2 = %d\n",func, Inp->lLat2 );
1170 DPRINT2("\t%s: lLon2 = %d\n",func, Inp->lLon2 );
1171 DPRINT2("\t%s: iDi = %u\n",func, Inp->iDi );
1172 DPRINT2("\t%s: iDj = %u\n",func, Inp->iDj );
1173 DPRINT2("\t%s: usRes_flag = %u\n",func, Inp->usRes_flag );
1174 DPRINT2("\t%s: usScan_mode = %u\n",func, Inp->usScan_mode );
1175 DPRINT2("\t%s: lLat_southpole = %ld\n",func, Inp->lLat_southpole);
1176 DPRINT2("\t%s: lLon_southpole = %ld\n",func, Inp->lLon_southpole);
1177 DPRINT2("\t%s: lRotate = %ld\n",func, Inp->lRotate );
1178 DPRINT2("\t%s: lPole_lat = %ld\n",func, Inp->lPole_lat );
1179 DPRINT2("\t%s: lPole_lon = %ld\n",func, Inp->lPole_lon );
1180 DPRINT2("\t%s: lStretch = %ld\n",func, Inp->lStretch );
1185 * G.3 IF (pointers passed in are null) THEN
1190 if ( !Inp
|| !pLatlon
) {
1191 DPRINT1 ("%s: lLatlon_inp || pLatlon is null\n",func
);
1192 sprintf(errmsg
, "%s: lLatlon_inp || pLatlon is null\n", func
);
1199 * G.4 FILL local struct from Inp
1201 /* convert usNi & usNj to 2 chars */
1202 set_bytes(Inp
->usNi
, 2, pLatlon
->achNi
);
1204 set_bytes(Inp
->usNj
, 2, pLatlon
->achNj
);
1206 /* convert lLat1 to 3chars */
1207 set_bytes(Inp
->lLat1
, 3, pLatlon
->achLat1
);
1209 /* convert lLon1 to 3chars */
1210 set_bytes(Inp
->lLon1
, 3, pLatlon
->achLon1
);
1212 pLatlon
->chRes_flag
= ( unsigned char ) Inp
->usRes_flag
;
1214 /* convert lLat2 to 3chars */
1215 set_bytes(Inp
->lLat2
, 3, pLatlon
->achLat2
);
1217 /* convert lLon2 to 3chars */
1218 set_bytes(Inp
->lLon2
, 3, pLatlon
->achLon2
);
1220 /* convert lon increment to 2chars */
1221 set_bytes(Inp
->iDi
, 2, pLatlon
->achDi
);
1223 /* convert lat increment to 2chars */
1224 set_bytes(Inp
->iDj
, 2, pLatlon
->achDj
);
1226 /* 1 byte scan mode */
1227 pLatlon
->chScan_mode
= ( unsigned char ) Inp
->usScan_mode
;
1229 /* 4 bytes of reserved zero */
1230 memset ((void*)pLatlon
->achZero
, '\0', 4);
1232 /* convert lLat_southpole to 3chars */
1233 set_bytes(Inp
->lLat_southpole
, 3, pLatlon
->achLat_southpole
);
1235 /* convert lLon_southpole to 3chars */
1236 set_bytes(Inp
->lLon_southpole
, 3, pLatlon
->achLon_southpole
);
1238 /* convert lRotate to 4chars */
1239 set_bytes(Inp
->lRotate
, 4, pLatlon
->achRotate
);
1241 /* convert lPole_lat to 3chars */
1242 set_bytes(Inp
->lPole_lat
, 3, pLatlon
->achPole_lat
);
1244 /* convert lPole_lon to 3chars */
1245 set_bytes(Inp
->lPole_lon
, 3, pLatlon
->achPole_lon
);
1247 /* convert lStretch to 4 chars */
1248 set_bytes(Inp
->lStretch
, 4, pLatlon
->achStretch
);
1252 * G.5 DEBUG print Input Proj Block & their equivalence in the Char array;
1254 DPRINT3("\t%s: achNi [%02d,%02d]\n",func
,pLatlon
->achNi
[0],pLatlon
->achNi
[1]);
1255 DPRINT3("\t%s: achNj [%02d,%02d]\n",func
,pLatlon
->achNj
[0],pLatlon
->achNj
[1]);
1256 DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n",
1257 func
, pLatlon
->achLat1
[0],pLatlon
->achLat1
[1],pLatlon
->achLat1
[2]);
1258 DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n", func
,
1259 pLatlon
->achLon1
[0],pLatlon
->achLon1
[1],pLatlon
->achLon1
[2]);
1260 DPRINT2("\t%s: chRes_flag [%02d]\n", func
, pLatlon
->chRes_flag
);
1261 DPRINT4("\t%s: achLat2 [%02d,%02d,%02d]\n",
1262 func
, pLatlon
->achLat2
[0], pLatlon
->achLat2
[1], pLatlon
->achLat2
[2]);
1263 DPRINT4("\t%s: achLon2 [%02d,%02d,%02d]\n",
1264 func
, pLatlon
->achLon2
[0], pLatlon
->achLon2
[1], pLatlon
->achLon2
[2]);
1265 DPRINT3("\t%s: achDi [%02d,%02d]\n",func
,pLatlon
->achDi
[0],pLatlon
->achDi
[1]);
1266 DPRINT3("\t%s: achDj [%02d,%02d]\n",func
,pLatlon
->achDj
[0],pLatlon
->achDj
[1]);
1267 DPRINT2("\t%s: chScan_mode [%02d]\n", func
, pLatlon
->chScan_mode
);
1268 DPRINT5("\t%s: achZero [%02d,%02d,%02d,%02d]\n",
1269 func
, pLatlon
->achZero
[0],pLatlon
->achZero
[1],pLatlon
->achZero
[2],
1270 pLatlon
->achZero
[3]);
1271 DPRINT4("\t%s achLat_southpole [%02d,%02d,%02d]\n",
1272 func
, pLatlon
->achLat_southpole
[0],pLatlon
->achLat_southpole
[1],
1273 pLatlon
->achLat_southpole
[2]);
1274 DPRINT4("\t%s achLon_southpole [%02d,%02d,%02d]\n",
1275 func
, pLatlon
->achLon_southpole
[0],pLatlon
->achLon_southpole
[1],
1276 pLatlon
->achLon_southpole
[2]);
1277 DPRINT5("\t%s achRotate [%02d,%02d,%02d,%02d]\n",
1278 func
, pLatlon
->achRotate
[0],pLatlon
->achRotate
[1],
1279 pLatlon
->achRotate
[2], pLatlon
->achRotate
[3]);
1280 DPRINT4("\t%s achPole_lat [%02d,%02d,%02d]\n",
1281 func
, pLatlon
->achPole_lat
[0],pLatlon
->achPole_lat
[1],
1282 pLatlon
->achPole_lat
[2]);
1283 DPRINT4("\t%s achPole_lon [%02d,%02d,%02d]\n",
1284 func
, pLatlon
->achPole_lon
[0],pLatlon
->achPole_lon
[1],
1285 pLatlon
->achPole_lon
[2]);
1286 DPRINT5("\t%s achStretch [%02d,%02d,%02d,%02d]\n",
1287 func
, pLatlon
->achStretch
[0],pLatlon
->achStretch
[1],
1288 pLatlon
->achStretch
[2], pLatlon
->achStretch
[3]);
1292 * G.6 STORE size of LATLON struct in lProj_size
1294 *lProj_size
= sizeof (LATLON
);
1298 DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func
,
1299 *lProj_size
, nStatus
);
1314 ****************************************************************************
1315 * F. FUNCTION: inp2grib_Mercator
1316 * This routine fills the special Mercator Projection structure for
1320 * int inp2grib_Mercator ( ppvGDS_Proj_Input, Polar, lProj_size ,errmsg)
1322 * ARGUMENTS (I=input, O=output, I&O=input and output):
1323 * (I) void **ppvGDS_Proj_Input;
1324 * holds input projection data
1325 * (O) MERCATOR *Mercator;
1326 * to be filled with Polar Stereographic projection info
1327 * (O) long *lProj_size;
1328 * to be filled with size of structure POLAR
1330 * empty array, filled if error occurred
1333 * 0> success, Mercator and lProj_size filled;
1334 * 1> pointers are null, errmsg filled;
1335 ****************************************************************************/
1337 #if PROTOTYPE_NEEDED
1338 int inp2grib_Mercator (void **ppvGDS_Proj_Input
, MERCATOR
*Mercator
,
1339 long *lProj_size
, char *errmsg
)
1341 int inp2grib_Mercator (ppvGDS_Proj_Input
, Mercator
, lProj_size
, errmsg
)
1342 void **ppvGDS_Proj_Input
; MERCATOR
*Mercator
;
1343 long *lProj_size
; char *errmsg
;
1348 * F.1 INIT variables !default stat=good
1350 mercator
*ProjInp
= 0;
1353 char *func
="inp2grib_PolarSt";
1355 DPRINT1 ("\t Entering %s.....\n", func
);
1358 * F.2 POINT local pProjInp to incoming ppvGDS_Proj_Input
1360 ProjInp
= ( mercator
*) *ppvGDS_Proj_Input
;
1364 * F.3 IF (true grib Mercator proj block OR input Polar block is null) THEN
1369 if (!Mercator
|| !ProjInp
)
1371 DPRINT1 ( "%s: Mercator or ProjInp is null\n", func
);
1372 sprintf(errmsg
,"%s: Mercator or ProjInp is null\n", func
);
1373 nStatus
= 1; goto BYE
;
1378 * F.4 FILL local struct from pProjInp
1380 /* convert cols to 2 chars */
1381 set_bytes(ProjInp
->cols
, 2, Mercator
->achNi
);
1383 /* convert rows to 2 chars */
1384 set_bytes(ProjInp
->rows
, 2, Mercator
->achNj
);
1386 /* convert first_lat to 3 chars */
1387 set_bytes(ProjInp
->first_lat
, 3, Mercator
->achLat1
);
1389 /* convert first_lon to 3 chars */
1390 set_bytes(ProjInp
->first_lon
, 3, Mercator
->achLon1
);
1392 Mercator
->chRes_flag
= ( unsigned char ) ProjInp
->usRes_flag
;
1394 /* convert La2 to 3 chars */
1395 set_bytes(ProjInp
->La2
, 3, Mercator
->achLat2
);
1397 /* convert Lo2 to 3 chars */
1398 set_bytes(ProjInp
->Lo2
, 3, Mercator
->achLon2
);
1400 /* convert lLon_orient to 3 chars */
1401 set_bytes(ProjInp
->latin
, 3, Mercator
->achLatin
);
1403 /* convert zero fill */
1404 Mercator
->achZero1
= ( unsigned char ) ProjInp
->usZero1
;
1406 Mercator
->chScan_mode
= ( unsigned char ) ProjInp
->usScan_mode
;
1408 /* convert ulDx to 3 char */
1409 set_bytes((int)(ProjInp
->lon_inc
+ 0.5), 3, Mercator
->achDi
);
1411 /* convert ulDy to 3chars */
1412 set_bytes((int)(ProjInp
->lat_inc
+ 0.5), 3, Mercator
->achDj
);
1414 Mercator
->chScan_mode
= ( unsigned char ) ProjInp
->usScan_mode
;
1416 /* 8 bytes of zero */
1417 memset((void*) Mercator
->achZero2
, '\0', 8);
1421 * F.5 DEBUG print GRIB Projection block
1423 DPRINT3("\t%s: achNi [%02d,%02d]\n",func
,Mercator
->achNi
[0],Mercator
->achNi
[1]);
1424 DPRINT3("\t%s: achNj [%02d,%02d]\n",func
, Mercator
->achNj
[0],Mercator
->achNj
[1]);
1425 DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n",func
, Mercator
->achLat1
[0],
1426 Mercator
->achLat1
[1], Mercator
->achLat1
[2]);
1427 DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n",func
, Mercator
->achLon1
[0],
1428 Mercator
->achLon1
[1] , Mercator
->achLon1
[2]);
1429 DPRINT2("\t%s: chRes_flag [%02d]\n",func
, Mercator
->chRes_flag
);
1430 DPRINT4("\t%s: achLatint [%02d,%02d,%02d]\n",func
,
1431 Mercator
->achLatin
[0], Mercator
->achLatin
[1], Mercator
->achLatin
[2]);
1432 DPRINT4("\t%s: achDi [%02d,%02d,%02d]\n",func
, Mercator
->achDi
[0],
1433 Mercator
->achDi
[1], Mercator
->achDi
[2]);
1434 DPRINT4("\t%s: achDj [%02d,%02d,%02d]\n",func
, Mercator
->achDj
[0],
1435 Mercator
->achDj
[1], Mercator
->achDj
[2]);
1436 DPRINT5("\t%s: achZero2 [%02d,%02d,%02d,%02d]\n",func
, Mercator
->achZero2
[0],
1437 Mercator
->achZero2
[1], Mercator
->achZero2
[2], Mercator
->achZero2
[3]);
1442 * F.7 STORE size of POLAR struct in lProj_size
1444 *lProj_size
= sizeof (MERCATOR
);
1447 DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func
,
1448 *lProj_size
, nStatus
);
1451 * F.8 RETURN Stat ! 0 or 1
1462 Old round--this is different from standard gnu round (gnu round returns a
1463 float). Depending on compile options, sometimes gnu round was used, other
1464 times this function was used. Removed and replaced by lrint by T. Hutchinson,
1466 long round(double value)
1469 retval=lrint(value);