PageRenderTime 58ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/wrfv2_fire/external/io_grib1/MEL_grib1/gribputgds.c

http://github.com/jbeezley/wrf-fire
C | 1478 lines | 637 code | 144 blank | 697 comment | 60 complexity | 9bb4c4ec5ef984c6186e9c1b8682be1e MD5 | raw file
Possible License(s): AGPL-1.0
  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. #elif defined(_WIN32)
  9. #include <Winsock2.h>
  10. #else
  11. #include <netinet/in.h>
  12. #endif
  13. #include "dprints.h" /* for dprints */
  14. #include "gribfuncs.h" /* prototypes */
  15. #include <math.h>
  16. /*
  17. ************************************************************************
  18. * A. FUNCTION gribputgds
  19. * used to decode Grib's Grid Defn Section. It returns with both
  20. * internal structures GDS_HEAD_INPUT and VOID* projblock filled,
  21. * and also with true GDS already appended to GribHeader's Entire_Msg;
  22. *
  23. * INTERFACE:
  24. * int gribputgds (Geom_In, pGDS_Head_Input, ppvGDS_Proj_Input,
  25. * ppgrib_hdr, errmsg)
  26. *
  27. * ARGUMENTS (I=input, O=output, I&O=input and output):
  28. * (I) GEOM_IN Geom_In
  29. * Geometry information used as input;
  30. * (O) GDS_HEAD_INPUT *pGDS_Head_Input
  31. * this is the internal GDS structure. Attributes (uslength,
  32. * usData_type, chData_type, usNum_v and usPl_Pv) gets updated;
  33. * (O) void **ppvGDS_Proj_Input;
  34. * This is a pre-alloced storage of type Void and has length of
  35. * MAX_INP_PROJ_SIZE bytes long. How this block is filled depends
  36. * on the type of Projection it is. Projections currently supported
  37. * are Spherical, Lambert, and Polar Stereographic.
  38. * (I&O) GRIB_HDR **ppgrib_hdr
  39. * may already have one or more of the other Grib Sections
  40. * (IDS, PDS, BMS, BDS, or EDS). Upon successful exit, will
  41. * also contain a GDS section.
  42. * (O) char *errmsg
  43. * empty array, returned filled if error occurred;
  44. *
  45. * RETURN CODE:
  46. * 0> no errors; GDS appended to GRIB_HDR's entire_msg, its info
  47. * stored in bds_len & bds_ptr; msg_length updated too;
  48. * 1> error, grib hdr is null; errmsg filled;
  49. ************************************************************************
  50. */
  51. /*
  52. NCAR AIX does not have lrint, make one up.
  53. */
  54. #ifdef NCARIBM_NOC99
  55. #define lrint(dbl) ((long)rint(dbl))
  56. #endif
  57. #ifdef _WIN32
  58. #define lrint(x) (floor(x+(x>0) ? 0.5 : -0.5))
  59. #endif
  60. #if PROTOTYPE_NEEDED
  61. int gribputgds ( GEOM_IN Geom_In, GDS_HEAD_INPUT *pGDS_Head_Input,
  62. void **ppvGDS_Proj_Input, GRIB_HDR **ppgrib_hdr,
  63. char *errmsg)
  64. #else
  65. int gribputgds ( Geom_In, pGDS_Head_Input, ppvGDS_Proj_Input,
  66. ppgrib_hdr, errmsg)
  67. GEOM_IN Geom_In;
  68. GDS_HEAD_INPUT *pGDS_Head_Input;
  69. void **ppvGDS_Proj_Input;
  70. GRIB_HDR **ppgrib_hdr;
  71. char *errmsg;
  72. #endif
  73. {
  74. /*
  75. * A.0 DEFAULT to err stat 1
  76. */
  77. char *func= "gribputgds";
  78. char *pgds=0; /* true grib, GDS_HEAD + Proj block */
  79. GDS_HEAD *pGDS_Head=0; /* first 6 bytes of PGDS */
  80. void *pvGDS_Proj=0; /* projection info, PGDS 7th byte and on... */
  81. long lProj_sz ; /* size of True-Grib projection block */
  82. long new_msgsz; /* size after adding GDS */
  83. GRIB_HDR *gh=0; /* temp ptr to struct */
  84. unsigned char ucflag;
  85. int tempsz, stat= 1;
  86. GDS_LATLON_INPUT *mp;
  87. DPRINT0 ("\nEntering gribputgds .....\n");
  88. /*
  89. *
  90. * A.1 IF (Grib Hdr is null) THEN
  91. * RETURN error Stat !null ptrs msg in errmsg
  92. * ENDIF
  93. */
  94. gh = *ppgrib_hdr;
  95. if (!gh || !gh->entire_msg) {
  96. DPRINT1("%s: grib header is null\n", func);
  97. sprintf(errmsg,"%s: grib header is null\n", func);
  98. goto BYE;
  99. }
  100. /*
  101. *
  102. * A.3 ALLOCATE space for True Grib Structs GDS_HEAD & VOID *proj;
  103. * IF (fails) THEN
  104. * RETURN with bad Stat !errmsg filled
  105. * ELSE
  106. * CLEAR out structs
  107. * ENDIF
  108. */
  109. if (! (pgds= (char *) malloc(sizeof (GDS_HEAD) + MAX_PROJ_SIZE))) {
  110. DPRINT1 ("%s: MALloced true Grib struct failed\n",func);
  111. sprintf(errmsg,"%s: MALloced true Grib struct failed\n",func);
  112. goto BYE;
  113. }
  114. else memset ((void *)pgds, '\0', sizeof(GDS_HEAD) + MAX_PROJ_SIZE);
  115. /*
  116. *
  117. * A.4 ASSIGN (GDS_HEAD *pGDS_Head) to be beginning of local PGDS block
  118. * ASSIGN (void *pvGDS_Proj) to byte #7 of local PGDS block
  119. */
  120. pGDS_Head = (GDS_HEAD *) pgds;
  121. pvGDS_Proj = (void *) (pgds + sizeof(GDS_HEAD));
  122. /*
  123. *
  124. * A.5 INIT some fields of GDS_HEAD & GDS_HEAD_INPUT structs
  125. */
  126. pGDS_Head->chNV = ( unsigned char ) 0;
  127. pGDS_Head->chPV = ( unsigned char ) 255;
  128. pGDS_Head_Input->usNum_v = 0; /* INPUT NOT USED AT THIS TIME */
  129. pGDS_Head_Input->usPl_Pv = 255;
  130. /*
  131. *
  132. * !now fill true GRIB Grid Defn Sect depending on Projection type
  133. * A.6.a IF (projection is Spherical) THEN
  134. */
  135. if ((strcmp(Geom_In.prjn_name,"spherical")==0) ||
  136. (strcmp(Geom_In.prjn_name,"gaussian") == 0)){
  137. /*
  138. * A.6.a.1 FUNCTION create_inpLatlon !create internal Latlon struct
  139. * !using GEOM_IN & USER_INPUT
  140. * A.6.a.2 FUNCTION inp2grib_Latlon !use internal Latlon struct to
  141. * !make true Latlon Grib Gds
  142. * A.6.a.3 IF (either failed) THEN
  143. * FUNCTION upd_child_errmsg !tack funcname to errmsg
  144. * RETURN with error !errmsg filled
  145. * ENDIF
  146. */
  147. if ( create_inpLatlon(Geom_In, ppvGDS_Proj_Input,errmsg)
  148. || inp2grib_Latlon (ppvGDS_Proj_Input,
  149. (LATLON *)(pgds+sizeof(GDS_HEAD)),&lProj_sz, errmsg))
  150. {
  151. upd_child_errmsg (func, errmsg); goto BYE;
  152. }
  153. /*
  154. * A.6.a.4 STORE Gds len, DataType=0 into internal GDS struct
  155. */
  156. pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz;
  157. if (strcmp(Geom_In.prjn_name,"spherical")==0) {
  158. pGDS_Head_Input->usData_type = LATLON_PRJ;
  159. pGDS_Head->chData_type = 0;
  160. } else {
  161. pGDS_Head_Input->usData_type = GAUSS_PRJ;
  162. pGDS_Head->chData_type = 4;
  163. }
  164. }
  165. /*
  166. * A.6.b ELSE IF (projection is Lambert) THEN
  167. */
  168. else if (strcmp(Geom_In.prjn_name,"lambert")==0)
  169. {
  170. /*
  171. * A.6.b.1 FUNCTION create_inpLambert !create internal Lambert struct
  172. * !using GEOM_IN & USER_INPUT
  173. * A.6.b.2 FUNCTION inp2grib_Lambert !use internal Lambert struct to
  174. * !make true Lambert Grib Gds
  175. * A.6.b.3 IF (either failed) THEN
  176. * FUNCTION upd_child_errmsg !tack funcname to errmsg
  177. * RETURN with error !errmsg filled
  178. * ENDIF
  179. */
  180. if ( create_inpLambert(Geom_In,ppvGDS_Proj_Input,errmsg)
  181. || inp2grib_Lambert( ppvGDS_Proj_Input,
  182. (LAMBERT *)(pgds+sizeof(GDS_HEAD)), &lProj_sz, errmsg))
  183. {
  184. upd_child_errmsg (func, errmsg); goto BYE;
  185. }
  186. /*
  187. * A.6.b.4 STORE Gds len, DataType=3 into internal GDS struct
  188. */
  189. pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz;
  190. pGDS_Head_Input->usData_type = LAMB_PRJ;
  191. pGDS_Head->chData_type = 3;
  192. }
  193. /*
  194. * A.6.c ELSE if (projection is Polar_Stereo) THEN
  195. */
  196. else if (strcmp(Geom_In.prjn_name,"polar_stereo")==0)
  197. {
  198. /*
  199. * A.6.c.1 FUNCTION create_inpPolar
  200. * !create internal Polar struct using GEOM_IN & USER_INPUT
  201. * A.6.c.2 FUNCTION inp2grib_PolarSt
  202. * !use internal PolarSt struct to make true PolarSt Grib Gds
  203. * A.6.c.3 IF (either failed) THEN
  204. * FUNCTION upd_child_errmsg !tack funcname to errmsg
  205. * RETURN with error !errmsg filled
  206. * ENDIF
  207. */
  208. /* make True Grib PPVGDS_PROJ & SIZE using internal ppvGds_proj_input : */
  209. if (create_inpPolar(Geom_In, ppvGDS_Proj_Input,errmsg)
  210. || inp2grib_PolarSt(ppvGDS_Proj_Input,
  211. (void *)(pgds+sizeof(GDS_HEAD)),&lProj_sz, errmsg) )
  212. {
  213. upd_child_errmsg (func, errmsg); goto BYE;
  214. }
  215. /*
  216. * A.6.c.4 STORE Gds len, DataType=5 into internal GDS struct
  217. */
  218. pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz;
  219. pGDS_Head_Input->usData_type = POLAR_PRJ;
  220. pGDS_Head->chData_type = 5;
  221. }
  222. /*
  223. * A.6.c ELSE if (projection is Mercator) THEN
  224. */
  225. else if (strcmp(Geom_In.prjn_name,"mercator")==0)
  226. {
  227. /*
  228. * A.6.c.1 FUNCTION create_inpMercator
  229. * !create internal Mercator struct using GEOM_IN & USER_INPUT
  230. * A.6.c.2 FUNCTION inp2grib_Mercator
  231. * !use internal Mercator struct to make true PolarSt Grib Gds
  232. * A.6.c.3 IF (either failed) THEN
  233. * FUNCTION upd_child_errmsg !tack funcname to errmsg
  234. * RETURN with error !errmsg filled
  235. * ENDIF
  236. */
  237. /* make True Grib PPVGDS_PROJ & SIZE using internal ppvGds_proj_input : */
  238. if (create_inpMercator(Geom_In, ppvGDS_Proj_Input,errmsg)
  239. || inp2grib_Mercator(ppvGDS_Proj_Input,
  240. (void *)(pgds+sizeof(GDS_HEAD)),&lProj_sz, errmsg) )
  241. {
  242. upd_child_errmsg (func, errmsg); goto BYE;
  243. }
  244. /*
  245. * A.6.c.4 STORE Gds len, DataType=5 into internal GDS struct
  246. */
  247. pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz;
  248. pGDS_Head_Input->usData_type = MERC_PRJ;
  249. pGDS_Head->chData_type = 1;
  250. }
  251. /*
  252. * A.6.d ELSE ! Projection unknown
  253. */
  254. else {
  255. /*
  256. * RETURN with error !errmsg filled
  257. */
  258. DPRINT2 ("%s: Projection '%s' unknown\n",func,Geom_In.prjn_name);
  259. sprintf (errmsg,"%s: Projection '%s' unknown\n",func,Geom_In.prjn_name);
  260. goto BYE;
  261. /*
  262. * A.6.d ENDIF
  263. */
  264. }
  265. /*
  266. *
  267. * A.7 STORE ptr to Gds and its Length in Grib hdr
  268. */
  269. gh->gds_ptr = gh->entire_msg + gh->msg_length;
  270. gh->gds_len = sizeof(GDS_HEAD) + lProj_sz;
  271. DPRINT3 ("Gds length= (%ld + %ld)= %ld \n",
  272. sizeof(GDS_HEAD), lProj_sz, gh->gds_len);
  273. /*
  274. *
  275. * A.8 STORE Gds length in the True Grib GDS block too
  276. */
  277. set_bytes(gh->gds_len, 3, pGDS_Head->achGDS_length);
  278. /*
  279. *
  280. * A.9 IF gribhdr's buffer is too small AND
  281. * FUCTION Expand_gribhdr failed
  282. * THEN
  283. * RETURN with error !errmsg filled
  284. * ENDIF
  285. */
  286. new_msgsz= gh->msg_length + gh->gds_len;
  287. if (new_msgsz > gh->abs_size
  288. && Expand_gribhdr (gh, new_msgsz, errmsg) !=0)
  289. {
  290. upd_child_errmsg (func, errmsg);
  291. goto BYE;
  292. }
  293. /*
  294. *
  295. * A.10 UPDATE Grib Header Struct
  296. * !copy true BDS block into Grib Header's Entire_Msg array;
  297. * !add gds length to Message length
  298. */
  299. memcpy ((void *)gh->gds_ptr, (void *)pgds, gh->gds_len);
  300. gh->msg_length += gh->gds_len;
  301. DPRINT1 ("copying %ld bytes from PGDS to gh->GDS_PTR \n", gh->gds_len);
  302. /*
  303. *
  304. * A.11 CHANGE return Status to no errors
  305. */
  306. stat = 0;
  307. BYE:
  308. /*
  309. *
  310. * A.12 FREE up storage
  311. *
  312. * A.13 RETURN Status
  313. */
  314. if (pgds) free (pgds);
  315. DPRINT3 ("Leaving %s, stat=%d, errmsg='%s'\n", func,stat,errmsg);
  316. return stat;
  317. /*
  318. *
  319. * END OF FUNCTION
  320. *
  321. *
  322. */
  323. }
  324. /*
  325. *
  326. *********************************************************************
  327. * B. FUNCTION: create_inpLambert
  328. * Fills Lambert Projection structure.
  329. *
  330. * INTERFACE:
  331. * int create_inpLambert ( geom_in, ppvGDS_Proj_Input, errmsg)
  332. *
  333. * ARGUMENTS (I=input, O=output, I&O=input and output):
  334. * (I) GEOM_IN geom_in Holds info to fill local Lambert block
  335. * (O) void **ppvGDS_Proj_Input pre-allocated block to be filled;
  336. * (O) char *errmsg returns filled if error occurred
  337. *
  338. * RETURN CODE
  339. * 0> success, ppvGDS_Proj_Input holds Lambert projection information;
  340. * 1> the input pre-MAlloced projection block is null; errmsg filled;
  341. **********************************************************************/
  342. #if PROTOTYPE_NEEDED
  343. int create_inpLambert (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
  344. #else
  345. int create_inpLambert (geom_in, ppvGDS_Proj_Input, errmsg)
  346. GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
  347. #endif
  348. {
  349. char *func= "create_inpLambert";
  350. /*
  351. *
  352. * B.1 DEFAULT status of 0
  353. */
  354. int nStatus = 0;
  355. double cut1, cut2, tmp;
  356. GDS_LAM_INPUT *pGDS_Lam_Input;
  357. DPRINT1 ( " Entering %s.....\n", func );
  358. /*
  359. *
  360. * B.2 IF (incoming projection block is Null)
  361. * THEN
  362. * FILL errmsg
  363. * SET return status to error
  364. */
  365. if (!(pGDS_Lam_Input= (GDS_LAM_INPUT *) *ppvGDS_Proj_Input) )
  366. {
  367. DPRINT1 ( "%s: ppvGDS_Proj_Input is null\n", func);
  368. sprintf(errmsg, "%s: ppvGDS_Proj_Input is null\n", func);
  369. nStatus = 1;
  370. }
  371. /*
  372. * B.2.b ELSE
  373. * USE info from GEOM_IN to fill the Lambert GDS struct
  374. */
  375. else
  376. {
  377. pGDS_Lam_Input->usData_type = LAMB_PRJ; /* data type flag (Tbl ) */
  378. pGDS_Lam_Input->iNx = (int) geom_in.nx; /* #pts along x-axis */
  379. pGDS_Lam_Input->iNy = (int) geom_in.ny;/* #pts along y-axis */
  380. /* latitude & lon of 1st grid point */
  381. pGDS_Lam_Input->lLat1 = lrint(geom_in.first_lat *1000.);
  382. pGDS_Lam_Input->lLon1 = lrint((geom_in.first_lon) *1000.);
  383. pGDS_Lam_Input->usRes_flag = geom_in.usRes_flag;/*Resolution flags Tbl7*/
  384. pGDS_Lam_Input->lLon_orient=lrint(geom_in.parm_3 *1000.);/*grid orient */
  385. pGDS_Lam_Input->ulDx=(unsigned long)lrint(geom_in.x_int_dis*1000.);/*Xdir gridlen*/
  386. pGDS_Lam_Input->ulDy=(unsigned long)lrint(geom_in.y_int_dis*1000.);/*Ydir gridlen*/
  387. if ((geom_in.y_int_dis != 0) && (geom_in.x_int_dis != 0))
  388. pGDS_Lam_Input->usRes_flag = pGDS_Lam_Input->usRes_flag + 0x88;
  389. if (geom_in.parm_1 > 0)
  390. pGDS_Lam_Input->usProj_flag = 0; /* projection flag */
  391. else
  392. pGDS_Lam_Input->usProj_flag = 1<<7; /* projection flag */
  393. pGDS_Lam_Input->usScan_mode = geom_in.scan; /* order of grid points (Tbl8)*/
  394. /* Make sure CUT1 is closest to Pole */
  395. cut1 = geom_in.parm_1;
  396. cut2 = geom_in.parm_2;
  397. if (cut1 >= 0.) {
  398. if (cut2 > cut1) { tmp = cut1; cut1 = cut2; cut2 = tmp; }
  399. }
  400. else {
  401. if (cut2 < cut1) { tmp = cut1; cut1 = cut2; cut2 = tmp; }
  402. }
  403. pGDS_Lam_Input->lLat_cut1=lrint(cut1 *1000.);/* 1stlat fr pole secant cuts*/
  404. pGDS_Lam_Input->lLat_cut2=lrint(cut2 *1000.);/* 2ndlat fr pole secant cuts*/
  405. pGDS_Lam_Input->lLat_southpole = -90000; /* lat of southern pole (millidegrees) */
  406. pGDS_Lam_Input->lLon_southpole = 0; /* lon of souther pole (millidegrees) */
  407. pGDS_Lam_Input->usZero = 0; /* filler zeroes */
  408. /*
  409. * DEBUG print
  410. */
  411. DPRINT3("\t%s: usData_type = %u (%s)\n",
  412. func,pGDS_Lam_Input->usData_type, prjn_name[pGDS_Lam_Input->usData_type] );
  413. DPRINT2("\t%s: iNx = %d\n", func,pGDS_Lam_Input->iNx );
  414. DPRINT2("\t%s: iNy = %d\n", func,pGDS_Lam_Input->iNy );
  415. DPRINT2("\t%s: lLat1 = %d\n", func,pGDS_Lam_Input->lLat1 );
  416. DPRINT2("\t%s: lLon1 = %d\n", func,pGDS_Lam_Input->lLon1 );
  417. DPRINT2("\t%s: lLon_orient = %d\n", func,pGDS_Lam_Input->lLon_orient);
  418. DPRINT2("\t%s: ulDx = %u\n", func, pGDS_Lam_Input->ulDx );
  419. DPRINT2("\t%s: ulDy = %u\n", func, pGDS_Lam_Input->ulDy );
  420. DPRINT2("\t%s: lLat_cut1 = %d\n", func, pGDS_Lam_Input->lLat_cut1);
  421. DPRINT2("\t%s: lLat_cut2 = %d\n", func, pGDS_Lam_Input->lLat_cut2);
  422. DPRINT2("\t%s: usRes_flag = %u\n", func,pGDS_Lam_Input->usRes_flag);
  423. DPRINT2("\t%s: usProj_flag = %u\n", func,pGDS_Lam_Input->usProj_flag);
  424. DPRINT2("\t%s: usScan_mode = %u\n", func,pGDS_Lam_Input->usScan_mode);
  425. /*
  426. * B.2 ENDIF
  427. */
  428. }
  429. DPRINT1(" Exiting %s.......\n" ,func);
  430. /*
  431. *
  432. * B.3 RETURN status
  433. */
  434. return ( nStatus );
  435. /*
  436. *
  437. * END OF FUNCTION
  438. *
  439. *
  440. */
  441. }
  442. /*
  443. *
  444. *********************************************************************
  445. * C. FUNCTION: create_inpPolar
  446. * Fills Polar Stereographic Projection structure.
  447. *
  448. * INTERFACE:
  449. * int create_inpPolar (geom_in, ppvGDS_Proj_Input, errmsg)
  450. *
  451. * ARGUMENTS (I=input, O=output, I&O=input and output):
  452. * (I) GEOM_IN geom_in holds info to fill local Polar block
  453. * (O) void **ppvGDS_Proj_Input block to filled with Polar Stereo info
  454. * (O) char *errmsg empty array filled if error occurs
  455. *
  456. * RETURN CODE:
  457. * 0> success, ppvGDS_Proj_Input holds Polar projection info;
  458. * 1> the input pre-Malloced projection block is null; errmsg filled;
  459. **********************************************************************/
  460. #if PROTOTYPE_NEEDED
  461. int create_inpPolar (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
  462. #else
  463. int create_inpPolar (geom_in, ppvGDS_Proj_Input, errmsg)
  464. GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
  465. #endif
  466. {
  467. char *func="create_inpPolar";
  468. /*
  469. *
  470. * C.1 DEFAULT status of 0
  471. */
  472. GDS_PS_INPUT *pGDS_PS_Input;
  473. int nStatus = 0;
  474. DPRINT1 (" Entering %s.....\n",func );
  475. /*
  476. *
  477. * C.2 IF (incoming projection block is Null)
  478. * C.2.a THEN
  479. * FILL errmsg
  480. * CHANGE return Status to error
  481. */
  482. if (!(pGDS_PS_Input= (GDS_PS_INPUT *) *ppvGDS_Proj_Input) )
  483. {
  484. DPRINT1 ("%s: ppvGDS_Proj_Input is null\n", func);
  485. sprintf(errmsg,"%s: ppvGDS_Proj_Input is null\n", func);
  486. nStatus = 1;
  487. }
  488. else {
  489. /*
  490. * C.2.b ELSE
  491. * C.2.b.1 FILL elements of Polar Stereo structure
  492. */
  493. pGDS_PS_Input->usData_type = POLAR_PRJ; /* data type flag (Tbl ) */
  494. pGDS_PS_Input->usNx = (unsigned short) geom_in.nx;/* #pts along x-axis*/
  495. pGDS_PS_Input->usNy = (unsigned short) geom_in.ny;/* #pts along y-axiz*/
  496. pGDS_PS_Input->lLat1 = lrint(geom_in.first_lat *1000.);/*lat of 1st gridpt*/
  497. pGDS_PS_Input->lLon1 = lrint(geom_in.first_lon *1000.);/*lon of 1st gridpt*/
  498. pGDS_PS_Input->usRes_flag = geom_in.usRes_flag;/* resolution flags Tbl7 */
  499. pGDS_PS_Input->lLon_orient = lrint(geom_in.parm_2 *1000.);/*grid orient*/
  500. pGDS_PS_Input->ulDx=(unsigned long)lrint(geom_in.x_int_dis*1000.);/*Xdir gridlen*/
  501. pGDS_PS_Input->ulDy=(unsigned long)lrint(geom_in.y_int_dis*1000.);/*Ydir gridlen*/
  502. if ((geom_in.y_int_dis != 0) && (geom_in.x_int_dis != 0))
  503. pGDS_PS_Input->usRes_flag = pGDS_PS_Input->usRes_flag + 0x88;
  504. if (geom_in.first_lat > 0)
  505. pGDS_PS_Input->usProj_flag = 0; /* projection flag */
  506. else
  507. pGDS_PS_Input->usProj_flag = 1<<7; /* projection flag */
  508. pGDS_PS_Input->usScan_mode = geom_in.scan; /* order of grid points (Tbl 8) */
  509. pGDS_PS_Input->usZero = 0; /* filler zeroes */
  510. /*
  511. * C.2.b.2 DEBUG print
  512. */
  513. DPRINT3 ("\t%s: usData_type = %u (%s)\n",func,pGDS_PS_Input->usData_type,
  514. prjn_name [pGDS_PS_Input->usData_type] );
  515. DPRINT2("\t%s: usNx = %u\n", func,pGDS_PS_Input->usNx );
  516. DPRINT2("\t%s: usNy = %u\n", func,pGDS_PS_Input->usNy );
  517. DPRINT2("\t%s: lLat1 = %d\n", func,pGDS_PS_Input->lLat1 );
  518. DPRINT2("\t%s: lLon1 = %d\n", func,pGDS_PS_Input->lLon1 );
  519. DPRINT2("\t%s: lLon_orient = %d\n", func,pGDS_PS_Input->lLon_orient);
  520. DPRINT2("\t%s: ulDx = %u\n", func,pGDS_PS_Input->ulDx);
  521. DPRINT2("\t%s: ulDy = %u\n", func,pGDS_PS_Input->ulDy);
  522. DPRINT2("\t%s: usRes_flag = %u\n", func,pGDS_PS_Input->usRes_flag);
  523. DPRINT2("\t%s: usProj_flag = %u\n", func,pGDS_PS_Input->usProj_flag);
  524. DPRINT2("\t%s: usScan_mode = %u\n", func,pGDS_PS_Input->usScan_mode);
  525. /*
  526. * C.2.b ENDIF
  527. */
  528. }
  529. DPRINT1(" Exiting %s.......\n" ,func);
  530. /*
  531. *
  532. * C.3 RETURN status
  533. */
  534. return ( nStatus );
  535. /*
  536. *
  537. * END OF FUNCTION
  538. *
  539. *
  540. */
  541. }
  542. /*
  543. *
  544. *********************************************************************
  545. * D. FUNCTION: create_inpLatlon
  546. * Fills Latitude Longitude Projection structure.
  547. *
  548. * INTERFACE:
  549. * int create_inpLatlon ( geom_in, ppvGDS_Proj_Input, errmsg)
  550. *
  551. * ARGUMENTS (I=input, O=output, I&O=input and output):
  552. * (I) GEOM_IN geom_in holds geom info to fill local Lat/Lon block
  553. * (O) void **ppvGDS_Proj_Input to be filled with LatLon projection info
  554. * (O) char *errmsg empty array, filled if error occurred
  555. *
  556. * OUTPUT:
  557. * 0> success, ppGDS_Proj_Input filled with Lat/Lon projection info
  558. * 1> pre-Malloced Projection block is null; errmsg filled;
  559. **********************************************************************/
  560. #if PROTOTYPE_NEEDED
  561. int create_inpLatlon (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
  562. #else
  563. int create_inpLatlon (geom_in, ppvGDS_Proj_Input, errmsg)
  564. GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
  565. #endif
  566. {
  567. char *func= "Create_InpLatLon";
  568. /*
  569. *
  570. * D.0 DEFAULT to return status of 0
  571. */
  572. GDS_LATLON_INPUT *pGDS_Latlon_Input;
  573. int nStatus = 0;
  574. DPRINT1 (" Entering %s......\n" ,func);
  575. /*
  576. *
  577. * D.2 IF (incoming projection block is Null)
  578. * THEN
  579. * FILL errmsg
  580. * CHANGE stat to 1
  581. */
  582. if (!(pGDS_Latlon_Input= (GDS_LATLON_INPUT *) *ppvGDS_Proj_Input) )
  583. {
  584. DPRINT1 (" %s: ppvGDS_Proj_Input is null\n", func);
  585. sprintf(errmsg," %s: ppvGDS_Proj_Input is null\n", func);
  586. nStatus = 1;
  587. }
  588. /*
  589. * D.2.b ELSE
  590. * D.2.b.1 FILL elements of the Lat/Lon GDS block
  591. */
  592. else
  593. {
  594. pGDS_Latlon_Input->usData_type = LATLON_PRJ; /* data type flag (Tbl )*/
  595. pGDS_Latlon_Input->usNi=(unsigned short)geom_in.nx;/*#pts along x-axis 109*/
  596. pGDS_Latlon_Input->usNj=(unsigned short)geom_in.ny;/* #pts along y-axiz 82*/
  597. pGDS_Latlon_Input->lLat1=lrint(geom_in.first_lat*1000.);/*lat of 1stgridpt*/
  598. pGDS_Latlon_Input->lLon1=lrint(geom_in.first_lon*1000.);/*lon of 1stgridpt*/
  599. pGDS_Latlon_Input->usRes_flag=geom_in.usRes_flag;/*resolution flags Tbl7*/
  600. pGDS_Latlon_Input->lLat2 =lrint(geom_in.last_lat*1000.);/*lat of 2ndgridpt*/
  601. pGDS_Latlon_Input->lLon2 =lrint(geom_in.last_lon*1000.);/*lon of 2ndgridpt*/
  602. pGDS_Latlon_Input->iDi = lrint(geom_in.parm_2 *1000.);/* i-dir incr*/
  603. pGDS_Latlon_Input->iDj = lrint(geom_in.parm_1 *1000.);/* j-dir incr*/
  604. if ((geom_in.parm_1 != 0) && (geom_in.parm_2 != 0))
  605. pGDS_Latlon_Input->usRes_flag = pGDS_Latlon_Input->usRes_flag + 0x88;
  606. pGDS_Latlon_Input->usScan_mode = geom_in.scan; /* order ofgridpts (Tbl 8)*/
  607. pGDS_Latlon_Input->usZero = 0; /* filler zeroes*/
  608. pGDS_Latlon_Input->lLat_southpole= -90000;/* lat of southern pole (millidegrees)*/
  609. pGDS_Latlon_Input->lLon_southpole= 0;/* lon of southern pole (millidegrees)*/
  610. pGDS_Latlon_Input->lRotate = 0;/* angle of rotation*/
  611. pGDS_Latlon_Input->lPole_lat = 0;/* lat of pole of stretching (mdeg)*/
  612. pGDS_Latlon_Input->lPole_lon = 0; /* lon of pole of stretching*/
  613. pGDS_Latlon_Input->lStretch = 0;/* stretching factor*/
  614. /*
  615. * D.2.b.2 DEBUG print
  616. */
  617. DPRINT3("\t%s: usData_type = %u (%s)\n", func,pGDS_Latlon_Input->usData_type,
  618. prjn_name[pGDS_Latlon_Input->usData_type] );
  619. DPRINT2("\t%s: usNi = %u\n",func,pGDS_Latlon_Input->usNi );
  620. DPRINT2("\t%s: usNj = %u\n",func,pGDS_Latlon_Input->usNj );
  621. DPRINT2("\t%s: lLat1 = %d\n",func,pGDS_Latlon_Input->lLat1 );
  622. DPRINT2("\t%s: lLon1 = %d\n",func,pGDS_Latlon_Input->lLon1 );
  623. DPRINT2("\t%s: lLat2 = %d\n",func,pGDS_Latlon_Input->lLat2 );
  624. DPRINT2("\t%s: lLon2 = %d\n",func,pGDS_Latlon_Input->lLon2 );
  625. DPRINT2("\t%s: iDi = %u\n",func,pGDS_Latlon_Input->iDi );
  626. DPRINT2("\t%s: iDj = %u\n",func,pGDS_Latlon_Input->iDj );
  627. DPRINT2("\t%s: usRes_flag = %u\n",func,pGDS_Latlon_Input->usRes_flag );
  628. DPRINT2("\t%s: usScan_mode = %u\n",func,pGDS_Latlon_Input->usScan_mode );
  629. DPRINT2("\t%s: lLat_southpole = %ld\n",func,pGDS_Latlon_Input->lLat_southpole);
  630. DPRINT2("\t%s: lLon_southpole = %ld\n",func,pGDS_Latlon_Input->lLon_southpole);
  631. DPRINT2("\t%s: lRotate = %ld\n",func,pGDS_Latlon_Input->lRotate );
  632. DPRINT2("\t%s: lPole_lat = %ld\n",func,pGDS_Latlon_Input->lPole_lat );
  633. DPRINT2("\t%s: lPole_lon = %ld\n",func,pGDS_Latlon_Input->lPole_lon );
  634. DPRINT2("\t%s: lStretch = %ld\n",func,pGDS_Latlon_Input->lStretch );
  635. /*
  636. * D.2.b ENDIF
  637. */
  638. }
  639. /*
  640. *
  641. * D.3 RET2URN status
  642. */
  643. DPRINT1(" Exiting %s.......\n" ,func);
  644. return ( nStatus );
  645. /*
  646. * END OF FUNCTION
  647. *
  648. */
  649. }
  650. /*
  651. *
  652. *********************************************************************
  653. * FUNCTION: create_inpMercator
  654. * Fills Mercator Projection structure.
  655. *
  656. * INTERFACE:
  657. * int create_inpMercator (geom_in, ppvGDS_Proj_Input, errmsg)
  658. *
  659. * ARGUMENTS (I=input, O=output, I&O=input and output):
  660. * (I) GEOM_IN geom_in holds info to fill local Mercator block
  661. * (O) void **ppvGDS_Proj_Input block to filled with Mercator info
  662. * (O) char *errmsg empty array filled if error occurs
  663. *
  664. * RETURN CODE:
  665. * 0> success, ppvGDS_Proj_Input holds Mercator projection info;
  666. * 1> the input pre-Malloced projection block is null; errmsg filled;
  667. **********************************************************************/
  668. #if PROTOTYPE_NEEDED
  669. int create_inpMercator (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
  670. #else
  671. int create_inpMercator (geom_in, ppvGDS_Proj_Input, errmsg)
  672. GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
  673. #endif
  674. {
  675. char *func="create_inpMercator";
  676. /*
  677. *
  678. * C.1 DEFAULT status of 0
  679. */
  680. mercator *pGDS_mercator_Input;
  681. int nStatus = 0;
  682. DPRINT1 (" Entering %s.....\n",func );
  683. /*
  684. *
  685. * C.2 IF (incoming projection block is Null)
  686. * C.2.a THEN
  687. * FILL errmsg
  688. * CHANGE return Status to error
  689. */
  690. if (!(pGDS_mercator_Input= (mercator *) *ppvGDS_Proj_Input) )
  691. {
  692. DPRINT1 ("%s: ppvGDS_Proj_Input is null\n", func);
  693. sprintf(errmsg,"%s: ppvGDS_Proj_Input is null\n", func);
  694. nStatus = 1;
  695. }
  696. else {
  697. /*
  698. * C.2.b ELSE
  699. * C.2.b.1 FILL elements of Polar Stereo structure
  700. */
  701. pGDS_mercator_Input->usData_type = MERC_PRJ; /* data type flag (Tbl ) */
  702. pGDS_mercator_Input->cols = (unsigned short) geom_in.nx;/* #pts along x-axis*/
  703. pGDS_mercator_Input->rows = (unsigned short) geom_in.ny;/* #pts along y-axiz*/
  704. pGDS_mercator_Input->first_lat = lrint(geom_in.first_lat *1000.);/*lat of 1st gridpt*/
  705. pGDS_mercator_Input->first_lon = lrint(geom_in.first_lon *1000.);/*lon of 1st gridpt*/
  706. pGDS_mercator_Input->usRes_flag = geom_in.usRes_flag;/* resolution flags Tbl7 */
  707. pGDS_mercator_Input->La2 = lrint(geom_in.last_lat *1000.);/*lat of last gridpt*/
  708. pGDS_mercator_Input->Lo2 = lrint(geom_in.last_lon *1000.);/*lon of last gridpt*/
  709. pGDS_mercator_Input->latin = lrint(geom_in.parm_1 *1000.);/*reference latitude*/
  710. pGDS_mercator_Input->usZero1 = 0; /* filler zeroes */
  711. pGDS_mercator_Input->usScan_mode = geom_in.scan; /* order of grid points (Tbl 8) */
  712. pGDS_mercator_Input->lon_inc = lrint(geom_in.parm_2 *1000.);/*longitude increment*/
  713. pGDS_mercator_Input->lat_inc = lrint(geom_in.parm_3 *1000.);/*latitude increment*/
  714. pGDS_mercator_Input->usZero = 0; /* filler zeroes */
  715. /*
  716. * C.2.b.2 DEBUG print
  717. */
  718. DPRINT3 ("\t%s: usData_type = %u (%s)\n",func,pGDS_mercator_Input->usData_type,
  719. prjn_name [pGDS_mercator_Input->usData_type] );
  720. DPRINT2("\t%s: cols = %u\n", func,pGDS_mercator_Input->cols );
  721. DPRINT2("\t%s: rows = %u\n", func,pGDS_mercator_Input->rows );
  722. DPRINT2("\t%s: first_lat = %d\n", func,pGDS_mercator_Input->first_lat );
  723. DPRINT2("\t%s: first_lon = %d\n", func,pGDS_mercator_Input->first_lon );
  724. DPRINT2("\t%s: usRes_flag = %d\n", func,pGDS_mercator_Input->usRes_flag);
  725. DPRINT2("\t%s: La2 = %d\n", func,pGDS_mercator_Input->La2);
  726. DPRINT2("\t%s: Lo2 = %d\n", func,pGDS_mercator_Input->Lo2);
  727. DPRINT2("\t%s: latin = %d\n", func,pGDS_mercator_Input->latin);
  728. DPRINT2("\t%s: usZero1 = %d\n", func,pGDS_mercator_Input->usZero1);
  729. DPRINT2("\t%s: usScan_mode = %d\n", func,pGDS_mercator_Input->usScan_mode);
  730. DPRINT2("\t%s: lon_inc = %f\n", func,pGDS_mercator_Input->lon_inc);
  731. DPRINT2("\t%s: lat_inc = %f\n", func,pGDS_mercator_Input->lat_inc);
  732. /*
  733. * C.2.b ENDIF
  734. */
  735. }
  736. DPRINT1(" Exiting %s.......\n" ,func);
  737. /*
  738. *
  739. * C.3 RETURN status
  740. */
  741. return ( nStatus );
  742. /*
  743. *
  744. * END OF FUNCTION
  745. *
  746. *
  747. */
  748. }
  749. /*
  750. *
  751. ****************************************************************************
  752. * E. FUNCTION: inp2gribLambert
  753. * This routine fills the special Lambert Projection structure for
  754. * the GDS.
  755. *
  756. * INTERFACE:
  757. * int inp2grib_Lambert (ppvGDS_Proj_Input, pLambert, lProj_size, errmsg)
  758. *
  759. * ARGUMENTS (I=input, O=output, I&O=input and output):
  760. * (I) void **ppvGDS_Proj_Input;
  761. * pointer to struct holds Input Projection data
  762. * (O) LAMBERT *pLambert;
  763. * block to be filled with Lambert Projection information
  764. * (O) long *lProj_size;
  765. * to be filled with size of LAMBERT struct;
  766. * (O) char *errmsg;
  767. * empty array, filled if error occurred;
  768. *
  769. * RETURN CODE:
  770. * 0> success, pLambert and lProj_size filled;
  771. * 1> got null pointers; errmsg filled;
  772. ****************************************************************************/
  773. #if PROTOTYPE_NEEDED
  774. int inp2grib_Lambert (void **ppvGDS_Proj_Input, LAMBERT *pLambert,
  775. long *lProj_size, char *errmsg)
  776. #else
  777. int inp2grib_Lambert (ppvGDS_Proj_Input, pLambert, lProj_size, errmsg)
  778. void **ppvGDS_Proj_Input; LAMBERT *pLambert;
  779. long *lProj_size; char *errmsg;
  780. #endif
  781. {
  782. /*
  783. * E.1 INIT status to success
  784. *
  785. * E.2 DEBUG printing
  786. */
  787. GDS_LAM_INPUT *vProjInp = 0;
  788. long lTemp = 0;
  789. int nStatus = 0;
  790. char *func= "inp2grib_Lambert";
  791. long tmp_byte4;
  792. DPRINT1 (" Entering %s.....\n",func);
  793. /*
  794. *
  795. * E.3 MAKE local ptr vProjInp point to Input Projection data block arg
  796. */
  797. vProjInp = ( GDS_LAM_INPUT * ) *ppvGDS_Proj_Input; /* read fr this */
  798. /*
  799. *
  800. * E.4 IF (either of the user's struct pointers are NUL) THEN
  801. * SET status = 1
  802. * RETURN
  803. * ENDIF
  804. */
  805. if (!vProjInp || !pLambert) {
  806. DPRINT1 ("%s: the VOID *ppvGDS_Proj_Input block is null\n",func);
  807. sprintf(errmsg, "%s: the VOID *ppvGDS_Proj_Input block is null\n",func);
  808. nStatus= 1;
  809. goto BYE;
  810. }
  811. /*
  812. * E.5 FILL local block type LAMBERT
  813. */
  814. set_bytes(vProjInp->iNx, 2, pLambert->achNx);
  815. set_bytes(vProjInp->iNy, 2, pLambert->achNy);
  816. /* convert lLat1 to 3chars */
  817. set_bytes(vProjInp->lLat1, 3, pLambert->achLat1);
  818. /* convert lLon1 to 3chars */
  819. set_bytes(vProjInp->lLon1, 3, pLambert->achLon1);
  820. pLambert->chRes_flag = ( unsigned char ) vProjInp->usRes_flag;
  821. /* convert lLon_orient to 3 bytes */
  822. set_bytes(vProjInp->lLon_orient, 3, pLambert->achLon_orient);
  823. /* convert ulDx to 3 bytes */
  824. set_bytes(vProjInp->ulDx, 3, pLambert->achDx);
  825. /* convert ulDy to 3 bytes */
  826. set_bytes(vProjInp->ulDy, 3, pLambert->achDy);
  827. pLambert->chProj_flag = ( unsigned char ) vProjInp->usProj_flag;
  828. pLambert->chScan_mode = ( unsigned char ) vProjInp->usScan_mode;
  829. /* convert lLat_cut1 to 3 chars */
  830. set_bytes(vProjInp->lLat_cut1, 3, pLambert->achLat_cut1);
  831. /* convert lLat_cut2 to 3 chars */
  832. set_bytes(vProjInp->lLat_cut2, 3, pLambert->achLat_cut2);
  833. /* convert lLat_southpole to 3chars */
  834. set_bytes(vProjInp->lLat_southpole, 3, pLambert->achLat_southpole);
  835. /* convert lLon_southpole to 3 chars */
  836. set_bytes(vProjInp->lLon_southpole, 3, pLambert->achLon_southpole);
  837. set_bytes(vProjInp->usZero, 2, pLambert->achZero);
  838. /*
  839. *
  840. * E.6 DEBUG print Grib LAMBERT block
  841. */
  842. DPRINT3("\t%s: achNx [%02d,%02d]\n", func,
  843. pLambert->achNx[0],pLambert->achNx[1]);
  844. DPRINT3("\t%s: achNy [%02d,%02d]\n", func,
  845. pLambert->achNy[0],pLambert->achNy[1]);
  846. DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n", func,
  847. pLambert->achLat1[0], pLambert->achLat1[1], pLambert->achLat1[2]);
  848. DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n", func,
  849. pLambert->achLon1[0], pLambert->achLon1[1], pLambert->achLon1[2]);
  850. DPRINT2("\t%s: chRes_flag [%02d]\n", func, pLambert->chRes_flag);
  851. DPRINT4("\t%s: achLon_orient [%02d,%02d,%02d]\n", func,
  852. pLambert->achLon_orient[0], pLambert->achLon_orient[1],
  853. pLambert->achLon_orient[2]);
  854. DPRINT4("\t%s: achDx [%02d,%02d,%02d]\n", func,
  855. pLambert->achDx[0], pLambert->achDx[1], pLambert->achDx[2]);
  856. DPRINT4("\t%s: achDy [%02d,%02d,%02d]\n", func,
  857. pLambert->achDy[0], pLambert->achDy[1], pLambert->achDy[2]);
  858. DPRINT2("\t%s: chProj_flag [%02d]\n", func, pLambert->chProj_flag);
  859. DPRINT2("\t%s: chScan_mode [%02d]\n", func, pLambert->chScan_mode);
  860. DPRINT4("\t%s: achLat_cut1 [%02d,%02d,%02d]\n", func,
  861. pLambert->achLat_cut1[0],
  862. pLambert->achLat_cut1[1], pLambert->achLat_cut1[2]);
  863. DPRINT4("\t%s: achLat_cut2 [%02d,%02d,%02d]\n", func,
  864. pLambert->achLat_cut2[0],
  865. pLambert->achLat_cut2[1], pLambert->achLat_cut2[2]);
  866. DPRINT4("\t%s: achLat_southpole [%02d,%02d,%02d]\n",func,
  867. pLambert->achLat_southpole[0],
  868. pLambert->achLat_southpole[1], pLambert->achLat_southpole[2] );
  869. DPRINT4("\t%s: achLon_southpole [%02d,%02d,%02d]\n",func,
  870. pLambert->achLon_southpole[0],
  871. pLambert->achLon_southpole[1], pLambert->achLon_southpole[2] );
  872. DPRINT3("\t%s: achZero [%02d,%02d]\n", func,
  873. pLambert->achZero[0], pLambert->achZero[1]);
  874. /*******/
  875. /*
  876. *
  877. * E.7 STORE proj size of LAMBERT struct in lProj_size
  878. */
  879. *lProj_size = sizeof (LAMBERT);
  880. BYE:
  881. DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func,
  882. *lProj_size, nStatus);
  883. /*
  884. *
  885. * E.9 RETURN status
  886. */
  887. return ( nStatus );
  888. /*
  889. *
  890. * END OF FUNCTION
  891. */
  892. }
  893. /*
  894. *
  895. ****************************************************************************
  896. * F. FUNCTION: inp2grib_PolarSt
  897. * This routine fills the special Polar Stereo Projection structure for
  898. * the GDS.
  899. *
  900. * INTERFACE:
  901. * int inp2grib_PolarSt ( ppvGDS_Proj_Input, Polar, lProj_size ,errmsg)
  902. *
  903. * ARGUMENTS (I=input, O=output, I&O=input and output):
  904. * (I) void **ppvGDS_Proj_Input;
  905. * holds input projection data
  906. * (O) POLAR *Polar;
  907. * to be filled with Polar Stereographic projection info
  908. * (O) long *lProj_size;
  909. * to be filled with size of structure POLAR
  910. * (O) char *errmsg
  911. * empty array, filled if error occurred
  912. *
  913. * RETURN CODE:
  914. * 0> success, Polar and lProj_size filled;
  915. * 1> pointers are null, errmsg filled;
  916. ****************************************************************************/
  917. #if PROTOTYPE_NEEDED
  918. int inp2grib_PolarSt (void **ppvGDS_Proj_Input, POLAR *Polar,
  919. long *lProj_size , char *errmsg)
  920. #else
  921. int inp2grib_PolarSt (ppvGDS_Proj_Input, Polar, lProj_size , errmsg)
  922. void **ppvGDS_Proj_Input; POLAR *Polar;
  923. long *lProj_size ; char *errmsg;
  924. #endif
  925. {
  926. /*
  927. *
  928. * F.1 INIT variables !default stat=good
  929. */
  930. GDS_PS_INPUT *pProjInp = 0;
  931. int lTemp = 0;
  932. int nStatus = 0;
  933. char *func="inp2grib_PolarSt";
  934. DPRINT1 ("\t Entering %s.....\n", func);
  935. /*
  936. *
  937. * F.2 POINT local pProjInp to incoming ppvGDS_Proj_Input
  938. */
  939. pProjInp = ( GDS_PS_INPUT *) *ppvGDS_Proj_Input;
  940. /*
  941. *
  942. * F.3 IF (true grib Polar proj block OR input Polar block is null) THEN
  943. * SET Status= 1
  944. * RETURN;
  945. * ENDIF
  946. */
  947. if (!Polar || !pProjInp )
  948. {
  949. DPRINT1 ( "%s: Polar or pProjInp is null\n", func);
  950. sprintf(errmsg,"%s: Polar or pProjInp is null\n", func);
  951. nStatus= 1; goto BYE;
  952. }
  953. /*
  954. *
  955. * F.4 FILL local struct from pProjInp
  956. */
  957. /* convert usNx to 2 chars */
  958. set_bytes(pProjInp->usNx, 2, Polar->achNx);
  959. /* convert usNy to 2 chars */
  960. set_bytes(pProjInp->usNy, 2, Polar->achNy);
  961. /* convert lLat1 to 3 chars */
  962. set_bytes(pProjInp->lLat1, 3, Polar->achLat1);
  963. /* convert lLon1 to 3 chars */
  964. set_bytes(pProjInp->lLon1, 3, Polar->achLon1);
  965. Polar->chRes_flag = ( unsigned char ) pProjInp->usRes_flag;
  966. /* convert lLon_orient to 3 chars */
  967. set_bytes(pProjInp->lLon_orient, 3, Polar->achLon_orient);
  968. /* convert ulDx to 3 char */
  969. set_bytes(pProjInp->ulDx, 3, Polar->achDx);
  970. /* convert ulDy to 3chars */
  971. set_bytes(pProjInp->ulDy, 3, Polar->achDy);
  972. Polar->chProj_flag = ( unsigned char ) pProjInp->usProj_flag;
  973. Polar->chScan_mode = ( unsigned char ) pProjInp->usScan_mode;
  974. /* 4 bytes of zero */
  975. memset((void*) Polar->achZero, '\0', 4);
  976. /*
  977. *
  978. * F.5 DEBUG print GRIB Projection block
  979. */
  980. DPRINT3("\t%s: achNx [%02d,%02d]\n",func, Polar->achNx[0],Polar->achNx[1]);
  981. DPRINT3("\t%s: achNy [%02d,%02d]\n",func, Polar->achNy[0],Polar->achNy[1]);
  982. DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n",func, Polar->achLat1[0],
  983. Polar->achLat1[1], Polar->achLat1[2]);
  984. DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n",func, Polar->achLon1[0],
  985. Polar->achLon1[1] , Polar->achLon1[2]);
  986. DPRINT2("\t%s: chRes_flag [%02d]\n",func, Polar->chRes_flag);
  987. DPRINT4("\t%s: achLon_orient [%02d,%02d,%02d]\n",func,
  988. Polar->achLon_orient[0], Polar->achLon_orient[1], Polar->achLon_orient[2]);
  989. DPRINT4("\t%s: achDx [%02d,%02d,%02d]\n",func, Polar->achDx[0],
  990. Polar->achDx[1], Polar->achDx[2]);
  991. DPRINT4("\t%s: achDy [%02d,%02d,%02d]\n",func, Polar->achDy[0],
  992. Polar->achDy[1], Polar->achDy[2]);
  993. DPRINT2("\t%s: chProj_flag [%02d]\n",func, Polar->chProj_flag);
  994. DPRINT2("\t%s: chScan_mode [%02d]\n",func, Polar->chScan_mode);
  995. DPRINT5("\t%s: achZero [%02d,%02d,%02d,%02d]\n",func, Polar->achZero[0],
  996. Polar->achZero[1], Polar->achZero[2], Polar->achZero[3]);
  997. /*******/
  998. /*
  999. *
  1000. * F.7 STORE size of POLAR struct in lProj_size
  1001. */
  1002. *lProj_size = sizeof (POLAR);
  1003. BYE:
  1004. DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func,
  1005. *lProj_size, nStatus);
  1006. /*
  1007. *
  1008. * F.8 RETURN Stat ! 0 or 1
  1009. */
  1010. return ( nStatus );
  1011. /*
  1012. *
  1013. * END OF FUNCTION
  1014. *
  1015. *
  1016. */
  1017. }
  1018. /*
  1019. *
  1020. ****************************************************************************
  1021. * G. FUNCTION: inp2grib_Latlon
  1022. * This routine fills the Latitude Longitude Projection structure for
  1023. * the GDS.
  1024. *
  1025. * INTERFACE:
  1026. * int inp2grib_Latlon ( ppvGDS_Proj_Input, pLatlon, lProj_size ,errmsg)
  1027. *
  1028. * ARGUMENTS (I=input, O=output, I&O=input and output):
  1029. * (I) void **ppvGDS_Proj_Input;
  1030. * holds input projection data
  1031. * (O) LATLON *pLatlon;
  1032. * to be filled with Lat/Lon projection info
  1033. * (O) long *lProj_size;
  1034. * to be filled with size of structure LATLON
  1035. * (O) char *errmsg;
  1036. * empty array, filled if error occurred
  1037. *
  1038. * RETURN CODE:
  1039. * 0> success, pLatlon and lProj_size filled;
  1040. * 1> got null pointers, errmsg filled;
  1041. ****************************************************************************/
  1042. #if PROTOTYPE_NEEDED
  1043. int inp2grib_Latlon (void **ppvGDS_Proj_Input, LATLON *pLatlon,
  1044. long *lProj_size, char *errmsg)
  1045. #else
  1046. int inp2grib_Latlon (ppvGDS_Proj_Input, pLatlon, lProj_size, errmsg)
  1047. void **ppvGDS_Proj_Input; LATLON *pLatlon;
  1048. long *lProj_size; char *errmsg;
  1049. #endif
  1050. {
  1051. GDS_LATLON_INPUT *Inp = 0;
  1052. int lTemp = 0;
  1053. char *func= "inp2grib_Latlon";
  1054. /*
  1055. *
  1056. * G.1 INIT status to success
  1057. */
  1058. int nStatus = 0;
  1059. DPRINT1 ( " Entering %s.....\n", func );
  1060. /*
  1061. *
  1062. * G.2 ASSIGN arguments to local pointers
  1063. */
  1064. Inp = (GDS_LATLON_INPUT *) *ppvGDS_Proj_Input;
  1065. /*
  1066. DPRINT3("\n%s: usData_type = %u (%s)\n", func, Inp->usData_type,
  1067. prjn_name[Inp->usData_type] );
  1068. DPRINT2("\t%s: usNi = %u\n",func, Inp->usNi );
  1069. DPRINT2("\t%s: usNj = %u\n",func, Inp->usNj );
  1070. DPRINT2("\t%s: lLat1 = %d\n",func, Inp->lLat1 );
  1071. DPRINT2("\t%s: lLon1 = %d\n",func, Inp->lLon1 );
  1072. DPRINT2("\t%s: lLat2 = %d\n",func, Inp->lLat2 );
  1073. DPRINT2("\t%s: lLon2 = %d\n",func, Inp->lLon2 );
  1074. DPRINT2("\t%s: iDi = %u\n",func, Inp->iDi );
  1075. DPRINT2("\t%s: iDj = %u\n",func, Inp->iDj );
  1076. DPRINT2("\t%s: usRes_flag = %u\n",func, Inp->usRes_flag );
  1077. DPRINT2("\t%s: usScan_mode = %u\n",func, Inp->usScan_mode );
  1078. DPRINT2("\t%s: lLat_southpole = %ld\n",func, Inp->lLat_southpole);
  1079. DPRINT2("\t%s: lLon_southpole = %ld\n",func, Inp->lLon_southpole);
  1080. DPRINT2("\t%s: lRotate = %ld\n",func, Inp->lRotate );
  1081. DPRINT2("\t%s: lPole_lat = %ld\n",func, Inp->lPole_lat );
  1082. DPRINT2("\t%s: lPole_lon = %ld\n",func, Inp->lPole_lon );
  1083. DPRINT2("\t%s: lStretch = %ld\n",func, Inp->lStretch );
  1084. */
  1085. /*
  1086. *
  1087. * G.3 IF (pointers passed in are null) THEN
  1088. * SET status to 1
  1089. * RETURN
  1090. * ENDIF
  1091. */
  1092. if ( !Inp || !pLatlon) {
  1093. DPRINT1 ("%s: lLatlon_inp || pLatlon is null\n",func);
  1094. sprintf(errmsg, "%s: lLatlon_inp || pLatlon is null\n", func);
  1095. nStatus = 1;
  1096. goto BYE;
  1097. }
  1098. /*
  1099. *
  1100. * G.4 FILL local struct from Inp
  1101. */
  1102. /* convert usNi & usNj to 2 chars */
  1103. set_bytes(Inp->usNi, 2, pLatlon->achNi);
  1104. set_bytes(Inp->usNj, 2, pLatlon->achNj);
  1105. /* convert lLat1 to 3chars */
  1106. set_bytes(Inp->lLat1, 3, pLatlon->achLat1);
  1107. /* convert lLon1 to 3chars */
  1108. set_bytes(Inp->lLon1, 3, pLatlon->achLon1);
  1109. pLatlon->chRes_flag = ( unsigned char ) Inp->usRes_flag;
  1110. /* convert lLat2 to 3chars */
  1111. set_bytes(Inp->lLat2, 3, pLatlon->achLat2);
  1112. /* convert lLon2 to 3chars */
  1113. set_bytes(Inp->lLon2, 3, pLatlon->achLon2);
  1114. /* convert lon increment to 2chars */
  1115. set_bytes(Inp->iDi, 2, pLatlon->achDi);
  1116. /* convert lat increment to 2chars */
  1117. set_bytes(Inp->iDj, 2, pLatlon->achDj);
  1118. /* 1 byte scan mode */
  1119. pLatlon->chScan_mode = ( unsigned char ) Inp->usScan_mode;
  1120. /* 4 bytes of reserved zero */
  1121. memset ((void*)pLatlon->achZero, '\0', 4);
  1122. /* convert lLat_southpole to 3chars */
  1123. set_bytes(Inp->lLat_southpole, 3, pLatlon->achLat_southpole);
  1124. /* convert lLon_southpole to 3chars */
  1125. set_bytes(Inp->lLon_southpole, 3, pLatlon->achLon_southpole);
  1126. /* convert lRotate to 4chars */
  1127. set_bytes(Inp->lRotate, 4, pLatlon->achRotate);
  1128. /* convert lPole_lat to 3chars */
  1129. set_bytes(Inp->lPole_lat, 3, pLatlon->achPole_lat);
  1130. /* convert lPole_lon to 3chars */
  1131. set_bytes(Inp->lPole_lon, 3, pLatlon->achPole_lon);
  1132. /* convert lStretch to 4 chars */
  1133. set_bytes(Inp->lStretch, 4, pLatlon->achStretch);
  1134. /*
  1135. *
  1136. * G.5 DEBUG print Input Proj Block & their equivalence in the Char array;
  1137. */
  1138. DPRINT3("\t%s: achNi [%02d,%02d]\n",func,pLatlon->achNi[0],pLatlon->achNi[1]);
  1139. DPRINT3("\t%s: achNj [%02d,%02d]\n",func,pLatlon->achNj[0],pLatlon->achNj[1]);
  1140. DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n",
  1141. func, pLatlon->achLat1[0],pLatlon->achLat1[1],pLatlon->achLat1[2]);
  1142. DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n", func,
  1143. pLatlon->achLon1[0],pLatlon->achLon1[1],pLatlon->achLon1[2]);
  1144. DPRINT2("\t%s: chRes_flag [%02d]\n", func, pLatlon->chRes_flag );
  1145. DPRINT4("\t%s: achLat2 [%02d,%02d,%02d]\n",
  1146. func, pLatlon->achLat2[0], pLatlon->achLat2[1], pLatlon->achLat2[2]);
  1147. DPRINT4("\t%s: achLon2 [%02d,%02d,%02d]\n",
  1148. func, pLatlon->achLon2[0], pLatlon->achLon2[1], pLatlon->achLon2[2]);
  1149. DPRINT3("\t%s: achDi [%02d,%02d]\n",func,pLatlon->achDi[0],pLatlon->achDi[1]);
  1150. DPRINT3("\t%s: achDj [%02d,%02d]\n",func,pLatlon->achDj[0],pLatlon->achDj[1]);
  1151. DPRINT2("\t%s: chScan_mode [%02d]\n", func, pLatlon->chScan_mode);
  1152. DPRINT5("\t%s: achZero [%02d,%02d,%02d,%02d]\n",
  1153. func, pLatlon->achZero[0],pLatlon->achZero[1],pLatlon->achZero[2],
  1154. pLatlon->achZero[3]);
  1155. DPRINT4("\t%s achLat_southpole [%02d,%02d,%02d]\n",
  1156. func, pLatlon->achLat_southpole[0],pLatlon->achLat_southpole[1],
  1157. pLatlon->achLat_southpole[2]);
  1158. DPRINT4("\t%s achLon_southpole [%02d,%02d,%02d]\n",
  1159. func, pLatlon->achLon_southpole[0],pLatlon->achLon_southpole[1],
  1160. pLatlon->achLon_southpole[2]);
  1161. DPRINT5("\t%s achRotate [%02d,%02d,%02d,%02d]\n",
  1162. func, pLatlon->achRotate[0],pLatlon->achRotate[1],
  1163. pLatlon->achRotate[2], pLatlon->achRotate[3]);
  1164. DPRINT4("\t%s achPole_lat [%02d,%02d,%02d]\n",
  1165. func, pLatlon->achPole_lat[0],pLatlon->achPole_lat[1],
  1166. pLatlon->achPole_lat[2]);
  1167. DPRINT4("\t%s achPole_lon [%02d,%02d,%02d]\n",
  1168. func, pLatlon->achPole_lon[0],pLatlon->achPole_lon[1],
  1169. pLatlon->achPole_lon[2]);
  1170. DPRINT5("\t%s achStretch [%02d,%02d,%02d,%02d]\n",
  1171. func, pLatlon->achStretch[0],pLatlon->achStretch[1],
  1172. pLatlon->achStretch[2], pLatlon->achStretch[3]);
  1173. /*******/
  1174. /*
  1175. *
  1176. * G.6 STORE size of LATLON struct in lProj_size
  1177. */
  1178. *lProj_size = sizeof (LATLON);
  1179. BYE:
  1180. DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func,
  1181. *lProj_size, nStatus);
  1182. /*
  1183. *
  1184. * G.7 RETURN stat
  1185. */
  1186. return ( nStatus );
  1187. /*
  1188. *
  1189. * END OF FUNCTION
  1190. *
  1191. *
  1192. */
  1193. }
  1194. /*
  1195. *
  1196. ****************************************************************************
  1197. * F. FUNCTION: inp2grib_Mercator
  1198. * This routine fills the special Mercator Projection structure for
  1199. * the GDS.
  1200. *
  1201. * INTERFACE:
  1202. * int inp2grib_Mercator ( ppvGDS_Proj_Input, Polar, lProj_size ,errmsg)
  1203. *
  1204. * ARGUMENTS (I=input, O=output, I&O=input and output):
  1205. * (I) void **ppvGDS_Proj_Input;
  1206. * holds input projection data
  1207. * (O) MERCATOR *Mercator;
  1208. * to be filled with Polar Stereographic projection info
  1209. * (O) long *lProj_size;
  1210. * to be filled with size of structure POLAR
  1211. * (O) char *errmsg
  1212. * empty array, filled if error occurred
  1213. *
  1214. * RETURN CODE:
  1215. * 0> success, Mercator and lProj_size filled;
  1216. * 1> pointers are null, errmsg filled;
  1217. ****************************************************************************/
  1218. #if PROTOTYPE_NEEDED
  1219. int inp2grib_Mercator (void **ppvGDS_Proj_Input, MERCATOR *Mercator,
  1220. long *lProj_size , char *errmsg)
  1221. #else
  1222. int inp2grib_Mercator (ppvGDS_Proj_Input, Mercator, lProj_size , errmsg)
  1223. void **ppvGDS_Proj_Input; MERCATOR *Mercator;
  1224. long *lProj_size ; char *errmsg;
  1225. #endif
  1226. {
  1227. /*
  1228. *
  1229. * F.1 INIT variables !default stat=good
  1230. */
  1231. mercator *ProjInp = 0;
  1232. int lTemp = 0;
  1233. int nStatus = 0;
  1234. char *func="inp2grib_PolarSt";
  1235. DPRINT1 ("\t Entering %s.....\n", func);
  1236. /*
  1237. *
  1238. * F.2 POINT local pProjInp to incoming ppvGDS_Proj_Input
  1239. */
  1240. ProjInp = ( mercator *) *ppvGDS_Proj_Input;
  1241. /*
  1242. *
  1243. * F.3 IF (true grib Mercator proj block OR input Polar block is null) THEN
  1244. * SET Status= 1
  1245. * RETURN;
  1246. * ENDIF
  1247. */
  1248. if (!Mercator || !ProjInp )
  1249. {
  1250. DPRINT1 ( "%s: Mercator or ProjInp is null\n", func);
  1251. sprintf(errmsg,"%s: Mercator or ProjInp is null\n", func);
  1252. nStatus= 1; goto BYE;
  1253. }
  1254. /*
  1255. *
  1256. * F.4 FILL local struct from pProjInp
  1257. */
  1258. /* convert cols to 2 chars */
  1259. set_bytes(ProjInp->cols, 2, Mercator->achNi);
  1260. /* convert rows to 2 chars */
  1261. set_bytes(ProjInp->rows, 2, Mercator->achNj);
  1262. /* convert first_lat to 3 chars */
  1263. set_bytes(ProjInp->first_lat, 3, Mercator->achLat1);
  1264. /* convert first_lon to 3 chars */
  1265. set_bytes(ProjInp->first_lon, 3, Mercator->achLon1);
  1266. Mercator->chRes_flag = ( unsigned char ) ProjInp->usRes_flag;
  1267. /* convert La2 to 3 chars */
  1268. set_bytes(ProjInp->La2, 3, Mercator->achLat2);
  1269. /* convert Lo2 to 3 chars */
  1270. set_bytes(ProjInp->Lo2, 3, Mercator->achLon2);
  1271. /* convert lLon_orient to 3 chars */
  1272. set_bytes(ProjInp->latin, 3, Mercator->achLatin);
  1273. /* convert zero fill */
  1274. Mercator->achZero1 = ( unsigned char ) ProjInp->usZero1;
  1275. Mercator->chScan_mode = ( unsigned char ) ProjInp->usScan_mode;
  1276. /* convert ulDx to 3 char */
  1277. set_bytes((int)(ProjInp->lon_inc + 0.5), 3, Mercator->achDi);
  1278. /* convert ulDy to 3chars */
  1279. set_bytes((int)(ProjInp->lat_inc + 0.5), 3, Mercator->achDj);
  1280. Mercator->chScan_mode = ( unsigned char ) ProjInp->usScan_mode;
  1281. /* 8 bytes of zero */
  1282. memset((void*) Mercator->achZero2, '\0', 8);
  1283. /*
  1284. *
  1285. * F.5 DEBUG print GRIB Projection block
  1286. */
  1287. DPRINT3("\t%s: achNi [%02d,%02d]\n",func,Mercator->achNi[0],Mercator->achNi[1]);
  1288. DPRINT3("\t%s: achNj [%02d,%02d]\n",func, Mercator->achNj[0],Mercator->achNj[1]);
  1289. DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n",func, Mercator->achLat1[0],
  1290. Mercator->achLat1[1], Mercator->achLat1[2]);
  1291. DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n",func, Mercator->achLon1[0],
  1292. Mercator->achLon1[1] , Mercator->achLon1[2]);
  1293. DPRINT2("\t%s: chRes_flag [%02d]\n",func, Mercator->chRes_flag);
  1294. DPRINT4("\t%s: achLatint [%02d,%02d,%02d]\n",func,
  1295. Mercator->achLatin[0], Mercator->achLatin[1], Mercator->achLatin[2]);
  1296. DPRINT4("\t%s: achDi [%02d,%02d,%02d]\n",func, Mercator->achDi[0],
  1297. Mercator->achDi[1], Mercator->achDi[2]);
  1298. DPRINT4("\t%s: achDj [%02d,%02d,%02d]\n",func, Mercator->achDj[0],
  1299. Mercator->achDj[1], Mercator->achDj[2]);
  1300. DPRINT5("\t%s: achZero2 [%02d,%02d,%02d,%02d]\n",func, Mercator->achZero2[0],
  1301. Mercator->achZero2[1], Mercator->achZero2[2], Mercator->achZero2[3]);
  1302. /*******/
  1303. /*
  1304. *
  1305. * F.7 STORE size of POLAR struct in lProj_size
  1306. */
  1307. *lProj_size = sizeof (MERCATOR);
  1308. BYE:
  1309. DPRINT3 (" Exiting %s (lProj_size=%ld), stat=%d\n", func,
  1310. *lProj_size, nStatus);
  1311. /*
  1312. *
  1313. * F.8 RETURN Stat ! 0 or 1
  1314. */
  1315. return ( nStatus );
  1316. /*
  1317. *
  1318. * END OF FUNCTION
  1319. *
  1320. *
  1321. */
  1322. }
  1323. /*
  1324. Old round--this is different from standard gnu round (gnu round returns a
  1325. float). Depending on compile options, sometimes gnu round was used, other
  1326. times this function was used. Removed and replaced by lrint by T. Hutchinson,
  1327. WSI. 4/14/05.
  1328. long round(double value)
  1329. {
  1330. long retval;
  1331. retval=lrint(value);
  1332. return retval;
  1333. }
  1334. */