merge standard release WRF/WPS V3.0.1.1 into wrffire
[wrffire.git] / wrfv2_fire / external / io_grib1 / MEL_grib1 / gribputgds.c
blob510c985c03196f47a3308db818e7fcb050f3097d
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #ifdef XT3_Catamount
5 #include <features.h>
6 #undef htonl
7 #define htonl(x) swap_byte4(x)
8 #else
9 #include <netinet/in.h>
10 #endif
11 #include "dprints.h" /* for dprints */
12 #include "gribfuncs.h" /* prototypes */
13 #include <math.h>
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;
22 * INTERFACE:
23 * int gribputgds (Geom_In, pGDS_Head_Input, ppvGDS_Proj_Input,
24 * ppgrib_hdr, errmsg)
26 * ARGUMENTS (I=input, O=output, I&O=input and output):
27 * (I) GEOM_IN Geom_In
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.
41 * (O) char *errmsg
42 * empty array, returned filled if error occurred;
44 * RETURN CODE:
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.
54 #ifdef NCARIBM_NOC99
55 #define lrint(dbl) ((long)rint(dbl))
56 #endif
58 #if PROTOTYPE_NEEDED
59 int gribputgds ( GEOM_IN Geom_In, GDS_HEAD_INPUT *pGDS_Head_Input,
60 void **ppvGDS_Proj_Input, GRIB_HDR **ppgrib_hdr,
61 char *errmsg)
62 #else
63 int gribputgds ( Geom_In, pGDS_Head_Input, ppvGDS_Proj_Input,
64 ppgrib_hdr, errmsg)
65 GEOM_IN Geom_In;
66 GDS_HEAD_INPUT *pGDS_Head_Input;
67 void **ppvGDS_Proj_Input;
68 GRIB_HDR **ppgrib_hdr;
69 char *errmsg;
70 #endif
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 */
82 unsigned char ucflag;
83 int tempsz, stat= 1;
85 GDS_LATLON_INPUT *mp;
88 DPRINT0 ("\nEntering gribputgds .....\n");
91 * A.1 IF (Grib Hdr is null) THEN
92 * RETURN error Stat !null ptrs msg in errmsg
93 * ENDIF
95 gh = *ppgrib_hdr;
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);
99 goto BYE;
104 * A.3 ALLOCATE space for True Grib Structs GDS_HEAD & VOID *proj;
105 * IF (fails) THEN
106 * RETURN with bad Stat !errmsg filled
107 * ELSE
108 * CLEAR out structs
109 * ENDIF
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);
115 goto BYE;
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
152 * ENDIF
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;
169 } else {
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
188 * ENDIF
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
218 * ENDIF
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
250 * ENDIF
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
272 else {
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);
278 goto BYE;
280 * A.6.d ENDIF
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
303 * THEN
304 * RETURN with error !errmsg filled
305 * ENDIF
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);
313 goto BYE;
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
329 stat = 0;
331 BYE:
334 * A.12 FREE up storage
336 * A.13 RETURN Status
338 if (pgds) free (pgds);
339 DPRINT3 ("Leaving %s, stat=%d, errmsg='%s'\n", func,stat,errmsg);
340 return stat;
343 * END OF FUNCTION
351 *********************************************************************
352 * B. FUNCTION: create_inpLambert
353 * Fills Lambert Projection structure.
355 * INTERFACE:
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
363 * RETURN CODE
364 * 0> success, ppvGDS_Proj_Input holds Lambert projection information;
365 * 1> the input pre-MAlloced projection block is null; errmsg filled;
366 **********************************************************************/
368 #if PROTOTYPE_NEEDED
369 int create_inpLambert (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
370 #else
371 int create_inpLambert (geom_in, ppvGDS_Proj_Input, errmsg)
372 GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
373 #endif
375 char *func= "create_inpLambert";
378 * B.1 DEFAULT status of 0
380 int nStatus = 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)
388 * THEN
389 * FILL errmsg
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);
396 nStatus = 1;
399 * B.2.b ELSE
400 * USE info from GEOM_IN to fill the Lambert GDS struct
402 else
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 */
418 else
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;
424 if (cut1 >= 0.) {
425 if (cut2 > cut1) { tmp = cut1; cut1 = cut2; cut2 = tmp; }
427 else {
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 */
438 * DEBUG print
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);
455 * B.2 ENDIF
459 DPRINT1(" Exiting %s.......\n" ,func);
462 * B.3 RETURN status
464 return ( nStatus );
467 * END OF FUNCTION
475 *********************************************************************
476 * C. FUNCTION: create_inpPolar
477 * Fills Polar Stereographic Projection structure.
479 * INTERFACE:
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
487 * RETURN CODE:
488 * 0> success, ppvGDS_Proj_Input holds Polar projection info;
489 * 1> the input pre-Malloced projection block is null; errmsg filled;
490 **********************************************************************/
492 #if PROTOTYPE_NEEDED
493 int create_inpPolar (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
494 #else
495 int create_inpPolar (geom_in, ppvGDS_Proj_Input, errmsg)
496 GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
497 #endif
499 char *func="create_inpPolar";
502 * C.1 DEFAULT status of 0
504 GDS_PS_INPUT *pGDS_PS_Input;
505 int nStatus = 0;
507 DPRINT1 (" Entering %s.....\n",func );
510 * C.2 IF (incoming projection block is Null)
511 * C.2.a THEN
512 * FILL errmsg
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);
519 nStatus = 1;
522 else {
524 * C.2.b ELSE
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 */
540 else
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);
562 * C.2.b ENDIF
566 DPRINT1(" Exiting %s.......\n" ,func);
569 * C.3 RETURN status
571 return ( nStatus );
574 * END OF FUNCTION
583 *********************************************************************
584 * D. FUNCTION: create_inpLatlon
585 * Fills Latitude Longitude Projection structure.
587 * INTERFACE:
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
595 * OUTPUT:
596 * 0> success, ppGDS_Proj_Input filled with Lat/Lon projection info
597 * 1> pre-Malloced Projection block is null; errmsg filled;
598 **********************************************************************/
600 #if PROTOTYPE_NEEDED
601 int create_inpLatlon (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
602 #else
603 int create_inpLatlon (geom_in, ppvGDS_Proj_Input, errmsg)
604 GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
605 #endif
607 char *func= "Create_InpLatLon";
610 * D.0 DEFAULT to return status of 0
612 GDS_LATLON_INPUT *pGDS_Latlon_Input;
613 int nStatus = 0;
615 DPRINT1 (" Entering %s......\n" ,func);
618 * D.2 IF (incoming projection block is Null)
619 * THEN
620 * FILL errmsg
621 * CHANGE stat to 1
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);
627 nStatus = 1;
630 * D.2.b ELSE
631 * D.2.b.1 FILL elements of the Lat/Lon GDS block
633 else
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 );
679 * D.2.b ENDIF
684 * D.3 RET2URN status
686 DPRINT1(" Exiting %s.......\n" ,func);
687 return ( nStatus );
689 * END OF FUNCTION
696 *********************************************************************
697 * FUNCTION: create_inpMercator
698 * Fills Mercator Projection structure.
700 * INTERFACE:
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
708 * RETURN CODE:
709 * 0> success, ppvGDS_Proj_Input holds Mercator projection info;
710 * 1> the input pre-Malloced projection block is null; errmsg filled;
711 **********************************************************************/
713 #if PROTOTYPE_NEEDED
714 int create_inpMercator (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
715 #else
716 int create_inpMercator (geom_in, ppvGDS_Proj_Input, errmsg)
717 GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
718 #endif
720 char *func="create_inpMercator";
723 * C.1 DEFAULT status of 0
725 mercator *pGDS_mercator_Input;
726 int nStatus = 0;
728 DPRINT1 (" Entering %s.....\n",func );
731 * C.2 IF (incoming projection block is Null)
732 * C.2.a THEN
733 * FILL errmsg
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);
740 nStatus = 1;
743 else {
745 * C.2.b ELSE
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);
781 * C.2.b ENDIF
785 DPRINT1(" Exiting %s.......\n" ,func);
788 * C.3 RETURN status
790 return ( nStatus );
793 * END OF FUNCTION
808 ****************************************************************************
809 * E. FUNCTION: inp2gribLambert
810 * This routine fills the special Lambert Projection structure for
811 * the GDS.
813 * INTERFACE:
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;
823 * (O) char *errmsg;
824 * empty array, filled if error occurred;
826 * RETURN CODE:
827 * 0> success, pLambert and lProj_size filled;
828 * 1> got null pointers; errmsg filled;
829 ****************************************************************************/
831 #if PROTOTYPE_NEEDED
832 int inp2grib_Lambert (void **ppvGDS_Proj_Input, LAMBERT *pLambert,
833 long *lProj_size, char *errmsg)
834 #else
835 int inp2grib_Lambert (ppvGDS_Proj_Input, pLambert, lProj_size, errmsg)
836 void **ppvGDS_Proj_Input; LAMBERT *pLambert;
837 long *lProj_size; char *errmsg;
838 #endif
841 * E.1 INIT status to success
843 * E.2 DEBUG printing
845 GDS_LAM_INPUT *vProjInp = 0;
846 long lTemp = 0;
847 int nStatus = 0;
848 char *func= "inp2grib_Lambert";
849 long tmp_byte4;
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
861 * SET status = 1
862 * RETURN
863 * ENDIF
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);
868 nStatus= 1;
869 goto BYE;
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]);
950 /*******/
954 * E.7 STORE proj size of LAMBERT struct in lProj_size
957 *lProj_size = sizeof (LAMBERT);
959 BYE:
960 DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func,
961 *lProj_size, nStatus);
964 * E.9 RETURN status
966 return ( nStatus );
969 * END OF FUNCTION
975 ****************************************************************************
976 * F. FUNCTION: inp2grib_PolarSt
977 * This routine fills the special Polar Stereo Projection structure for
978 * the GDS.
980 * INTERFACE:
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
986 * (O) POLAR *Polar;
987 * to be filled with Polar Stereographic projection info
988 * (O) long *lProj_size;
989 * to be filled with size of structure POLAR
990 * (O) char *errmsg
991 * empty array, filled if error occurred
993 * RETURN CODE:
994 * 0> success, Polar and lProj_size filled;
995 * 1> pointers are null, errmsg filled;
996 ****************************************************************************/
998 #if PROTOTYPE_NEEDED
999 int inp2grib_PolarSt (void **ppvGDS_Proj_Input, POLAR *Polar,
1000 long *lProj_size , char *errmsg)
1001 #else
1002 int inp2grib_PolarSt (ppvGDS_Proj_Input, Polar, lProj_size , errmsg)
1003 void **ppvGDS_Proj_Input; POLAR *Polar;
1004 long *lProj_size ; char *errmsg;
1005 #endif
1009 * F.1 INIT variables !default stat=good
1011 GDS_PS_INPUT *pProjInp = 0;
1012 int lTemp = 0;
1013 int nStatus = 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
1026 * SET Status= 1
1027 * RETURN;
1028 * ENDIF
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]);
1091 /*******/
1095 * F.7 STORE size of POLAR struct in lProj_size
1097 *lProj_size = sizeof (POLAR);
1099 BYE:
1100 DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func,
1101 *lProj_size, nStatus);
1104 * F.8 RETURN Stat ! 0 or 1
1106 return ( nStatus );
1109 * END OF FUNCTION
1117 ****************************************************************************
1118 * G. FUNCTION: inp2grib_Latlon
1119 * This routine fills the Latitude Longitude Projection structure for
1120 * the GDS.
1122 * INTERFACE:
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
1132 * (O) char *errmsg;
1133 * empty array, filled if error occurred
1135 * RETURN CODE:
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)
1142 #else
1143 int inp2grib_Latlon (ppvGDS_Proj_Input, pLatlon, lProj_size, errmsg)
1144 void **ppvGDS_Proj_Input; LATLON *pLatlon;
1145 long *lProj_size; char *errmsg;
1146 #endif
1148 GDS_LATLON_INPUT *Inp = 0;
1149 int lTemp = 0;
1150 char *func= "inp2grib_Latlon";
1153 * G.1 INIT status to success
1155 int nStatus = 0;
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
1186 * SET status to 1
1187 * RETURN
1188 * ENDIF
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);
1193 nStatus = 1;
1194 goto BYE;
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]);
1289 /*******/
1292 * G.6 STORE size of LATLON struct in lProj_size
1294 *lProj_size = sizeof (LATLON);
1297 BYE:
1298 DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func,
1299 *lProj_size, nStatus);
1302 * G.7 RETURN stat
1304 return ( nStatus );
1307 * END OF FUNCTION
1314 ****************************************************************************
1315 * F. FUNCTION: inp2grib_Mercator
1316 * This routine fills the special Mercator Projection structure for
1317 * the GDS.
1319 * INTERFACE:
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
1329 * (O) char *errmsg
1330 * empty array, filled if error occurred
1332 * RETURN CODE:
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)
1340 #else
1341 int inp2grib_Mercator (ppvGDS_Proj_Input, Mercator, lProj_size , errmsg)
1342 void **ppvGDS_Proj_Input; MERCATOR *Mercator;
1343 long *lProj_size ; char *errmsg;
1344 #endif
1348 * F.1 INIT variables !default stat=good
1350 mercator *ProjInp = 0;
1351 int lTemp = 0;
1352 int nStatus = 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
1365 * SET Status= 1
1366 * RETURN;
1367 * ENDIF
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]);
1438 /*******/
1442 * F.7 STORE size of POLAR struct in lProj_size
1444 *lProj_size = sizeof (MERCATOR);
1446 BYE:
1447 DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func,
1448 *lProj_size, nStatus);
1451 * F.8 RETURN Stat ! 0 or 1
1453 return ( nStatus );
1456 * END OF FUNCTION
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,
1465 WSI. 4/14/05.
1466 long round(double value)
1468 long retval;
1469 retval=lrint(value);
1470 return retval;