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)++; }
void clo_closest ( float *lat, float *lon, int npts, float plat, float plon, int nclose, int *order, int *iret ) /************************************************************************ * clo_closest * * * * This function returns the order of the lat/lon arrays in terms of * * their geographical closeness to the point in question, ie., the pair * * (lat[order[0]],lon[order[0]]) is closest to point (plat,plon). * * Only the closest nclose pairs will be determined. * * * * clo_closest ( lat, lon, npts, plat, plon, nclose, order, iret ) * * * * Input parameters: * * *lat float Latitude array * * *lon float Longitude array * * npts int Number of lat/lon pairs * * plat float Latitude of point * * plon float Longitude of point * * nclose int Return this number of indices * * * * Output parameters: * * *order int Index into lat/lon arrays * * *iret int Return code * ** * * Log: * * D.W.Plummer/NCEP 1/99 Add nclose to calling sequence; * * re-write algorithm to use clo_dist. * * D.W.Plummer/NCEP 4/99 Added check for npts == 0 * * M. Li/GSC 10/99 Modified clo_dist code * * M. Li/GSC 10/99 Added multi-points cal. to clo_dist * * D.W.Plummer/NCEP 1/00 bug fix when some lat/lons are invalid * ***********************************************************************/ { int i, j, which, ier; float *dist, mindist; /*---------------------------------------------------------------------*/ *iret = 0; if ( npts == 0 ) { *iret = -1; return; } dist = (float *) malloc ( (size_t)npts * sizeof(float) ); clo_dist( &plat, &plon, &npts, lat, lon, dist, &ier ); for ( i = 0 ; i < nclose ; i++ ) { mindist = FLT_MAX; which = IMISSD; for ( j = 0 ; j < npts ; j++ ) { if ( !ERMISS(dist[j]) && dist[j] <= mindist ) { which = j; order[i] = which; mindist = dist[which]; } } if ( which != IMISSD ) { dist[which] = RMISSD; } else { order[i] = IMISSD; } } free ( dist ); }
void clo_tdirect ( char *name, float lat, float lon, char *stn, float *dist, float *dir, int *iret ) /************************************************************************ * clo_tdirect * * * * This function takes a latitude/longitude point and computes * * the nearest station (type loctyp), its distance from the point in * * statute miles and the direction. * * * * clo_tdirect ( name, lat, lon, stn, dist, dir, iret ) * * * * Input parameters: * * *name char Location name * * lat float Latitude * * lon float Longitude * * * * Output parameters: * * *stn char Station * * *dist float Distance from point (statute miles) * * *dir float Direction from point (degrees from N) * * *iret int Return value * * * ** * * Log: * * D.W.Plummer/NCEP 4/98 Create * * T. Piper/GSC 10/98 Prolog update * * D.W.Plummer/NCEP 12/98 Rename from clo_direct to clo_tdirect * * D.W.Plummer/NCEP 12/98 Change clo_tclsst to clo_tclosest * * D.W.Plummer/NCEP 12/98 Changed how clo_tgid is called * * S. Law/GSC 01/99 Moved direction stuff to clo_direct * * M. Li/GSC 10/99 Modified clo_direct and clo_dist codes * * M. Li/GSC 10/99 Added multi-point cal. to clo_dist * * D.W.Plummer/NCEP 12/99 Add check when no points are returned * ***********************************************************************/ { int npt, nclose, ier, np; float vlat, vlon, ddist, ddir; char id[20]; /*---------------------------------------------------------------------*/ *iret = 0; /* * Consider all points of type name */ nclose = 1; clo_tclosest( name, lat, lon, nclose, &ier); /* * Get station id. */ clo_tgid( name, 1, sizeof(id), &npt, id, &ier ); if ( npt == 0 ) { *iret = -1; stn[0] = CHNULL; *dist = RMISSD; *dir = RMISSD; } else { strcpy( stn, strtok( id, ";" ) ); /* * Get lat/lon. */ clo_tgltln( name, 1, &npt, &vlat, &vlon, &ier ); /* * Compute distance between two earth points. */ np = 1; clo_dist( &lat, &lon, &np, &vlat, &vlon, &ddist, iret ); *dist = ddist; /* * Compute directional angle (degrees from N). */ if ( G_DIFF(*dist, 0.0F) ) { *dir = 0.0F; } else { clo_direct (&lat, &lon, &vlat, &vlon, &ddir, &ier); *dir = ddir; } } return; }