int main ( int argc, char **argv ) /************************************************************************ * clipvgf * * * * This program clips elements in a VGF file based on a bounds * * specification. By default, a simple clipping algorithm is used * * where element points either inside or outside the polygon are kept * * or thrown away based on an input flag. Alternatively, an exact * * algorithm may be requested which clips precisely at the borders. * * * * The bound definition must be in the format: * * bound_name|<area_tag_name>area_tag_value * * and must be enclosed w/ quotes so the shell will ignore directives. * * * * Examples: * * clipvgf input.vgf "STATE_BNDS|<STATE>WY" keep output.vgf rough * * clipvgf input.vgf "STATE_BNDS|<STATE>WY" keep output.vgf exact * * Where "rough" uses the simple clipping algorithm and "exact" yields * * precise clipping at the bounds borders. * * * * The following element classes are not processed: * * CLASS_WATCHES, CLASS_TRACKS, CLASS_SIGMETS * * * * 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 2/02 * * D.W.Plummer/NCEP 5/02 Added exact clipping and label moving * * D.W.Plummer/NCEP 8/02 Account for text grouped with symbol * * D.W.Plummer/NCEP 8/02 Create output VGF, even if it is empty * * H. Zeng/XTRIA 02/03 converted CLASS_CIRCLE to CLASS LINES * * D.W.Plummer/NCEP 8/03 Bug fix - add pt to closed lines * * R. Tian/SAIC 11/04 Added clip jet element * * S. Danz/AWC 07/06 Update to new cvg_writef() parameter * * T. Piper/SAIC 03/07 Added ninout-- for closed line case * * L. Hinson/AWC 07/07 Added clip code for GFA elements * * L. Hinson/AWC 07/07 Add recalcGFAtLblArwLoc function * for GFA elements * * X.Guo/CWS 10/10 Bug fix - Low level graphic don't make * * it all the way north in central US * * L. Hinson/AWC 09/13 Fixed improperly clipped JET_ELM Barbs * * and hashes * ***********************************************************************/ { int ii, jj, ip, ibeg, iend, loc, ne, found, found_txt, joffset, kept, ier; int wrtflg, pagflg; int minpts, maxpts, npts, numpts, npoly; char vg_class, vg_type; char bnd[128], keep[32], bnd_name[64], bnd_tag[64]; char infile[128], ifname[128], outfile[128]; char *cptr; long ifilesize; int more, curpos; float flat, flon, filt, px[LLMXPT], py[LLMXPT]; float plat[LLMXPT], plon[LLMXPT], *ptrlat, *ptrlon; float tlat[LLMXPT], tlon[LLMXPT]; float fltmin, fltmax, flnmin, flnmax; int inout[LLMXPT], tinout[LLMXPT]; char device[8], dfilnam[128], pro[32]; float xsize, ysize, lllat, lllon, urlat, urlon; float prjang1, prjang2, prjang3; int mode, istat, iunit, itype; char errgrp[8]; int ninout; float xinout[LLMXPT], yinout[LLMXPT]; char precision[8]; int tltpts, nbarb, nhash; int tmaxpts, tnpts, tnclip; char hazList[ STD_STRLEN ]; VG_DBStruct el, el_t, el_q, el_lin; FILE *ifptr; int ninxarr, inxarr[100]; /*---------------------------------------------------------------------*/ /* * First check if number of input arguments is correct. */ if ( argc < 5 ) { pagflg = G_FALSE; strcpy ( errgrp, "CLIPVGF" ); ip_help ( errgrp, &pagflg, &ier, strlen(errgrp) ); exit (0); } /* * First input on command line is input vgf file name. */ strcpy ( infile, argv[1] ); wrtflg = 0; cvg_open ( infile, wrtflg, &(ifptr), &ier ); if ( ier != 0 ) { printf("Error opening VGF file %s\n", infile ); exit (0); } cfl_inqr ( infile, NULL, &ifilesize, ifname, &ier ); /* * Second input on command line is bounds name. */ clo_init ( &ier ); strcpy ( bnd, argv[2] ); cptr = cst_split( bnd, '|', sizeof(bnd_name), bnd_name, &ier ); clo_bstype ( bnd_name, &ier ); if ( ier != 0 ) { printf("Error finding bounds type %s\n", bnd_name ); exit (0); } if ( cptr != (char *)NULL ) { strcpy ( bnd_tag, cptr ); clo_bstag ( bnd_tag, &ier ); } fltmin = -90.0F; fltmax = 90.0F; flnmin = -180.0F; flnmax = 180.0F; clo_bsarea ( &fltmin, &flnmin, &fltmax, &flnmax, &ier ); minpts = 3; maxpts = sizeof(px)/sizeof(float); filt = 0.0F; clo_bgnext ( &minpts, &maxpts, &filt, &npoly, px, py, &ier ); if ( ier < 0 ) { printf("Error retrieving bound area %s|%s\n", bnd_name, bnd_tag ); exit (0); } /* * Third input on command line is keep flag. */ strcpy ( keep, argv[3] ); /* * Fourth input on command line is output vgf file name; create it. */ strcpy ( outfile, argv[4] ); cvg_crvgf ( outfile, &ier ); /* * Fifth input on command line is clip precision = "rough" or "exact" */ if ( argv[5] != (char *)NULL ) strcpy ( precision, argv[5] ); else strcpy ( precision, "ROUGH" ); cst_lcuc ( precision, precision, &ier ); /* * All input checks out OK; set up GAREA and PROJ for inpoly. */ mode = 1; ginitp ( &mode, &istat, &ier ); strcpy ( device, "GN" ); iunit = 1; strcpy ( dfilnam, "CLIPVGF" ); itype = 1; xsize = 500.0F; ysize = 500.0F; gsdeva ( device, &iunit, dfilnam, &itype, &xsize, &ysize, &ier, strlen(device), strlen(dfilnam)); /* * Something more sophisticated may be needed here in the future * to set up a proper proj and garea based on the clip area. * For instance, the following definitions probably won't work * on a clipping bound equivalent to Antartica. */ lllat = 0.0F; lllon = -135.0F; urlat = 0.0F; urlon = 45.0F; strcpy ( pro, "str" ); prjang1 = 90.0F; prjang2 = -105.0F; prjang3 = 0.0F; gsmprj ( pro, &prjang1, &prjang2, &prjang3, &lllat, &lllon, &urlat, &urlon, &ier, strlen(pro)); /* * Loop through all the elements to set the range records. */ crg_init ( &ier ); ne = 0; more = G_TRUE; curpos = 0; ifptr = (FILE *) cfl_ropn(ifname, "", &ier); while ( ne < MAX_EDITABLE_ELEMS && more == G_TRUE ) { cvg_rdrecnoc ( ifname, ifptr, curpos, &el, &ier ); if ( ier < 0 ) { more = G_FALSE; } else { crg_set ( &el, curpos, 1, &ier ); curpos += el.hdr.recsz; ne++; } } cfl_clos ( ifptr, &ier ); /* * Loop through all the elements. */ ne = 0; more = G_TRUE; curpos = 0; ifptr = (FILE *) cfl_ropn(ifname, "", &ier); while ( ne < MAX_EDITABLE_ELEMS && more == G_TRUE ) { cvg_rdrecnoc( ifname, ifptr, curpos, &el, &ier ); if ( ier < 0 ) { more = G_FALSE; } else if ( el.hdr.recsz > 0 ) { crg_gginx( el.hdr.grptyp, el.hdr.grpnum, sizeof(inxarr)/sizeof(inxarr[0]), inxarr, &ninxarr, &ier ); /* * Increment file pointer now because element hdrsz may change. */ curpos += el.hdr.recsz; vg_class = el.hdr.vg_class; vg_type = el.hdr.vg_type; switch ( (int)vg_class ) { case CLASS_SYMBOLS: case CLASS_TEXT: case CLASS_WINDS: case CLASS_COMSYM: case CLASS_MARKER: switch ( (int)vg_type ) { case TEXT_ELM: case TEXTC_ELM: flat = el.elem.txt.info.lat; flon = el.elem.txt.info.lon; break; case SPTX_ELM: flat = el.elem.spt.info.lat; flon = el.elem.spt.info.lon; break; case BARB_ELM: case ARROW_ELM: case DARR_ELM: case HASH_ELM: flat = el.elem.wnd.data.latlon[0]; flon = el.elem.wnd.data.latlon[1]; break; case WXSYM_ELM: case CTSYM_ELM: case ICSYM_ELM: case PTSYM_ELM: case PWSYM_ELM: case SKSYM_ELM: case SPSYM_ELM: case TBSYM_ELM: case MARK_ELM: case CMBSY_ELM: flat = el.elem.sym.data.latlon[0]; flon = el.elem.sym.data.latlon[1]; break; } npts = 1; cgr_inpoly ( "M", &npts, &flat, &flon, "M", &npoly, px, py, inout, &ier ); if ( ( inout[0] == 1 && strcmp(keep,"keep") == 0 ) || ( inout[0] == 0 && strcmp(keep,"keep") != 0 ) ) { /* * Check if element is TEXT grouped with a SYMBOL. If this text was going * to be kept but it's symbol was going to be throw away, throw it away also. */ if ( (int)vg_class == CLASS_TEXT && (int)el.hdr.grptyp != 0 && ninxarr > 1 ) { found = G_FALSE; ii = 0; while ( ii < ninxarr && found == G_FALSE ) { crg_goffset ( inxarr[ii], &joffset, &ier ); cvg_rdrecnoc( ifname, ifptr, joffset, &el_q, &ier ); if ( el_q.hdr.vg_class == CLASS_SYMBOLS ) { found = G_TRUE; flat = el_q.elem.sym.data.latlon[0]; flon = el_q.elem.sym.data.latlon[1]; npts = 1; cgr_inpoly ( "M", &npts, &flat, &flon, "M", &npoly, px, py, inout, &ier ); if ((inout[0] == 1 && strcmp(keep,"keep") == 0) || (inout[0] == 0 && strcmp(keep,"keep") != 0)) { cvg_writef( &el, -1, el.hdr.recsz, outfile, FALSE, &loc, &ier ); kept = G_TRUE; } else { kept = G_FALSE; } } ii++; } if ( found == G_FALSE ) { cvg_writef( &el, -1, el.hdr.recsz, outfile, FALSE, &loc, &ier ); kept = G_TRUE; } } else { /* * non-TEXT -- keep it. */ cvg_writef( &el, -1, el.hdr.recsz, outfile, FALSE, &loc, &ier ); kept = G_TRUE; } } else { /* * Element is not to be kept. */ kept = G_FALSE; } /* * Check if element was kept and is a SYMBOL element grouped with TEXT; * make sure any text elements are saved off they were going to be thrown away. */ if ( kept == G_TRUE && (int)vg_class == CLASS_SYMBOLS && (int)el.hdr.grptyp != 0 && ninxarr > 1 ) { ii = 0; while ( ii < ninxarr ) { crg_goffset ( inxarr[ii], &joffset, &ier ); cvg_rdrecnoc( ifname, ifptr, joffset, &el_q, &ier ); if ( el_q.hdr.vg_class == CLASS_TEXT ) { el_t = el_q; switch ( (int)el_t.hdr.vg_type ) { case TEXT_ELM: case TEXTC_ELM: flat = el_t.elem.txt.info.lat; flon = el_t.elem.txt.info.lon; break; case SPTX_ELM: flat = el_t.elem.spt.info.lat; flon = el_t.elem.spt.info.lon; break; } npts = 1; cgr_inpoly ( "M", &npts, &flat, &flon, "M", &npoly, px, py, inout, &ier ); if ( ( kept == G_TRUE ) && ( ( inout[0] == 1 && strcmp(keep,"keep") == 0 ) || ( inout[0] == 0 && strcmp(keep,"keep") != 0 ) ) ) { } else { cvg_writef ( &el_t, -1, el_t.hdr.recsz, outfile, FALSE, &loc, &ier ); } } ii++; } } break; case CLASS_CIRCLE: case CLASS_LINES: case CLASS_FRONTS: /* * convert a circle element to a line element */ if ( vg_class == CLASS_CIRCLE ) { cvg_cir2lin ( &el, 10, &el_lin, &ier ); el = el_lin; vg_class = el.hdr.vg_class; vg_type = el.hdr.vg_type; } switch ( (int)vg_type ) { case LINE_ELM: npts = el.elem.lin.info.numpts; ptrlat = &(el.elem.lin.latlon[ 0]); ptrlon = &(el.elem.lin.latlon[npts]); break; case SPLN_ELM: npts = el.elem.spl.info.numpts; ptrlat = &(el.elem.spl.latlon[ 0]); ptrlon = &(el.elem.spl.latlon[npts]); break; case FRONT_ELM: npts = el.elem.frt.info.numpts; ptrlat = &(el.elem.frt.latlon[ 0]); ptrlon = &(el.elem.frt.latlon[npts]); break; } memcpy ( plat, ptrlat, (size_t)npts*sizeof(float) ); memcpy ( plon, ptrlon, (size_t)npts*sizeof(float) ); if ( el.hdr.closed == 1 ) { plat[npts] = plat[0]; plon[npts] = plon[0]; npts++; } if ( strcmp(precision,"EXACT") == 0 ) { clip_line ( npoly, px, py, npts, plat, plon, (int)el.hdr.closed, sizeof(xinout)/sizeof(float), &ninout, xinout, yinout, inout, &ier ); } else if ( strcmp(precision,"ROUGH") == 0 ) { cgr_inpoly ( "M", &npts, plat, plon, "M", &npoly, px, py, inout, &ier ); ninout = npts; memcpy ( xinout, plat, (size_t)ninout*sizeof(float) ); memcpy ( yinout, plon, (size_t)ninout*sizeof(float) ); } /* * If element is closed, and some points are to be kept and others are not, * then rotate the locations arrays such that a transition point is the first point. */ if ( el.hdr.closed == 1 ) { ip = 0; ninout--; while ( inout[ip] == inout[0] && ip < ninout ) ip++; if ( ip != ninout ) { if (( inout[0] == 1 && strcmp(keep,"keep") == 0 ) || ( inout[0] == 0 && strcmp(keep,"keep") != 0 ) ) { memcpy ( tlat, xinout, (size_t)ninout*sizeof(float) ); memcpy ( tlon, yinout, (size_t)ninout*sizeof(float) ); memcpy ( tinout, inout, (size_t)ninout*sizeof(float) ); for ( ii = 0; ii < ninout; ii++ ) { xinout[ii] = tlat[(ii+ip) % ninout]; yinout[ii] = tlon[(ii+ip) % ninout]; inout[ii] = tinout[(ii+ip) % ninout]; } } } } ip = 0; while ( ip < ninout ) { ibeg = ip; iend = ip; while ( inout[ip] == inout[ibeg] && ip < ninout ) ip++; iend = ip - 1; numpts = iend - ibeg + 1; /* * If element is closed, and some points are to be kept and others are not, * then reset the closed flag. */ if ( el.hdr.closed == 1 && numpts != ninout ) el.hdr.closed = 0; if ( numpts > 1 ) { if (( inout[ibeg] == 1 && strcmp(keep,"keep") == 0 ) || ( inout[ibeg] == 0 && strcmp(keep,"keep") != 0 ) ) { switch ( (int)vg_type ) { case LINE_ELM: el.elem.lin.info.numpts = numpts; ptrlat = &(el.elem.lin.latlon[ 0]); ptrlon = &(el.elem.lin.latlon[numpts]); el.hdr.recsz = ( (int)((sizeof(float) * 2 * (size_t)numpts) + sizeof(VG_HdrStruct) + sizeof(LineInfo) )); break; case SPLN_ELM: el.elem.spl.info.numpts = numpts; ptrlat = &(el.elem.spl.latlon[ 0]); ptrlon = &(el.elem.spl.latlon[numpts]); el.hdr.recsz = ( (int)((sizeof(float) * 2 * (size_t)numpts) + sizeof(VG_HdrStruct) + sizeof(SpLineInfo) )); break; case FRONT_ELM: el.elem.frt.info.numpts = numpts; ptrlat = &(el.elem.frt.latlon[ 0]); ptrlon = &(el.elem.frt.latlon[numpts]); el.hdr.recsz = ( (int)((sizeof(float) * 2 * (size_t)numpts) + sizeof(VG_HdrStruct) + sizeof(FrontInfo) )); break; } memcpy(ptrlat, &(xinout[ibeg]), (size_t)numpts*sizeof(float)); memcpy(ptrlon, &(yinout[ibeg]), (size_t)numpts*sizeof(float)); cvg_writef ( &el, -1, el.hdr.recsz, outfile, FALSE, &loc, &ier ); if ( (int)el.hdr.grptyp != 0 && ninxarr > 1 ) { found = G_FALSE; found_txt = G_FALSE; ii = 0; while ( ii < ninxarr && found == G_FALSE ) { crg_goffset ( inxarr[ii], &joffset, &ier ); cvg_rdrecnoc( ifname, ifptr, joffset, &el_q, &ier ); if ( el_q.hdr.vg_class == CLASS_TEXT ) { found_txt = G_TRUE; el_t = el_q; switch ( (int)el_t.hdr.vg_type ) { case TEXT_ELM: case TEXTC_ELM: flat = el_t.elem.txt.info.lat; flon = el_t.elem.txt.info.lon; break; case SPTX_ELM: flat = el_t.elem.spt.info.lat; flon = el_t.elem.spt.info.lon; break; } npts = 1; cgr_inpoly ( "M", &npts, &flat, &flon, "M", &npoly, px, py, inout, &ier ); if ( ( inout[0] == 1 && strcmp(keep,"keep") == 0 ) || ( inout[0] == 0 && strcmp(keep,"keep") != 0 ) ) { found = G_TRUE; break; } } ii++; } if ( found == G_FALSE && ii == ninxarr && found_txt == G_TRUE ) { switch ( (int)vg_type ) { case LINE_ELM: flat = ( el.elem.lin.latlon[0] + el.elem.lin.latlon[1] ) / 2.0F; flon = ( el.elem.lin.latlon[numpts] + el.elem.lin.latlon[numpts+1] ) / 2.0F; break; case SPLN_ELM: flat = ( el.elem.spl.latlon[0] + el.elem.spl.latlon[1] ) / 2.0F; flon = ( el.elem.spl.latlon[numpts] + el.elem.spl.latlon[numpts+1] ) / 2.0F; break; case FRONT_ELM: flat = ( el.elem.frt.latlon[0] + el.elem.frt.latlon[1] ) / 2.0F; flon = ( el.elem.frt.latlon[numpts] + el.elem.frt.latlon[numpts+1] ) / 2.0F; break; } switch ( (int)el_t.hdr.vg_type ) { case TEXT_ELM: case TEXTC_ELM: el_t.elem.txt.info.lat = flat; el_t.elem.txt.info.lon = flon; break; case SPTX_ELM: el_t.elem.spt.info.lat = flat; el_t.elem.spt.info.lon = flon; break; } cvg_writef ( &el_t, -1, el_t.hdr.recsz, outfile, FALSE, &loc, &ier ); } } } } } break; case CLASS_MET: switch ( (int)vg_type ) { case JET_ELM: npts = tltpts = el.elem.jet.line.spl.info.numpts; ptrlat = &(el.elem.jet.line.spl.latlon[ 0]); ptrlon = &(el.elem.jet.line.spl.latlon[npts]); memcpy ( plat, ptrlat, (size_t)npts*sizeof(float) ); memcpy ( plon, ptrlon, (size_t)npts*sizeof(float) ); if ( strcmp(precision,"EXACT") == 0 ) { clip_line ( npoly, px, py, npts, plat, plon, (int)el.hdr.closed, sizeof(xinout)/sizeof(float), &ninout, xinout, yinout, inout, &ier ); } else if ( strcmp(precision,"ROUGH") == 0 ) { cgr_inpoly ( "M", &npts, plat, plon, "M", &npoly, px, py, inout, &ier ); ninout = npts; memcpy ( xinout, plat, (size_t)ninout*sizeof(float) ); memcpy ( yinout, plon, (size_t)ninout*sizeof(float) ); } ip = 0; while ( ip < ninout ) { ibeg = ip; iend = ip; while ( inout[ip] == inout[ibeg] && ip < ninout ) ip++; iend = ip - 1; numpts = iend - ibeg + 1; if ( numpts > 1 ) { if (( inout[ibeg] == 1 && strcmp(keep,"keep") == 0 ) || ( inout[ibeg] == 0 && strcmp(keep,"keep") != 0 ) ) { memcpy ( &(el_t.hdr), &(el.hdr), sizeof(VG_HdrStruct) ); el_t.elem.jet.line.splcol = el.elem.jet.line.splcol; memcpy ( &(el_t.elem.jet.line.spl.info), &(el.elem.jet.line.spl.info), sizeof(SpLineInfo) ); el_t.elem.jet.line.spl.info.numpts = numpts; ptrlat = &(el_t.elem.jet.line.spl.latlon[ 0]); ptrlon = &(el_t.elem.jet.line.spl.latlon[numpts]); memcpy(ptrlat, &(xinout[ibeg]), (size_t)numpts*sizeof(float)); memcpy(ptrlon, &(yinout[ibeg]), (size_t)numpts*sizeof(float)); nbarb = 0; for ( ii = 0; ii < el.elem.jet.nbarb; ii++ ) { flat = el.elem.jet.barb[ii].wnd.data.latlon[0]; flon = el.elem.jet.barb[ii].wnd.data.latlon[1]; npts = 1; cgr_inpoly ( "M", &npts, &flat, &flon, "M", &npoly, px, py, tinout, &ier ); if (( tinout[0] == 1 && strcmp(keep,"keep") == 0 ) || ( tinout[0] == 0 && strcmp(keep,"keep") != 0 ) ) { memcpy ( &(el_t.elem.jet.barb[nbarb]), &(el.elem.jet.barb[ii]), sizeof(BarbAttr) ); nbarb++; } } el_t.elem.jet.nbarb = nbarb; nhash = 0; for ( ii = 0; ii < el.elem.jet.nhash; ii++ ) { flat = el.elem.jet.hash[ii].wnd.data.latlon[0]; flon = el.elem.jet.hash[ii].wnd.data.latlon[1]; npts = 1; cgr_inpoly ( "M", &npts, &flat, &flon, "M", &npoly, px, py, tinout, &ier ); if (( tinout[0] == 1 && strcmp(keep,"keep") == 0 ) || ( tinout[0] == 0 && strcmp(keep,"keep") != 0 ) ) { memcpy ( &(el_t.elem.jet.hash[nhash]), &(el.elem.jet.hash[ii]), sizeof(HashAttr) ); nhash++; } } el_t.elem.jet.nhash = nhash; cvg_writef ( &el_t, -1, el.hdr.recsz, outfile, FALSE, &loc, &ier ); } } } break; case GFA_ELM: /* Get the Hazard Type... */ cvg_getFld ( &el, TAG_GFA_AREATYPE, hazList, &ier ); npts = el.elem.gfa.info.npts; ptrlat = &(el.elem.gfa.latlon[0]); ptrlon = &(el.elem.gfa.latlon[npts]); memcpy ( plat, ptrlat, (size_t)npts*sizeof(float) ); memcpy ( plon, ptrlon, (size_t)npts*sizeof(float) ); if ( el.hdr.closed == 1 ) { plat[npts] = plat[0]; plon[npts] = plon[0]; npts++; } if(strcmp(hazList,"FZLVL")==0) { /* Is this a Freezing Level? */ if ( strcmp(precision,"EXACT") == 0 ) { clip_line ( npoly, px, py, npts, plat, plon, (int)el.hdr.closed, sizeof(xinout)/sizeof(float), &ninout, xinout, yinout, inout, &ier ); } else if (strcmp(precision,"ROUGH") == 0 ) { cgr_inpoly ( "M", &npts, plat, plon, "M", &npoly, px, py, inout, &ier ); ninout = npts; memcpy ( xinout, plat, (size_t)ninout*sizeof(float) ); memcpy ( yinout, plon, (size_t)ninout*sizeof(float) ); } if ( el.hdr.closed == 1 ) { ip = 0; ninout--; while ( inout[ip] == inout[0] && ip < ninout ) ip++; if ( ip != ninout ) { if (( inout[0] == 1 && strcmp(keep,"keep") == 0 ) || ( inout[0] == 0 && strcmp(keep,"keep") != 0 ) ) { memcpy ( tlat, xinout, (size_t)ninout*sizeof(float) ); memcpy ( tlon, yinout, (size_t)ninout*sizeof(float) ); memcpy ( tinout, inout, (size_t)ninout*sizeof(float) ); for ( ii = 0; ii < ninout; ii++ ) { xinout[ii] = tlat[(ii+ip) % ninout]; yinout[ii] = tlon[(ii+ip) % ninout]; inout[ii] = tinout[(ii+ip) % ninout]; } } } } ip = 0; while ( ip < ninout ) { ibeg = ip; iend = ip; while ( inout[ip] == inout[ibeg] && ip < ninout ) ip++; iend = ip - 1; numpts = iend - ibeg + 1; if (el.hdr.closed == 1 && numpts != ninout ) el.hdr.closed = 0; if ( numpts > 1 ) { if (( inout[ibeg] == 1 && strcmp(keep,"keep") == 0 ) || ( inout[ibeg] == 0 && strcmp(keep,"keep") != 0 )) { el.elem.gfa.info.npts = numpts; ptrlat = &(el.elem.gfa.latlon[ 0]); ptrlon = &(el.elem.gfa.latlon[numpts]); memcpy(ptrlat, &(xinout[ibeg]), (size_t)numpts*sizeof(float)); memcpy(ptrlon, &(yinout[ibeg]), (size_t)numpts*sizeof(float)); /* Recompute Default Text Label & Arrow location */ recalcGFAtLblArwLoc( &el ); el.hdr.recsz = (int) (sizeof(VG_HdrStruct) + sizeof(int)*2 + sizeof(char)* STD_STRLEN * el.elem.gfa.info.nblocks ) + sizeof(float)*numpts*2; cvg_writef ( &el, -1, el.hdr.recsz, outfile, FALSE, &loc, &ier ); } } } } else { /* We have a GFA object (that's not a freezing level) to be clipped */ /* Use clo_clip to clip the GFA Polygon against the specified bounds area. The resulting number of clipped areas (tnclips), and max points (tmaxpts) is returned */ clo_clip(&npts, plat, plon, sys_M, bnd_name, bnd_tag, &tnclip, &tmaxpts, &ier); /* Foreach of the clipped areas, get the clipped area, and write it out to the VGF file */ for (ii = 0; ii < tnclip; ii++) { clo_clipget(&ii, &tnpts, tlat, tlon, &ier); el.elem.gfa.info.npts = tnpts; ptrlat = &(el.elem.gfa.latlon[ 0]); ptrlon = &(el.elem.gfa.latlon[tnpts]); /* Re-Initialize the latlon struct. */ for (jj =0; jj < MAXPTS*2; jj++) { el.elem.gfa.latlon[jj] = 0.00; } memcpy(ptrlat, &(tlat[0]), (size_t)tnpts*sizeof(float)); memcpy(ptrlon, &(tlon[0]), (size_t)tnpts*sizeof(float)); /* Recompute Default Text Label & Arrow location */ recalcGFAtLblArwLoc( &el ); el.hdr.recsz = (int) (sizeof(VG_HdrStruct) + sizeof(int)*2 + sizeof(char)* STD_STRLEN * el.elem.gfa.info.nblocks ) + sizeof(float)*tnpts*2; cvg_writef (&el, -1, el.hdr.recsz, outfile, FALSE, &loc, &ier ); } /* Free up memory left over from the clo routines */ clo_clipdone(&ier); } break; } break; } } ne++; } cfl_clos ( ifptr, &ier ); return(0); }
void cvg_rfrshLayer ( FILE *fp, char *fname, int layer, int fsize, float llx, float lly, float urx, float ury, int *iret ) /************************************************************************ * cvg_rfrshLayer * * * * This function re-displays all VG records that fall within a specified* * range on a given layer. The elements are displayed in sequence of * * their displaying level. By default, records on the given layer of * * WORK_FILE will be drawn. * * * * Note: The displaying level refers to the order in which VG elements * * are displayed ( i.e.,filled elements first, then lines, etc.) * * This is different from production layers. * * * * cvg_rfrshLayer ( fp, fname, layer, fsize, llx, lly, urx, ury, iret ) * * * * Input parameters: * * *fp FILE Pointer to VG "fname" * * *fname char VG File to be read * * layer int layer to to be drawn * * fsize int size of the VG file in bytes * * llx float Lower left X coordinate * * lly float Lower left Y coordinate * * urx float Upper right X coordinate * * ury float Upper right Y coordinate * * * * Output parameters: * * *iret int Return code * * -8 = No VG file is open * ** * * Log: * * J. Wu/SAIC 03/02 initial coding * * T. Lee/SAIC 11/03 used cvgcmn.h * * J. Wu/SAIC 07/04 add display filter * * 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 * * J. Wu/SAIC 06/06 call cvg_matchfilter * * M. Li/SAIC 03/07 Updated cvg_matchfilter * ***********************************************************************/ { int ii, kk, ier, flag, level, location, el_layer; int elms[3][MAX_EDITABLE_ELEMS], lvl_cnt[LEVELS]; float fllx, flly, furx, fury; VG_DBStruct el; filter_t el_filter, timeMatched; Boolean filter_match, matchAny = False; /*---------------------------------------------------------------------*/ *iret = 0; for ( ii = 0; ii < 3; ii++ ) { lvl_cnt[ ii ] = 0; } if ( fp == NULL ) { *iret = -1; return; } /* * Scan the range records and locate elements on the given layer. */ for ( ii = 0; ii < MAX_EDITABLE_ELEMS; ii++ ) { crg_goffset( ii, &location, &ier ); if ( location >= 0 ) { crg_get( ii, &el_layer, el_filter, &fllx, &flly, &furx, &fury, &ier); if ( el_layer == layer && cgr_ntrsct(llx, lly, urx, ury, fllx, flly, furx, fury, &ier) ) { cvg_matchfilter ( el_filter, matchAny, &filter_match, timeMatched, &ier ); if ( filter_match ) { cvg_rdhdr( fname, fp, location, fsize, &el, &flag, &ier ); cvg_level( &el.hdr, &level, &ier ); if ( ier == 0 ) { elms[ level ] [ lvl_cnt[level]++ ] = location; } } } } } /* * Now loop thru the levels and display elements on the given layer. */ level = 0; for ( ii = 0; ii < LEVELS; ii++ ) { for ( kk = 0; kk < lvl_cnt[level]; kk++ ) { location = elms[ii][kk]; cvg_rdhdr( fname, fp, location, fsize, &el, &flag, &ier ); cvg_rdele( &el, location, el.hdr.recsz, fp, &ier ); cds_dspelm( &el, &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 ); } } level++; } }
/* 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 cvg_scangfa ( char *fname, int layer, int subtype, int areatype, char *tag, VG_DBStruct *el, int *selected, int *iret ) /************************************************************************ * cvg_scangfa * * * * This function scans a vector graphics file looking for a GFA element * * that matches the layer, subtype, area type (hazard) and tag input. * * The first matching record is returned in "el". Also, * * the element should match one of the active filters. * * * * cvg_scan ( fname, layer, subtype, areatype, tag, el, selected, iret )* * * * Input parameters: * * *fname char Name of file to scan from * * layer int layer to test against * * subtype int subtype to test against * * areatype int area type to test against * * tag char gfa tag to test against * * * * Output parameters: * * *el VG_DBStruct Pointer to VG record structure * * *selected int Offset to selected element * * *iret int Return code * * -1 = error opening VG file * * -2 = error closing VG file * * -6 = element not found * * -13 = error reading VG header * * -14 = error reading VG element * * * ** * * Log: * * J. Wu/SAIC 08/04 initial coding (modified from cvg_scan) * * J. Wu/SAIC 10/04 use cvg_getFld to access GFA attributes * * E. Safford/SAIC 07/05 replace seqnum param with tag * * J. Wu/SAIC 06/06 call cvg_matchfilter * * M. Li/SAIC 03/07 Updated cvg_matchfilter * ***********************************************************************/ { int ii, ier, el_layer, location; float llx,lly,urx,ury; long size; char newfil[133], reqfil[133], cclass, ctype, value[32]; FILE *fp; filter_t el_filter, timeMatched; Boolean filter_match, matchAny = False; /*---------------------------------------------------------------------*/ *iret = 0; *selected = -1; if ( !fname ) { strcpy ( reqfil, work_file ); } else { strcpy ( reqfil, fname ); } /* * Inquire the size of the VG file and open the file for update. */ cfl_inqr ( reqfil, NULL, &size, newfil, &ier ); fp = (FILE *) cfl_uopn ( newfil, &ier ); if ( (ier != 0) || (fp == NULL) ) { *iret = -1; return; } /* * Loop through all elements to find a match. */ for ( ii = 0; ii < MAX_EDITABLE_ELEMS; ii++ ) { crg_goffset ( ii, &location, &ier ); if ( location < 0 ) { continue; } crg_get ( ii, &el_layer, el_filter, &llx, &lly, &urx, &ury, &ier ); if ( ier >= 0 ) { crg_gtyp ( ii, &cclass, &ctype, &ier ); } if ( ier < 0 ) { continue; } /* * Match layer, class, vg type first. */ if ( (el_layer == layer) && (cclass == CLASS_MET) && (ctype == GFA_ELM) ) { /* * Then check if the element matches one of the filters. */ cvg_matchfilter ( el_filter, matchAny, &filter_match, timeMatched, &ier ); if ( !filter_match ) { continue; } /* * Read the element. */ cvg_rdrecnoc ( newfil, fp, location, el, iret ); if ( *iret != 0 ) { continue; } /* * Match the subtype, area type, and tag. */ cvg_getFld ( el, TAG_GFA_SUBTYPE, value, &ier ); if ( subtype == atoi(value) ) { cvg_getFld ( el, TAG_GFA_AREATYPE, value, &ier ); if ( areatype == atoi(value) ) { cvg_getFld ( el, TAG_GFA_TAG, value, &ier ); if( strcmp( tag, value ) == 0 ) { *selected = location; break; } } } } } /* * Check if there is an matching record found. */ if ( *selected < 0 ) { *iret = -6; } /* * Close the VG file. */ cfl_clos(fp, &ier); if ( ier != 0 ) *iret = -2; }
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 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 pggrpch_popup ( void ) /************************************************************************ * pggrpch_popup * * * * This function pops up VG Group Change window. * * * * void pggrpch_popup() * * * * Input parameters: * * Output parameters: * * Return parameters: * * NONE * * * ** * * Log: * * H. Zeng/EAI 05/01 initial coding * * H. Zeng/EAI 03/02 renamed for new nmap_pggrpch file * * H. Zeng/EAI 04/02 modified to initialize _grpStr * * H. Zeng/EAI 05/02 modified to use master group type list * ***********************************************************************/ { int ii, el_num, el_loc, grpnum, ngrp, selection, iret, ier2; char grptyp, cc[20], grpnam[20]; char *names = NULL; char *ptr; XmString xmstr; static Boolean first = TRUE; /*---------------------------------------------------------------------*/ /* * Set "CURRENT GROUP" and "CHANGE TO" option menus at * the first time. */ if( first ) { /* * Initialize _curGrpStr and _chngToStr. */ ces_gtgmgrps(FALSE, &ngrp, &names, &iret); _numCurGrp = ngrp; _curGrpStr = (char**) malloc( _numCurGrp * sizeof(char*) ); ii = 0; ptr = strtok(names, ";"); while ( ptr != (char *)NULL ) { _curGrpStr[ii] = (char*) malloc( strlen(ptr)+5 ); strcpy(_curGrpStr[ii], ptr); ptr = strtok(NULL, ";" ); ii++; } if ( names != NULL ) free (names); ces_gtggrps(&ngrp, &names, &iret); _numChngTo = ngrp; _chngToStr = (char**) malloc( _numChngTo * sizeof(char*) ); ii = 0; ptr = strtok(names, ";"); while ( ptr != (char *)NULL ) { _chngToStr[ii] = (char*) malloc( strlen(ptr)+5 ); strcpy(_chngToStr[ii], ptr); ptr = strtok(NULL, ";" ); ii++; } if ( names != NULL ) free (names); _curGrpNum = _numCurGrp + 1; _chngToNum = _numChngTo + 1; /* * Set "CURRENT GROUP" option menu: */ sprintf (cc, "%s", "ALL GROUPS"); xmstr = XmStringCreateLocalized (cc); XtVaSetValues(_curGrpStrc.pb[0], XmNlabelString, xmstr, NULL); XtManageChild(_curGrpStrc.pb[0]); XmStringFree (xmstr); for (ii = 1; ii < _curGrpNum; ii++) { sprintf (cc, "%s", _curGrpStr[ii-1] ); xmstr = XmStringCreateLocalized (cc); XtVaSetValues(_curGrpStrc.pb[ii], XmNlabelString, xmstr, NULL); XtManageChild(_curGrpStrc.pb[ii]); XmStringFree (xmstr); } for (ii = _curGrpNum; ii < MAXNOPT; ii++) { XtUnmanageChild( _curGrpStrc.pb[ii] ); } /* * Set "CHANGE TO" option menu. */ sprintf (cc, "%s", "NO CHANGE"); xmstr = XmStringCreateLocalized (cc); XtVaSetValues(_chngToStrc.pb[0], XmNlabelString, xmstr, NULL); XtManageChild(_curGrpStrc.pb[0]); XmStringFree (xmstr); for (ii = 1; ii < _chngToNum; ii++) { sprintf (cc, "%s", _chngToStr[ii-1] ); xmstr = XmStringCreateLocalized (cc); XtVaSetValues(_chngToStrc.pb[ii], XmNlabelString, xmstr, NULL); XtManageChild(_chngToStrc.pb[ii]); XmStringFree (xmstr); } for (ii = _chngToNum; ii < MAXNOPT; ii++) { XtUnmanageChild( _chngToStrc.pb[ii] ); } first = FALSE; } /* * Set default info. when popping up the VG Group Change window. */ _curGrpCurr = 0; for (ii = 0; ii < _curGrpNum; ii++) { _chngToStrc.current[ii] = 0; _chngToStrc.chng_flag[ii] = FALSE; _chngToStrc.exist[ii] = FALSE; _chngToStrc.disabled[ii] = FALSE; XtSetSensitive( _curGrpStrc.pb[ii], FALSE ); } XtSetSensitive( _curGrpStrc.form, FALSE ); /* * Search available group types based on the VG file on main window. */ for (el_num = 0; el_num < MAX_EDITABLE_ELEMS; el_num++) { crg_goffset (el_num, &el_loc, &ier2); /* * Skip cleared range record */ if (el_loc == -1) { continue; } crg_ggrp (el_num, &grptyp, &grpnum, &ier2); if (grpnum && grptyp != GRPTYP_OTHERS && grptyp != GRPTYP_COMSYM && grptyp != GRPTYP_WATCH && grptyp != GRPTYP_CCF ) { ces_gtgnam((int)grptyp, grpnam, &ier2); for( ii = 0; ii < _numCurGrp; ii++ ) { if(strcmp(_curGrpStr[ii], grpnam) == 0) { selection = ii + 1; break; } } if( ii < _numCurGrp ) { _chngToStrc.exist[selection] = TRUE; XtSetSensitive( _curGrpStrc.pb[selection], TRUE ); /* * When there is at least one group, "ALL GROUPS" choice * makes sense. */ _chngToStrc.exist[0] = TRUE; } /* the end of if( ii < _numCurGrp ) */ } /* the end of if (grpnum &&... */ } /* the end of for (el_num... */ /* * Make "ALL GROUPS" choice sensitive or insensitive according to * its "exist" flag. */ if( _chngToStrc.exist[0] == TRUE ) { XtSetSensitive( _curGrpStrc.pb[0], TRUE ); XtSetSensitive( _curGrpStrc.form, TRUE ); } /* * Update the VG Group Change Window */ pggrpch_update(); if( !pggrpch_isUp() ) { XtManageChild (_grpChngWin); } }