void utl_gmon ( int dtmonth, char *pmm, int *iret ) /************************************************************************ * utl_gmon * * * * This function converts the numerical value of a month into the three * * character abbreviation for the month. * * * * utl_gmon ( dtmonth, pmm, iret ) * * * * Input parameters: * * dtmonth int Month * * * * Output parameters: * * *pmm char 3-character month name * * *iret int Return code * * -6 = Bad month number * ** * * Log: * * A. Hardy/NCEP 7/03 * * A. Hardy/NCEP 8/03 Changed length check 4 -> 3 * ***********************************************************************/ { int len1, lenp, ier; char noname[12][4] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; /*---------------------------------------------------------------------*/ *iret = 0; lenp = 4; pmm[0] = '\0'; /* * Retrieve the 3 character month. */ if ( dtmonth >= 1 && dtmonth <= 12 ) { len1 = G_MIN ( lenp, 3 ); cst_ncpy ( pmm, noname[dtmonth-1], len1, &ier); } else { *iret = -6; return; } }
void _getrpt ( srchinfo_t *srchinfo, char *report, int *iret ) /************************************************************************ * _getrpt * * * * This routine will retrieve the report for the requested location. * * * * _getrpt ( srchinfo, report, iret ) * * * * Input parameters: * * *srchinfo srchinfo_t Search info structure * * * * Output parameters: * * *report char Report * * *iret int Return code * * * * * ** * * Log: * * L. Williams/EAI 6/96 modified from srchb_fosdFndrepWW * * S. Jacobs/NCEP 12/98 Changed fclose to cfl_clos * * S. Chiswell/UCAR 04/01 Changed strchr to memchr * * R.Tian/SAIC 1/02 Avoid possible overflow report * * R. Tian/SAIC 04/02 Query file size before open it * ***********************************************************************/ { int rep_len; long flen; char dumyname[133]; char *iepos, *ispos, *text; /*---------------------------------------------------------------------*/ /* * Get the size of the new file. If the size is 0, skip it. */ cfl_inqr(srchinfo->file_info.filnam, NULL, &flen, dumyname, iret); if ( *iret != 0 || flen == 0 ) { report[0] = '\0'; *iret = -1; return; /* error in query file */ } srchinfo->file_info.file_len = (int)flen; /* * Open the new file. */ srchinfo->file_info.fptr = cfl_ropn( srchinfo->file_info.filnam, NULL, iret ); if ( *iret != 0 ) { report[0] = '\0'; *iret = -1; return; /* error in opening file */ } /* * Allocate enough space to hold the entire contents of the file. */ text = (char *) malloc((size_t)(srchinfo->file_info.file_len + 1) * sizeof(char) ); /* * Read the contents of the file into the TEXT string. */ if ( fread( text, (size_t)srchinfo->file_info.file_len, 1, srchinfo->file_info.fptr) != (size_t)1 ){ /* * reading error */ report[0] = '\0'; *iret = -1; free( text ); return; } /* * Copy the report from string text to string report */ ispos = &text[reportInfo[srchinfo->current].position]; iepos = memchr( &text[reportInfo[srchinfo->current].position], CHCTLC, (size_t)(srchinfo->file_info.file_len - reportInfo[srchinfo->current].position)); if ( iepos != NULL ) rep_len = G_MIN((iepos - ispos), (REPMAX - 1)); else rep_len = 0; strncpy( report, &text[reportInfo[srchinfo->current].position], (size_t)rep_len ); report[rep_len] = '\0'; free( text ); /* * Close the data file. */ if ( srchinfo->file_info.fptr != NULL ) { cfl_clos ( srchinfo->file_info.fptr, iret ); srchinfo->file_info.fptr = NULL; } }
void srchw_fosdMarkrep ( srchinfo_t *srch_info, char *text_rep, char *srch_str, int called_from, int *iret ) /************************************************************************ * srchw_fosdMarkrep * * * * This routine will search for the search string of each report and * * the beginning position and save that position in a structure. * * * * srchw_fosdMarkrep (srch_info, text_rep, srch_str, called_from, iret) * * * * Input parameters: * * *srch_info srchinfo_t Search structure * * *text_rep char file contents * * *srch_str char search string * * called_from int Indicate from where it is called* * 1 - from user click * * 2 - from auto-update * * * * Output parameters: * * *iret int Return code * ** * * Log: * * D.Plummer/NCEP 12/95 Reorganize for fosd type W * * L.Williams/EAI 6/96 Check for duplicate reports * * R.Tian/SAIC 1/02 Avoid possible overflow buf * * R. Tian/SAIC 11/03 Added called_from arg * * E. Safford/SAIC 12/07 rm direct access to textW widget * ***********************************************************************/ { char *str, t_str[15]; char buf[REPMAX]; int ibeg, ipos; int flag; int replen; int index, ier; char notfound_msg[80]; char exceeds_msg[80]; struct data_file_info *file_info; struct directory_info *dir_info; /* ------------------------------------------------------------------- */ ipos=0; flag=0; file_info = &(srch_info->file_info); dir_info = &(srch_info->dir_info); ibeg = file_info->file_len - 1; _cache[0] = '\0'; while ( ( ipos >= 0 ) && ( *iret == 0 ) ) { /* * Locate the starting position of each report */ cst_srch( ibeg, 0, srch_str, text_rep, &ipos, iret ); /* * Copy report into a temporary buffer */ replen = G_MIN((ibeg - ipos), (REPMAX - 1)); strncpy(buf, &text_rep[ipos], (size_t)replen); buf[replen] = '\0'; /* * Advance to the correct line */ str = strtok(buf, DELMTR); if ( str != NULL ) { str = strtok(NULL, DELMTR); str = strtok(NULL, DELMTR); } if ( str ) { str = strtok(str, " "); /* * Get the station and the WMO id */ while ( str ) { if ( isalpha(str[0]) ) { if ( flag == 0 ) { strcpy(t_str, str); flag = 1; } else { if ( repnum < MAX_REPORTS ) { sprintf(reportInfo[repnum].stnid, " %s ", str); index = srchw_binSrch( stnList.srchstr, stnList.nstn, reportInfo[repnum].stnid ); if( index >= 0 ) { if( strncmp( _cache, &(text_rep[ipos+CACHE_POS]), 30 ) != 0 ) { reportInfo[repnum].stnindex = index; reportInfo[repnum].position = ipos; sprintf(reportInfo[repnum].fname, "%s/%s", dir_info->dirpath, dir_info->filnam[srch_info->dir_info.cfilnum] ); repnum++; cst_ncpy( _cache, &(text_rep[ipos+CACHE_POS]), 30, iret ); } } else { sprintf( notfound_msg, "PRODUCT STATION \"%s\" not found in table.\n", reportInfo[repnum].stnid ); if ( called_from == 1 ) { pdata_setReportText( notfound_msg, &ier ); txtw_dsplyReport( &ier ); } reportInfo[repnum].stnid[0] = '\0'; } } else { sprintf( exceeds_msg, "Report limit reached (%d) -- " "Reduce Time Covered.\n", MAX_REPORTS ); if ( called_from == 1 ) { pdata_setReportText( exceeds_msg, &ier ); txtw_dsplyReport( &ier ); } } } } else { flag = 0; break; } str = strtok(NULL, " "); } } ibeg = --ipos; } stnList.nreports = repnum; }
static void _vrfyTimes ( char *instr, int *iret ) /************************************************************************ * _vrfyTimes * * * * Validates a time filter string. Valid entries include "AIRM", "OTLK",* * and time strings in forms of "HH+", and "HH-HH". Note that '+', '-',* * and the "HH" after the '-' are optional; e.g, "1", "2+", "2-", and * * "2-3" are valid entries ( "2-" will be truncated as "2" ). * * * * static void _vrfyTimes ( instr, iret ) * * * * Input/Output parameters: * * *instr char string to be verified. It will be cut * * off at the proper position after check. * * * * Output parameters: * * *iret int return code * * 0 - Normal * * -1 - Invalid entry * * 1 - Partially valid entry * * cut off at postion "pos" * ** * * Log: * * J. Wu/SAIC 06/06 move from nmap_pgfilter.c and allow * * "AIRM", "OTLK", & '+' * ***********************************************************************/ { int ii, dashPos, plusPos, len, ier; /*---------------------------------------------------------------------*/ *iret = 0; /* * Null string or string starting with non-digit char are invalid * except "AIRMET" and "OTLK". */ if ( !instr ) { *iret = -1; return; } if ( !isdigit(instr[0]) ) { if ( !strcmp( instr, "AIRM" ) == 0 && !strcmp( instr, "OTLK" ) == 0 ) { *iret = -1; instr[0] = '\0'; } return; } /* * One '+' is acceptable as the 2nd or 3rd char. */ cst_nocc ( instr, '+', 1, TRUE, &plusPos, &ier ); if ( ier == 0 ) { if ( plusPos > 2 ) { instr[ plusPos ] = '\0'; } else { if ( plusPos == 1 || ( plusPos == 2 && isdigit( instr[1] ) ) ) { instr[ plusPos + 1 ] = '\0'; } else { *iret = -1; instr[0] = '\0'; } return; } } /* * One '-' is acceptable as the 2nd, 3rd, or 4th char. */ cst_nocc ( instr, '-', 1, TRUE, &dashPos, &ier ); len = strlen ( instr ); if ( dashPos == 0 || dashPos > 3 ) { for ( ii = 0; ii < 3; ii++ ) { if ( !isdigit(instr[ii]) ) break; } } else { /* dashPos == 1, 2, or 3 */ for ( ii = dashPos+1; ii < G_MIN(len,dashPos+4); ii++ ) { if ( !isdigit(instr[ii]) ) { break; } } if ( ii == (dashPos+1) ) ii--; } instr[ii] = '\0'; if ( ii != len ) { *iret = 1; /* indicate cutoff at position "ii" */ } }
/* 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); }
/* 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); }
void wbc_area ( char *locnam, char *vorstr, int len, char *areastr, int *iret ) /************************************************************************ * wbc_area * * * * This function converts the VOR stations string to the VOR watch area * * string,containing distance, direction, county names and state ids. * * * * Input example: * * 17 WNW DEC;26 E FAM;26 WNW FAM;55 SSE COU;22 NNW UIN;47 ENE UIN; * * * * Output example: * * 17 WNW OF DECATUR, IL..TO 26 E OF FARMINGTON, MO..TO 26 WNW OF * * FARMINGTON, MO..TO 55 SSE OF COLUMBIA, MO..TO 22 NNW OF QUINCY, * * IL..TO 47 ENE OF QUINCY, IL. * * * * wbc_area ( locnam, vorstr, len, areastr, iret ) * * * * Input parameters: * * *locnam char Locator type * * *vorstr char Polygon text string * * len int Max length of 'areastr' * * * * Output parameters: * * *areastr char Polygon area text string * * *iret int Return value * * -5 = VORSTR too big * * * ** * * Log: * * A. Hardy/NCEP 5/03 From VF_AREA * ************************************************************************/ { int ii, nstn, maxlen, nstr, np, icnt, ier, exp, max, len1; char tmpstr[420], holdstr[200], qstate[1], pstn[180]; char arrgrp[15], **aryvor, county[30], state[3]; /*---------------------------------------------------------------------*/ *iret = 0; np = 1; icnt = 1; max = 6; exp = 4; qstate[0] = '\0'; tmpstr[0] = '\0'; maxlen = sizeof(pstn); if ( strcmp ( locnam, "VOR") != 0 ) { *iret = -2; return; } cst_lstr ( vorstr, &len1, &ier ); if ( len1 >= 400 ) { *iret = -5; return; } /* * Set up the memory space to break up the VOR area string. */ clo_init ( &ier ); aryvor = (char **) malloc(sizeof(char *) * 4); for ( ii = 0; ii < 4; ii++ ) { aryvor[ii] = (char *) malloc(6) ; } /* * Get the city and state of the VOR station. */ for ( ii = 0; ii < 6; ii++) { vorstr = (char *) cst_split ( vorstr, ';', 12, arrgrp, &ier); cst_clst ( arrgrp, ' ', " ", exp, max, aryvor, &nstr, &ier); if ( nstr == 3 ) { clo_findstn ( locnam, aryvor[2], qstate, np, maxlen, &nstn, pstn, &ier); } else if ( nstr == 2) { clo_findstn ( locnam, aryvor[1], qstate, np, maxlen, &nstn, pstn, &ier); } cst_gtag ( "NAME", pstn, " ", county, &ier ); cst_gtag ( "ST", pstn, " ", state, &ier ); cst_rnan (county, county, &ier); /* * Create the watch area string. */ holdstr[0] = '\0'; if ( icnt < 6 ) { if ( strcmp ( aryvor[0], "..") != 0 ) { sprintf( holdstr," %s %s OF %s, %s..TO ",aryvor[0], aryvor[1], county, state); } else { /* * Print string for zero distance and no direction. */ sprintf( holdstr," %s, %s..TO ", county, state); } } else { if ( strcmp ( aryvor[0], "..") != 0 ) { sprintf( holdstr," %s %s OF %s, %s.",aryvor[0], aryvor[1], county, state); } else { /* * Print string for zero distance and no direction. */ sprintf( holdstr," %s, %s.", county, state); } } icnt++; cst_ncat ( tmpstr, holdstr, &len1, &ier); } len1 = G_MIN ( len, (int)strlen(tmpstr) ); cst_ncpy( areastr, tmpstr, len1, &ier); /* * Free memory space. */ for ( ii = 0; ii < 4; ii++ ) { free ( aryvor[ii] ); } free ( aryvor); }
void pglpfw_loadLPF ( int *iret ) /************************************************************************ * pglpfw_loadLPF * * * * This function opens a LP file and load the VG files into different * * layers by the specified color, fill modes, and group types. If the * * the VG file does not exist, it will be created. * * * * void pglpfw_loadLPF ( iret ) * * * * Input parameters: * * Output parameters: * * *iret int 0 = normal * * -1 = no file name * * -2 = error on read * * Return parameters: * * NONE * * * ** * * Log: * * T. Lee/SAIC 04/02 * * T. Lee/SAIC 05/02 added layer display mode * * E. Safford/SAIC 06/02 param change to ctb_lygetname * * J. Wu/SAIC 12/02 fix the crashing from multi-exposures * * H. Zeng/XTRIA 03/03 removed one call to pglayer_setDefGrp() * * E. Safford/SAIC 04/04 ChngMade flag TRUE if outfile specified * ***********************************************************************/ { Widget curwid; char fname[FILE_FULLSZ], vfile[FILE_FULLSZ]; char outfile[FILE_FULLSZ]; char path[LLPATH]; char gtype[10], ugtype[10], laynam[10], mode[4], umode[4]; char cmode[5], ucmode[5], *cptr; int ipos, ier, ier1, ntop, icolr, layer_num; int ii, grpid; Boolean can_open, outfile_ok; /*---------------------------------------------------------------------*/ *iret = 0; can_open = FALSE; outfile_ok = FALSE; if ( strlen(_fileName) <= (size_t)0 ) { *iret = -1; return; } else { strcpy (fname, _dirPath); strcat (fname, _fileName); cst_srch ( 0, strlen(fname), ".lpf", fname, &ipos, &ier ); if ( ier == -4 ) { strcat(fname, ".lpf"); } } /* * Open the layer product file. */ ctb_lyrd ( fname, &ntop, &ier ); if ( ntop < 0 || ier < 0 ) { er_wmsg ( "CTB", &ier, fname, &ier1, 3, strlen(fname) ); NxmErr_update(); pglayer_setChngMade ( 0, FALSE ); *iret = -2; return; } /* * Prompt error message if default is used. */ else if ( ier > 0 ) { er_wmsg ( "CTB", &ier, " ", &ier1, 3, 1 ); NxmErr_update(); } /* * Delete all records and clear drawing area */ pgpalw_deleteAll(); /* * Store the LPF into layer structure. */ ntop = G_MIN ( ntop, MAX_LAYERS ); curwid = pgpalw_getOperWid ( FUNC_LAYER ); pgpalw_setCurOper ( curwid ); pgpalw_actvLayer ( False ); for ( ii = 0; ii < ntop; ii++ ) { /* * Set color mode. */ ctb_lygetcmode ( ii, cmode, &ier ); cst_lcuc ( cmode, ucmode, &ier1 ); if ( strcmp ( ucmode, "MONO" ) == 0 ) { pglayer_setDsplClr ( ii, FALSE ); } else { pglayer_setDsplClr ( ii, TRUE ); } /* * Set color ID. */ ctb_lygetcolor ( ii, &icolr, &ier ); if ( ier == 0 ) { pglayer_setMonoClr ( ii, icolr ); } else { icolr = 19; pglayer_setMonoClr ( ii, icolr ); } /* * Get the output VG file name */ outfile_ok = FALSE; ctb_lygetoutfile( ii, outfile, &ier ); if ( strlen( outfile ) > (size_t)0 ) { /* * Check if the outfile is valid VG file. If the file does not exist, * create it. If the file is invalid, an error message is generated. * * The outfile_ok flag signals a good outfile condition. Otherwise * we have no outfile available. */ cvg_valid ( outfile, &ier ); if ( ier >= 0 ) { outfile_ok = TRUE; if ( ier > 0 ) { cvg_crvgf( outfile, &ier ); ier = 2; er_wmsg( "CVG", &ier, outfile, &ier1, 3, strlen(outfile) ); NxmErr_update(); } } else { er_wmsg ( "CVG", &ier, outfile, &ier1, 3, strlen(vfile)); NxmErr_update(); } } /* * Set input VG file name. */ ctb_lygetfile ( ii, vfile, &ier ); /* * Check if this is a valid VG file. * * If the file does not exist, and we did not find a file and there, * is no specified output file, then create one. If the file is * invalid, an error message is written out. */ cvg_valid ( vfile, &ier ); if ( ier >= 0 ) { can_open = TRUE; if ( ier > 0 && !outfile_ok ) { cvg_crvgf ( vfile, &ier ); ier = 2; er_wmsg ( "CVG", &ier, vfile, &ier1, 3, strlen(vfile)); NxmErr_update(); } } else { can_open = FALSE; er_wmsg ( "CVG", &ier, vfile, &ier1, 3, strlen(vfile)); NxmErr_update(); } if ( (cptr = strrchr (vfile, '/') ) == (char *) NULL) { pglayer_setFileName ( ii, vfile ); strcpy (path, "./"); } else { cptr++; pglayer_setFileName ( ii, cptr ); cptr[0] = '\0'; strcpy ( path, vfile ); } pglayer_setFilePath ( ii, path ); /* * Set group type. */ ctb_lygetgrptyp ( ii, gtype, &ier ); cst_lcuc ( gtype, ugtype, &ier1 ); if ( ier == 0 ) { ces_gtgid ( ugtype, &grpid, &ier1 ); if ( ier1 == 0 ) { pglayer_setDefGrp ( ii, grpid ); } } /* * Set fill mode. */ ctb_lygetfmode ( ii, mode, &ier ); cst_lcuc ( mode, umode, &ier1 ); if ( strcmp (umode, "OFF") == 0 ) { pglayer_setFill ( ii, FALSE ); } else { pglayer_setFill ( ii, TRUE ); } /* * Set display mode. */ ctb_lygetdsply ( ii, mode, &ier ); cst_lcuc ( mode, umode, &ier1 ); if ( strcmp (umode, "OFF") == 0 ) { pglayer_setDsplOn ( ii, FALSE ); } else { pglayer_setDsplOn ( ii, TRUE ); } /* * Set layer name. */ ctb_lygetname ( ii, sizeof(laynam), laynam, &ier ); if ( ier == 0 ) { pglayer_setName ( ii, laynam ); } /* * Prepare to draw in a new layer. */ pglpfw_prepLPF ( ii ); /* * Reset flags for change mode. */ pglayer_setChngMade ( ii, FALSE ); /* * Load VG files. */ if ( can_open ) { pgfilw_openVGF (FALSE, &ier); } /* * If the outfile_ok is true, then reset the file name for the layer. * * Also, since there is a specified output file in the lpf, set the * save flag so any save to it is done without the initial Save As. */ if ( outfile_ok ) { if ( (cptr = strrchr (outfile, '/') ) == (char *) NULL) { pglayer_setFileName ( ii, outfile ); strcpy (path, "./"); } else { cptr++; pglayer_setFileName ( ii, cptr ); cptr[0] = '\0'; strcpy ( path, outfile ); } pglayer_setFilePath ( ii, path ); pglayer_setChngMade ( ii, TRUE ); pglayer_setFileSaved( ii, True ); } } /* * If reaching MAX_LAYERS, set "ADD LAYER" button insensitive. */ layer_num = pglayer_getNumLayers(); if ( layer_num == MAX_LAYERS ) { pgpalw_setBtnSntv ( FUNC_LAYER, FALSE ); } /* * Bring up the layering window. */ pglayrw_manageLayers (); }
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 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 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; } }
int main (void) /************************************************************************ * TESTDA * * * * This program tests the GEMLIB DA functions. * * * ** * * Log: * * S. Jacobs/NCEP 5/13 Initial coding * ***********************************************************************/ { int cont, ier, iret, numsub, is, ie, ii; char select[5]; char pyfile[MXFLSZ], pymeth[MXFLSZ]; /*---------------------------------------------------------------------*/ in_bdta(&ier); cont = G_TRUE; while ( cont ) { printf ( "\n\n" ); printf ( " 1 = DA_RUNPY for CHAR output\n" ); printf ( " 2 = DA_RUNPY for INT output\n" ); printf ( " 3 = DA_RUNPY for FLOAT output\n" ); printf ( "\n" ); printf ( "Select a subroutine number or type EXIT: " ); ier = getinp ( 1, select, NULL, NULL, 4 ); switch ( select[0] ) { case 'e': case 'E': cont = G_FALSE; default: numsub = atoi ( select ); break; } /*---------------------------------------------------------------------*/ if ( numsub == 1 ) { printf ( "Enter the Python file name (without .py):\n" ); ier = getinp ( 1, pyfile, NULL, NULL, MXFLSZ ); if ( ier < 0 ) { break; } printf ( "Enter the Python method name:\n" ); ier = getinp ( 1, pymeth, NULL, NULL, MXFLSZ ); if ( ier < 0 ) { break; } printf ( "Enter the number of input strings:\n" ); ier = getinp ( 2, NULL, &danarg, NULL, STRSIZE ); if ( ier < 0 ) { break; } daargs = (char **) malloc ( danarg * sizeof(char *) ); for ( ii = 0; ii < danarg; ii++ ) { daargs[ii] = (char *) malloc ( STRSIZE * sizeof(char) ); printf ( "Enter input string %d:\n", ii ); ier = getinp ( 1, daargs[ii], NULL, NULL, STRSIZE ); if ( ier < 0 ) { break; } } datype = DACHAR; da_runpy ( pyfile, pymeth, &iret ); printf ( "\nDA_RUNPY: iret = %d\n\n", iret ); if ( iret >= 0 ) { printf ( "The length of result is: %ld\n", strlen(daoutc) ); printf ( "The result is: %s\n\n", daoutc ); free ( daoutc ); } free ( daargs ); } /*---------------------------------------------------------------------*/ if ( numsub == 2 ) { printf ( "Enter the Python file name (without .py):\n" ); ier = getinp ( 1, pyfile, NULL, NULL, MXFLSZ ); if ( ier < 0 ) { break; } printf ( "Enter the Python method name:\n" ); ier = getinp ( 1, pymeth, NULL, NULL, MXFLSZ ); if ( ier < 0 ) { break; } printf ( "Enter the number of input strings:\n" ); ier = getinp ( 2, NULL, &danarg, NULL, STRSIZE ); if ( ier < 0 ) { break; } daargs = (char **) malloc ( danarg * sizeof(char *) ); for ( ii = 0; ii < danarg; ii++ ) { daargs[ii] = (char *) malloc ( STRSIZE * sizeof(char) ); printf ( "Enter input string %d:\n", ii ); ier = getinp ( 1, daargs[ii], NULL, NULL, STRSIZE ); if ( ier < 0 ) { break; } } datype = DAINT; da_runpy ( pyfile, pymeth, &iret ); printf ( "\nDA_RUNPY: iret = %d\n\n", iret ); if ( iret >= 0 ) { printf ( "The array size of result is: %d\n", danumi ); printf ( "The result array is:\n" ); is = 0; ie = G_MIN ( 8, danumi ); while ( is < danumi ) { for ( ii = is; ii < ie; ii++ ) { printf ( "%9d ", daouti[ii] ); } printf ( "\n" ); is = ie; ie = G_MIN ( is+8, danumi ); } printf ( "\n" ); free ( daouti ); } free ( daargs ); } /*---------------------------------------------------------------------*/ if ( numsub == 3 ) { printf ( "Enter the Python file name (without .py):\n" ); ier = getinp ( 1, pyfile, NULL, NULL, MXFLSZ ); if ( ier < 0 ) { break; } printf ( "Enter the Python method name:\n" ); ier = getinp ( 1, pymeth, NULL, NULL, MXFLSZ ); if ( ier < 0 ) { break; } printf ( "Enter the number of input strings:\n" ); ier = getinp ( 2, NULL, &danarg, NULL, STRSIZE ); if ( ier < 0 ) { break; } daargs = (char **) malloc ( danarg * sizeof(char *) ); for ( ii = 0; ii < danarg; ii++ ) { daargs[ii] = (char *) malloc ( STRSIZE * sizeof(char) ); printf ( "Enter input string %d:\n", ii ); ier = getinp ( 1, daargs[ii], NULL, NULL, STRSIZE ); if ( ier < 0 ) { break; } } datype = DAFLOAT; da_runpy ( pyfile, pymeth, &iret ); printf ( "\nDA_RUNPY: iret = %d\n\n", iret ); if ( iret >= 0 ) { printf ( "The array size of result is: %d\n", danumf ); printf ( "The result array is:\n" ); is = 0; ie = G_MIN ( 8, danumf ); while ( is < danumf ) { for ( ii = is; ii < ie; ii++ ) { printf ( "%9.2f ", daoutf[ii] ); } printf ( "\n" ); is = ie; ie = G_MIN ( is+8, danumf ); } printf ( "\n" ); free ( daoutf ); } free ( daargs ); } /*---------------------------------------------------------------------*/ } return 0; }
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; }
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 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; }
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 ); } }
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 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]; } } } }
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 ); }