#include #include #include #ifdef XT3_Catamount #include #undef htonl #define htonl(x) swap_byte4(x) #elif defined(_WIN32) #include #else #include #endif #include "dprints.h" /* for dprints */ #include "gribfuncs.h" /* prototypes */ #include /* ************************************************************************ * A. FUNCTION gribputgds * used to decode Grib's Grid Defn Section. It returns with both * internal structures GDS_HEAD_INPUT and VOID* projblock filled, * and also with true GDS already appended to GribHeader's Entire_Msg; * * INTERFACE: * int gribputgds (Geom_In, pGDS_Head_Input, ppvGDS_Proj_Input, * ppgrib_hdr, errmsg) * * ARGUMENTS (I=input, O=output, I&O=input and output): * (I) GEOM_IN Geom_In * Geometry information used as input; * (O) GDS_HEAD_INPUT *pGDS_Head_Input * this is the internal GDS structure. Attributes (uslength, * usData_type, chData_type, usNum_v and usPl_Pv) gets updated; * (O) void **ppvGDS_Proj_Input; * This is a pre-alloced storage of type Void and has length of * MAX_INP_PROJ_SIZE bytes long. How this block is filled depends * on the type of Projection it is. Projections currently supported * are Spherical, Lambert, and Polar Stereographic. * (I&O) GRIB_HDR **ppgrib_hdr * may already have one or more of the other Grib Sections * (IDS, PDS, BMS, BDS, or EDS). Upon successful exit, will * also contain a GDS section. * (O) char *errmsg * empty array, returned filled if error occurred; * * RETURN CODE: * 0> no errors; GDS appended to GRIB_HDR's entire_msg, its info * stored in bds_len & bds_ptr; msg_length updated too; * 1> error, grib hdr is null; errmsg filled; ************************************************************************ */ /* NCAR AIX does not have lrint, make one up. */ #ifdef NCARIBM_NOC99 #define lrint(dbl) ((long)rint(dbl)) #endif #ifdef _WIN32 #define lrint(x) (floor(x+(x>0) ? 0.5 : -0.5)) #endif #if PROTOTYPE_NEEDED int gribputgds ( GEOM_IN Geom_In, GDS_HEAD_INPUT *pGDS_Head_Input, void **ppvGDS_Proj_Input, GRIB_HDR **ppgrib_hdr, char *errmsg) #else int gribputgds ( Geom_In, pGDS_Head_Input, ppvGDS_Proj_Input, ppgrib_hdr, errmsg) GEOM_IN Geom_In; GDS_HEAD_INPUT *pGDS_Head_Input; void **ppvGDS_Proj_Input; GRIB_HDR **ppgrib_hdr; char *errmsg; #endif { /* * A.0 DEFAULT to err stat 1 */ char *func= "gribputgds"; char *pgds=0; /* true grib, GDS_HEAD + Proj block */ GDS_HEAD *pGDS_Head=0; /* first 6 bytes of PGDS */ void *pvGDS_Proj=0; /* projection info, PGDS 7th byte and on... */ long lProj_sz ; /* size of True-Grib projection block */ long new_msgsz; /* size after adding GDS */ GRIB_HDR *gh=0; /* temp ptr to struct */ unsigned char ucflag; int tempsz, stat= 1; GDS_LATLON_INPUT *mp; DPRINT0 ("\nEntering gribputgds .....\n"); /* * * A.1 IF (Grib Hdr is null) THEN * RETURN error Stat !null ptrs msg in errmsg * ENDIF */ gh = *ppgrib_hdr; if (!gh || !gh->entire_msg) { DPRINT1("%s: grib header is null\n", func); sprintf(errmsg,"%s: grib header is null\n", func); goto BYE; } /* * * A.3 ALLOCATE space for True Grib Structs GDS_HEAD & VOID *proj; * IF (fails) THEN * RETURN with bad Stat !errmsg filled * ELSE * CLEAR out structs * ENDIF */ if (! (pgds= (char *) malloc(sizeof (GDS_HEAD) + MAX_PROJ_SIZE))) { DPRINT1 ("%s: MALloced true Grib struct failed\n",func); sprintf(errmsg,"%s: MALloced true Grib struct failed\n",func); goto BYE; } else memset ((void *)pgds, '\0', sizeof(GDS_HEAD) + MAX_PROJ_SIZE); /* * * A.4 ASSIGN (GDS_HEAD *pGDS_Head) to be beginning of local PGDS block * ASSIGN (void *pvGDS_Proj) to byte #7 of local PGDS block */ pGDS_Head = (GDS_HEAD *) pgds; pvGDS_Proj = (void *) (pgds + sizeof(GDS_HEAD)); /* * * A.5 INIT some fields of GDS_HEAD & GDS_HEAD_INPUT structs */ pGDS_Head->chNV = ( unsigned char ) 0; pGDS_Head->chPV = ( unsigned char ) 255; pGDS_Head_Input->usNum_v = 0; /* INPUT NOT USED AT THIS TIME */ pGDS_Head_Input->usPl_Pv = 255; /* * * !now fill true GRIB Grid Defn Sect depending on Projection type * A.6.a IF (projection is Spherical) THEN */ if ((strcmp(Geom_In.prjn_name,"spherical")==0) || (strcmp(Geom_In.prjn_name,"gaussian") == 0)){ /* * A.6.a.1 FUNCTION create_inpLatlon !create internal Latlon struct * !using GEOM_IN & USER_INPUT * A.6.a.2 FUNCTION inp2grib_Latlon !use internal Latlon struct to * !make true Latlon Grib Gds * A.6.a.3 IF (either failed) THEN * FUNCTION upd_child_errmsg !tack funcname to errmsg * RETURN with error !errmsg filled * ENDIF */ if ( create_inpLatlon(Geom_In, ppvGDS_Proj_Input,errmsg) || inp2grib_Latlon (ppvGDS_Proj_Input, (LATLON *)(pgds+sizeof(GDS_HEAD)),&lProj_sz, errmsg)) { upd_child_errmsg (func, errmsg); goto BYE; } /* * A.6.a.4 STORE Gds len, DataType=0 into internal GDS struct */ pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz; if (strcmp(Geom_In.prjn_name,"spherical")==0) { pGDS_Head_Input->usData_type = LATLON_PRJ; pGDS_Head->chData_type = 0; } else { pGDS_Head_Input->usData_type = GAUSS_PRJ; pGDS_Head->chData_type = 4; } } /* * A.6.b ELSE IF (projection is Lambert) THEN */ else if (strcmp(Geom_In.prjn_name,"lambert")==0) { /* * A.6.b.1 FUNCTION create_inpLambert !create internal Lambert struct * !using GEOM_IN & USER_INPUT * A.6.b.2 FUNCTION inp2grib_Lambert !use internal Lambert struct to * !make true Lambert Grib Gds * A.6.b.3 IF (either failed) THEN * FUNCTION upd_child_errmsg !tack funcname to errmsg * RETURN with error !errmsg filled * ENDIF */ if ( create_inpLambert(Geom_In,ppvGDS_Proj_Input,errmsg) || inp2grib_Lambert( ppvGDS_Proj_Input, (LAMBERT *)(pgds+sizeof(GDS_HEAD)), &lProj_sz, errmsg)) { upd_child_errmsg (func, errmsg); goto BYE; } /* * A.6.b.4 STORE Gds len, DataType=3 into internal GDS struct */ pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz; pGDS_Head_Input->usData_type = LAMB_PRJ; pGDS_Head->chData_type = 3; } /* * A.6.c ELSE if (projection is Polar_Stereo) THEN */ else if (strcmp(Geom_In.prjn_name,"polar_stereo")==0) { /* * A.6.c.1 FUNCTION create_inpPolar * !create internal Polar struct using GEOM_IN & USER_INPUT * A.6.c.2 FUNCTION inp2grib_PolarSt * !use internal PolarSt struct to make true PolarSt Grib Gds * A.6.c.3 IF (either failed) THEN * FUNCTION upd_child_errmsg !tack funcname to errmsg * RETURN with error !errmsg filled * ENDIF */ /* make True Grib PPVGDS_PROJ & SIZE using internal ppvGds_proj_input : */ if (create_inpPolar(Geom_In, ppvGDS_Proj_Input,errmsg) || inp2grib_PolarSt(ppvGDS_Proj_Input, (void *)(pgds+sizeof(GDS_HEAD)),&lProj_sz, errmsg) ) { upd_child_errmsg (func, errmsg); goto BYE; } /* * A.6.c.4 STORE Gds len, DataType=5 into internal GDS struct */ pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz; pGDS_Head_Input->usData_type = POLAR_PRJ; pGDS_Head->chData_type = 5; } /* * A.6.c ELSE if (projection is Mercator) THEN */ else if (strcmp(Geom_In.prjn_name,"mercator")==0) { /* * A.6.c.1 FUNCTION create_inpMercator * !create internal Mercator struct using GEOM_IN & USER_INPUT * A.6.c.2 FUNCTION inp2grib_Mercator * !use internal Mercator struct to make true PolarSt Grib Gds * A.6.c.3 IF (either failed) THEN * FUNCTION upd_child_errmsg !tack funcname to errmsg * RETURN with error !errmsg filled * ENDIF */ /* make True Grib PPVGDS_PROJ & SIZE using internal ppvGds_proj_input : */ if (create_inpMercator(Geom_In, ppvGDS_Proj_Input,errmsg) || inp2grib_Mercator(ppvGDS_Proj_Input, (void *)(pgds+sizeof(GDS_HEAD)),&lProj_sz, errmsg) ) { upd_child_errmsg (func, errmsg); goto BYE; } /* * A.6.c.4 STORE Gds len, DataType=5 into internal GDS struct */ pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz; pGDS_Head_Input->usData_type = MERC_PRJ; pGDS_Head->chData_type = 1; } /* * A.6.d ELSE ! Projection unknown */ else { /* * RETURN with error !errmsg filled */ DPRINT2 ("%s: Projection '%s' unknown\n",func,Geom_In.prjn_name); sprintf (errmsg,"%s: Projection '%s' unknown\n",func,Geom_In.prjn_name); goto BYE; /* * A.6.d ENDIF */ } /* * * A.7 STORE ptr to Gds and its Length in Grib hdr */ gh->gds_ptr = gh->entire_msg + gh->msg_length; gh->gds_len = sizeof(GDS_HEAD) + lProj_sz; DPRINT3 ("Gds length= (%ld + %ld)= %ld \n", sizeof(GDS_HEAD), lProj_sz, gh->gds_len); /* * * A.8 STORE Gds length in the True Grib GDS block too */ set_bytes(gh->gds_len, 3, pGDS_Head->achGDS_length); /* * * A.9 IF gribhdr's buffer is too small AND * FUCTION Expand_gribhdr failed * THEN * RETURN with error !errmsg filled * ENDIF */ new_msgsz= gh->msg_length + gh->gds_len; if (new_msgsz > gh->abs_size && Expand_gribhdr (gh, new_msgsz, errmsg) !=0) { upd_child_errmsg (func, errmsg); goto BYE; } /* * * A.10 UPDATE Grib Header Struct * !copy true BDS block into Grib Header's Entire_Msg array; * !add gds length to Message length */ memcpy ((void *)gh->gds_ptr, (void *)pgds, gh->gds_len); gh->msg_length += gh->gds_len; DPRINT1 ("copying %ld bytes from PGDS to gh->GDS_PTR \n", gh->gds_len); /* * * A.11 CHANGE return Status to no errors */ stat = 0; BYE: /* * * A.12 FREE up storage * * A.13 RETURN Status */ if (pgds) free (pgds); DPRINT3 ("Leaving %s, stat=%d, errmsg='%s'\n", func,stat,errmsg); return stat; /* * * END OF FUNCTION * * */ } /* * ********************************************************************* * B. FUNCTION: create_inpLambert * Fills Lambert Projection structure. * * INTERFACE: * int create_inpLambert ( geom_in, ppvGDS_Proj_Input, errmsg) * * ARGUMENTS (I=input, O=output, I&O=input and output): * (I) GEOM_IN geom_in Holds info to fill local Lambert block * (O) void **ppvGDS_Proj_Input pre-allocated block to be filled; * (O) char *errmsg returns filled if error occurred * * RETURN CODE * 0> success, ppvGDS_Proj_Input holds Lambert projection information; * 1> the input pre-MAlloced projection block is null; errmsg filled; **********************************************************************/ #if PROTOTYPE_NEEDED int create_inpLambert (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg) #else int create_inpLambert (geom_in, ppvGDS_Proj_Input, errmsg) GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg; #endif { char *func= "create_inpLambert"; /* * * B.1 DEFAULT status of 0 */ int nStatus = 0; double cut1, cut2, tmp; GDS_LAM_INPUT *pGDS_Lam_Input; DPRINT1 ( " Entering %s.....\n", func ); /* * * B.2 IF (incoming projection block is Null) * THEN * FILL errmsg * SET return status to error */ if (!(pGDS_Lam_Input= (GDS_LAM_INPUT *) *ppvGDS_Proj_Input) ) { DPRINT1 ( "%s: ppvGDS_Proj_Input is null\n", func); sprintf(errmsg, "%s: ppvGDS_Proj_Input is null\n", func); nStatus = 1; } /* * B.2.b ELSE * USE info from GEOM_IN to fill the Lambert GDS struct */ else { pGDS_Lam_Input->usData_type = LAMB_PRJ; /* data type flag (Tbl ) */ pGDS_Lam_Input->iNx = (int) geom_in.nx; /* #pts along x-axis */ pGDS_Lam_Input->iNy = (int) geom_in.ny;/* #pts along y-axis */ /* latitude & lon of 1st grid point */ pGDS_Lam_Input->lLat1 = lrint(geom_in.first_lat *1000.); pGDS_Lam_Input->lLon1 = lrint((geom_in.first_lon) *1000.); pGDS_Lam_Input->usRes_flag = geom_in.usRes_flag;/*Resolution flags Tbl7*/ pGDS_Lam_Input->lLon_orient=lrint(geom_in.parm_3 *1000.);/*grid orient */ pGDS_Lam_Input->ulDx=(unsigned long)lrint(geom_in.x_int_dis*1000.);/*Xdir gridlen*/ pGDS_Lam_Input->ulDy=(unsigned long)lrint(geom_in.y_int_dis*1000.);/*Ydir gridlen*/ if ((geom_in.y_int_dis != 0) && (geom_in.x_int_dis != 0)) pGDS_Lam_Input->usRes_flag = pGDS_Lam_Input->usRes_flag + 0x88; if (geom_in.parm_1 > 0) pGDS_Lam_Input->usProj_flag = 0; /* projection flag */ else pGDS_Lam_Input->usProj_flag = 1<<7; /* projection flag */ pGDS_Lam_Input->usScan_mode = geom_in.scan; /* order of grid points (Tbl8)*/ /* Make sure CUT1 is closest to Pole */ cut1 = geom_in.parm_1; cut2 = geom_in.parm_2; if (cut1 >= 0.) { if (cut2 > cut1) { tmp = cut1; cut1 = cut2; cut2 = tmp; } } else { if (cut2 < cut1) { tmp = cut1; cut1 = cut2; cut2 = tmp; } } pGDS_Lam_Input->lLat_cut1=lrint(cut1 *1000.);/* 1stlat fr pole secant cuts*/ pGDS_Lam_Input->lLat_cut2=lrint(cut2 *1000.);/* 2ndlat fr pole secant cuts*/ pGDS_Lam_Input->lLat_southpole = -90000; /* lat of southern pole (millidegrees) */ pGDS_Lam_Input->lLon_southpole = 0; /* lon of souther pole (millidegrees) */ pGDS_Lam_Input->usZero = 0; /* filler zeroes */ /* * DEBUG print */ DPRINT3("\t%s: usData_type = %u (%s)\n", func,pGDS_Lam_Input->usData_type, prjn_name[pGDS_Lam_Input->usData_type] ); DPRINT2("\t%s: iNx = %d\n", func,pGDS_Lam_Input->iNx ); DPRINT2("\t%s: iNy = %d\n", func,pGDS_Lam_Input->iNy ); DPRINT2("\t%s: lLat1 = %d\n", func,pGDS_Lam_Input->lLat1 ); DPRINT2("\t%s: lLon1 = %d\n", func,pGDS_Lam_Input->lLon1 ); DPRINT2("\t%s: lLon_orient = %d\n", func,pGDS_Lam_Input->lLon_orient); DPRINT2("\t%s: ulDx = %u\n", func, pGDS_Lam_Input->ulDx ); DPRINT2("\t%s: ulDy = %u\n", func, pGDS_Lam_Input->ulDy ); DPRINT2("\t%s: lLat_cut1 = %d\n", func, pGDS_Lam_Input->lLat_cut1); DPRINT2("\t%s: lLat_cut2 = %d\n", func, pGDS_Lam_Input->lLat_cut2); DPRINT2("\t%s: usRes_flag = %u\n", func,pGDS_Lam_Input->usRes_flag); DPRINT2("\t%s: usProj_flag = %u\n", func,pGDS_Lam_Input->usProj_flag); DPRINT2("\t%s: usScan_mode = %u\n", func,pGDS_Lam_Input->usScan_mode); /* * B.2 ENDIF */ } DPRINT1(" Exiting %s.......\n" ,func); /* * * B.3 RETURN status */ return ( nStatus ); /* * * END OF FUNCTION * * */ } /* * ********************************************************************* * C. FUNCTION: create_inpPolar * Fills Polar Stereographic Projection structure. * * INTERFACE: * int create_inpPolar (geom_in, ppvGDS_Proj_Input, errmsg) * * ARGUMENTS (I=input, O=output, I&O=input and output): * (I) GEOM_IN geom_in holds info to fill local Polar block * (O) void **ppvGDS_Proj_Input block to filled with Polar Stereo info * (O) char *errmsg empty array filled if error occurs * * RETURN CODE: * 0> success, ppvGDS_Proj_Input holds Polar projection info; * 1> the input pre-Malloced projection block is null; errmsg filled; **********************************************************************/ #if PROTOTYPE_NEEDED int create_inpPolar (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg) #else int create_inpPolar (geom_in, ppvGDS_Proj_Input, errmsg) GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg; #endif { char *func="create_inpPolar"; /* * * C.1 DEFAULT status of 0 */ GDS_PS_INPUT *pGDS_PS_Input; int nStatus = 0; DPRINT1 (" Entering %s.....\n",func ); /* * * C.2 IF (incoming projection block is Null) * C.2.a THEN * FILL errmsg * CHANGE return Status to error */ if (!(pGDS_PS_Input= (GDS_PS_INPUT *) *ppvGDS_Proj_Input) ) { DPRINT1 ("%s: ppvGDS_Proj_Input is null\n", func); sprintf(errmsg,"%s: ppvGDS_Proj_Input is null\n", func); nStatus = 1; } else { /* * C.2.b ELSE * C.2.b.1 FILL elements of Polar Stereo structure */ pGDS_PS_Input->usData_type = POLAR_PRJ; /* data type flag (Tbl ) */ pGDS_PS_Input->usNx = (unsigned short) geom_in.nx;/* #pts along x-axis*/ pGDS_PS_Input->usNy = (unsigned short) geom_in.ny;/* #pts along y-axiz*/ pGDS_PS_Input->lLat1 = lrint(geom_in.first_lat *1000.);/*lat of 1st gridpt*/ pGDS_PS_Input->lLon1 = lrint(geom_in.first_lon *1000.);/*lon of 1st gridpt*/ pGDS_PS_Input->usRes_flag = geom_in.usRes_flag;/* resolution flags Tbl7 */ pGDS_PS_Input->lLon_orient = lrint(geom_in.parm_2 *1000.);/*grid orient*/ pGDS_PS_Input->ulDx=(unsigned long)lrint(geom_in.x_int_dis*1000.);/*Xdir gridlen*/ pGDS_PS_Input->ulDy=(unsigned long)lrint(geom_in.y_int_dis*1000.);/*Ydir gridlen*/ if ((geom_in.y_int_dis != 0) && (geom_in.x_int_dis != 0)) pGDS_PS_Input->usRes_flag = pGDS_PS_Input->usRes_flag + 0x88; if (geom_in.first_lat > 0) pGDS_PS_Input->usProj_flag = 0; /* projection flag */ else pGDS_PS_Input->usProj_flag = 1<<7; /* projection flag */ pGDS_PS_Input->usScan_mode = geom_in.scan; /* order of grid points (Tbl 8) */ pGDS_PS_Input->usZero = 0; /* filler zeroes */ /* * C.2.b.2 DEBUG print */ DPRINT3 ("\t%s: usData_type = %u (%s)\n",func,pGDS_PS_Input->usData_type, prjn_name [pGDS_PS_Input->usData_type] ); DPRINT2("\t%s: usNx = %u\n", func,pGDS_PS_Input->usNx ); DPRINT2("\t%s: usNy = %u\n", func,pGDS_PS_Input->usNy ); DPRINT2("\t%s: lLat1 = %d\n", func,pGDS_PS_Input->lLat1 ); DPRINT2("\t%s: lLon1 = %d\n", func,pGDS_PS_Input->lLon1 ); DPRINT2("\t%s: lLon_orient = %d\n", func,pGDS_PS_Input->lLon_orient); DPRINT2("\t%s: ulDx = %u\n", func,pGDS_PS_Input->ulDx); DPRINT2("\t%s: ulDy = %u\n", func,pGDS_PS_Input->ulDy); DPRINT2("\t%s: usRes_flag = %u\n", func,pGDS_PS_Input->usRes_flag); DPRINT2("\t%s: usProj_flag = %u\n", func,pGDS_PS_Input->usProj_flag); DPRINT2("\t%s: usScan_mode = %u\n", func,pGDS_PS_Input->usScan_mode); /* * C.2.b ENDIF */ } DPRINT1(" Exiting %s.......\n" ,func); /* * * C.3 RETURN status */ return ( nStatus ); /* * * END OF FUNCTION * * */ } /* * ********************************************************************* * D. FUNCTION: create_inpLatlon * Fills Latitude Longitude Projection structure. * * INTERFACE: * int create_inpLatlon ( geom_in, ppvGDS_Proj_Input, errmsg) * * ARGUMENTS (I=input, O=output, I&O=input and output): * (I) GEOM_IN geom_in holds geom info to fill local Lat/Lon block * (O) void **ppvGDS_Proj_Input to be filled with LatLon projection info * (O) char *errmsg empty array, filled if error occurred * * OUTPUT: * 0> success, ppGDS_Proj_Input filled with Lat/Lon projection info * 1> pre-Malloced Projection block is null; errmsg filled; **********************************************************************/ #if PROTOTYPE_NEEDED int create_inpLatlon (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg) #else int create_inpLatlon (geom_in, ppvGDS_Proj_Input, errmsg) GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg; #endif { char *func= "Create_InpLatLon"; /* * * D.0 DEFAULT to return status of 0 */ GDS_LATLON_INPUT *pGDS_Latlon_Input; int nStatus = 0; DPRINT1 (" Entering %s......\n" ,func); /* * * D.2 IF (incoming projection block is Null) * THEN * FILL errmsg * CHANGE stat to 1 */ if (!(pGDS_Latlon_Input= (GDS_LATLON_INPUT *) *ppvGDS_Proj_Input) ) { DPRINT1 (" %s: ppvGDS_Proj_Input is null\n", func); sprintf(errmsg," %s: ppvGDS_Proj_Input is null\n", func); nStatus = 1; } /* * D.2.b ELSE * D.2.b.1 FILL elements of the Lat/Lon GDS block */ else { pGDS_Latlon_Input->usData_type = LATLON_PRJ; /* data type flag (Tbl )*/ pGDS_Latlon_Input->usNi=(unsigned short)geom_in.nx;/*#pts along x-axis 109*/ pGDS_Latlon_Input->usNj=(unsigned short)geom_in.ny;/* #pts along y-axiz 82*/ pGDS_Latlon_Input->lLat1=lrint(geom_in.first_lat*1000.);/*lat of 1stgridpt*/ pGDS_Latlon_Input->lLon1=lrint(geom_in.first_lon*1000.);/*lon of 1stgridpt*/ pGDS_Latlon_Input->usRes_flag=geom_in.usRes_flag;/*resolution flags Tbl7*/ pGDS_Latlon_Input->lLat2 =lrint(geom_in.last_lat*1000.);/*lat of 2ndgridpt*/ pGDS_Latlon_Input->lLon2 =lrint(geom_in.last_lon*1000.);/*lon of 2ndgridpt*/ pGDS_Latlon_Input->iDi = lrint(geom_in.parm_2 *1000.);/* i-dir incr*/ pGDS_Latlon_Input->iDj = lrint(geom_in.parm_1 *1000.);/* j-dir incr*/ if ((geom_in.parm_1 != 0) && (geom_in.parm_2 != 0)) pGDS_Latlon_Input->usRes_flag = pGDS_Latlon_Input->usRes_flag + 0x88; pGDS_Latlon_Input->usScan_mode = geom_in.scan; /* order ofgridpts (Tbl 8)*/ pGDS_Latlon_Input->usZero = 0; /* filler zeroes*/ pGDS_Latlon_Input->lLat_southpole= -90000;/* lat of southern pole (millidegrees)*/ pGDS_Latlon_Input->lLon_southpole= 0;/* lon of southern pole (millidegrees)*/ pGDS_Latlon_Input->lRotate = 0;/* angle of rotation*/ pGDS_Latlon_Input->lPole_lat = 0;/* lat of pole of stretching (mdeg)*/ pGDS_Latlon_Input->lPole_lon = 0; /* lon of pole of stretching*/ pGDS_Latlon_Input->lStretch = 0;/* stretching factor*/ /* * D.2.b.2 DEBUG print */ DPRINT3("\t%s: usData_type = %u (%s)\n", func,pGDS_Latlon_Input->usData_type, prjn_name[pGDS_Latlon_Input->usData_type] ); DPRINT2("\t%s: usNi = %u\n",func,pGDS_Latlon_Input->usNi ); DPRINT2("\t%s: usNj = %u\n",func,pGDS_Latlon_Input->usNj ); DPRINT2("\t%s: lLat1 = %d\n",func,pGDS_Latlon_Input->lLat1 ); DPRINT2("\t%s: lLon1 = %d\n",func,pGDS_Latlon_Input->lLon1 ); DPRINT2("\t%s: lLat2 = %d\n",func,pGDS_Latlon_Input->lLat2 ); DPRINT2("\t%s: lLon2 = %d\n",func,pGDS_Latlon_Input->lLon2 ); DPRINT2("\t%s: iDi = %u\n",func,pGDS_Latlon_Input->iDi ); DPRINT2("\t%s: iDj = %u\n",func,pGDS_Latlon_Input->iDj ); DPRINT2("\t%s: usRes_flag = %u\n",func,pGDS_Latlon_Input->usRes_flag ); DPRINT2("\t%s: usScan_mode = %u\n",func,pGDS_Latlon_Input->usScan_mode ); DPRINT2("\t%s: lLat_southpole = %ld\n",func,pGDS_Latlon_Input->lLat_southpole); DPRINT2("\t%s: lLon_southpole = %ld\n",func,pGDS_Latlon_Input->lLon_southpole); DPRINT2("\t%s: lRotate = %ld\n",func,pGDS_Latlon_Input->lRotate ); DPRINT2("\t%s: lPole_lat = %ld\n",func,pGDS_Latlon_Input->lPole_lat ); DPRINT2("\t%s: lPole_lon = %ld\n",func,pGDS_Latlon_Input->lPole_lon ); DPRINT2("\t%s: lStretch = %ld\n",func,pGDS_Latlon_Input->lStretch ); /* * D.2.b ENDIF */ } /* * * D.3 RET2URN status */ DPRINT1(" Exiting %s.......\n" ,func); return ( nStatus ); /* * END OF FUNCTION * */ } /* * ********************************************************************* * FUNCTION: create_inpMercator * Fills Mercator Projection structure. * * INTERFACE: * int create_inpMercator (geom_in, ppvGDS_Proj_Input, errmsg) * * ARGUMENTS (I=input, O=output, I&O=input and output): * (I) GEOM_IN geom_in holds info to fill local Mercator block * (O) void **ppvGDS_Proj_Input block to filled with Mercator info * (O) char *errmsg empty array filled if error occurs * * RETURN CODE: * 0> success, ppvGDS_Proj_Input holds Mercator projection info; * 1> the input pre-Malloced projection block is null; errmsg filled; **********************************************************************/ #if PROTOTYPE_NEEDED int create_inpMercator (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg) #else int create_inpMercator (geom_in, ppvGDS_Proj_Input, errmsg) GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg; #endif { char *func="create_inpMercator"; /* * * C.1 DEFAULT status of 0 */ mercator *pGDS_mercator_Input; int nStatus = 0; DPRINT1 (" Entering %s.....\n",func ); /* * * C.2 IF (incoming projection block is Null) * C.2.a THEN * FILL errmsg * CHANGE return Status to error */ if (!(pGDS_mercator_Input= (mercator *) *ppvGDS_Proj_Input) ) { DPRINT1 ("%s: ppvGDS_Proj_Input is null\n", func); sprintf(errmsg,"%s: ppvGDS_Proj_Input is null\n", func); nStatus = 1; } else { /* * C.2.b ELSE * C.2.b.1 FILL elements of Polar Stereo structure */ pGDS_mercator_Input->usData_type = MERC_PRJ; /* data type flag (Tbl ) */ pGDS_mercator_Input->cols = (unsigned short) geom_in.nx;/* #pts along x-axis*/ pGDS_mercator_Input->rows = (unsigned short) geom_in.ny;/* #pts along y-axiz*/ pGDS_mercator_Input->first_lat = lrint(geom_in.first_lat *1000.);/*lat of 1st gridpt*/ pGDS_mercator_Input->first_lon = lrint(geom_in.first_lon *1000.);/*lon of 1st gridpt*/ pGDS_mercator_Input->usRes_flag = geom_in.usRes_flag;/* resolution flags Tbl7 */ pGDS_mercator_Input->La2 = lrint(geom_in.last_lat *1000.);/*lat of last gridpt*/ pGDS_mercator_Input->Lo2 = lrint(geom_in.last_lon *1000.);/*lon of last gridpt*/ pGDS_mercator_Input->latin = lrint(geom_in.parm_1 *1000.);/*reference latitude*/ pGDS_mercator_Input->usZero1 = 0; /* filler zeroes */ pGDS_mercator_Input->usScan_mode = geom_in.scan; /* order of grid points (Tbl 8) */ pGDS_mercator_Input->lon_inc = lrint(geom_in.parm_2 *1000.);/*longitude increment*/ pGDS_mercator_Input->lat_inc = lrint(geom_in.parm_3 *1000.);/*latitude increment*/ pGDS_mercator_Input->usZero = 0; /* filler zeroes */ /* * C.2.b.2 DEBUG print */ DPRINT3 ("\t%s: usData_type = %u (%s)\n",func,pGDS_mercator_Input->usData_type, prjn_name [pGDS_mercator_Input->usData_type] ); DPRINT2("\t%s: cols = %u\n", func,pGDS_mercator_Input->cols ); DPRINT2("\t%s: rows = %u\n", func,pGDS_mercator_Input->rows ); DPRINT2("\t%s: first_lat = %d\n", func,pGDS_mercator_Input->first_lat ); DPRINT2("\t%s: first_lon = %d\n", func,pGDS_mercator_Input->first_lon ); DPRINT2("\t%s: usRes_flag = %d\n", func,pGDS_mercator_Input->usRes_flag); DPRINT2("\t%s: La2 = %d\n", func,pGDS_mercator_Input->La2); DPRINT2("\t%s: Lo2 = %d\n", func,pGDS_mercator_Input->Lo2); DPRINT2("\t%s: latin = %d\n", func,pGDS_mercator_Input->latin); DPRINT2("\t%s: usZero1 = %d\n", func,pGDS_mercator_Input->usZero1); DPRINT2("\t%s: usScan_mode = %d\n", func,pGDS_mercator_Input->usScan_mode); DPRINT2("\t%s: lon_inc = %f\n", func,pGDS_mercator_Input->lon_inc); DPRINT2("\t%s: lat_inc = %f\n", func,pGDS_mercator_Input->lat_inc); /* * C.2.b ENDIF */ } DPRINT1(" Exiting %s.......\n" ,func); /* * * C.3 RETURN status */ return ( nStatus ); /* * * END OF FUNCTION * * */ } /* * **************************************************************************** * E. FUNCTION: inp2gribLambert * This routine fills the special Lambert Projection structure for * the GDS. * * INTERFACE: * int inp2grib_Lambert (ppvGDS_Proj_Input, pLambert, lProj_size, errmsg) * * ARGUMENTS (I=input, O=output, I&O=input and output): * (I) void **ppvGDS_Proj_Input; * pointer to struct holds Input Projection data * (O) LAMBERT *pLambert; * block to be filled with Lambert Projection information * (O) long *lProj_size; * to be filled with size of LAMBERT struct; * (O) char *errmsg; * empty array, filled if error occurred; * * RETURN CODE: * 0> success, pLambert and lProj_size filled; * 1> got null pointers; errmsg filled; ****************************************************************************/ #if PROTOTYPE_NEEDED int inp2grib_Lambert (void **ppvGDS_Proj_Input, LAMBERT *pLambert, long *lProj_size, char *errmsg) #else int inp2grib_Lambert (ppvGDS_Proj_Input, pLambert, lProj_size, errmsg) void **ppvGDS_Proj_Input; LAMBERT *pLambert; long *lProj_size; char *errmsg; #endif { /* * E.1 INIT status to success * * E.2 DEBUG printing */ GDS_LAM_INPUT *vProjInp = 0; long lTemp = 0; int nStatus = 0; char *func= "inp2grib_Lambert"; long tmp_byte4; DPRINT1 (" Entering %s.....\n",func); /* * * E.3 MAKE local ptr vProjInp point to Input Projection data block arg */ vProjInp = ( GDS_LAM_INPUT * ) *ppvGDS_Proj_Input; /* read fr this */ /* * * E.4 IF (either of the user's struct pointers are NUL) THEN * SET status = 1 * RETURN * ENDIF */ if (!vProjInp || !pLambert) { DPRINT1 ("%s: the VOID *ppvGDS_Proj_Input block is null\n",func); sprintf(errmsg, "%s: the VOID *ppvGDS_Proj_Input block is null\n",func); nStatus= 1; goto BYE; } /* * E.5 FILL local block type LAMBERT */ set_bytes(vProjInp->iNx, 2, pLambert->achNx); set_bytes(vProjInp->iNy, 2, pLambert->achNy); /* convert lLat1 to 3chars */ set_bytes(vProjInp->lLat1, 3, pLambert->achLat1); /* convert lLon1 to 3chars */ set_bytes(vProjInp->lLon1, 3, pLambert->achLon1); pLambert->chRes_flag = ( unsigned char ) vProjInp->usRes_flag; /* convert lLon_orient to 3 bytes */ set_bytes(vProjInp->lLon_orient, 3, pLambert->achLon_orient); /* convert ulDx to 3 bytes */ set_bytes(vProjInp->ulDx, 3, pLambert->achDx); /* convert ulDy to 3 bytes */ set_bytes(vProjInp->ulDy, 3, pLambert->achDy); pLambert->chProj_flag = ( unsigned char ) vProjInp->usProj_flag; pLambert->chScan_mode = ( unsigned char ) vProjInp->usScan_mode; /* convert lLat_cut1 to 3 chars */ set_bytes(vProjInp->lLat_cut1, 3, pLambert->achLat_cut1); /* convert lLat_cut2 to 3 chars */ set_bytes(vProjInp->lLat_cut2, 3, pLambert->achLat_cut2); /* convert lLat_southpole to 3chars */ set_bytes(vProjInp->lLat_southpole, 3, pLambert->achLat_southpole); /* convert lLon_southpole to 3 chars */ set_bytes(vProjInp->lLon_southpole, 3, pLambert->achLon_southpole); set_bytes(vProjInp->usZero, 2, pLambert->achZero); /* * * E.6 DEBUG print Grib LAMBERT block */ DPRINT3("\t%s: achNx [%02d,%02d]\n", func, pLambert->achNx[0],pLambert->achNx[1]); DPRINT3("\t%s: achNy [%02d,%02d]\n", func, pLambert->achNy[0],pLambert->achNy[1]); DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n", func, pLambert->achLat1[0], pLambert->achLat1[1], pLambert->achLat1[2]); DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n", func, pLambert->achLon1[0], pLambert->achLon1[1], pLambert->achLon1[2]); DPRINT2("\t%s: chRes_flag [%02d]\n", func, pLambert->chRes_flag); DPRINT4("\t%s: achLon_orient [%02d,%02d,%02d]\n", func, pLambert->achLon_orient[0], pLambert->achLon_orient[1], pLambert->achLon_orient[2]); DPRINT4("\t%s: achDx [%02d,%02d,%02d]\n", func, pLambert->achDx[0], pLambert->achDx[1], pLambert->achDx[2]); DPRINT4("\t%s: achDy [%02d,%02d,%02d]\n", func, pLambert->achDy[0], pLambert->achDy[1], pLambert->achDy[2]); DPRINT2("\t%s: chProj_flag [%02d]\n", func, pLambert->chProj_flag); DPRINT2("\t%s: chScan_mode [%02d]\n", func, pLambert->chScan_mode); DPRINT4("\t%s: achLat_cut1 [%02d,%02d,%02d]\n", func, pLambert->achLat_cut1[0], pLambert->achLat_cut1[1], pLambert->achLat_cut1[2]); DPRINT4("\t%s: achLat_cut2 [%02d,%02d,%02d]\n", func, pLambert->achLat_cut2[0], pLambert->achLat_cut2[1], pLambert->achLat_cut2[2]); DPRINT4("\t%s: achLat_southpole [%02d,%02d,%02d]\n",func, pLambert->achLat_southpole[0], pLambert->achLat_southpole[1], pLambert->achLat_southpole[2] ); DPRINT4("\t%s: achLon_southpole [%02d,%02d,%02d]\n",func, pLambert->achLon_southpole[0], pLambert->achLon_southpole[1], pLambert->achLon_southpole[2] ); DPRINT3("\t%s: achZero [%02d,%02d]\n", func, pLambert->achZero[0], pLambert->achZero[1]); /*******/ /* * * E.7 STORE proj size of LAMBERT struct in lProj_size */ *lProj_size = sizeof (LAMBERT); BYE: DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func, *lProj_size, nStatus); /* * * E.9 RETURN status */ return ( nStatus ); /* * * END OF FUNCTION */ } /* * **************************************************************************** * F. FUNCTION: inp2grib_PolarSt * This routine fills the special Polar Stereo Projection structure for * the GDS. * * INTERFACE: * int inp2grib_PolarSt ( ppvGDS_Proj_Input, Polar, lProj_size ,errmsg) * * ARGUMENTS (I=input, O=output, I&O=input and output): * (I) void **ppvGDS_Proj_Input; * holds input projection data * (O) POLAR *Polar; * to be filled with Polar Stereographic projection info * (O) long *lProj_size; * to be filled with size of structure POLAR * (O) char *errmsg * empty array, filled if error occurred * * RETURN CODE: * 0> success, Polar and lProj_size filled; * 1> pointers are null, errmsg filled; ****************************************************************************/ #if PROTOTYPE_NEEDED int inp2grib_PolarSt (void **ppvGDS_Proj_Input, POLAR *Polar, long *lProj_size , char *errmsg) #else int inp2grib_PolarSt (ppvGDS_Proj_Input, Polar, lProj_size , errmsg) void **ppvGDS_Proj_Input; POLAR *Polar; long *lProj_size ; char *errmsg; #endif { /* * * F.1 INIT variables !default stat=good */ GDS_PS_INPUT *pProjInp = 0; int lTemp = 0; int nStatus = 0; char *func="inp2grib_PolarSt"; DPRINT1 ("\t Entering %s.....\n", func); /* * * F.2 POINT local pProjInp to incoming ppvGDS_Proj_Input */ pProjInp = ( GDS_PS_INPUT *) *ppvGDS_Proj_Input; /* * * F.3 IF (true grib Polar proj block OR input Polar block is null) THEN * SET Status= 1 * RETURN; * ENDIF */ if (!Polar || !pProjInp ) { DPRINT1 ( "%s: Polar or pProjInp is null\n", func); sprintf(errmsg,"%s: Polar or pProjInp is null\n", func); nStatus= 1; goto BYE; } /* * * F.4 FILL local struct from pProjInp */ /* convert usNx to 2 chars */ set_bytes(pProjInp->usNx, 2, Polar->achNx); /* convert usNy to 2 chars */ set_bytes(pProjInp->usNy, 2, Polar->achNy); /* convert lLat1 to 3 chars */ set_bytes(pProjInp->lLat1, 3, Polar->achLat1); /* convert lLon1 to 3 chars */ set_bytes(pProjInp->lLon1, 3, Polar->achLon1); Polar->chRes_flag = ( unsigned char ) pProjInp->usRes_flag; /* convert lLon_orient to 3 chars */ set_bytes(pProjInp->lLon_orient, 3, Polar->achLon_orient); /* convert ulDx to 3 char */ set_bytes(pProjInp->ulDx, 3, Polar->achDx); /* convert ulDy to 3chars */ set_bytes(pProjInp->ulDy, 3, Polar->achDy); Polar->chProj_flag = ( unsigned char ) pProjInp->usProj_flag; Polar->chScan_mode = ( unsigned char ) pProjInp->usScan_mode; /* 4 bytes of zero */ memset((void*) Polar->achZero, '\0', 4); /* * * F.5 DEBUG print GRIB Projection block */ DPRINT3("\t%s: achNx [%02d,%02d]\n",func, Polar->achNx[0],Polar->achNx[1]); DPRINT3("\t%s: achNy [%02d,%02d]\n",func, Polar->achNy[0],Polar->achNy[1]); DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n",func, Polar->achLat1[0], Polar->achLat1[1], Polar->achLat1[2]); DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n",func, Polar->achLon1[0], Polar->achLon1[1] , Polar->achLon1[2]); DPRINT2("\t%s: chRes_flag [%02d]\n",func, Polar->chRes_flag); DPRINT4("\t%s: achLon_orient [%02d,%02d,%02d]\n",func, Polar->achLon_orient[0], Polar->achLon_orient[1], Polar->achLon_orient[2]); DPRINT4("\t%s: achDx [%02d,%02d,%02d]\n",func, Polar->achDx[0], Polar->achDx[1], Polar->achDx[2]); DPRINT4("\t%s: achDy [%02d,%02d,%02d]\n",func, Polar->achDy[0], Polar->achDy[1], Polar->achDy[2]); DPRINT2("\t%s: chProj_flag [%02d]\n",func, Polar->chProj_flag); DPRINT2("\t%s: chScan_mode [%02d]\n",func, Polar->chScan_mode); DPRINT5("\t%s: achZero [%02d,%02d,%02d,%02d]\n",func, Polar->achZero[0], Polar->achZero[1], Polar->achZero[2], Polar->achZero[3]); /*******/ /* * * F.7 STORE size of POLAR struct in lProj_size */ *lProj_size = sizeof (POLAR); BYE: DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func, *lProj_size, nStatus); /* * * F.8 RETURN Stat ! 0 or 1 */ return ( nStatus ); /* * * END OF FUNCTION * * */ } /* * **************************************************************************** * G. FUNCTION: inp2grib_Latlon * This routine fills the Latitude Longitude Projection structure for * the GDS. * * INTERFACE: * int inp2grib_Latlon ( ppvGDS_Proj_Input, pLatlon, lProj_size ,errmsg) * * ARGUMENTS (I=input, O=output, I&O=input and output): * (I) void **ppvGDS_Proj_Input; * holds input projection data * (O) LATLON *pLatlon; * to be filled with Lat/Lon projection info * (O) long *lProj_size; * to be filled with size of structure LATLON * (O) char *errmsg; * empty array, filled if error occurred * * RETURN CODE: * 0> success, pLatlon and lProj_size filled; * 1> got null pointers, errmsg filled; ****************************************************************************/ #if PROTOTYPE_NEEDED int inp2grib_Latlon (void **ppvGDS_Proj_Input, LATLON *pLatlon, long *lProj_size, char *errmsg) #else int inp2grib_Latlon (ppvGDS_Proj_Input, pLatlon, lProj_size, errmsg) void **ppvGDS_Proj_Input; LATLON *pLatlon; long *lProj_size; char *errmsg; #endif { GDS_LATLON_INPUT *Inp = 0; int lTemp = 0; char *func= "inp2grib_Latlon"; /* * * G.1 INIT status to success */ int nStatus = 0; DPRINT1 ( " Entering %s.....\n", func ); /* * * G.2 ASSIGN arguments to local pointers */ Inp = (GDS_LATLON_INPUT *) *ppvGDS_Proj_Input; /* DPRINT3("\n%s: usData_type = %u (%s)\n", func, Inp->usData_type, prjn_name[Inp->usData_type] ); DPRINT2("\t%s: usNi = %u\n",func, Inp->usNi ); DPRINT2("\t%s: usNj = %u\n",func, Inp->usNj ); DPRINT2("\t%s: lLat1 = %d\n",func, Inp->lLat1 ); DPRINT2("\t%s: lLon1 = %d\n",func, Inp->lLon1 ); DPRINT2("\t%s: lLat2 = %d\n",func, Inp->lLat2 ); DPRINT2("\t%s: lLon2 = %d\n",func, Inp->lLon2 ); DPRINT2("\t%s: iDi = %u\n",func, Inp->iDi ); DPRINT2("\t%s: iDj = %u\n",func, Inp->iDj ); DPRINT2("\t%s: usRes_flag = %u\n",func, Inp->usRes_flag ); DPRINT2("\t%s: usScan_mode = %u\n",func, Inp->usScan_mode ); DPRINT2("\t%s: lLat_southpole = %ld\n",func, Inp->lLat_southpole); DPRINT2("\t%s: lLon_southpole = %ld\n",func, Inp->lLon_southpole); DPRINT2("\t%s: lRotate = %ld\n",func, Inp->lRotate ); DPRINT2("\t%s: lPole_lat = %ld\n",func, Inp->lPole_lat ); DPRINT2("\t%s: lPole_lon = %ld\n",func, Inp->lPole_lon ); DPRINT2("\t%s: lStretch = %ld\n",func, Inp->lStretch ); */ /* * * G.3 IF (pointers passed in are null) THEN * SET status to 1 * RETURN * ENDIF */ if ( !Inp || !pLatlon) { DPRINT1 ("%s: lLatlon_inp || pLatlon is null\n",func); sprintf(errmsg, "%s: lLatlon_inp || pLatlon is null\n", func); nStatus = 1; goto BYE; } /* * * G.4 FILL local struct from Inp */ /* convert usNi & usNj to 2 chars */ set_bytes(Inp->usNi, 2, pLatlon->achNi); set_bytes(Inp->usNj, 2, pLatlon->achNj); /* convert lLat1 to 3chars */ set_bytes(Inp->lLat1, 3, pLatlon->achLat1); /* convert lLon1 to 3chars */ set_bytes(Inp->lLon1, 3, pLatlon->achLon1); pLatlon->chRes_flag = ( unsigned char ) Inp->usRes_flag; /* convert lLat2 to 3chars */ set_bytes(Inp->lLat2, 3, pLatlon->achLat2); /* convert lLon2 to 3chars */ set_bytes(Inp->lLon2, 3, pLatlon->achLon2); /* convert lon increment to 2chars */ set_bytes(Inp->iDi, 2, pLatlon->achDi); /* convert lat increment to 2chars */ set_bytes(Inp->iDj, 2, pLatlon->achDj); /* 1 byte scan mode */ pLatlon->chScan_mode = ( unsigned char ) Inp->usScan_mode; /* 4 bytes of reserved zero */ memset ((void*)pLatlon->achZero, '\0', 4); /* convert lLat_southpole to 3chars */ set_bytes(Inp->lLat_southpole, 3, pLatlon->achLat_southpole); /* convert lLon_southpole to 3chars */ set_bytes(Inp->lLon_southpole, 3, pLatlon->achLon_southpole); /* convert lRotate to 4chars */ set_bytes(Inp->lRotate, 4, pLatlon->achRotate); /* convert lPole_lat to 3chars */ set_bytes(Inp->lPole_lat, 3, pLatlon->achPole_lat); /* convert lPole_lon to 3chars */ set_bytes(Inp->lPole_lon, 3, pLatlon->achPole_lon); /* convert lStretch to 4 chars */ set_bytes(Inp->lStretch, 4, pLatlon->achStretch); /* * * G.5 DEBUG print Input Proj Block & their equivalence in the Char array; */ DPRINT3("\t%s: achNi [%02d,%02d]\n",func,pLatlon->achNi[0],pLatlon->achNi[1]); DPRINT3("\t%s: achNj [%02d,%02d]\n",func,pLatlon->achNj[0],pLatlon->achNj[1]); DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n", func, pLatlon->achLat1[0],pLatlon->achLat1[1],pLatlon->achLat1[2]); DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n", func, pLatlon->achLon1[0],pLatlon->achLon1[1],pLatlon->achLon1[2]); DPRINT2("\t%s: chRes_flag [%02d]\n", func, pLatlon->chRes_flag ); DPRINT4("\t%s: achLat2 [%02d,%02d,%02d]\n", func, pLatlon->achLat2[0], pLatlon->achLat2[1], pLatlon->achLat2[2]); DPRINT4("\t%s: achLon2 [%02d,%02d,%02d]\n", func, pLatlon->achLon2[0], pLatlon->achLon2[1], pLatlon->achLon2[2]); DPRINT3("\t%s: achDi [%02d,%02d]\n",func,pLatlon->achDi[0],pLatlon->achDi[1]); DPRINT3("\t%s: achDj [%02d,%02d]\n",func,pLatlon->achDj[0],pLatlon->achDj[1]); DPRINT2("\t%s: chScan_mode [%02d]\n", func, pLatlon->chScan_mode); DPRINT5("\t%s: achZero [%02d,%02d,%02d,%02d]\n", func, pLatlon->achZero[0],pLatlon->achZero[1],pLatlon->achZero[2], pLatlon->achZero[3]); DPRINT4("\t%s achLat_southpole [%02d,%02d,%02d]\n", func, pLatlon->achLat_southpole[0],pLatlon->achLat_southpole[1], pLatlon->achLat_southpole[2]); DPRINT4("\t%s achLon_southpole [%02d,%02d,%02d]\n", func, pLatlon->achLon_southpole[0],pLatlon->achLon_southpole[1], pLatlon->achLon_southpole[2]); DPRINT5("\t%s achRotate [%02d,%02d,%02d,%02d]\n", func, pLatlon->achRotate[0],pLatlon->achRotate[1], pLatlon->achRotate[2], pLatlon->achRotate[3]); DPRINT4("\t%s achPole_lat [%02d,%02d,%02d]\n", func, pLatlon->achPole_lat[0],pLatlon->achPole_lat[1], pLatlon->achPole_lat[2]); DPRINT4("\t%s achPole_lon [%02d,%02d,%02d]\n", func, pLatlon->achPole_lon[0],pLatlon->achPole_lon[1], pLatlon->achPole_lon[2]); DPRINT5("\t%s achStretch [%02d,%02d,%02d,%02d]\n", func, pLatlon->achStretch[0],pLatlon->achStretch[1], pLatlon->achStretch[2], pLatlon->achStretch[3]); /*******/ /* * * G.6 STORE size of LATLON struct in lProj_size */ *lProj_size = sizeof (LATLON); BYE: DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func, *lProj_size, nStatus); /* * * G.7 RETURN stat */ return ( nStatus ); /* * * END OF FUNCTION * * */ } /* * **************************************************************************** * F. FUNCTION: inp2grib_Mercator * This routine fills the special Mercator Projection structure for * the GDS. * * INTERFACE: * int inp2grib_Mercator ( ppvGDS_Proj_Input, Polar, lProj_size ,errmsg) * * ARGUMENTS (I=input, O=output, I&O=input and output): * (I) void **ppvGDS_Proj_Input; * holds input projection data * (O) MERCATOR *Mercator; * to be filled with Polar Stereographic projection info * (O) long *lProj_size; * to be filled with size of structure POLAR * (O) char *errmsg * empty array, filled if error occurred * * RETURN CODE: * 0> success, Mercator and lProj_size filled; * 1> pointers are null, errmsg filled; ****************************************************************************/ #if PROTOTYPE_NEEDED int inp2grib_Mercator (void **ppvGDS_Proj_Input, MERCATOR *Mercator, long *lProj_size , char *errmsg) #else int inp2grib_Mercator (ppvGDS_Proj_Input, Mercator, lProj_size , errmsg) void **ppvGDS_Proj_Input; MERCATOR *Mercator; long *lProj_size ; char *errmsg; #endif { /* * * F.1 INIT variables !default stat=good */ mercator *ProjInp = 0; int lTemp = 0; int nStatus = 0; char *func="inp2grib_PolarSt"; DPRINT1 ("\t Entering %s.....\n", func); /* * * F.2 POINT local pProjInp to incoming ppvGDS_Proj_Input */ ProjInp = ( mercator *) *ppvGDS_Proj_Input; /* * * F.3 IF (true grib Mercator proj block OR input Polar block is null) THEN * SET Status= 1 * RETURN; * ENDIF */ if (!Mercator || !ProjInp ) { DPRINT1 ( "%s: Mercator or ProjInp is null\n", func); sprintf(errmsg,"%s: Mercator or ProjInp is null\n", func); nStatus= 1; goto BYE; } /* * * F.4 FILL local struct from pProjInp */ /* convert cols to 2 chars */ set_bytes(ProjInp->cols, 2, Mercator->achNi); /* convert rows to 2 chars */ set_bytes(ProjInp->rows, 2, Mercator->achNj); /* convert first_lat to 3 chars */ set_bytes(ProjInp->first_lat, 3, Mercator->achLat1); /* convert first_lon to 3 chars */ set_bytes(ProjInp->first_lon, 3, Mercator->achLon1); Mercator->chRes_flag = ( unsigned char ) ProjInp->usRes_flag; /* convert La2 to 3 chars */ set_bytes(ProjInp->La2, 3, Mercator->achLat2); /* convert Lo2 to 3 chars */ set_bytes(ProjInp->Lo2, 3, Mercator->achLon2); /* convert lLon_orient to 3 chars */ set_bytes(ProjInp->latin, 3, Mercator->achLatin); /* convert zero fill */ Mercator->achZero1 = ( unsigned char ) ProjInp->usZero1; Mercator->chScan_mode = ( unsigned char ) ProjInp->usScan_mode; /* convert ulDx to 3 char */ set_bytes((int)(ProjInp->lon_inc + 0.5), 3, Mercator->achDi); /* convert ulDy to 3chars */ set_bytes((int)(ProjInp->lat_inc + 0.5), 3, Mercator->achDj); Mercator->chScan_mode = ( unsigned char ) ProjInp->usScan_mode; /* 8 bytes of zero */ memset((void*) Mercator->achZero2, '\0', 8); /* * * F.5 DEBUG print GRIB Projection block */ DPRINT3("\t%s: achNi [%02d,%02d]\n",func,Mercator->achNi[0],Mercator->achNi[1]); DPRINT3("\t%s: achNj [%02d,%02d]\n",func, Mercator->achNj[0],Mercator->achNj[1]); DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n",func, Mercator->achLat1[0], Mercator->achLat1[1], Mercator->achLat1[2]); DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n",func, Mercator->achLon1[0], Mercator->achLon1[1] , Mercator->achLon1[2]); DPRINT2("\t%s: chRes_flag [%02d]\n",func, Mercator->chRes_flag); DPRINT4("\t%s: achLatint [%02d,%02d,%02d]\n",func, Mercator->achLatin[0], Mercator->achLatin[1], Mercator->achLatin[2]); DPRINT4("\t%s: achDi [%02d,%02d,%02d]\n",func, Mercator->achDi[0], Mercator->achDi[1], Mercator->achDi[2]); DPRINT4("\t%s: achDj [%02d,%02d,%02d]\n",func, Mercator->achDj[0], Mercator->achDj[1], Mercator->achDj[2]); DPRINT5("\t%s: achZero2 [%02d,%02d,%02d,%02d]\n",func, Mercator->achZero2[0], Mercator->achZero2[1], Mercator->achZero2[2], Mercator->achZero2[3]); /*******/ /* * * F.7 STORE size of POLAR struct in lProj_size */ *lProj_size = sizeof (MERCATOR); BYE: DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func, *lProj_size, nStatus); /* * * F.8 RETURN Stat ! 0 or 1 */ return ( nStatus ); /* * * END OF FUNCTION * * */ } /* Old round--this is different from standard gnu round (gnu round returns a float). Depending on compile options, sometimes gnu round was used, other times this function was used. Removed and replaced by lrint by T. Hutchinson, WSI. 4/14/05. long round(double value) { long retval; retval=lrint(value); return retval; } */