void uka_jtin ( int njp, float jlat[], float jlon[], int nwp, float wlat[], float wlon[], float wspd [], float wlvl[], float wlvla[], float wlvlb[], int wtyp[], int *nop, float olat[], float olon[], float ospd[], float olvl[], float olvla[], float olvlb[], int *iret ) /************************************************************************ * uka_jtin * * * * This function puts the core points, the wind barb points and the * * hash points in the correct order, and gets the wind speed values * * for the hash marks. * * * * uka_jtin ( njp, jlat, jlon, nwp, wlat, wlon, wspd, wlvl, wlvla, * * wlvlb, wtyp, nop, olat, olon, ospd, olvl, olvla, olvlb, * * iret ) * * * * Input parameters: * * njp int Number of jet core points * * jlat[] float Latitudes of core points * * jlon[] float Longitudes of core points * * nwp int No. of wind (barb & hash) pts * * wlat[] float Latitudes of wind points * * wlon[] float Longitudes of wind points * * wspd[] float Speed of wind points (m/sec) * * wlvl[] float Flight level of wind pts (m) * * wlvla[] float Flight level above jet (m) * * wlvlb[] float Flight level below jet (m) * * wtyp[] int Wind point types * * 1 = wind barb point * * 2 = hash point * * * * Output parameters: * * *nop int Total number of points * * olat[] float Latitudes of points * * olon[] float Longitudes of points * * ospd[] float Speed of points (m/sec) * * olvl[] float Flight levels of points (m) * * olvla[] float Flight level above jet (m) * * olvlb[] float Flight level below jet (m) * * *iret int Return code * * 0 = normal return * * 15 = curve fit problem * ** * * Log: * * M. Li/SAIC 02/04 Extracted from sig_jets * * M. Li/SAIC 04/04 Added flight level above/below jet * * M. Li/SAIC 05/04 Copied from sig_jtin * * M. Li/SAIC 07/04 Added olvl to UKA_JTSP * * M. Li/SAIC 01/06 Added CED projection * ***********************************************************************/ { int ii, ier; char proj[8]; float minlat, maxlat, lllat, lllon, urlat, urlon; float angle1, angle2, angle3; float dens, crvscl; float px[MAXPTS], py[MAXPTS], qx[MAXPTS], qy[MAXPTS], tx[MAXPTS], ty[MAXPTS]; int otyp[MAXPTS]; int widx[MAXPTS]; /*---------------------------------------------------------------------*/ *iret = 0; dens = 5.0F; crvscl = 30.0F; *nop = MAXPTS; minlat = 9999.0F; maxlat = -9999.0F; for ( ii = 0; ii < njp; ii++ ) { minlat = G_MIN ( minlat, jlat[ii] ); maxlat = G_MAX ( maxlat, jlat[ii] ); } if ( minlat >= 0.0F ) { /* * Use North STR projection. */ strcpy ( proj, "STR" ); angle1 = 90.0F; angle2 = -90.0F; angle3 = 0.0F; lllat = -15.0F; lllon = -135.0F; urlat = -15.0F; urlon = -135.0F; } else if (maxlat < 0.0F ) { /* * Use South STR projection. */ strcpy ( proj, "STR" ); angle1 = -90.0F; angle2 = -90.0F; angle3 = 0.0F; lllat = 15.0F; lllon = -135.0F; urlat = 15.0F; urlon = -135.0F; } else { /* * Use CED projection. */ strcpy ( proj, "CED" ); angle1 = 0.0F; angle2 = 0.0F; angle3 = 0.0F; lllat = -90.0F; lllon = -180.0F; urlat = 90.0F; urlon = 180.0F; } gsmprj ( proj, &angle1, &angle2, &angle3, &lllat, &lllon, &urlat, &urlon, &ier, strlen(proj) ); gtrans ( sys_M, sys_D, &njp, jlat, jlon, px, py, &ier, strlen(sys_M), strlen(sys_D) ); gtrans ( sys_M, sys_D, &nwp, wlat, wlon, qx, qy, &ier, strlen(sys_M), strlen(sys_D) ); cgr_insert ( px, py, njp, qx, qy, nwp, dens, crvscl, tx, ty, nop, widx, &ier ); if ( ier != 0 ) { *iret = 15; } else { gtrans ( sys_D, sys_M, nop, tx, ty, olat, olon, &ier, strlen(sys_D), strlen(sys_M) ); for ( ii = 0; ii < *nop; ii++) { olvl[ii] = SIGRLMS; olvla[ii] = SIGRLMS; olvlb[ii] = SIGRLMS; ospd[ii] = SIGRLMS; otyp[ii] = ILINE; } for ( ii = 0; ii < nwp; ii++ ) { ospd[widx[ii]] = wspd[ii]; olvl[widx[ii]] = wlvl[ii]; olvla[widx[ii]] = wlvla[ii]; olvlb[widx[ii]] = wlvlb[ii]; otyp[widx[ii]] = wtyp[ii]; } /* * Calculate wind speed for hash marks. */ uka_jtsp ( *nop, otyp, ospd, olvl, &ier ); } }
void cgr_segdist ( int *np, float *xx, float *yy, float *fx, float *fy, float *distance, int *nearest_vrt, int *next_vrt, float *nx, float *ny, int *iret ) /************************************************************************ * cgr_segdist * * * * This function determines the nearest and next vertices of a * * multipoint line to a fixed point, the closest point (on the line * * segment defined by those two vertices) to the fixed point, and the * * distance between the fixed point and the closest point. * * The "next vertex" is simply the vertex following the nearest vertex * * in the order of the points, not the next closest vertex to the fixed * * point. * * * * cgr_segdist ( np, xx, yy, fx, fy, distance, nearest_vrt, next_vrt, * * nx, ny, iret ) * * * * Input parameters: * * *np int Number of points in figure * * *xx float X coordinates of figure * * *yy float Y coordinates of figure * * *fx float X coordinate of fixed point * * *fy float Y coordinate of fixed point * * * * Output parameters: * * *distance float Distance to the point * * *nearest_vrt int Closest vertex number * * *next_vrt int Other end of nearest segment * * *nx float Nearest x coord on figure * * *ny float Nearest y coord on figure * * *iret int Status return * * 0 = great, 1 = not a line * * * ** * * Log: * * E. Safford/GSC 02/98 copied cgr_dist * * E. Safford/GSC 05/98 add G_NINT to handle rounding problem * * E. Safford/GSC 07/98 add equal condition to horiz & vert * * T. Piper/GSC 10/98 Prolog update * * S. Law/GSC 03/99 clean up and commentary * * W.D.Plummer/NCEP 12/02 make all inputs pointers * * W.D.Plummer/NCEP 02/03 expand documenation in prologue * ***********************************************************************/ { int ii; float qx, qy, curr_dist, d0, d1, m2, m1, b2, b1; float xmin, xmax, ymin, ymax; /*---------------------------------------------------------------------*/ if (*np == 1) { *iret = 1; *nearest_vrt = *next_vrt = 0; *nx = xx[0]; *ny = yy[0]; *distance = (float) G_DIST (xx[0], yy[0], *fx, *fy); return; } *iret = 0; *distance = FLT_MAX; /* * Isolate which line segment is closest to desired point. */ for (ii = 0; ii < *np-1; ii++ ) { xmin = (float) G_MIN (xx[ii], xx[ii+1]); xmax = (float) G_MAX (xx[ii], xx[ii+1]); ymin = (float) G_MIN (yy[ii], yy[ii+1]); ymax = (float) G_MAX (yy[ii], yy[ii+1]); /* * Must find the closest point on vertical and horiztonal * seperately since the slope formula would cause a * divide by zero error */ /* * Vertical segments */ if (G_DIFF(xmin, xmax)) { qx = xmin; if (*fy < ymin) qy = ymin; else if (*fy > ymax) qy = ymax; else qy = *fy; } /* * Horizontal segments */ else if ( G_DIFF(ymin, ymax) ) { qy = ymin; if (*fx < xmin) qx = xmin; else if (*fx > xmax) qx = xmax; else qx = *fx; } /* * All the rest */ else { /* * find slope and intercept for initial line */ m1 = (yy[ii+1] - yy[ii]) / (xx[ii+1] - xx[ii]); b1 = yy[ii] - (m1 * xx[ii]); /* * find slope and intercept for perpendicular */ m2 = - 1.0F / m1; b2 = *fy - (m2 * *fx); /* * find the intersection of the two lines * which would be the closest point * * formula for a line is y = mx + b * y = (m1 * x) + b1 && y = (m2 * x) + b2 * (m1 * x) + b1 = (m2 * x) + b2 * (m1 * x) - (m2 * x) = (b2 - b1) * x * (m1 - m2) = (b2 - b1) * x = (b2 - b1) / (m1 - m2) */ qx = (b2 - b1) / (m1 - m2); qy = (m2 * qx) + b2; } /* * find the distance */ if (xmin <= qx && qx <= xmax) { curr_dist = (float) G_DIST (*fx, *fy, qx, qy); } else { d0 = (float) G_DIST (*fx, *fy, xx[ii], yy[ii]); d1 = (float) G_DIST (*fx, *fy, xx[ii+1], yy[ii+1]); curr_dist = (d0 <= d1) ? d0 : d1; } if (curr_dist < *distance) { *distance = curr_dist; *nx = qx; *ny = qy; /* * Figure which end of segment is closest to point. */ d0 = (float) G_DIST (*fx, *fy, xx[ii], yy[ii]); d1 = (float) G_DIST (*fx, *fy, xx[ii+1], yy[ii+1]); if (d0 < d1) { *nearest_vrt = ii; *next_vrt = ii + 1; } else { *nearest_vrt = ii + 1; *next_vrt = ii; } if ((*nx < xmin) || (xmax < *nx)) { *nx = xx[*nearest_vrt]; *ny = yy[*nearest_vrt]; } } } }
int main (int argc , char **argv) /************************************************************************ * main * * * * Main program of createbinfo. * * * * Output (from printf) must be re-directed to the proper info file * * within the script. * * * * main(argc, argv) * * * * Input parameters: * * argc int number of parameters of command line * * argv char** parameter array of command line * * * * Output parameters: * * Return parameters: * * NONE * * * ** * * Log: * * D.W.Plummer/NCEP 12/98 * * T. Piper/GSC 8/00 Modified for new generic boundary info * * D.W.Plummer/NCEP 6/05 Incr accuracy from 2 decimal digits to 4* ***********************************************************************/ { char buff[256], id[7], name[64]; int i, ier, ilat, ilon, k, length, nparts, nptot, npts, num, pst; float fltptr[20], lat1, lat2, lon1, lon2, minlat, minlon, maxlat, maxlon; FILE *fp; long lpos, lposp; Bnd_t boundary; /*---------------------------------------------------------------------*/ /* * Print out the name of the BOUNDARY file. */ boundary.filename = (char *)malloc( sizeof(char) * strlen(argv[1]) + 1); strcpy ( boundary.filename, argv[1] ); printf("!\n! BOUNDARIES FILENAME \n%s\n!\n", boundary.filename ); fp = (FILE *)cfl_tbop ( boundary.filename, "bounds", &ier ); /* * Allocate and initialize boundary location structure */ boundary.nbnd = 0; boundary.bound = (BInfo_t *)malloc(MAX_BOUNDS*sizeof(BInfo_t)); for ( i = 0; i < MAX_BOUNDS; i++ ) { boundary.bound[i].name = (char *)malloc( sizeof(char) * MAX_NAMELEN + 1); boundary.bound[i].name[0] = '\0'; boundary.bound[i].info = (char *)malloc( sizeof(char) * MAX_NAMELEN + 1); boundary.bound[i].info[0] = '\0'; boundary.bound[i].strec = 0; boundary.bound[i].cenlat = RMISSD; boundary.bound[i].cenlon = RMISSD; boundary.bound[i].minlat = RMISSD; boundary.bound[i].minlon = RMISSD; boundary.bound[i].maxlat = RMISSD; boundary.bound[i].maxlon = RMISSD; boundary.bound[i].nparts = 0; } cfl_wher ( fp, &lpos, &ier ); cfl_trln ( fp, sizeof(buff), buff, &ier ); if ( ier == 0 ) { sscanf ( buff, "%s %s %d %d %d", id, name, &ilat, &ilon, &nparts ); boundary.bound[0].bndspt = (Bndsprt_t *)malloc(nparts*sizeof(Bndsprt_t)); /* Read the second header line */ cfl_trln ( fp, sizeof(buff), buff, &ier ); strcpy ( boundary.bound[0].info, buff); for ( k = 0; k < nparts; k++ ) { cfl_wher ( fp, &lposp, &ier ); cfl_trln ( fp, sizeof(buff), buff, &ier ); sscanf ( buff, "%d %f %f %f %f", &npts, &lat1, &lat2, &lon1, &lon2 ); boundary.bound[0].bndspt[k].minlat = G_MIN ( lat1, lat2 ); boundary.bound[0].bndspt[k].maxlat = G_MAX ( lat1, lat2 ); boundary.bound[0].bndspt[k].minlon = G_MIN ( lon1, lon2 ); boundary.bound[0].bndspt[k].maxlon = G_MAX ( lon1, lon2 ); boundary.bound[0].bndspt[k].strec = lposp; boundary.bound[0].bndspt[k].npts = npts / 2; cst_rxbl ( buff, buff, &length, &ier ); cst_rlst ( buff, ' ', RMISSD, (int) (sizeof(fltptr)/sizeof(float)), fltptr, &num, &ier); nptot = ( num - 5 ); while ( ier == 0 && nptot < npts ) { cfl_trln ( fp, sizeof(buff), buff, &ier ); if ( ier == 0 ) { cst_rxbl ( buff, buff, &length, &ier ); cst_rlst ( buff, ' ', RMISSD, sizeof(fltptr)/sizeof(float), fltptr, &num, &ier); nptot += num; } /* Loop over all points in one part */ } } /* Loop over all parts in one bound */ if ( ier == 0 ) { strcpy ( boundary.bound[0].name, name ); boundary.bound[0].strec = lpos; boundary.bound[0].cenlat = ilat / 100.0; boundary.bound[0].cenlon = ilon / 100.0; boundary.bound[0].nparts = nparts; boundary.nbnd++; } } while ( ier == 0 ) { cfl_wher ( fp, &lpos, &ier ); cfl_trln ( fp, sizeof(buff), buff, &ier ); if ( ier == 0 ) { boundary.nbnd++; pst = boundary.nbnd - 1; sscanf ( buff, "%s %s %d %d %d", id, name, &ilat, &ilon, &nparts ); strcpy ( boundary.bound[pst].name, name ); boundary.bound[pst].strec = lpos; boundary.bound[pst].cenlat = ilat / 100.0; boundary.bound[pst].cenlon = ilon / 100.0; boundary.bound[pst].nparts = nparts; /* Read the second header line */ cfl_trln ( fp, sizeof(buff), buff, &ier ); strcpy ( boundary.bound[pst].info, buff); boundary.bound[pst].bndspt = (Bndsprt_t *)malloc(nparts*sizeof(Bndsprt_t)); for ( k = 0; k < nparts; k++ ) { cfl_wher ( fp, &lposp, &ier ); cfl_trln ( fp, sizeof(buff), buff, &ier ); sscanf ( buff, "%d %f %f %f %f", &npts, &lat1, &lat2, &lon1, &lon2 ); boundary.bound[pst].bndspt[k].minlat = G_MIN(lat1,lat2); boundary.bound[pst].bndspt[k].maxlat = G_MAX(lat1,lat2); boundary.bound[pst].bndspt[k].minlon = G_MIN(lon1,lon2); boundary.bound[pst].bndspt[k].maxlon = G_MAX(lon1,lon2); boundary.bound[pst].bndspt[k].strec = lposp; boundary.bound[pst].bndspt[k].npts = npts / 2; cst_rxbl( buff, buff, &length, &ier ); cst_rlst( buff, ' ', RMISSD, (int) (sizeof(fltptr)/sizeof(float)), fltptr, &num, &ier); nptot = ( num - 5 ); while ( ier == 0 && nptot < npts ) { cfl_trln ( fp, sizeof(buff), buff, &ier ); if ( ier == 0 ) { cst_rxbl ( buff, buff, &length, &ier ); cst_rlst ( buff, ' ', RMISSD, sizeof(fltptr)/sizeof(float), fltptr, &num, &ier); nptot += num; } } } } } boundary.maxpts = 0; for ( i = 0; i < boundary.nbnd; i++ ) { minlat = 90.0; minlon = 360.0; maxlat = -90.0; maxlon = -360.0; for ( k = 0; k < boundary.bound[i].nparts; k++ ) { minlat=G_MIN ( minlat, boundary.bound[i].bndspt[k].minlat ); minlon=G_MIN ( minlon, boundary.bound[i].bndspt[k].minlon ); maxlat=G_MAX ( maxlat, boundary.bound[i].bndspt[k].maxlat ); maxlon=G_MAX ( maxlon, boundary.bound[i].bndspt[k].maxlon ); boundary.maxpts = G_MAX ( boundary.maxpts, boundary.bound[i].bndspt[k].npts ); } boundary.bound[i].minlat = minlat; boundary.bound[i].minlon = minlon; boundary.bound[i].maxlat = maxlat; boundary.bound[i].maxlon = maxlon; } /* * Print out number of bounds. */ printf("! TOTAL NUMBER OF BOUNDS\n%d\n!\n", boundary.nbnd ); printf("! MAX NUMBER OF POINTS per BOUND\n%d\n!\n", boundary.maxpts ); printf("! BOUNDARY STRUCTURE INFORMATION\n!\n" ); /* * Dump the information. */ for ( i = 0; i < boundary.nbnd; i++ ) { printf("!\n%-s %-12ld %-.2f %-.2f %-.2f %-.2f %-.2f %-.2f %-5d\n", boundary.bound[i].name, boundary.bound[i].strec, boundary.bound[i].cenlat, boundary.bound[i].cenlon, boundary.bound[i].minlat, boundary.bound[i].minlon, boundary.bound[i].maxlat, boundary.bound[i].maxlon, boundary.bound[i].nparts ); printf("%s\n", boundary.bound[i].info); for ( k = 0; k < boundary.bound[i].nparts; k++ ) { printf("\t%-12ld %-.2f %-.2f %-.2f %-.2f %-8d \n", boundary.bound[i].bndspt[k].strec, boundary.bound[i].bndspt[k].minlat, boundary.bound[i].bndspt[k].minlon, boundary.bound[i].bndspt[k].maxlat, boundary.bound[i].bndspt[k].maxlon, boundary.bound[i].bndspt[k].npts ); } } return(0); }
void cvg_allocGfaBlock ( VG_DBStruct *el ) /************************************************************************ * cvg_allocGfaBlock * * * * This function allocates a new block for the GFA element. * * * * cvg_allocGfaBlock ( el ) * * * * Input parameters: * * *el VG_DBStruct Pointer to the VG record * * * * Output parameters: * * None * * * ** * * Log: * * J. Wu/SAIC 10/04 initial coding * ***********************************************************************/ { int nblks, blk_size, ii; /*---------------------------------------------------------------------*/ /* * If not GFA element or all block pointers are used, do nothing. */ if ( el->hdr.vg_type != GFA_ELM || el->elem.gfa.info.nblocks >= MAX_GFA_BLOCKS ) { return; } /* * Calculate the size of a single block. */ blk_size = sizeof(char) * STD_STRLEN; /* * Allocate memory for one more block. */ nblks = G_MAX ( el->elem.gfa.info.nblocks, 0 ); el->elem.gfa.info.blockPtr[nblks] = malloc ( blk_size ); if ( !el->elem.gfa.info.blockPtr[nblks] ) { return; } /* * Increase the number of blocks by 1. */ el->elem.gfa.info.nblocks = nblks + 1; /* * Initialize the new space to all '\0'. */ memset ( el->elem.gfa.info.blockPtr[nblks], '\0', (size_t)STD_STRLEN ); /* * Initialize all unused block pointers to NULL. */ for ( ii = el->elem.gfa.info.nblocks; ii < MAX_GFA_BLOCKS; ii++ ) { el->elem.gfa.info.blockPtr[ii] = NULL; } /* * Update the element's record size in the header. */ el->hdr.recsz = sizeof(VG_HdrStruct) + sizeof(int) * 2 + el->elem.gfa.info.nblocks * blk_size + el->elem.gfa.info.npts * sizeof(float) * 2; }
/* ARGSUSED */ static void _pgmvcp_elDropEh ( Widget w, XtPointer clnt, XEvent *event, Boolean *ctdr ) /************************************************************************ * _pgmvcp_elDropEh * * * * This function is the callback for a drop on a selected element. * * * * static void _pgmvcp_elDropEh (w, clnt, event, ctdr) * * * * Input parameters: * * w Widget Parent widget * * clnt XtPointer State information record * * *event XEvent Button press event record * * * ** * * Log: * * E. Safford/GSC 06/97 Modified to handle Special Text * * E. Wehner/EAi 07/97 Remove offsets when replacing text. * * E. Safford/GSC 07/97 Fixed drag with special text problem * * E. Wehner/EAi 08/97 Remove watch box slide * * C. Lin/EAI 8/97 Add offsets for 'S' coord(roam) * * D.W.Plummer/NCEP 9/97 Combine into NxmDraw for new vgstruct.h * * E. Wehner/EAi 9/97 Remove graphics info record * * C. Lin/EAi 10/97 rename from NxmDrSlDropCb, cleanup * * C. Lin/EAi 10/97 add WBOX_ELEM related functions * * C. Lin/EAi 11/97 further cleanup * * E. Safford/GSC 02/98 add _storedEl for undo function * * S. Law/GSC 04/98 added copy function * * E. Safford/GSC 04/98 added FUNC_SELECT to FUNC_MOVE ops * * S. Law/GSC 05/98 cleaned up drag, added group box * * E. Safford/GSC 05/98 mod for new undo routines * * E. Safford/GSC 05/98 move to nmap_pgmvcp.c * * E. Safford/GSC 06/98 split from mvcpDrop.c * * G. Krueger/EAI 06/98 Uniform status hints * * E. Safford/GSC 07/98 reset _dcN for closed figures * * C. Lin/EAI 08/98 fix ghosting problem & reset _dragCount * * G. Krueger/EAI 09/98 Added ghost veiling * * G. Krueger/EAI 10/98 Using table for hints * * E. Safford/GSC 12/98 modify refresh to limit area affected * * D.W.Plummer/NCEP 4/99 remove call to pgwlst_update * * E. Safford/GSC 11/00 wipe the county list for watches * * H. Zeng/EAI 11/00 changed for the new undo design * * H. Zeng/EAI 11/00 changed cvg_rdrec() parameters * * A. Hardy/GSC 11/00 renamed coordinate system declaration * * H. Zeng/EAI 12/00 modified for multiple undo steps * * J. Wu/SAIC 12/01 add layer in crg_set() call * * J. Wu/SAIC 01/02 add layer in crg_get() call * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * J. Wu/SAIC 11/03 adjust jet barb/hash position * * J. Wu/SAIC 02/04 adjust gfa attribute box position * * J. Wu/SAIC 07/04 add filter param. to crg_get() * * J. Wu/SAIC 07/04 free GFA block memory * * B. Yin/SAIC 02/05 add a call to snap for GFA * * E. Safford/SAIC 06/05 allow smear to get smaller on edit * * S. Danz/AWC 07/06 Added new cvg_delet placement argument * * S. Danz/AWC 08/06 New flag to pgvgf_saveNewElm to place el* * S. Danz/AWC 08/06 Updated to use cvg_checkplace to find * * area impacted and call crg_rebuild() * * S. Danz/AWC 02/07 Add logic to update GFA centroid * * L. Hinson/AWC 07/09 Add code to update CCF centroid * ***********************************************************************/ { int location, ier, currfunc, new_location, num, layer, el_layer; int found, update_crg, one = 1; float llx, lly, urx, ury; float x_cntr, y_cntr, c_lat, c_lon, area; float o_llx, o_lly, o_urx, o_ury, inf_bbox[4]; char value[32]; VG_DBStruct el, del_el; filter_t filter; /*---------------------------------------------------------------------*/ _dragCount = 0; mcanvw_disarmDrag(); mcanvw_disarmDrop(); if ( _wboxElm ) { pgwpts_setSnap (TRUE); _pgmvcp_wboxCalc ( ); } pggst_clearGhost(TRUE); if (!_midDrag) return; _midDrag = FALSE; update_crg = 0; currfunc = pgpalw_getCurOperId(); pgundo_newStep(); location = pgactv_getElmLoc(); cvg_rdrec(cvg_getworkfile(), location, &el, &ier); crg_getinx (location, &num, &ier); crg_get (num, &el_layer, filter, &o_llx, &o_lly, &o_urx, &o_ury, &ier); pghdlb_deselectEl (location, FALSE); if ((currfunc == FUNC_MOVE) || (currfunc == FUNC_SELECT)) { /* * Mark elements in placement that are effected by * the delete, and get the area of influence back */ cvg_rdrec(cvg_getworkfile(), location, &del_el, &ier); cvg_checkplace(&del_el, 1, location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ o_llx = G_MIN(o_llx, inf_bbox[0]); o_lly = G_MIN(o_lly, inf_bbox[2]); o_urx = G_MAX(o_urx, inf_bbox[1]); o_ury = G_MAX(o_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( del_el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &del_el ); } else if ( del_el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &del_el ); } /* * delete old element */ cvg_delet (cvg_getworkfile(), location, TRUE, &ier); crg_clear (num, &ier); pgundo_storeThisLoc(location, UNDO_DEL, &ier); } if ( el.hdr.vg_type == WBOX_ELM ) { pgwbxw_getAnchor ( 0, el.elem.wbx.info.w_a0id, &el.elem.wbx.info.w_a0lt, &el.elem.wbx.info.w_a0ln, &el.elem.wbx.info.w_a0dis, el.elem.wbx.info.w_a0dir, &ier ); pgwbxw_getAnchor ( 1, el.elem.wbx.info.w_a1id, &el.elem.wbx.info.w_a1lt, &el.elem.wbx.info.w_a1ln, &el.elem.wbx.info.w_a1dis, el.elem.wbx.info.w_a1dir, &ier ); /* * Wipe the county list */ el.elem.wbx.info.numcnty = 0; } /* * adjust jet barb/hash position accordingly */ if ( el.hdr.vg_type == JET_ELM ) { _pgmvcp_jetCalc ( &el, 0, 0, False ); } if ( el.hdr.vg_type == SIGCCF_ELM ) { _pgmvcp_ccfCalc ( &el, 0, 0, False ); gtrans ( sys_D, sys_M, &_dcN, _dcX, _dcY, &(el.elem.ccf.latlon[0]), &(el.elem.ccf.latlon[_dcN]), &ier, strlen(sys_D), strlen(sys_M) ); _dcN = el.elem.ccf.info.npts; cvg_todev ( &el, &_dcN, _dcX, _dcY, &ier ); if ( el.hdr.closed ) { cgr_centroid ( _dcX, _dcY, &_dcN, &x_cntr, &y_cntr, &area, &ier ); } else { x_cntr = _dcX[0] ; y_cntr = _dcY[0] ; } gtrans( sys_D, sys_M, &one, &x_cntr, &y_cntr, &c_lat, &c_lon, &ier, strlen(sys_D), strlen(sys_M) ); el.elem.ccf.info.arrowlat = c_lat; el.elem.ccf.info.arrowlon = c_lon; } /* * adjust GFA attribute box position accordingly */ if ( el.hdr.vg_type == GFA_ELM ) { _pgmvcp_gfaCalc ( &el, 0, 0, False ); gtrans ( sys_D, sys_M, &_dcN, _dcX, _dcY, &(el.elem.gfa.latlon[0]), &(el.elem.gfa.latlon[_dcN]), &ier, strlen(sys_D), strlen(sys_M) ); pgsmear_snapEl ( FALSE, &el, &ier ); _dcN = el.elem.gfa.info.npts; cvg_todev( &el, &_dcN, _dcX, _dcY, &ier ); if ( pggfaw_isClosed() ) { cgr_centroid( _dcX, _dcY, &_dcN, &x_cntr, &y_cntr, &area, &ier ); } else { x_cntr = _dcX[ 0 ]; y_cntr = _dcY[ 0 ]; } gtrans( sys_D, sys_M, &one, &x_cntr, &y_cntr, &c_lat, &c_lon, &ier, strlen(sys_D), strlen(sys_M) ); sprintf ( value, "%7.2f", c_lat ); cvg_setFld ( &el, TAG_GFA_ARROW_LAT, value, &ier ); sprintf ( value, "%7.2f", c_lon ); cvg_setFld ( &el, TAG_GFA_ARROW_LON, value, &ier ); } /* * save new element */ pgvgf_saveNewElm(NULL, sys_D, &el, _dcN, _dcX, _dcY, FALSE, &new_location, &ier); pgundo_storeThisLoc (new_location, UNDO_ADD, &ier); pgundo_endStep(); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } cvg_rdrec(cvg_getworkfile(), new_location, &el, &ier); layer = pglayer_getCurLayer( ); crg_set (&el, new_location, layer, &ier); pgactv_setActvElm (&el, new_location); crg_getinx (new_location, &num, &ier); crg_get(num, &el_layer, filter, &llx, &lly, &urx, &ury, &ier); if (o_llx < llx) llx = o_llx; if (o_lly < lly) lly = o_lly; if (o_urx > urx) urx = o_urx; if (o_ury > ury) ury = o_ury; /* * Mark elements in placement that are effected by * the new element, and get the area of influence back */ cvg_checkplace(&el, 0, new_location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ llx = G_MIN(llx, inf_bbox[0]); lly = G_MIN(lly, inf_bbox[2]); urx = G_MAX(urx, inf_bbox[1]); ury = G_MAX(ury, inf_bbox[3]); update_crg = 1; } xpgpaste (llx, lly, urx, ury, &ier); cvg_rfrsh (NULL, llx, lly, urx, ury, &ier); /* * If we may have impacted other elements with placement * we will need to rebuild the range records */ if (update_crg) { crg_rebuild(); } pghdlb_select (&el, new_location); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } mbotw_mouseSet(LMHINT_DRAG, MMHINT_DONE); }
/* ARGSUSED */ static void _pgmvcp_groupDropEh ( Widget w, XtPointer clnt, XEvent *event, Boolean *ctdr ) /************************************************************************ * _pgmvcp_groupDropEh * * * * This function is the callback for a drop on a group. * * * * static void _pgmvcp_groupDropEh (w, clnt, event, ctdr) * * * * Input parameters: * * w Widget Parent widget * * clnt XtPointer State information record * * *event XEvent Button press event record * * * ** * * Log: * * E. Safford/GSC 06/97 Modified to handle Special Text * * E. Wehner/EAi 07/97 Remove offsets when replacing text. * * E. Safford/GSC 07/97 Fixed drag with special text problem * * E. Wehner/EAi 08/97 Remove watch box slide * * C. Lin/EAI 8/97 Add offsets for 'S' coord(roam) * * D.W.Plummer/NCEP 9/97 Combine into NxmDraw for new vgstruct.h * * E. Wehner/EAi 9/97 Remove graphics info record * * C. Lin/EAi 10/97 rename from NxmDrSlDropCb, cleanup * * C. Lin/EAi 10/97 add WBOX_ELEM related functions * * C. Lin/EAi 11/97 further cleanup * * E. Safford/GSC 02/98 add _storedEl for undo function * * S. Law/GSC 04/98 added copy function * * E. Safford/GSC 04/98 added FUNC_SELECT to FUNC_MOVE ops * * S. Law/GSC 05/98 cleaned up drag, added group box * * E. Safford/GSC 05/98 mod for new undo routines * * E. Safford/GSC 05/98 move to nmap_pgmvcp.c * * E. Safford/GSC 06/98 split from mvcpDrop.c * * E. Safford/GSC 06/98 added call to cgr_grfrsh.c * * G. Krueger/EAI 06/98 Uniform status hints * * C. Lin/EAI 08/98 fix ghosting problem & reset _dragCount * * G. Krueger/EAI 09/98 Added ghost veiling * * G. Krueger/EAI 10/98 Using table for hints * * E. Safford/GSC 12/98 modify refresh to limit area affected * * D.W.Plummer/NCEP 4/99 remove call to pgwlst_update * * E. Safford/GSC 10/99 update for new xwcmn.h * * S. Law/GSC 06/00 changed to use xgtoff * * H. Zeng/EAI 11/00 changed for the new undo design * * H. Zeng/EAI 11/00 changed cvg_rdrec() parameters * * A. Hardy/GSC 11/00 renamed coordinate system declarations * * H. Zeng/EAI 12/00 modified for multiple undo steps * * J. Wu/SAIC 12/01 add layer in crg_set() call * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * J. Wu/SAIC 11/03 adjust jet barb/hash position * * J. Wu/SAIC 02/04 adjust gfa attribute box position * * J. Wu/SAIC 10/04 free GFA block memory * * S. Danz/AWC 07/06 Added new cvg_delet placement argument * * S. Danz/AWC 08/06 New flag to pgvgf_saveNewElm to place el* * S. Danz/AWC 08/06 Updated to use cvg_checkplace to find * * area impacted and call crg_rebuild() * ***********************************************************************/ { int location, ier, nelm, ii, jj, *inxarry, layer, update_crg; int currfunc, newnum, old_location, xoff, yoff, found; float llx, lly, urx, ury, delx, dely; float o_llx, o_lly, o_urx, o_ury, inf_bbox[4]; char newtyp; VG_DBStruct el, del_el; /*---------------------------------------------------------------------*/ _dragCount = 0; mcanvw_disarmDrag(); mcanvw_disarmDrop(); pggst_clearGhost(TRUE); if (!_midDrag) return; _midDrag = FALSE; update_crg = 0; currfunc = pgpalw_getCurOperId(); old_location = pgactv_getElmLoc(); cvg_rdrec(cvg_getworkfile(), old_location, &el, &ier); crg_ggnel(el.hdr.grptyp, el.hdr.grpnum, &nelm, &ier); if (nelm <= 0) return; inxarry = (int *)malloc(nelm*sizeof(int)); crg_gginx (el.hdr.grptyp, el.hdr.grpnum, nelm, inxarry, &nelm, &ier); newtyp = el.hdr.grptyp; newnum = el.hdr.grpnum; crg_ggbnd (newtyp, newnum, &o_llx, &o_urx, &o_ury, &o_lly, &ier); if (currfunc == FUNC_COPY) crg_ggnxt (el.hdr.grptyp, &newnum, &ier); /* * set "delta" amounts... */ xgtoff (&xoff, &yoff, &ier); delx = (float)event->xbutton.x + (float)xoff - _dragX; dely = (float)event->xbutton.y + (float)yoff - _dragY; _dragX += delx; _dragY += dely; delx = _dragX - _origX - _goffX; dely = _dragY - _origY - _goffY; pghdlb_deselectEl (old_location, FALSE); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } pgundo_newStep(); layer = pglayer_getCurLayer( ); for (ii = 0; ii < nelm; ii++) { crg_goffset(inxarry[ii], &location, &ier); cvg_rdrec(cvg_getworkfile(), location, &el, &ier); pgactv_setActvElm ( &el, location); pgactv_getDevPts (&_dcN, &_dcX, &_dcY); for (jj = 0; jj < _dcN; jj++) { pgactv_modPt (jj, *(_dcX + jj) + delx, *(_dcY + jj) + dely); } if ((currfunc == FUNC_MOVE) || (currfunc == FUNC_SELECT)) { /* * Mark elements in placement that are effected by * the delete, and get the area of influence back */ cvg_rdrec(cvg_getworkfile(), location, &del_el, &ier); cvg_checkplace(&del_el, 1, location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ o_llx = G_MIN(o_llx, inf_bbox[0]); o_lly = G_MIN(o_lly, inf_bbox[2]); o_urx = G_MAX(o_urx, inf_bbox[1]); o_ury = G_MAX(o_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( del_el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &del_el ); } else if ( del_el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &del_el ); } /* * delete old element */ cvg_delet (cvg_getworkfile(), location, TRUE, &ier); crg_clear (inxarry[ii], &ier); pgundo_storeThisLoc(location, UNDO_DEL, &ier); } /* * adjust jet barb/hash position accordingly */ if ( el.hdr.vg_type == JET_ELM ) { _pgmvcp_jetCalc ( &el, delx, dely, True ); } /* * adjust GFA attribute box position accordingly */ if ( el.hdr.vg_type == GFA_ELM ) { _pgmvcp_gfaCalc ( &el, delx, dely, True ); } /* * save new element */ el.hdr.grptyp = newtyp; el.hdr.grpnum = newnum; pgvgf_saveNewElm(NULL, sys_D, &el, _dcN, _dcX, _dcY, FALSE, &location, &ier); pgundo_storeThisLoc (location, UNDO_ADD, &ier); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } cvg_rdrec(cvg_getworkfile(), location, &el, &ier); crg_set (&el, location, layer, &ier); /* * Mark elements in placement that are effected by * the new element, and get the area of influence back */ cvg_checkplace(&el, 0, location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ o_llx = G_MIN(o_llx, inf_bbox[0]); o_lly = G_MIN(o_lly, inf_bbox[2]); o_urx = G_MAX(o_urx, inf_bbox[1]); o_ury = G_MAX(o_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } } /* for */ pgundo_endStep(); pgactv_setActvElm (&el, location); crg_ggbnd (newtyp, newnum, &llx, &urx, &ury, &lly, &ier); free (inxarry); o_llx -= EXTRA; o_lly -= EXTRA; o_urx += EXTRA; o_ury += EXTRA; if (o_llx < llx) llx = o_llx; if (o_lly < lly) lly = o_lly; if (o_urx > urx) urx = o_urx; if (o_ury > ury) ury = o_ury; xpgpaste (llx, lly, urx, ury, &ier); cvg_rfrsh (NULL, llx, lly, urx, ury, &ier); /* * If we may have impacted other elements with placement * we will need to rebuild the range records */ if (update_crg) { crg_rebuild(); } pghdlb_select (&el, location); mbotw_mouseSet(LMHINT_DRAG, MMHINT_DONE); }
void de_srng ( const char *uarg, char *stprm, int *iret ) /************************************************************************ * de_srng * * * * This subroutine computes the range of its scalar arguments among * * ensemble members. The range is the difference between the maximum * * and the minimum. * * * * de_srng ( uarg, stprm, iret ) * * * * Input and parameters: * * *uarg const char Function argument string * * * * Output parameters: * * *stprm char Substitution string * * *iret int Return code * * 0 = normal return * * -8 = cannot parse argument * * -9 = ensemble cannot computed * ** * * Log: * * R. Tian/SAIC 6/05 * * R. Tian/SAIC 1/06 Translated from Fortran * ************************************************************************/ { char tname[13], pdum[13], time1[21], time2[21]; int nsmax, nsmin, num, kxd, kyd, ksub1, ksub2, level1, level2, ivcord, nina, one, zero, i, j, ier; float *gnsmax, *gnsmin, *gnum, d1, d2, d3; /*----------------------------------------------------------------------*/ *iret = 0; one = 1; zero = 0; dg_ssub ( iret ); /* * Get new grid numbers for maximum and minimum fields. */ dg_nxts ( &nsmax, iret ); if ( *iret != 0 ) return; dg_nxts ( &nsmin, iret ); if ( *iret != 0 ) return; /* * Initialize the output grid. */ dg_getg ( &nsmax, &gnsmax, &kxd, &kyd, &ksub1, &ksub2, iret ); dg_getg ( &nsmin, &gnsmin, &kxd, &kyd, &ksub1, &ksub2, iret ); for ( i = ksub1 - 1; i < ksub2; i++ ) { gnsmax[i] = -FLT_MAX; gnsmin[i] = FLT_MAX; } /* * Set the number of input arguments. There is only one argument * for DE_SRNG. */ nina = 1; for ( i = 0; i < MXARGS; i++ ) { _ensdiag.allarg[i][0] = '\0'; } strcpy ( _ensdiag.allarg[0], uarg ); /* * Scan the allarg array. */ de_scan ( &nina, iret ); if ( *iret != 0 ) return; /* * Loop over number of members set by DE_SCAN. */ for ( i = 0; i < _ensdiag.nummbr; i++ ) { de_mset ( &i, iret ); dg_pfun ( _ensdiag.allarg[0], iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, " ", &ier, strlen("DG"), strlen(" ") ); *iret = -8; return; } dg_driv ( &one, iret ); if ( *iret != 0 ) { er_wmsg ( "DG", iret, _ensdiag.allarg[0], &ier, strlen("DG"), strlen(_ensdiag.allarg[0]) ); *iret = -9; return; } /* * Retrieve the output grid from the stack. Check that the * output is a scalar. */ dg_tops ( tname, &num, time1, time2, &level1, &level2, &ivcord, pdum, iret ); dg_getg ( &num, &gnum, &kxd, &kyd, &ksub1, &ksub2, iret ); /* * Compute the maximum and minimum. */ for ( j = ksub1 - 1; j < ksub2; j++ ) { d1 = gnum[j]; d2 = gnsmax[j]; d3 = gnsmin[j]; if ( ERMISS ( d1 ) ) { gnsmax[j] = RMISSD; gnsmin[j] = RMISSD; } else { if ( ! ERMISS ( d2 ) ) { gnsmax[j] = G_MAX ( d1, d2 ); } if ( ! ERMISS ( d2 ) ) { gnsmin[j] = G_MIN ( d1, d3 ); } } } dg_frig ( &num, &ier ); } /* * Compute the range. */ for ( i = ksub1 - 1; i < ksub2; i++ ) { d1 = gnsmax[i]; d2 = gnsmin[i]; if ( ERMISS ( d1 ) || ERMISS ( d2 ) ) { gnsmax[i] = RMISSD; } else { gnsmax[i] = d1 - d2; } } dg_frig ( &nsmin, &ier ); /* * Reset DGCMN.CMN and set internal grid identifier. */ de_rset ( iret ); dg_udig ( "EXX_", &nsmax, &zero, &_ensdiag.idgens, stprm, iret ); dg_esub ( &nsmax, &zero, &zero, &zero, &ier ); if ( ier != 0 ) *iret = ier; return; }
static int pgdel_deleteElms ( void ) /************************************************************************ * pgdel_deleteElms * * * * This function deletes all the currently selected elements. * * * * static void pgdel_deleteElms ( ) * * * * Input parameters: * * Output parameters: * * none * * * * Return: * * int number of deleted elements * ** * * Log: * * E. Safford/GSC 04/04 initial coding * * B. Yin/SAIC 08/04 Added code to free TCA memory * * B. Yin/SAIC 08/04 Changed pgtca_freeBkpts to cvg_freeBkpts* * J. Wu/SAIC 10/04 free GFA block pointers * * S. Danz/AWC 07/06 Added new cvg_delet placement argument * ***********************************************************************/ { int num = 0, ier = 0, found, update_crg; int grpnum = 0, ii = 0, nelm = 0; int curIndex = -1, selIndex = 0, selLoc = 0; int iret = 0, *inxarry = NULL, count = 0; char grptyp = '0'; float llx = 0, lly = 0, urx = 0, ury = 0, inf_bbox[4]; VG_DBStruct el; /*---------------------------------------------------------------------*/ pghdlb_getNextIndex( curIndex, &selIndex, &selLoc, &iret ); update_crg = 0; while ( iret >= 0 ) { /* * If this is the first deletion, start the undo step */ if( count == 0 ) { pgundo_newStep(); } crg_getinx(selLoc, &num, &ier); crg_ggrp (num, &grptyp, &grpnum, &ier); /* * If deleting _by_ group, process the whole group */ if (grptyp && grpnum && (grptyp == GRPTYP_COMSYM || grptyp == GRPTYP_CCF || pgpalw_getMode() == TYPE_GRP)) { crg_ggbnd (grptyp, grpnum, &llx, &urx, &ury, &lly, &ier); llx -= EXTRA; lly -= EXTRA; urx += EXTRA; ury += EXTRA; crg_ggnel(grptyp, grpnum, &nelm, &ier); inxarry = (int *)malloc(nelm*sizeof(int)); crg_gginx(grptyp, grpnum, nelm, inxarry, &nelm, &ier); for ( ii = 0; ii < nelm; ii++ ) { /* * Mark elements in placement that are effected by * the delete, and get the area of influence back */ cvg_rdrec ( cvg_getworkfile(), selLoc, &el, &ier ); cvg_checkplace(&el, 1, selLoc, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by placement is bigger */ llx = G_MIN(llx, inf_bbox[0]); lly = G_MIN(lly, inf_bbox[2]); urx = G_MAX(urx, inf_bbox[1]); ury = G_MAX(ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA break point/GFA block memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } crg_goffset(inxarry[ii], &selLoc, &ier); pgundo_storeThisLoc(selLoc, UNDO_DEL, &ier); cvg_delet(cvg_getworkfile(), selLoc, TRUE, &ier); count++; crg_clear (inxarry[ii], &ier); } free(inxarry); xpgpaste(llx, lly, urx, ury, &ier); /* * The deleted elements are deselected here so we won't * try to process them again in the outer while loop. */ pghdlb_deselectEl (num, TRUE); cvg_rfrsh(NULL, llx, lly, urx, ury, &ier); } else { /* non-group mode */ pgutls_prepNew (selLoc, &el, &llx, &lly, &urx, &ury, &ier); pgundo_storeThisLoc(selLoc, UNDO_DEL, &ier); /* * Free TCA break point/GFA block memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } count++; } /* * Check for the next selected element */ curIndex = selIndex; pghdlb_getNextIndex( curIndex, &selIndex, &selLoc, &iret ); } if( count > 0 ) { pgundo_endStep(); pglayer_setChngMade( pglayer_getCurLayer(), TRUE ); pgactv_clearActv(); } /* * If we may have impacted other elements with placement * we will need to rebuild the range records */ if (update_crg) { crg_rebuild(); } return ( count ); }
void clo_from ( int vgtype, int reorder, int npin, int flag, float *lat, float *lon, int maxchar, char *str, int *iret ) /************************************************************************ * clo_from * * * * This function returns a "from" line given a series of lat-lon * * coordinates. The format of the "from" line is determined by vgtype. * * The parameter reorder is an indicator whether the points consist of * * an area which is closed and the points should be re-ordered in a * * clockwise fashion, if necessary, and that the first point listed in * * the "from" line is the northernmost point. The flag parameter * * indicates whether lat-lon coordinates in International SIGMETs are to* * be formatted with direction prepended (flag==0) or with direction * * postpended (flag==1) or as VOR (flag==2). * * * * clo_from ( vgtype, reorder, npin, flag, lat, lon, maxchar, * * str, iret ) * * * * Input parameters: * * vgtype int VG type of "from" line * * reorder int VG reorder of "from" line * * npin int Number of points * * flag int Flag for coordinate format * * *lat float Latitudes * * *lon float Longitudes * * maxchar int Maximum number of chars in str * * * * Output parameters: * * *str char "From" line string * * *iret int Return value * * = 0 - OK * * * ** * * Log: * * D.W.Plummer/NCEP 7/99 Create * * D.W.Plummer/NCEP 8/99 Add CONVSIG, NCONVSIG, CONVOLK & AIRMET * * D.W.Plummer/NCEP 9/99 Sort area types northernmost & clockwise* * M. Li/GSC 10/99 Modified clo_direct and clo_compass code* * A. Hardy/GSC 12/99 Added flag for lat/lon * * D.W.Plummer/NCEP 12/99 Added processing for WSM_ELM vgtype * * F. J. Yen/NCEP 8/00 Made intl sig lat/lon at least 4 digits * * D.W.Plummer/NCEP 2/01 Changed units of WSM from NM to SM * * D.W.Plummer/NCEP 5/01 Simplified conversion of DD to DM * * D.W.Plummer/NCEP 5/01 Added chk of pt order for SIGTYP_LINE * * D.W.Plummer/NCEP 6/01 Change criteria for line point ordering * * D.W.Plummer/NCEP 10/01 Change meaning of flag for intl sigmets * * from dd or dms to pre or post ordinate * * m.gamazaychikov/SAIC 9/02 remove portion of the code duplicating * * function clo_reorder; * * add call to clo_reorder * * S. Jacobs/NCEP 10/02 Increased np for area type * * F. J. Yen/NCEP 1/04 Handled VOR format for intl SIGMETs. * * Updated and corrected prolog about flag.* * J. Lewis/AWC 3/05 Added chk for new from line format * * J. Lewis/AWC 6/05 remove reference to LLMXPT * * B. Yin/SAIC 6/05 increase indx size by 1 besause of np++ * * D.W.Plummer/NCEP 7/05 Add NEW_VAA_LATLON_FORMAT and VAA type * * S. Jacobs/NCEP 9/05 Add break to WSM case before VAA * * B. Yin/SAIC 10/05 Add separator flags for GFAs * * B. Yin/SAIC 1/06 remove the space around hyphen * * D.W.Plummer/NCEP 11/06 Explicit processing for GFAs * * D.W.Plummer/NCEP 01/07 clo_tmatch for GFAs, not clo_tclosest * * K. Tyle/UAlbany 11/10 Increased dimension of prefs_tag * ***********************************************************************/ { int ii, jj, idist, np, ier, icmp; float dist, dir, minlat, maxlat, dlat; char tstr[8], id[9], dir16[4], prefs_tag[22]; char vaafmt[20], vaasep[8]; int *indx; int lattmp, lontmp; int line_order, reverse, format_type; Boolean newcoord, newvaacoord; int n_nms, nclose; char nm[17]; float GFAtol=GFA_TOL; /*---------------------------------------------------------------------*/ *iret = 0; str[0] = '\0'; /* * Check if the new coordinate format is to be used. */ strcpy ( prefs_tag, "NEW_LATLON_FORMAT" ); ctb_pfbool ( prefs_tag, &newcoord, &ier ); strcpy ( prefs_tag, "NEW_VAA_LATLON_FORMAT" ); ctb_pfbool ( prefs_tag, &newvaacoord, &ier ); /* * Allocate memory. */ G_MALLOC ( indx, int, npin + 1, "CLO_FROM" ); np = npin; for ( jj = 0; jj < np; jj++ ) indx[jj] = jj; if ( reorder == SIGTYP_AREA ) { clo_reorder( np, lat, lon, indx, iret ); np++; } else if ( reorder == SIGTYP_LINE ) { /* * If reorder is a line, re-order processing of * points to do either west-to-east or north-to-south. * West-to-east defined as all points within W2ELIM * degrees of one another. */ minlat = lat[0]; maxlat = minlat; for ( jj = 1; jj < np; jj++ ) { minlat = G_MIN ( minlat, lat[jj] ); maxlat = G_MAX ( maxlat, lat[jj] ); } dlat = G_ABS( maxlat - minlat ); line_order = N2S; if ( dlat <= W2ELIM ) line_order = W2E; reverse = G_FALSE; if ( line_order == N2S && lat[0] < lat[np-1] ) reverse = G_TRUE; if ( line_order == W2E && lon[0] > lon[np-1] ) reverse = G_TRUE; if ( reverse ) { for ( jj = 0; jj < np; jj++ ) indx[jj] = np-1-jj; } } /* * Set format_type. */ if ( vgtype == SIGINTL_ELM ) { /* * International SIGMET */ if ( flag != 2 ) format_type = LATLON; else format_type = VOR_FMT; } else if ( vgtype == SIGNCON_ELM || vgtype == SIGCONV_ELM || vgtype == SIGOUTL_ELM || vgtype == SIGAIRM_ELM ) /* * Non-Convective SIGMET, Convective SIGMET, * Convective Outlook */ format_type = VOR_FMT; else if ( vgtype == GFA_ELM ) /* * AIRMET */ format_type = GFA_FMT; else if ( vgtype == WSM_ELM ) /* * Watch Status Message */ format_type = WSM; else if ( vgtype == VOLC_ELM || vgtype == ASHCLD_ELM ) /* * VAA volcano and ash clouds. */ format_type = VAA; else format_type = IMISSD; /* * Loop through all the points using the indx array. */ for ( jj = 0; jj < np; jj++ ) { ii = indx[jj]; switch ( format_type ) { case LATLON: /* latitude/longitude display */ /* eg., 3913N7705W 4134N8120W */ /* eg., N3913W07705 N4134W08120 */ if ( jj != 0 ) strcat ( str, " " ); if ( flag == 0 ) { if ( ( newcoord == G_TRUE ) && ( jj != 0 ) ) strcat ( str, "- " ); if ( lat[ii] >= 0.0F ) strcat ( str, "N" ); else strcat ( str, "S" ); /* * Convert degree, decimal to degree, minutes. */ lattmp = DDTODM ( G_ABS( lat[ii] ) ); sprintf( tstr, "%04d", lattmp ); strcat ( str, tstr ); if ( newcoord == G_TRUE ) strcat ( str, " " ); if ( lon[ii] >= 0.0F ) strcat ( str, "E" ); else strcat ( str, "W" ); /* * Convert degree, decimal to degree, minutes. */ lontmp = DDTODM ( G_ABS( lon[ii] ) ); sprintf( tstr, "%05d", lontmp ); strcat ( str, tstr ); } else { /* * Convert degree, decimal to degree, minutes. */ lattmp = DDTODM ( G_ABS( lat[ii] ) ); sprintf( tstr, "%04d", lattmp ); strcat ( str, tstr ); if ( lat[ii] >= 0.0F ) strcat ( str, "N" ); else strcat ( str, "S" ); /* * Convert degree, decimal to degree, minutes. */ lontmp = DDTODM ( G_ABS( lon[ii] ) ); sprintf( tstr, "%05d", lontmp ); strcat ( str, tstr ); if ( lon[ii] >= 0.0F ) strcat ( str, "E" ); else strcat ( str, "W" ); } break; case VOR_FMT: /* distance and 16-pt compass */ /* to closest VOR point */ /* eg., 20SSW EMI TO 20ENE CLE */ clo_tdirect( "VOR", lat[ii], lon[ii], id, &dist, &dir, &ier ); clo_compass ( &dir, dir16, &icmp, &ier ); /* * Round distance to the nearest 10 nautical miles; * If convective outlook and less than 30 nm, set to 0. */ idist = G_NINT ( dist * M2NM / 10.0F ) * 10; if ( vgtype == SIGOUTL_ELM && idist < 30 ) idist = 0; if ( jj > 0 ) { /* * Different separators for different products. */ if ( vgtype == SIGCONV_ELM || vgtype == SIGOUTL_ELM || vgtype == SIGINTL_ELM ) strcat ( str, "-" ); else if ( vgtype == SIGAIRM_ELM || vgtype == SIGNCON_ELM ) strcat ( str, " TO " ); } if ( idist != 0 ) { sprintf( tstr, "%d", idist ); strcat ( str, tstr ); if ( vgtype == SIGINTL_ELM ) strcat ( str, " " ); strcat ( str, dir16 ); strcat ( str, " " ); } strcat ( str, id ); break; case GFA_FMT: /* closest SNAP point */ /* * Use clo_tmatch since all points are already snapped */ clo_tmatch( "SNAP", lat[ii], lon[ii], GFAtol, &ier ); if ( ier != 0 ) { nclose = 1; clo_tclosest( "SNAP", lat[ii], lon[ii], nclose, &ier ); } clo_tgnm ( "SNAP", 1, (sizeof(nm)-1), &n_nms, nm, &ier ); cst_rpst ( nm, "_", " ", nm, &ier ); if ( jj > 0 ) { if ( flag == SEPARATOR_TO ) { strcat ( str, " TO " ); } else if ( flag == SEPARATOR_DASH ) { strcat ( str, "-" ); } } strcat ( str, nm ); break; case WSM: /* Watch status messages */ /* SM distance and 16-pt compass*/ /* to closest ANCHOR point */ /* eg., 10 N DCA TO 20 NW HGR */ clo_tdirect( "ANCHOR", lat[ii], lon[ii], id, &dist, &dir, &ier ); clo_compass ( &dir, dir16, &icmp, &ier ); /* * Round distance to the nearest 5 statute miles. */ idist = G_NINT ( dist * M2SM / 5.0F ) * 5; if ( jj > 0 ) strcat ( str, " TO " ); if ( idist != 0 ) { sprintf( tstr, "%d ", idist ); strcat ( str, tstr ); strcat ( str, dir16 ); strcat ( str, " " ); } strcat ( str, id ); break; case VAA: /* VAA volcano and ash clouds */ if ( newvaacoord == G_FALSE ) { strcpy ( vaafmt, "%s%04d%s%05d" ); strcpy ( vaasep, " - " ); } else if ( newvaacoord == G_TRUE ) { strcpy ( vaafmt, "%s%04d %s%05d" ); strcpy ( vaasep, " - " ); } /* * Convert degree, decimal to degree, minutes. */ lattmp = DDTODM ( G_ABS( lat[ii] ) ); lontmp = DDTODM ( G_ABS( lon[ii] ) ); sprintf( tstr, vaafmt, ( lat[ii] >= 0.0F ) ? "N" : "S", lattmp, ( lon[ii] >= 0.0F ) ? "E" : "W", lontmp ); strcat ( str, tstr ); if ( jj < (np-1) ) strcat ( str, vaasep ); break; } } G_FREE ( indx, int ); return; }
void pggrpch_chngGrp ( void ) /************************************************************************ * pggrpch_chngGrp * * * * Change the group type of the elements according to instructions on * * VG Group Change Window. * * * * void pggrpch_chngGrp () * * * * Input parameters: * * Output parameters: * * Return: * * NONE * * * ** * * Log: * * H. Zeng/EAI 05/01 initial coding * * J. Wu/SAIC 12/01 add layer in crg_set() call * * J. Wu/SAIC 01/02 change only groups on current layer * * H. Zeng/EAI 03/02 renamed for new nmap_pggrpch file * * H. Zeng/EAI 05/02 modified to use master group type list * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * J. Wu/SAIC 07/04 add filter param to crg_get * * B. Yin/SAIC 08/04 added code to free TCA memory * * B. Yin/SAIC 08/04 changed pgtca_freeBkpts to cvg_freeBkpts* * J. Wu/SAIC 10/04 free GFA block memory * * S. Danz/AWC 07/06 Added new cvg_delet placement argument * * S. Danz/AWC 08/06 New flag to pgvgf_saveNewElm to place el* * S. Danz/AWC 08/06 Updated to use cvg_checkplace to find * * area impacted and call crg_rebuild() * ***********************************************************************/ { int el_num, new_num, el_loc, extra = 5, dest_grpnum; int ori_grpnum, ier2, elN, new_location, ii, selection, iret; int grpid, cur_layer, el_layer, pl_found, update_crg; float llx, lly, urx, ury, m_llx, m_lly, m_urx, m_ury; float *elX, *elY, inf_bbox[4]; char ori_grptyp, dest_grptyp, ori_grpnam[20], dest_grpnam[20]; Boolean found; VG_DBStruct el; struct convertTblStrc *convert_tbl, *ptr, *ptr_prev; filter_t filter; /*---------------------------------------------------------------------*/ m_llx = 999999.0F; m_lly = 999999.0F; m_urx = 0.0F; m_ury = 0.0F; convert_tbl = NULL; ptr = NULL; ptr_prev = NULL; update_crg = 0; pgundo_newStep(); cur_layer = pglayer_getCurLayer( ); for (el_num = 0; el_num < MAX_EDITABLE_ELEMS; el_num++) { crg_goffset (el_num, &el_loc, &ier2); el_layer = crg_getLayer ( el_loc ); /* * Skip cleared range record or those not on current layer. */ if (el_loc == -1 || el_layer != cur_layer) { continue; } crg_ggrp (el_num, &ori_grptyp, &ori_grpnum, &ier2); if (ori_grpnum && ori_grptyp != GRPTYP_OTHERS && ori_grptyp != GRPTYP_COMSYM && ori_grptyp != GRPTYP_WATCH && ori_grptyp != GRPTYP_CCF ) { ces_gtgnam((int)ori_grptyp, ori_grpnam, &ier2); for( ii = 0; ii < _numCurGrp; ii++ ) { if(strcmp(_curGrpStr[ii], ori_grpnam) == 0) { selection = ii + 1; break; } } if(ii < _numCurGrp && _chngToStrc.chng_flag[selection] == TRUE) { strcpy(dest_grpnam, _chngToStr[ _chngToStrc.current[selection]-1 ]); ces_gtgid(dest_grpnam, &grpid, &ier2); dest_grptyp = (char)grpid; /* Search on conversion table to see if there is entry * that has the same ori_grptyp, ori_grpnum and dest_grptyp. * If yes, get dest_grpnum from there. */ found = FALSE; ptr = convert_tbl; while(ptr != NULL) { if(ori_grptyp == ptr->ori_grptyp && dest_grptyp== ptr->dest_grptyp&& ori_grpnum == ptr->ori_grpnum ) { dest_grpnum = ptr->dest_grpnum; found = TRUE; break; } ptr = ptr->next; } /* * If not found on conversion table, get next available * group number. Add new entry into conversion table. */ if(!found) { crg_ggnxt(dest_grptyp, &dest_grpnum, &ier2); if(convert_tbl == NULL) { convert_tbl = (struct convertTblStrc*)malloc( sizeof(struct convertTblStrc) ); convert_tbl->ori_grptyp = ori_grptyp; convert_tbl->dest_grptyp= dest_grptyp; convert_tbl->ori_grpnum = ori_grpnum; convert_tbl->dest_grpnum= dest_grpnum; convert_tbl->next = NULL; convert_tbl->prev = NULL; } else { ptr = convert_tbl; while(ptr->next != NULL) ptr = ptr->next; ptr->next = (struct convertTblStrc*)malloc( sizeof(struct convertTblStrc) ); ptr_prev = ptr; ptr = ptr->next; ptr->ori_grptyp = ori_grptyp; ptr->dest_grptyp= dest_grptyp; ptr->ori_grpnum = ori_grpnum; ptr->dest_grpnum= dest_grpnum; ptr->next = NULL; ptr->prev = ptr_prev; } } /* the end of if(!found... */ cvg_rdrec (cvg_getworkfile(), el_loc, &el, &ier2); /* * Create a copy of the element with new group info, */ pgactv_setActvElm ( &el, el_loc); pgactv_getDevPts (&elN, &elX, &elY); pgvgf_saveNewElm(NULL, sys_D, &el, elN, elX, elY, FALSE, &new_location, &iret); cvg_setginf(cvg_getworkfile(), new_location, dest_grptyp, dest_grpnum, &iret); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } cvg_rdrec(cvg_getworkfile(), new_location, &el, &iret); crg_set (&el, new_location, cur_layer, &iret); crg_getinx (new_location, &new_num, &iret); crg_get(new_num, &el_layer, filter, &llx, &lly, &urx, &ury, &iret); if (m_llx > llx) m_llx = llx; if (m_lly > lly) m_lly = lly; if (m_urx < urx) m_urx = urx; if (m_ury < ury) m_ury = ury; /* * Mark elements in placement that are effected by * the new element, and get the area of influence back */ cvg_checkplace(&el, 0, new_location, &pl_found, inf_bbox, &iret); if (pl_found > 0) { /* * Update the refresh extent if the area impacted by * placement is bigger */ m_llx = G_MIN(m_llx, inf_bbox[0]); m_lly = G_MIN(m_lly, inf_bbox[2]); m_urx = G_MAX(m_urx, inf_bbox[1]); m_ury = G_MAX(m_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } pgundo_storeThisLoc(new_location, UNDO_ADD, &iret); /* * Mark elements in placement that are effected by * the delete, and get the area of influence back */ cvg_rdrec(cvg_getworkfile(), el_loc, &el, &iret); cvg_checkplace(&el, 1, el_loc, &pl_found, inf_bbox, &iret); if (pl_found > 0) { /* * Update the refresh extent if the area impacted by * placement is bigger */ m_llx = G_MIN(m_llx, inf_bbox[0]); m_lly = G_MIN(m_lly, inf_bbox[2]); m_urx = G_MAX(m_urx, inf_bbox[1]); m_ury = G_MAX(m_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } /* * Mark the original element as deleted. */ cvg_delet(cvg_getworkfile(), el_loc, TRUE, &ier2); crg_get (el_num, &el_layer, filter, &llx, &lly, &urx, &ury, &ier2); if (m_llx > llx) m_llx = llx; if (m_lly > lly) m_lly = lly; if (m_urx < urx) m_urx = urx; if (m_ury < ury) m_ury = ury; crg_clear(el_num, &ier2); pgundo_storeThisLoc (el_loc, UNDO_DEL, &ier2); } /* the end of if(ii < _numCurGrp ... ) */ } /* the end of if (ori_grpnum &&... */ } /* for (el_num = 0 ... */ pgundo_endStep(); m_llx -= (float)extra; m_lly -= (float)extra; m_urx += (float)extra; m_ury += (float)extra; xpgpaste (m_llx, m_lly, m_urx, m_ury, &ier2); cvg_rfrsh (NULL, m_llx, m_lly, m_urx, m_ury, &ier2); /* * If we may have impacted other elements with placement * we will need to rebuild the range records */ if (update_crg) { crg_rebuild(); } /* * Free conversion table */ if(convert_tbl != NULL) { ptr = convert_tbl; while(ptr->next != NULL) ptr = ptr->next; do { ptr_prev = ptr->prev; free(ptr); ptr = ptr_prev; } while(ptr != NULL); } }
void db_setsubgnav ( float lllat, float lllon, float urlat, float urlon, int *iret ) /************************************************************************ * db_setsubgnav * * * * This subroutine initializes internal sub grid navigation. * * dgc_setsubgnav (lllat, lllon, urlat, urlon, irer ) * * Input parameters: * * lllat float Lower left latitude * * lllon float Lower left Longitude * * urlat float Upper right latitude * * urlon float Upper right Longitude * * Output parameters: * * *iret int Return code * * 0 = normal return * * -46 = invalid grid point * ** * * Log: * * X. Guo 12/04 Initial * ***********************************************************************/ { int nc,ier; char gprj[5]; float rltmin, rlnmin, rltmax, rlnmax; float dlatll, dlonll, dlatur, dlonur; /*----------------------------------------------------------------------*/ *iret = 0; cst_itos ( (int *)&_dgsubg.refnav[1], 1, &nc, gprj, &ier ); cst_rmbl ( gprj, gprj, &nc, &ier ); /* * Define sub-grid area */ rltmin = G_MIN ( lllat, urlat ); rlnmin = G_MIN ( lllon, urlon ); rltmax = G_MAX ( lllat, urlat ); rlnmax = G_MAX ( lllon, urlon ); /* * Take care of the sub-grid area across the date-line */ if ( ( rlnmax - rlnmin ) > 180. ) { dlatll = rltmin; dlonll = rlnmax; dlatur = rltmax; dlonur = rlnmin; } else { dlatll = rltmin; dlonll = rlnmin; dlatur = rltmax; dlonur = rlnmax; } /* * *Set internal sub-grid navigation */ gsmprj ( gprj, &_dgsubg.refnav[10], &_dgsubg.refnav[11], &_dgsubg.refnav[12], &dlatll, &dlonll, &dlatur, &dlonur, &ier, strlen(gprj) ); /* * IF set sub-grid navigation fail, change center longitude */ if ( ier != 0 ) { *iret = -46; } }
void cgr_segintwn ( float *xin1, float *yin1, float *xin2, float *yin2, float *xint, float *yint, int *intrsct, int *iret ) /************************************************************************ * cgr_segintwn * * * * This function accepts two line segments and determines if they * * intersect one another. Note that if two line segments are extended * * as lines, they will always intersect (unless they are parallel, ie. * * their slopes are equal). This intersecting point is returned * * regardless of whether it falls on the segments themselves. If the * * segments are parallel, the intersecting point is (RMISSD,RMISSD). * * * * This is simply a copy of cgr_segint without the use of normalized * * coordinates. Output is in sys_M, inputs are assumed to be sys_M as * * well. If they are in any other coordinate system the results will * * be undefined. * * * * cgr_segint ( xin1, yin1, xin2, yin2, xint, yint, intrsct, iret ) * * * * Input parameters: * * *xin1 float X-coordinate of endpoints for segment #1 * * *yin1 float Y-coordinate of endpoints for segment #1 * * *xin2 float X-coordinate of endpoints for segment #2 * * *yin2 float Y-coordinate of endpoints for segment #2 * * * * Output parameters: * * *xint float X-coordinate of intersecting point * * *yint float Y-coordinate of intersecting point * * *intrsct int Result: * * 0-FALSE (the segments do not intersect), * * 1-TRUE (the segments intersect) * * *iret int Return code * ** * * Log: * * E. Safford/SAIC 09/06 copied from cgr_segint * * E. Safford/SAIC 10/06 make internal variables double to * * ensure same results on all platforms * ***********************************************************************/ { double x, y, m1, b1, m2, b2; double x1[2], y1[2], x2[2], y2[2]; /*---------------------------------------------------------------------*/ *iret = 0; *intrsct = 0; *xint = RMISSD; *yint = RMISSD; x = RMISSD; y = RMISSD; /* * Make local copies of the inputs. */ x1[0] = xin1[0]; x1[1] = xin1[1]; y1[0] = yin1[0]; y1[1] = yin1[1]; x2[0] = xin2[0]; x2[1] = xin2[1]; y2[0] = yin2[0]; y2[1] = yin2[1]; /* * Check for vertical first segment and compute (x,y) intersect. */ if ( G_DIFF(x1[0], x1[1]) ) { x = x1[0]; if ( G_DIFF(x2[0], x2[1]) ) return; m2 = (y2[1]-y2[0]) / (x2[1]-x2[0]); b2 = y2[0] - m2 * x2[0]; y = m2 * x + b2; } /* * Check for vertical second segment and compute (x,y) intersect. */ else if ( G_DIFF(x2[0], x2[1]) ) { x = x2[0]; if ( G_DIFF(x1[0], x1[1]) ) return; m1 = (y1[1]-y1[0]) / (x1[1]-x1[0]); b1 = y1[0] - m1 * x1[0]; y = m1 * x + b1; } /* * Finally compute (x,y) intersect for all other cases. */ else { m1 = (y1[1]-y1[0]) / (x1[1]-x1[0]); b1 = y1[0] - m1 * x1[0]; m2 = (y2[1]-y2[0]) / (x2[1]-x2[0]); b2 = y2[0] - m2 * x2[0]; if ( G_DIFF(m1, m2) ) { x = RMISSD; y = RMISSD; } else { if ( G_DIFF(m1, 0.0F) ) { x = ( b2 - y1[0] ) / ( - m2 ); y = y1[0]; } else if ( G_DIFF(m2, 0.0F) ) { x = ( y2[0] - b1 ) / ( m1 ); y = y2[0]; } else { x = ( b2 - b1 ) / ( m1 - m2 ); y = m1 * x + b1; } } } /* * Check if intersecting point is within each segment's bounds. */ if ( ERMISS(x) || ERMISS(y) ) return; *xint = x; *yint = y; if ( x < G_MIN(x1[0],x1[1]) || x > G_MAX(x1[0],x1[1]) ) return; if ( x < G_MIN(x2[0],x2[1]) || x > G_MAX(x2[0],x2[1]) ) return; if ( y < G_MIN(y1[0],y1[1]) || y > G_MAX(y1[0],y1[1]) ) return; if ( y < G_MIN(y2[0],y2[1]) || y > G_MAX(y2[0],y2[1]) ) return; *intrsct = 1; return; }
void pd_hans ( const float *tc1, const float *tc2, const float *dwpc, const int *np, const int *type, float *haines, int *iret ) /************************************************************************ * pd_hans * * * * This subroutine computes low, middle, and high elevation Haines * * Indices from TMPC and DWPC. * * * * pd_hans ( tc1, tc2, dwpc, np, type, haines, iret ) * * * * Input parameters: * * *tc1 const float Temperature in Celsius * * *tc2 const float Temperature in Celsius * * *dwpc const float Dewpoint in Celsius * * *np const int Number of points * * *type const int Type of Haines index * * 1 = Low * * 2 = Middle * * 3 = High * * * * Output parameters: * * *haines float Haines index * * *iret int Return code * * 0 = normal return * ** * * Log: * * T. Lee/SAIC 6/03 Created * * R. Tian/SAIC 9/05 Translated from FORTRAN * ************************************************************************/ { float a, b; int i, npt, itype; /*----------------------------------------------------------------------*/ *iret = 0; npt = *np; itype = *type; /* * Loop through all the points. */ for ( i = 0; i < npt; i++ ) { /* * Check for missing data. */ if ( ( ERMISS ( tc1 [i] ) ) || ( ERMISS ( tc2 [i] ) ) || ( ERMISS ( dwpc [i] ) ) ) { haines [i] = RMISSD; } else { /* * Compute the Haines index. */ if ( itype == 1 ) { a = ( ( tc2 [i] - tc1 [i] ) - 3.0F ) * (2.0F/5.0F) + 1.0F; b = ( ( tc1 [i] - dwpc [i] ) - 5.0F ) * (2.0F/5.0F) + 1.0F; } else if ( itype == 2 ) { a = ( ( tc1 [i] - tc2 [i] ) - 5.0F ) * (2.0F/6.0F) + 1.0F; b = ( ( tc1 [i] - dwpc [i] ) - 5.0F ) * (2.0F/8.0F) + 1.0F; } else if ( itype == 3 ) { a = ( ( tc1 [i] - tc2 [i] ) - 17.0F) * (2.0F/5.0F) + 1.0F; b = ( ( tc1 [i] - dwpc [i] ) - 14.0F) * (2.0F/7.0F) + 1.0F; } a = G_MAX ( a, 0.9F ); a = G_MIN ( a, 3.1F ); b = G_MAX ( b, 0.9F ); b = G_MIN ( b, 3.1F ); haines [i] = a + b; } } return; }
void rscnfll ( int *np, int ix[], int iy[], int *iret ) /************************************************************************ * rscnfll * * * * This function draws a filled polygon on a raster bitmap. * * * * void rscnfll ( np, ix, iy, iret ) * * * * Input parameters: * * *np int Number of points in the polygon * * ix [] int Array of x coordinates * * iy [] int Array of y coordinates * * * * Output parameters: * * *iret int Return code * ** * * Log: * * E. Wehner/EAi 4/96 Created * * E. Safford/GSC 3/97 Modified to use new cgr_ routintes * * E. Wehner/EAi 3/97 change xsize/ysize to scanlines * * M. Linda/GSC 7/97 Added a call to RLINE following fill * * S. Jacobs/NCEP 7/97 Cleaned up header files and global vars * * D.W.Plummer/NCEP 8/97 Rewrite * ***********************************************************************/ { int npts, *ixarr, *iyarr, iymin, iymax, i, j, index, nx1, nx2, ny2; float tau, xout[100]; /*---------------------------------------------------------------------*/ *iret = G_NORMAL; /* * Get the number of points and make sure that the polygon * is closed. */ npts = *np; if ( ix[0] != ix[npts-1] || iy[0] != iy[npts-1] ) npts++; /* * Allocate space for the working arrays. */ ixarr = (int *) malloc ( npts * sizeof(int) ); iyarr = (int *) malloc ( npts * sizeof(int) ); iymin = INT_MAX; iymax = -INT_MAX; /* * Double the dimensions for easier computations. Find the min * and max in the Y direction. */ for ( i = 0; i < npts-1; i++ ) { ixarr[i] = ix[i] * 2; iyarr[i] = iy[i] * 2; iymin = G_MIN ( iyarr[i], iymin ); iymax = G_MAX ( iyarr[i], iymax ); } ixarr[npts-1] = ixarr[0]; iyarr[npts-1] = iyarr[0]; /* * For each scan line, compute intersections and fill. */ for ( j = iymin+1; j < iymax; j = j+2 ) { index = 0; for ( i = 0; i < npts-1; i++ ) { if ( iyarr[i] != iyarr[i+1] ) { tau = (float) ( j - iyarr[i] ) / (float) ( iyarr[i+1] - iyarr[i] ); if ( tau >= 0.0 && tau <= 1.0 ) { xout[index] = tau * ( ixarr[i+1] - ixarr[i] ) + ixarr[i]; index++; } } } /* * Sort the values of the X coordinate. * Added (int(*)(const void*, const void*)) cast to satisfy qsort */ qsort ( xout, index, sizeof(float), (int(*)(const void*, const void*))_cmp_xout ); /* * Loop over all the scan lines, filling the pixels * in the pattern. */ for ( i = 0; i < index; i=i+2 ) { ny2 = j / 2; nx1 = xout[i ] / 2; nx2 = xout[i+1] / 2; fillScan ( ny2, nx1, nx2, iret ); } } /* * Free the working arrays. */ free ( ixarr ); free ( iyarr ); }
void dg_g2gc ( const int *inttyp, const int *glbwi, const int *kxi, const int *kyi, const float *grdi, const int *kxo, const int *kyo, float *gixo, float *giyo, float *grdo, int *iret ) /************************************************************************ * dg_g2gc * * * * This subroutine remaps cosines of data from one grid to another grid.* * * * A globe-wrapping grid must be configured so that the last column * * and first column are identical. * * * * If INTTYP=0, the code determines automatically whether to use a * * simple bi-linear interpolation or an area average preserving re- * * mapping of data. The method is determined locally and may vary * * across the grid. The transition to area average preserving remap- * * ping occurs when one output grid box contains approximately four (4) * * or more input grid boxes. Since bilinear interpolation preserves * * the area average when grid resolutions are comparable or when the * * input grid is coarse compared to the output grid, this method always * * preserves area averages. * * * * If INTTYP=1, the code performs nearest neighbor assignment. * * If INTTYP=2, the code performs only bi-linear interpolation. * * * * dg_g2gc ( inttyp, glbwi, kxi, kyi, grdi, kxo, kyo, gixo, giyo, grdo, * * iret ) * * * * Input parameters: * * *inttyp const int Remapping type * * = 0 area average preserving * * = 1 nearest point assignment * * = 2 bi-linear interpolation * * *glbwi const int Flg for globe-wrapping input grd* * *kxi const int Number of x pts on input grid * * *kyi const int Number of y pts on input grid * * *grdi const float Input grid * * *kxo const int Number of x pts on output grid * * *kyo const int Number of y pts on output grid * * *gixo flaot Input grd rltv x on output grid * * *giyo float Input grd rltv y on output grid * * * * Output parameters: * * *grdo float Output grid of results * * *iret int Return code * * 0 = normal return * * -68 = INTTYP is not valid * * -69 = grid rel position error * ** * * Log: * * K. Brill/HPC 3/04 Created from DG_G2GI * * K. Brill/HPC 4/04 IF (k==0) k=1; add .005 to rad * * R. Tian/SAIC 2/06 Recoded from Fortran * ************************************************************************/ { float rkio2, rdtst, xchk, rad2m, dx, dy, d2, x, y, xi, omx, omy, rad, rad2, radx2, sum, sumw, ri, r2, dr2, dr22, wt, tmp; int ir[4], jr[4], kio2, ityp, cidx, cidx1, i, j, k, io, jo, in, jn, idx1, idx2, idx3, idx4, ip, ib, jb, ie, je, ii, jj, jdif, npts; int rflct; /*----------------------------------------------------------------------*/ *iret = 0; if ( (*inttyp) < 0 || (*inttyp) > 2 ) { *iret = -68; return; } kio2 = (*kxi) / 2; rkio2 = (float)kio2; rdtst = 4. / PI; if ( (*inttyp) == 0 && (*glbwi) == G_TRUE && ( (*kxi) % 2 ) == 1 ) { /* * Check to relect points across the pole of a global grid. * All points along bottom and top rows must be identical. */ rflct = G_TRUE; for ( j = 1; j <= (*kyi); j += (*kyi) - 1 ) { cidx = (j - 1 ) * (*kxi); xchk = cos ( grdi[cidx] ); i = 2; while ( i <= (*kxi) && rflct == G_TRUE ) { cidx = ( j - 1 ) * (*kxi) + i - 1; rflct = ( ! ERMISS ( grdi[cidx] ) ) ? G_TRUE : G_FALSE; if ( rflct == G_TRUE ) { if ( G_ABS ( xchk - cos ( grdi[cidx] ) ) < RDIFFD ) { rflct = G_FALSE; } } i++; } } } else { rflct = G_FALSE; } /* * Loop over all output grid points. */ rad2m = -9999.; for ( jo = 1; jo <= (*kyo); jo++ ) { for ( io = 1; io <= (*kxo); io++ ) { cidx = ( jo - 1 ) * (*kxo) + io - 1; grdo[cidx] = RMISSD; if ( ERMISS ( gixo[cidx] ) || ERMISS ( giyo[cidx] ) ) { ityp = 2; } else if ( (*inttyp) == 1 ) { /* * Assign value at nearest point. */ ityp = 2; in = G_NINT ( gixo[cidx] ); if ( (*glbwi) == G_TRUE ) { if ( in > (*kxi) ) in = in - (*kxi) + 1; if ( in < 1 ) in = in + (*kxi) - 1; } jn = G_NINT ( giyo[cidx] ); if ( in >= 1 && in <= (*kxi) && jn >= 1 && jn <= (*kyi) ) { /* * Nearest point value assignment. */ cidx1 = ( jn - 1 ) * (*kxi) + in - 1; grdo[cidx] = cos ( grdi[cidx1] ); } } else if ( (*inttyp) == 2 ) { ityp = 1; } else { ityp = 0; /* * Get radius in input grid units of the circle * circumscribing the the diamond formed by the * four points closest to the current point on * the output grid. */ rad2 = -1.1E31; ir[0] = io - 1; jr[0] = jo; ir[1] = io; jr[1] = jo - 1; ir[2] = io + 1; jr[2] = jo; ir[3] = io; jr[3] = jo + 1; for ( ip = 0; ip < 4; ip++ ) { cidx1 = ( jr[ip] - 1 ) * (*kxo) + ir[ip] - 1; if ( ir[ip] >= 1 && ir[ip] <= (*kxo) && jr[ip] >= 1 && jr[ip] <= (*kyo) && ! ERMISS ( gixo[cidx1] ) && ! ERMISS ( giyo[cidx1] ) ) { dx = gixo[cidx1] - gixo[cidx]; if ( (*glbwi) == G_TRUE && G_ABS (dx) > rkio2 ) { /* * Skip this point. */ } else if ( G_ABS (dx) > rkio2 ) { *iret = -69; return; } else { dy = giyo[cidx1] - giyo[cidx]; d2 = dx * dx + dy * dy; rad2 = G_MAX ( d2, rad2 ); } } } /* * Since RAD2 is the square of the radius of the * circle circumscribing the output grid diamond * in input grid units, multiply by .5 to get the * the square of the radius of the inscribed circle. * This circle circumscribes the output grid box. */ if ( rad2 > -1.0E30 ) { rad2 *= .5; /* * If the radius is much larger than that at the * adjacent point, then reduce it. */ if ( rad2m > 0.0 && rad2 > 1.5 * rad2m ) { rad2 = 1.5 * rad2m; } rad2m = rad2; } else { rad2m = -9999.; } /* * If the squared radius of the inscribed circle is * small enough (4/PI), then there are less than four * input grid boxes per output grid box and linear * interpolation will suffice. */ if ( rad2 < rdtst ) { ityp = 1; } } if ( ityp == 1 ) { /* * Do bi-linear interpolation. */ i = (int)gixo[cidx]; if ( (*glbwi) == G_TRUE ) { if ( i >= (*kxi) ) { i = i - (*kxi) + 1; xi = gixo[cidx] - (float)(*kxi) + 1; } else if ( i < 1 ) { i = i + (*kxi) - 1; xi = gixo[cidx] + (float)(*kxi) - 1; if ( gixo[cidx] < 0.0 ) i--; } else { xi = gixo[cidx]; } } else { xi = gixo[cidx]; } j = (int)giyo[cidx]; if ( i >= 1 && i <= (*kxi) && j >= 1 && j <= (*kyi) ) { if ( i == (*kxi) ) i--; if ( j == (*kyi) ) j--; idx1 = ( j - 1 ) * (*kxi) + i - 1; idx2 = ( j - 1 ) * (*kxi) + i; idx3 = j * (*kxi) + i - 1; idx4 = j * (*kxi) + i; if ( ! ERMISS ( grdi[idx1] ) && ! ERMISS ( grdi[idx2] ) && ! ERMISS ( grdi[idx3] ) && ! ERMISS ( grdi[idx4] ) ) { x = xi - (float)i; y = giyo[cidx] - (float)j; omx = 1. - x; omy = 1. - y; grdo[cidx] = ( cos ( grdi[idx1] ) * omx + cos ( grdi[idx2] ) * x ) * omy + ( cos ( grdi[idx3] ) * omx + cos ( grdi[idx4] ) * x ) * y; } } } else if ( ityp == 0 ) { /* * Do area average preserving interpolation. * * This integer truncation acts to pull the * output grid box circumscribing circle in * just a bit. */ tmp = sqrt ( rad2 ); k = (int)tmp; if ( k == 0 ) k = 1; /* * Reset rad2 accordingly. */ rad = (float)k + .005; rad2 = rad * rad; radx2 = 1. / ( 2. * rad ); ib = G_NINT ( gixo[cidx] ) - k; jb = G_NINT ( giyo[cidx] ) - k; ie = G_NINT ( gixo[cidx] ) + k; je = G_NINT ( giyo[cidx] ) + k; sum = 0.0; sumw = 0.0; npts = 0; for ( j = jb; j <= je; j++ ) { for ( i = ib; i <= ie; i++ ) { jj = j; ii = i; ri = (float)i; if ( (*glbwi) == G_TRUE ) { if ( i > (*kxi) ) ii = i - (*kxi) + 1; if ( i < 1 ) ii = i + (*kxi) - 1; } dx = ri - gixo[cidx]; dy = (float)j - giyo[cidx]; r2 = dx * dx + dy * dy; if ( rflct == G_TRUE ) { if ( j > (*kyi) ) { jdif = j - (*kyi); jj = (*kyi) - jdif; if ( ii <= kio2 ) { ii += kio2; } else { ii -= kio2; } } else if ( j < 1 ) { jdif = 1 - j; jj = 1 + jdif; if ( ii <= kio2 ) { ii += kio2; } else { ii -= kio2; } } } if ( r2 <= rad2 ) { if ( ii >= 1 && ii <= (*kxi) && jj >= 1 && jj <= (*kyi) ) { cidx1 = ( jj - 1 ) * (*kxi) + ii - 1; if ( ! ERMISS (grdi[cidx1] ) ) { /* * Compute a weighting factor based * on an estimate of how much of * the area of the input grid box * is contributing to the area * covered by the output grid box. * The criterion is (rad-r) < .5. * Using the approximation that * rad ~ r, then (rad2-r2) is nearly * equal to 2*rad(rad-r). Substi- * tute into above inequality and * rearrange to get this criterion: * (rad2-r2)**2<rad2. The weight is * either 1 or [.5+(rad2-r2)/rad*2]. * The .5 is added on because a * point on the circle has about * half of its area inside. */ dr2 = rad2 - r2; dr22 = dr2 * dr2; if ( dr22 < rad2 ) { wt = .5 + dr2 * radx2; } else { wt = 1.0; } sum += wt * cos ( grdi[cidx1] ); sumw += wt; npts++; } } } } } if ( sumw >= 2.0 && npts >= 4 ) { /* * The value 2.0 is used as the criterion here * because at least 4 points must contribute * at least a half. */ grdo[cidx] = sum / sumw; } else { /* * Perform linear interpolation, which itself * preserves area averages when grid resolutions * are comparable. */ i = (int)gixo[cidx]; if ( (*glbwi) == G_TRUE ) { if ( i >= (*kxi) ) { i = i - (*kxi) + 1; xi = gixo[cidx] - (float)(*kxi) + 1; } else if ( i < 1 ) { i = i + (*kxi) - 1; xi = gixo[cidx] + (float)(*kxi) - 1; if ( gixo[cidx] < 0.0 ) i--; } else { xi = gixo[cidx]; } } else { xi = gixo[cidx]; } j = (int)giyo[cidx]; if ( i >= 1 && i <= (*kxi) && j >= 1 && j <= (*kyi) ) { if ( i == (*kxi) ) i--; if ( j == (*kyi) ) j--; idx1 = ( j - 1 ) * (*kxi) + i - 1; idx2 = ( j - 1 ) * (*kxi) + i; idx3 = j * (*kxi) + i - 1; idx4 = j * (*kxi) + i; if ( ! ERMISS ( grdi[idx1] ) && ! ERMISS ( grdi[idx2] ) && ! ERMISS ( grdi[idx3] ) && ! ERMISS ( grdi[idx4] ) ) { x = xi - (float)i; y = giyo[cidx] - (float)j; omx = 1. - x; omy = 1. - y; grdo[cidx] = ( cos ( grdi[idx1] ) * omx + cos ( grdi[idx2] ) * x ) * omy + ( cos ( grdi[idx3] ) * omx + cos ( grdi[idx4] ) * x ) * y; } } } } } } return; }