void clip_line ( int npoly, float *px, float *py, int npts, float *plat, float *plon, int closed, int maxpts, int *ninout, float *xinout, float *yinout, int *inout, int *iret ) /************************************************************************ * clip_line * * * * This program clips a single line against a single polygon. * * * * clip_line( npoly, px, py, npts, plat, plon, closed, maxpts, ninout, * * xinout, yinout, inout, iret ) * * * * Input parameters: * * npoly int number of points in clipping polygon * * *px float array of x-coords in clipping polygon * * *py float array of y-coords in clipping polygon * * npts int number of points in line to be clipped * * *plat float array of latitudes in line to be clipped * * *plon float array of longitudes in line to be clipped * * closed int flag indicating if line is closed or not * * maxpts int maximum number of points returned * * * * Output parameters: * * *ninout int number of returned points * * *xinout float array of x points * * *yinout float array of y points * * *inout int array of indicators as to in or out * * *iret int Return code * * * ** * * Log: * * D.W.Plummer/NCEP 3/02 * * X.Guo/CWS 10/10 Missed calculating some intersection pts* * between line and polygon * ***********************************************************************/ { int ii, jj, kk, ll, nint, ier; int intrsct, tinout[LLMXPT]; float xint, yint, temp; float fxint[LLMXPT], fyint[LLMXPT], dist[LLMXPT]; float Nplat[LLMXPT], Nplon[LLMXPT], Npx[LLMXPT], Npy[LLMXPT]; float x11[2], y11[2]; /*---------------------------------------------------------------------*/ *iret = 0; cgr_inpoly ( "M", &npts, plat, plon, "M", &npoly, px, py, tinout, &ier ); gtrans ( sys_M, sys_N, &npts, plat, plon, Nplat, Nplon, &ier, strlen(sys_N), strlen(sys_N) ); gtrans ( sys_M, sys_N, &npoly, px, px, Npx, Npy, &ier, strlen(sys_N), strlen(sys_N) ); *ninout = 0; for ( ii = 0; ii < npts-1; ii++ ) { xinout[*ninout] = plat[ii]; yinout[*ninout] = plon[ii]; inout[*ninout] = tinout[ii]; (*ninout)++; nint = 0; for ( jj = 0; jj < npoly; jj++ ) { if ( jj == npoly - 1 ) { x11[0] = px[jj]; x11[1] = px[0]; y11[0] = py[jj]; y11[1] = py[0]; } else { x11[0] = px[jj]; x11[1] = px[jj+1]; y11[0] = py[jj]; y11[1] = py[jj+1]; } cgr_segint ( sys_M, &(plat[ii%npts]), &(plon[ii%npts]), sys_M, x11, y11, sys_M, &xint, &yint, &intrsct, &ier ); if ( intrsct == G_TRUE ) { fxint[nint] = xint; fyint[nint] = yint; nint++; } } if ( nint > 0 ) { clo_dist ( &(plat[ii]), &(plon[ii]), &nint, fxint, fyint, dist, &ier ); for ( kk = 0; kk < nint-1; kk++ ) { for ( ll = 0; ll < nint-kk-1; ll++ ) { if ( dist[ll] > dist[ll+1] ) { temp = fxint[ll]; fxint[ll] = fxint[ll+1]; fxint[ll+1] = temp; temp = fyint[ll]; fyint[ll] = fyint[ll+1]; fyint[ll+1] = temp; temp = dist[ll]; dist[ll] = dist[ll+1]; dist[ll+1] = temp; } } } for ( kk = 0; kk < nint; kk++ ) { xinout[*ninout] = fxint[kk]; yinout[*ninout] = fyint[kk]; inout[*ninout] = inout[(*ninout)-1]; (*ninout)++; xinout[*ninout] = fxint[kk]; yinout[*ninout] = fyint[kk]; if ( inout[(*ninout)-1] == 0 ) inout[*ninout] = 1; if ( inout[(*ninout)-1] == 1 ) inout[*ninout] = 0; (*ninout)++; } } } xinout[*ninout] = plat[npts-1]; yinout[*ninout] = plon[npts-1]; inout[*ninout] = tinout[npts-1]; (*ninout)++; }
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 cgr_polylink ( int *npin0, float *xin0, float *yin0, int *npin1, float *xin1, float *yin1, int *maxnpo, int *npo, float *xo, float *yo, int *iret ) /************************************************************************ * cgr_polylink * * * * This function 'links' two polygons together. * * * * Cartesian (Device, sys_D) coordinates are assumed with the first and * * last points not being equal. * * * * Both incoming polygon's points are assumed to be ordered counter- * * clockwise * * * * If the link cannot be found, as in the case of embedded polygons, * * then the encompassing polygon is returned. * * * * cgr_polylink ( npin0, xin0, yin0, npin1, xin1, yin1, maxnpo, * * npo, xo, yo, iret ) * * * * Input parameters: * * *npin0 int Number of points in polygon1 * * *xin0 float X coordinates of polygon 1 * * *yin0 float Y coordinates of polygon 1 * * *npin1 int Number of points in polygon2 * * *xin1 float X coordinates of polygon 2 * * *yin1 float Y coordinates of polygon 2 * * *maxnpo int Maximum number of output points * * * * Output parameters: * * *npo int Number of points in output polygon * * *xo float X coordinates of output polygon * * *yo float Y coordinates of output polygon * * *iret int Return code * * = G_NORMAL - normal * * = +1 - embedded polygon, returned outermost * * = -2 - one or both polygons <= 2 points * * * ** * * Log: * * D.W.Plummer/NCEP 11/03 * ***********************************************************************/ { int ii, found, *inout, ier; POLYGON poly_0, poly_1, poly_link; /*---------------------------------------------------------------------*/ *iret = G_NORMAL; if ( *npin0 <= 2 || *npin1 <= 2 ) { *iret = -2; return; } /* * Create the two POLYGON structures. */ poly_0.first = polyp_create ( npin0, xin0, yin0 ); poly_1.first = polyp_create ( npin1, xin1, yin1 ); /* * Process them into a 'linked' POLYGON. */ poly_link.first = NULL_POLYPOINT; polyp_link ( &poly_0, &poly_1, &poly_link, &ier ); /* * Free the memory from the original POLYGON structures. */ polyp_destroy ( poly_1.first ); polyp_destroy ( poly_0.first ); if ( ier == 0 ) { /* * Retrieve the points from the 'linked' POLYGON. */ polyp_getpts ( poly_link.first, npo, xo, yo ); /* * Free 'linked' POLYGON memory. */ if ( poly_link.first != NULL_POLYPOINT ) { polyp_destroy ( poly_link.first ); } } else { inout = NEW ( int, ((*npin0)*(*npin1)) ); /* * Test polygon #0 points against polygon #1 */ cgr_inpoly ( sys_D, npin0, xin0, yin0, sys_D, npin1, xin1, yin1, inout, &ier ); found = G_FALSE; ii = 0; while ( !found && ii < *npin0 ) { if ( inout[ii] == OUT ) { found = G_TRUE; break; } ii++; } if ( !found ) { /* * None of polygon #0 points are outside polygon #1; * return polygon #1. */ *npo = *npin1; for ( ii = 0; ii < *npin1; ii++ ) { xo[ii] = xin1[ii]; yo[ii] = yin1[ii]; } } else { /* * Return polygon #0 for all other cases. */ *npo = *npin0; for ( ii = 0; ii < *npin0; ii++ ) { xo[ii] = xin0[ii]; yo[ii] = yin0[ii]; } } free ( inout ); *iret = +1; } return; }
void cds_ccf ( VG_DBStruct *el, int indx, int *iret ) /************************************************************************ * cds_ccf * * * * This function displays CCFs to the output device. * * * * cds_ccf (el, indx, iret) * * * * Input parameters: * * *el VG_DBStruct Pointer to VG record structure * * indx int Index into user attribute table * * * * Output parameters: * * *iret int Return code * * * ** * * Log: * * D.W.Plummer/NCEP 7/99 Copied from cds_sig * * S. Law/GSC 02/00 added smoothing * * S. Law/GSC 05/00 added fill, moved color setting to pgen * * A. Hardy/GSC 11/00 renamed output coord. system declaration* * J. Wu/GSC 02/01 Modified 'unused1' in VG to 'smooth' * * D.W.Plummer/NCEP 5/01 Added check for cdsColor * * M. Li/SAIC 01/03 delete vgstruct.h * * H. Zeng/SAIC 02/05 assigned iftyp with a new value * * L. Hinson/AWC 07/09 Add Setting/Uattrib tbl functionality * * Add Connector, if needed, from text box * * to polygon. Add motion vector/speed * * L. Hinson/AWC 02/10 Fix uninitialized 'ifilled' on Lines * ***********************************************************************/ { int ii, np, ier, istyp, width, lintyp, lthw, lwhw; int iltypx, ilthwx, iwidthx, iwhwx, icolrx, iftypx; int ifilled, iftyp; float szfilx, szfil, lat[MAX_SIGMET], lon[MAX_SIGMET]; int idx; VG_DBStruct el_tmp; CCFType *pccf; int npts, npls, *inout; float *xpt, *ypt, *xpl, *ypl; float areadir, areaspd, xcent, ycent, minangle, V1x, V1y, V2u, V2v; float angle, latmv[2], lonmv[2]; int i, motionvertexnum, foundmotionvertex; char textLayoutStr[256]; Boolean textLayoutNIL = False; /*---------------------------------------------------------------------*/ *iret = 0; /* * Save plot attributes. */ gqcolr (&icolrx, &ier); gqline (&iltypx, &ilthwx, &iwidthx, &iwhwx, &ier); gqfill (&szfilx, &iftypx, &ier); /* * setup basic information */ lintyp = 1; lthw = 0; width = 3; lwhw = 0; gsline (&lintyp, <hw, &width, &lwhw, &ier); pccf = &(el->elem.ccf); np = pccf->info.npts; /* * Set the color for the feature. */ if (cdsColor == 0) { if ( cdsUattr[indx].maj_col == 0 ) { if (pccf->info.prob == (CCFLVL_HIGH + 1)) { /*1 = High, 2= Low */ gscolr ( &(el->hdr.maj_col), &ier); } else { gscolr ( &(el->hdr.min_col), &ier); } } else { /* Use the Uattrib table */ if (pccf->info.prob == (CCFLVL_HIGH + 1)) { gscolr ( &cdsUattr[indx].maj_col, &ier); el->hdr.maj_col = cdsUattr[indx].maj_col; /* Colors everything else */ } else { gscolr ( &cdsUattr[indx].min_col, &ier); el->hdr.maj_col = cdsUattr[indx].min_col; /* Colors everything else */ } } } else { gscolr ( &cdsColor, &ier); } /* * Set the smoothing level_tmp */ ii = (cdsUattr[indx].smooth == -1) ? (int) el->hdr.smooth : cdsUattr[indx].smooth; istyp = (ii == 0) ? 0 : 2; gssmth (&istyp, &cdsSmthDens[ii], &ier); /* * If fill is set, fill the polygon. */ ifilled=0; if (cdsUattr[indx].filled == 0) { ifilled = (int) el->hdr.filled; } else { if (pccf->info.subtype == SIGTYP_AREA) { if (pccf->info.cover == CCFLVL_HIGH + 1) { ifilled = cdsUattr[indx].info.ccf->fillhi; } if (pccf->info.cover == CCFLVL_MEDIUM + 1) { ifilled = cdsUattr[indx].info.ccf->fillmed; } if (pccf->info.cover == CCFLVL_LOW + 1) { ifilled = cdsUattr[indx].info.ccf->filllow; } } } if (ifilled >= 1 && cdsFill == 1) { iftyp = ifilled; szfil = 1.0F; gsfill (&szfil, &iftyp, &ier); gfill (sys_M, &np, pccf->latlon, &(pccf->latlon[np]), &ier, strlen (sys_M)); iftyp = 1; gsfill (&szfil, &iftyp, &ier); } if (cdsUattr[indx].info.ccf->linetype == 0) { lintyp = el->elem.ccf.info.linetype; } else { lintyp = cdsUattr[indx].info.ccf->linetype; } switch (pccf->info.subtype) { case SIGTYP_LINE_HIGH: /* line */ gsline (&lintyp, <hw, &width, &lwhw, &ier); for (ii = 0; ii < np; ii++) { lat[ii] = pccf->latlon[ii]; lon[ii] = pccf->latlon[ii+np]; } gline (sys_M, &np, lat, lon, &ier, strlen (sys_M)); break; case SIGTYP_LINE_MED: /* line */ gsline (&lintyp, <hw, &width, &lwhw, &ier); for (ii = 0; ii < np; ii++) { lat[ii] = pccf->latlon[ii]; lon[ii] = pccf->latlon[ii+np]; } gline (sys_M, &np, lat, lon, &ier, strlen (sys_M)); break; case SIGTYP_AREA: /* area */ gsline (&lintyp, <hw, &width, &lwhw, &ier); for ( ii = 0; ii < np; ii++ ) { lat[ii] = pccf->latlon[ii]; lon[ii] = pccf->latlon[ii+np]; } lat[np] = pccf->latlon[0]; lon[np] = pccf->latlon[np]; np++; gline (sys_M, &np, lat, lon, &ier, strlen (sys_M)); break; } /* Check to see if textLayoutString for CCF Text contains NIL */ /* If so, set the variable textLayoutNIL to TRUE. */ if ( cdsUattr[indx].info.ccf->textLayout[0] == '\0' ) { strcpy(textLayoutStr, el->elem.ccf.textLayout); } else { strcpy(textLayoutStr, cdsUattr[indx].info.ccf->textLayout); } if (strstr(textLayoutStr, "NIL") != NULL) { textLayoutNIL = True; } /* * Reset smooth level to 0 */ if (istyp > 0) { istyp = 0; gssmth (&istyp, &cdsSmthDens[0], &ier); } /* * Restore the saved plot attribute values */ gsline ( &iltypx, &ilthwx, &iwidthx, &iwhwx, &ier ); gscolr ( &icolrx, &ier ); gsfill (&szfilx, &iftypx, &ier); if (! (pccf->info.subtype == SIGTYP_LINE_HIGH || pccf->info.subtype == SIGTYP_LINE_MED)) { /* Create an arrow if the text box is outside the CCF polygon*/ cds_getinx( el, &idx, &ier); /* Get the idx to the arrow size */ npts = 1; G_MALLOC( xpt, float, npts, "cds_ccf: xpt" ); G_MALLOC( ypt, float, npts, "cds_ccf: ypt" ); G_MALLOC( inout, int, npts, "cds_ccf: inout" ); xpt[0] = el->elem.ccf.info.textlat; ypt[0] = el->elem.ccf.info.textlon; npls = el->elem.ccf.info.npts; G_MALLOC( xpl, float, npls, "cds_ccf: xpl" ); G_MALLOC( ypl, float, npls, "cds_ccf: ypl" ); for ( ii = 0; ii < npls; ii++ ) { xpl[ii] = el->elem.ccf.latlon[ii]; ypl[ii] = el->elem.ccf.latlon[ii+npls]; } cgr_inpoly ( sys_M, &npts, xpt, ypt, sys_M, &npls, xpl, ypl, inout, &ier ); /* * If the center of the text box is outside of GFA polygon, and TextLayoutNIL * not set display an arrowed line. */ if ( inout[0] == 0 && textLayoutNIL == False) { el_tmp.hdr.delete = 0; el_tmp.hdr.vg_type = SPLN_ELM; el_tmp.hdr.vg_class = (char)CLASS_LINES; el_tmp.hdr.filled = 0; el_tmp.hdr.closed = 0; el_tmp.hdr.smooth = 0; el_tmp.hdr.version = 0; el_tmp.hdr.grptyp = 0; el_tmp.hdr.grpnum = 0; el_tmp.hdr.maj_col = el->hdr.maj_col; el_tmp.hdr.min_col = el->hdr.min_col; el_tmp.hdr.recsz = 0; el_tmp.hdr.range_min_lat = 0; el_tmp.hdr.range_min_lon = 0; el_tmp.hdr.range_max_lat = 0; el_tmp.hdr.range_max_lon = 0; el_tmp.elem.spl.info.numpts = 2; el_tmp.elem.spl.info.spltyp = 4; el_tmp.elem.spl.info.splstr = 0.5; el_tmp.elem.spl.info.spldir = 1; el_tmp.elem.spl.info.splsiz = 1.0; el_tmp.elem.spl.info.splsiz = el->elem.ccf.info.szarrow; /* Set the Arrow Size from the settings table... */ if ( fabs (cdsUattr[idx].info.ccf->szarrow < 0.01) ) { el_tmp.elem.spl.info.splsiz = el->elem.ccf.info.szarrow; } else { el_tmp.elem.spl.info.splsiz = cdsUattr[idx].info.ccf->szarrow; } el_tmp.elem.spl.latlon[0] = el->elem.ccf.info.textlat; el_tmp.elem.spl.latlon[1] = el->elem.ccf.info.arrowlat; el_tmp.elem.spl.latlon[2] = el->elem.ccf.info.textlon; el_tmp.elem.spl.latlon[3] = el->elem.ccf.info.arrowlon; el_tmp.elem.spl.info.splwid = 3; el_tmp.hdr.maj_col = el_tmp.hdr.min_col = 31; cds_dspelm(&el_tmp, &ier); el_tmp.elem.spl.info.splwid = 1; el_tmp.hdr.maj_col = el_tmp.hdr.min_col = 32; cds_dspelm(&el_tmp, &ier); }
void cpcg_srch ( char *tblnam, char *fname, int *nstn, int *istnm, int *iflag, int *iclr, int *iret ) /************************************************************************ * cpcg_srch * * * * This function searches which stations are located inside the * * given polygon. If the polygon is open, construct a closed polygon * * using the open polygon and the US bounds. * * * * cpcg_srch (tblnam, fname, nstn, istnm, iflag, iclr, iret) * * * * Input parameters: * * *tblnam char Station table file name * * *fname char Polygon vg file name * * * * Output parameters: * * *nstn int Number of station in the table * * *istnm int Station number * * *iflag int Array of in or out results * * 1 = station inside polygon * * 0 = station outside polygon * * *iclr int Color of polygon * * *iret int Return code * * * ** * * Log: * * M. Li/SAIC 08/01 Created * ***********************************************************************/ { int ii, jj, kk, nbnd, maxstn, np3, ier; int ispri[LLSTFL], npts[MAXPTS], lnpts[MAXPTS]; int nlin, lcolr[MXBND], close[MXBND], inout[LLSTFL]; float slat[LLSTFL], slon[LLSTFL], selv[LLSTFL]; float blat[MXBND][LLMXPT], blon[MXBND][LLMXPT]; float llat[MXBND][MAXPTS], llon[MXBND][MAXPTS]; float xp3[MAXPTS], yp3[MAXPTS]; char stid[LLSTFL][9], stnnam[LLSTFL][33], stat[LLSTFL][3], coun[LLSTFL][3], tbchrs[LLSTFL][21]; /*---------------------------------------------------------------------*/ *iret = 0; /* * Read the station table */ maxstn = LLSTFL; ctb_astn ( tblnam, STNFILDIR, &maxstn, nstn, stid, stnnam, istnm, stat, coun, slat, slon, selv, ispri, tbchrs, &ier ); if ( ier != 0 || *nstn <= 0 ) { *iret = -3; return; } for (ii = 0; ii < *nstn; ii++) { iflag[ii] = 0; iclr[ii] = 0; } /* * Read bounds US bounds */ cpcg_rdbnd(BNDTYP, &nbnd, npts, blat, blon, &ier); if ( ier != 0 || nbnd <= 0 ) { *iret = -4; return; } /* * Read vg files */ cpcg_rdln(fname, &nlin, lnpts, lcolr, close, llat, llon, &ier); if ( ier != 0 ) { *iret = -2; return; } /* * Check if the stations are inside the polygons */ for (ii = 0; ii < nlin; ii++) { /* * Close polygon */ if ( close[ii] ) { np3 = lnpts[ii]; for (kk = 0; kk < np3; kk++) { xp3[kk] = llat[ii][kk]; yp3[kk] = llon[ii][kk]; } } /* * For open polygon, construct a closed polygon with the US bounds */ else { for (jj = 0; jj < nbnd; jj++) { cpcg_newpoly(&lnpts[ii], llat[ii], llon[ii], &npts[jj], blat[jj], blon[jj], &np3, xp3, yp3, &ier); if (ier == 0) break; } } cgr_inpoly (sys_M, nstn, slat, slon, sys_M, &np3, xp3, yp3, inout, &ier); for (kk = 0; kk < *nstn; kk++) { if ( iflag[kk] == 0 && inout[kk] == 1 ) { iflag[kk] = 1; iclr[kk] = lcolr[ii]; } } } }