예제 #1
0
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)++;
}
예제 #2
0
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 );

}
예제 #3
0
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;

}