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); }
/* 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 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); } }
/* 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 cvg_load ( char *fname, Boolean selflag, Boolean wrtflg, Boolean plotflg, int layer, int icol, int *iret ) /************************************************************************ * cvg_load * * * * This function loads data from a VGF formatted file and converts * * encountered records to a set of actions that display the feature * * to an appropriate driver. The parameter icol controls whether the * * graphics will be plotted with the file-specified colors (icol=0) * * or whether the VGF file will be plotted monochrome (icol=other). * * * * void cvg_load ( fname, selflag, wrtflg, plotflg, layer, icol, iret ) * * * * Input parameters: * * *fname char Name of file to load * * selflag Boolean Are elements "selectable" * * wrtflg Boolean Write flag for file * * plotflg Boolean Display the elements or not * * layer int Layer the file contents will be * * assigned to * * icol int Plot color * * * * Output parameters: * * *iret int Return code * * 1 = elms in file exceeded * * (MAX_EDITABLE_ELEMS) * * -1 = error opening VG file * * -2 = error closing VG file * * -4 = error reading el hdr * * -5 = VG file is empty * ** * * Log: * * E. Wehner/EAi 10/96 Created * * D. Keiser/GSC 1/97 Clean up * * E. Wehner/EAi 2/97 Added selection flag. * * E. Wehner/EAi 5/97 Add double tier loading * * E. Wehner/EAi 5/97 Stop loading if > MAX_EDITABLE_ELEMS * * E. Wehner/EAi 5/97 Added refresh after displaying * * D. Keiser/GSC 5/97 Change cvg_dsply to cds_dspvg * * S. Jacobs/NCEP 6/97 Added write flag * * C. Lin/NCEP 6/97 Bug fix in calling cfl_ropn * * E. Wehner/EAi 6/97 Added check to not load header * * E. Wehner/EAi 7/97 Filled areas on all elements * * E. Wehner/EAi 8/97 Removed the graphics info record. * * E. Wehner/EAi 9/97 Allow NULL file name * * F. Yen/NCEP 1/98 Updated calls for crg library cleanup * * I. Durham/GSC 5/98 Changed underscore decl. to an include * * F. J. Yen/NCEP 5/98 Updated cds function names * * E. Safford/GSC 10/98 added display levels revised file reads * * T. Piper/GSC 10/98 Prolog update * * E. Safford/GSC 12/98 move display levels to pgprm.h * * S. Jacobs/NCEP 3/99 Added symbols to the last display level * * A. Hardy/GSC 1/01 changed fptr from int to FILE * * J. WU/SAIC 11/01 change prototype & add plotflg param * * J. WU/SAIC 12/01 add layer param to feed crg_set() * * J. WU/SAIC 12/01 locate displaying level with cvg_level * * T. Lee/SAIC 11/03 changed .DEFAULT.vgf to work_file * * T. Lee/SAIC 11/03 used cvgcmn.h * * M. Li/SAIC 08/04 Added time 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 * * S. Danz/AWC 03/06 Call autoplacement if enabled * * J. Wu/SAIC 06/06 call cvg_matchfilter * * M. Li/SAIC 03/07 Updated cvg_matchfilter * * m.gamazaychikov/SAIC 06/07 Add code to free TCB and TCT memory * ***********************************************************************/ { int curpos, ier, flag, el_level; long maxbytes; int ier1, loglev, ic, icx, ii, jj, kk, one=1; int elms[3][MAX_EDITABLE_ELEMS], lvl_cnt[LEVELS], total_elms; char newfil[LLPATH], reqfil[LLPATH], grp[4], dbgfile[LLPATH]; Boolean autopl_enabled; VG_DBStruct el; filter_t el_filter, timeMatched; Boolean filter_match, matchAny = False; FILE *fptr; CMDObjectSet nmap_metadata = NULL; PlacementSet nmap_placements = NULL; cvg_group_info *nmap_group_check = NULL; /*---------------------------------------------------------------------*/ ic = icol; icx = 256; if ( ic > icx || ic < 0 ) ic = 0; cds_scol ( ic, iret ); strcpy(grp, "CVG"); loglev = 0; *iret = 0; curpos = 0; maxbytes = 0; if (!fname) { strcpy(reqfil, work_file); } else { strcpy(reqfil, fname); } cvg_open(reqfil, (int)wrtflg, &fptr, &ier); if (( ier != 0 ) || ( fptr == NULL )) { *iret = -1; er_lmsg( &loglev, grp, &ier, reqfil, &ier1, strlen(grp),strlen(reqfil)); return; } cfl_inqr(reqfil, NULL, &maxbytes, newfil, &ier); if (ier < 0) { *iret = -1; er_lmsg( &loglev, grp, &ier, reqfil, &ier1, strlen(grp),strlen(reqfil)); return; } /* * Get each el.hdr and assign each elem offset to one of the levels. */ for (ii = 0; ii < 3; ii++) { lvl_cnt[ii] = 0; } /* * Scan the vg file and load the offsets of all non-deleted elements. * Stop loading at end of file or MAX_EDITABLE_ELEMS. */ total_elms = 0; while (((long)curpos < maxbytes) && (total_elms < MAX_EDITABLE_ELEMS)) { cvg_rdhdr(newfil, fptr, curpos, (int)maxbytes, &el, &flag, &ier); if (ier < 0 || el.hdr.recsz < 0 || el.hdr.recsz > 65536) { *iret = -4; return; } cvg_level( &el.hdr, &el_level, &ier ); if ( ier == 0 ) { elms[ el_level ] [ lvl_cnt[el_level]++ ] = curpos; total_elms++; } curpos += el.hdr.recsz; } if (total_elms >= MAX_EDITABLE_ELEMS) { *iret = 1; er_lmsg( &loglev, grp, &ier, newfil, &ier1, strlen(grp),strlen(reqfil)); } /* * Create the structures to manage the metadata and object placement * information. If there were structures already in place, hold them * aside as they were put there by product generation. */ ctb_pfbool( "ENABLE_AUTOPLACE", &autopl_enabled, &ier ); if (autopl_enabled) { if (cvg_metadata) { nmap_metadata = cvg_metadata; nmap_placements = cvg_placements; nmap_group_check = cvg_group_check; } cmd_osnew(&cvg_metadata, &ier); cap_psnew(&cvg_placements, &ier); G_CALLOC(cvg_group_check, cvg_group_info, one, "cvg_load: cvg_group_check"); /* * Fill in the structures with the information needed */ cvg_ld4place(fname, iret); /* * Ok, its all loaded, so place all the objects where they belong */ cap_psplace(cvg_placements, cvg_metadata, iret); ctb_pfstr("AUTOPLACE_DBG", dbgfile, &ier ); if (dbgfile[0] != '\0') { dump_objects(dbgfile, cvg_metadata, cvg_placements); } } /* * Now loop thru the levels and display the elements */ kk = 0; for (ii = 0; ii < LEVELS; ii++) { for (jj=0; jj<lvl_cnt[kk]; jj++) { curpos = elms[ii][jj]; cvg_rdhdr(newfil, fptr, curpos, (int)maxbytes, &el, &flag, &ier); cvg_rdele(&el, curpos, el.hdr.recsz, fptr, &ier); cvg_getElFilter ( &el, el_filter, &ier ); cvg_matchfilter ( el_filter, matchAny, &filter_match, timeMatched, &ier ); if (selflag) { crg_set(&el, curpos, layer, &ier); } if ( filter_match ) { cds_dspelm( &el, &ier); } /* * Free TCA/GFA/TCT/TCB memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } else if ( el.hdr.vg_type == TCTRK_ELM ) { cvg_freeTct ( &el ); } else if ( el.hdr.vg_type == TCBKL_ELM ) { cvg_freeTcb ( &el ); } } kk++; } cvg_clos(fptr, &ier); if ( ier != 0 ) *iret = -2; if ( plotflg ) geplot(&ier); ic = 0; cds_scol ( ic, iret ); /* * Free up the metadata and placement information now that we * are done plotting everything */ if (autopl_enabled) { cmd_osdel(cvg_metadata, iret); cap_psdel(cvg_placements, iret); G_FREE(cvg_group_check, cvg_group_info); /* * Put back the product generation metadata */ cvg_metadata = nmap_metadata; cvg_placements = nmap_placements; cvg_group_check = nmap_group_check; } return; }