Exemplo n.º 1
0
void uka_jtin ( int njp, float jlat[], float jlon[], int nwp,
                float wlat[], float wlon[], float wspd [],
                float wlvl[], float wlvla[], float wlvlb[], int wtyp[], 
		int *nop, float olat[], float olon[], float ospd[], 
		float olvl[], float olvla[], float olvlb[], int *iret )
/************************************************************************
 * uka_jtin								*
 *                                                                      *
 * This function puts the core points, the wind barb points and the 	*
 * hash points in the correct order, and gets the wind speed values 	*
 * for the hash marks.							* 
 *                                                                      *
 * uka_jtin ( njp, jlat, jlon, nwp, wlat, wlon, wspd, wlvl, wlvla, 	*
 *            wlvlb, wtyp, nop,	olat, olon, ospd, olvl, olvla, olvlb, 	*
 *            iret )							*
 *                                                                      *
 * Input parameters:                                                    *
 *      njp             int             Number of jet core points	*
 *      jlat[]          float           Latitudes of core points	*
 *      jlon[]          float           Longitudes of core points	*
 *      nwp             int             No. of wind (barb & hash) pts	*
 *      wlat[]          float           Latitudes of wind points        *
 *      wlon[]          float           Longitudes of wind points  	*
 *      wspd[]          float           Speed of wind points (m/sec)	*
 *      wlvl[]          float           Flight level of wind pts (m)	*
 *	wlvla[]		float		Flight level above jet (m)	*
 *	wlvlb[]		float		Flight level below jet (m)	*
 *      wtyp[]          int             Wind point types		*
 *                                         1 = wind barb point		*
 *                                         2 = hash point		*
 *									*
 * Output parameters:							*
 *      *nop            int             Total number of points		*
 *      olat[]          float           Latitudes of points		*
 *      olon[]          float           Longitudes of points		*
 *      ospd[]          float           Speed of points (m/sec)		*
 *      olvl[]          float           Flight levels of points (m)	*
 *	olvla[]		float		Flight level above jet (m)	*
 *	olvlb[]		float		Flight level below jet (m)	*
 *      *iret           int             Return code			*
 *                                         0 = normal return		*
 *                                        15 = curve fit problem	*
 **                                                                     *
 * Log:                                                                 *
 * M. Li/SAIC		02/04	Extracted from sig_jets			*
 * M. Li/SAIC		04/04	Added flight level above/below jet	*
 * M. Li/SAIC		05/04	Copied from sig_jtin			*
 * M. Li/SAIC		07/04	Added olvl to UKA_JTSP			*
 * M. Li/SAIC		01/06	Added CED projection  			*
 ***********************************************************************/
{
    int 	ii, ier;
    char	proj[8];
    float 	minlat, maxlat, lllat, lllon, urlat, urlon;
    float 	angle1, angle2, angle3;
    float	dens, crvscl;
    float 	px[MAXPTS], py[MAXPTS], qx[MAXPTS], qy[MAXPTS],
          	tx[MAXPTS], ty[MAXPTS];
    int    	otyp[MAXPTS];
    int		widx[MAXPTS];
/*---------------------------------------------------------------------*/
    *iret   = 0;

    dens = 5.0F;
    crvscl = 30.0F;
    *nop = MAXPTS;
    minlat = 9999.0F;
    maxlat = -9999.0F;
    for ( ii = 0; ii < njp; ii++ ) {
    	minlat = G_MIN ( minlat, jlat[ii] );
    	maxlat = G_MAX ( maxlat, jlat[ii] );

    }

    if ( minlat >= 0.0F ) {
    	/*
    	 * Use North STR projection.
    	 */
    	strcpy ( proj, "STR" );
    	angle1 = 90.0F;
    	angle2 = -90.0F;
    	angle3 = 0.0F;
    	lllat = -15.0F;
    	lllon = -135.0F;
    	urlat = -15.0F;
    	urlon = -135.0F;
    }
    else if (maxlat < 0.0F ) {
    	/*
    	 * Use South STR projection.
    	 */
    	strcpy ( proj, "STR" );
    	angle1 = -90.0F;
    	angle2 = -90.0F;
    	angle3 = 0.0F;
    	lllat = 15.0F;
    	lllon = -135.0F;
    	urlat = 15.0F;
    	urlon = -135.0F;
    }
    else {
	/*
         * Use CED projection.
         */
	strcpy ( proj, "CED" );
        angle1 = 0.0F;
        angle2 = 0.0F;
        angle3 = 0.0F;
        lllat = -90.0F;
        lllon = -180.0F;
        urlat = 90.0F;
        urlon = 180.0F;
    }
    gsmprj ( proj, &angle1, &angle2, &angle3,
     	     &lllat, &lllon, &urlat, &urlon, &ier, strlen(proj) );
    gtrans ( sys_M, sys_D, &njp, jlat, jlon, px, py, &ier,
     	     strlen(sys_M), strlen(sys_D) );
    gtrans ( sys_M, sys_D, &nwp, wlat, wlon, qx, qy, &ier,
     	     strlen(sys_M), strlen(sys_D) );
    cgr_insert ( px, py, njp, qx, qy, nwp, dens, crvscl,
                 tx, ty, nop, widx, &ier );

    if ( ier != 0 ) {
        *iret = 15;
    }
    else {
    	gtrans ( sys_D, sys_M, nop, tx, ty, olat, olon, &ier,
     		 strlen(sys_D), strlen(sys_M) );

    	for ( ii = 0; ii < *nop; ii++) {
	    olvl[ii]  = SIGRLMS;
	    olvla[ii] = SIGRLMS;
	    olvlb[ii] = SIGRLMS;
	    ospd[ii]  = SIGRLMS;
	    otyp[ii]  = ILINE;
      	}
    	for ( ii = 0; ii < nwp; ii++ ) {
	    ospd[widx[ii]] = wspd[ii];
	    olvl[widx[ii]] = wlvl[ii];
	    olvla[widx[ii]] = wlvla[ii];
	    olvlb[widx[ii]] = wlvlb[ii];
	    otyp[widx[ii]] = wtyp[ii]; 
    	}

    	/*
     	 * Calculate wind speed for hash marks.
     	 */

    	uka_jtsp ( *nop, otyp, ospd, olvl, &ier );
    }

}
Exemplo n.º 2
0
void cgr_segdist ( int *np, float *xx, float *yy, float *fx, float *fy, 
			float *distance, int *nearest_vrt, int *next_vrt, 
			float *nx, float *ny, int *iret )
/************************************************************************
 * cgr_segdist								*
 *									*
 * This function determines the nearest and next vertices of a		*
 * multipoint line to a fixed point, the closest point (on the line	*
 * segment defined by those two vertices) to the fixed point, and the	*
 * distance between the fixed point and the closest point.		*
 * The "next vertex" is simply the vertex following the nearest vertex	*
 * in the order of the points, not the next closest vertex to the fixed	*
 * point.								*
 *									*
 * cgr_segdist ( np, xx, yy, fx, fy, distance, nearest_vrt, next_vrt,	*
 *                                         nx, ny, iret )		*
 *									*
 * Input parameters:							*
 *	*np		int		Number of points in figure	*
 *	*xx		float		X coordinates of figure		*
 *	*yy		float		Y coordinates of figure		*
 *	*fx		float		X coordinate of fixed point	*
 *	*fy		float		Y coordinate of fixed point	*
 *									*
 * Output parameters:							*
 *	*distance	float		Distance to the point		*
 *	*nearest_vrt	int		Closest vertex number		*
 *	*next_vrt	int		Other end of nearest segment	*
 *	*nx		float		Nearest x coord on figure	*
 *	*ny		float		Nearest y coord on figure	*
 *	*iret		int		Status return			*
 *					0 = great, 1 = not a line	*
 *									*
 **									*
 * Log:									*
 * E. Safford/GSC	02/98	copied cgr_dist				*
 * E. Safford/GSC	05/98	add G_NINT to handle rounding problem	*
 * E. Safford/GSC	07/98	add equal condition to horiz & vert	*
 * T. Piper/GSC		10/98	Prolog update				*
 * S. Law/GSC		03/99	clean up and commentary			*
 * W.D.Plummer/NCEP	12/02	make all inputs pointers		*
 * W.D.Plummer/NCEP	02/03	expand documenation in prologue		*
 ***********************************************************************/
{
    int		ii;
    float	qx, qy, curr_dist, d0, d1, m2, m1, b2, b1;
    float	xmin, xmax, ymin, ymax;
/*---------------------------------------------------------------------*/

    if (*np == 1) {
	*iret = 1;

	*nearest_vrt = *next_vrt = 0;
	*nx = xx[0];
	*ny = yy[0];

	*distance = (float) G_DIST (xx[0], yy[0], *fx, *fy);

	return;
    }

    *iret = 0;
    *distance = FLT_MAX;

    /*
     * Isolate which line segment is closest to desired point.
     */

    for (ii = 0; ii < *np-1; ii++ ) {

  	xmin = (float) G_MIN (xx[ii], xx[ii+1]);
	xmax = (float) G_MAX (xx[ii], xx[ii+1]);
	ymin = (float) G_MIN (yy[ii], yy[ii+1]);
	ymax = (float) G_MAX (yy[ii], yy[ii+1]);

	/*
	 * Must find the closest point on vertical and horiztonal
	 * seperately since the slope formula would cause a 
	 * divide by zero error
	 */

	/*
	 *  Vertical segments
	 */
	if (G_DIFF(xmin, xmax)) {
	    qx = xmin;
	    if (*fy < ymin)
	        qy = ymin;
	    else if (*fy > ymax)
		qy = ymax;
	    else
		qy = *fy;
	}

	/*
	 *  Horizontal segments
	 */
    	else if ( G_DIFF(ymin, ymax) ) {
	    qy = ymin;
	    if (*fx < xmin)
	        qx = xmin;
	    else if (*fx > xmax)
		qx = xmax;
	    else
		qx = *fx;
	}

	/*
	 *  All the rest
	 */
	else {
	    /*
	     * find slope and intercept for initial line
	     */
	    m1 = (yy[ii+1] - yy[ii]) / (xx[ii+1] - xx[ii]);
	    b1 = yy[ii] - (m1 * xx[ii]);

	    /*
	     * find slope and intercept for perpendicular
	     */
	    m2 = - 1.0F / m1;
	    b2 = *fy - (m2 * *fx);

	    /* 
	     * find the intersection of the two lines
	     * which would be the closest point
	     *
	     * formula for a line is y = mx + b
	     * y = (m1 * x) + b1  &&  y = (m2 * x) + b2
	     * (m1 * x) + b1 = (m2 * x) + b2
	     * (m1 * x) - (m2 * x) = (b2 - b1)
	     * x * (m1 - m2) = (b2 - b1)
	     * x = (b2 - b1) / (m1 - m2)
	     */
	    qx = (b2 - b1) / (m1 - m2);
	    qy = (m2 * qx) + b2;
	}

	/*
	 * find the distance
	 */
	if (xmin <= qx && qx <= xmax) {
	    curr_dist = (float) G_DIST (*fx, *fy, qx, qy);
	}
	else {
	    d0 = (float) G_DIST (*fx, *fy, xx[ii], yy[ii]);
	    d1 = (float) G_DIST (*fx, *fy, xx[ii+1], yy[ii+1]);
	    curr_dist = (d0 <= d1) ? d0 : d1;
	}

	if (curr_dist < *distance) {
	    *distance = curr_dist;

	    *nx = qx;
	    *ny = qy;	

	    /*
	     *  Figure which end of segment is closest to point.
	     */
	    d0 = (float) G_DIST (*fx, *fy, xx[ii], yy[ii]);
	    d1 = (float) G_DIST (*fx, *fy, xx[ii+1], yy[ii+1]);

	    if (d0 < d1) {
		*nearest_vrt = ii;
		*next_vrt    = ii + 1;
	    }
	    else {
		*nearest_vrt = ii + 1;
		*next_vrt    = ii;
	    }

	    if ((*nx < xmin) || (xmax < *nx)) {
		*nx = xx[*nearest_vrt];
		*ny = yy[*nearest_vrt];
	    } 
	}
    }
}
Exemplo n.º 3
0
int main (int argc , char **argv)

/************************************************************************
 * main                                                                 *
 *                                                                      *
 * Main program of createbinfo.                                         *
 *                                                                      *
 * Output (from printf) must be re-directed to the proper info file 	*
 * within the script.        						*
 *                                                                      *
 * 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     12/98						* 
 * T. Piper/GSC		 8/00	Modified for new generic boundary info  *
 * D.W.Plummer/NCEP	 6/05	Incr accuracy from 2 decimal digits to 4*
 ***********************************************************************/

{
char	buff[256], id[7], name[64];
int	i, ier, ilat, ilon, k, length, nparts, nptot, npts, num, pst;
float	fltptr[20], lat1, lat2, lon1, lon2, minlat, minlon, maxlat, maxlon;

FILE	*fp;
long	lpos, lposp;

Bnd_t	boundary;
/*---------------------------------------------------------------------*/
    /*
     *  Print out the name of the BOUNDARY file.
     */
    boundary.filename = (char *)malloc( sizeof(char) * strlen(argv[1]) + 1);
    strcpy ( boundary.filename, argv[1] );
    printf("!\n!    BOUNDARIES FILENAME \n%s\n!\n", 
		boundary.filename );

    fp = (FILE *)cfl_tbop ( boundary.filename, "bounds", &ier );

    /*
     *  Allocate and initialize boundary location structure
     */
    boundary.nbnd = 0;
    boundary.bound = (BInfo_t *)malloc(MAX_BOUNDS*sizeof(BInfo_t));
    for ( i = 0; i < MAX_BOUNDS; i++ )  {
	boundary.bound[i].name = (char *)malloc( sizeof(char) * MAX_NAMELEN + 1);
	boundary.bound[i].name[0] = '\0';
	boundary.bound[i].info = (char *)malloc( sizeof(char) * MAX_NAMELEN + 1);
	boundary.bound[i].info[0] = '\0';
	boundary.bound[i].strec   = 0;
    	boundary.bound[i].cenlat  = RMISSD;
	boundary.bound[i].cenlon  = RMISSD;
	boundary.bound[i].minlat  = RMISSD;
	boundary.bound[i].minlon  = RMISSD;
	boundary.bound[i].maxlat  = RMISSD;
	boundary.bound[i].maxlon  = RMISSD;
	boundary.bound[i].nparts  = 0;
    }
    
    cfl_wher ( fp, &lpos, &ier );
    cfl_trln ( fp, sizeof(buff), buff, &ier );

    if ( ier == 0 )  {

	sscanf ( buff, "%s %s %d %d %d", id,
		     name, &ilat, &ilon, &nparts );

	boundary.bound[0].bndspt = 
	    (Bndsprt_t *)malloc(nparts*sizeof(Bndsprt_t));

	/*  Read the second header line  */
	cfl_trln ( fp, sizeof(buff), buff, &ier );
	strcpy ( boundary.bound[0].info, buff);
	
	for ( k = 0; k < nparts; k++ )  {

    	    cfl_wher ( fp, &lposp, &ier );
            cfl_trln ( fp, sizeof(buff), buff, &ier );
	
	    sscanf ( buff, "%d %f %f %f %f", &npts,
		    &lat1, &lat2, &lon1, &lon2 );
	    boundary.bound[0].bndspt[k].minlat = G_MIN ( lat1, lat2 );
	    boundary.bound[0].bndspt[k].maxlat = G_MAX ( lat1, lat2 );
	    boundary.bound[0].bndspt[k].minlon = G_MIN ( lon1, lon2 );
	    boundary.bound[0].bndspt[k].maxlon = G_MAX ( lon1, lon2 );
	    boundary.bound[0].bndspt[k].strec = lposp;
	    boundary.bound[0].bndspt[k].npts = npts / 2;
	    cst_rxbl ( buff, buff, &length, &ier );
	    cst_rlst ( buff, ' ', RMISSD, (int) (sizeof(fltptr)/sizeof(float)), 
		       fltptr, &num, &ier);
	    nptot = ( num - 5 );
	    while ( ier == 0 && nptot < npts )  {
                cfl_trln ( fp, sizeof(buff), buff, &ier );
	        if ( ier == 0 )  {
		    cst_rxbl ( buff, buff, &length, &ier );
		    cst_rlst ( buff, ' ', RMISSD, sizeof(fltptr)/sizeof(float), 
			       fltptr, &num, &ier);
		    nptot += num;
	        }   /*  Loop over all points in one part  */
	    }

	}  /*  Loop over all parts in one bound  */

	if ( ier == 0 )  {

	    strcpy ( boundary.bound[0].name, name );
	    boundary.bound[0].strec = lpos;
	    boundary.bound[0].cenlat = ilat / 100.0;
	    boundary.bound[0].cenlon = ilon / 100.0;
	    boundary.bound[0].nparts = nparts;

	    boundary.nbnd++;

	}

    }

    while ( ier == 0 )  {

        cfl_wher ( fp, &lpos, &ier );
	cfl_trln ( fp, sizeof(buff), buff, &ier );

        if ( ier == 0 )  {

	    boundary.nbnd++;
	    pst = boundary.nbnd - 1;
	    sscanf ( buff, "%s %s %d %d %d", id,
		   name,  &ilat, &ilon, &nparts );
	    strcpy ( boundary.bound[pst].name, name );
	    boundary.bound[pst].strec = lpos;
	    boundary.bound[pst].cenlat = ilat / 100.0;
            boundary.bound[pst].cenlon = ilon / 100.0;
	    boundary.bound[pst].nparts = nparts;

	/*  Read the second header line  */
	    cfl_trln ( fp, sizeof(buff), buff, &ier );
  	    strcpy ( boundary.bound[pst].info, buff);

            boundary.bound[pst].bndspt = 
		(Bndsprt_t *)malloc(nparts*sizeof(Bndsprt_t));

	    for ( k = 0; k < nparts; k++ )  {

    	      cfl_wher ( fp, &lposp, &ier );
              cfl_trln ( fp, sizeof(buff), buff, &ier );

	      sscanf ( buff, "%d %f %f %f %f", &npts,
		    &lat1, &lat2, &lon1, &lon2 );
	      boundary.bound[pst].bndspt[k].minlat = G_MIN(lat1,lat2);
	      boundary.bound[pst].bndspt[k].maxlat = G_MAX(lat1,lat2);
	      boundary.bound[pst].bndspt[k].minlon = G_MIN(lon1,lon2);
	      boundary.bound[pst].bndspt[k].maxlon = G_MAX(lon1,lon2);
	      boundary.bound[pst].bndspt[k].strec = lposp;
	      boundary.bound[pst].bndspt[k].npts = npts / 2;
	      cst_rxbl( buff, buff, &length, &ier );
	      cst_rlst( buff, ' ', RMISSD, (int) (sizeof(fltptr)/sizeof(float)),
		       fltptr, &num, &ier);
	      nptot = ( num - 5 );
	      while ( ier == 0 && nptot < npts )  {
                cfl_trln ( fp, sizeof(buff), buff, &ier );
	        if ( ier == 0 )  {
		    cst_rxbl ( buff, buff, &length, &ier );
		    cst_rlst ( buff, ' ', RMISSD, sizeof(fltptr)/sizeof(float), 
			       fltptr, &num, &ier);
		    nptot += num;
	        }
	      }

	    }

	}

    }

    boundary.maxpts = 0;
    for ( i = 0; i < boundary.nbnd; i++ )  {
        minlat =   90.0;
        minlon =  360.0;
        maxlat =  -90.0;
        maxlon = -360.0;
        for ( k = 0; k < boundary.bound[i].nparts; k++ )  {
	  minlat=G_MIN ( minlat, boundary.bound[i].bndspt[k].minlat );
	  minlon=G_MIN ( minlon, boundary.bound[i].bndspt[k].minlon );
	  maxlat=G_MAX ( maxlat, boundary.bound[i].bndspt[k].maxlat );
	  maxlon=G_MAX ( maxlon, boundary.bound[i].bndspt[k].maxlon );
	  boundary.maxpts = 
	    G_MAX ( boundary.maxpts, boundary.bound[i].bndspt[k].npts );
        }
	boundary.bound[i].minlat = minlat;
	boundary.bound[i].minlon = minlon;
	boundary.bound[i].maxlat = maxlat;
	boundary.bound[i].maxlon = maxlon;
   } 

    /*
     *  Print out number of bounds.
     */
    printf("!    TOTAL NUMBER OF BOUNDS\n%d\n!\n", boundary.nbnd );

    printf("!    MAX NUMBER OF POINTS per BOUND\n%d\n!\n", boundary.maxpts );

    printf("!    BOUNDARY STRUCTURE INFORMATION\n!\n" );

    /*
     *  Dump the information.
     */
    for ( i = 0; i < boundary.nbnd; i++ )  {
	printf("!\n%-s %-12ld %-.2f %-.2f %-.2f %-.2f %-.2f %-.2f %-5d\n",
		boundary.bound[i].name, 
		boundary.bound[i].strec, 
		boundary.bound[i].cenlat,
		boundary.bound[i].cenlon,
		boundary.bound[i].minlat, 
		boundary.bound[i].minlon, 
		boundary.bound[i].maxlat, 
		boundary.bound[i].maxlon,
		boundary.bound[i].nparts );
	printf("%s\n", boundary.bound[i].info);
	for ( k = 0; k < boundary.bound[i].nparts; k++ )  {
	    printf("\t%-12ld %-.2f %-.2f %-.2f %-.2f %-8d \n",
		boundary.bound[i].bndspt[k].strec, 
		boundary.bound[i].bndspt[k].minlat, 
		boundary.bound[i].bndspt[k].minlon, 
		boundary.bound[i].bndspt[k].maxlat, 
		boundary.bound[i].bndspt[k].maxlon, 
		boundary.bound[i].bndspt[k].npts );
        }
    }
    return(0);
}
Exemplo n.º 4
0
void cvg_allocGfaBlock ( VG_DBStruct *el )
/************************************************************************
 * cvg_allocGfaBlock							*
 *									*
 * This function allocates a new block for the GFA element.		*
 *									*
 * cvg_allocGfaBlock  ( el )						*
 *									*
 * Input parameters:							*
 *	*el		VG_DBStruct 	Pointer to the VG record	*
 *									*
 * Output parameters:							*
 *	None								*
 *									*
 **									*
 * Log:									*
 * J. Wu/SAIC		10/04	initial coding				*
 ***********************************************************************/
{
    int		nblks, blk_size, ii;
/*---------------------------------------------------------------------*/

/*
 *  If not GFA element or all block pointers are used, do nothing.
 */         
    if ( el->hdr.vg_type != GFA_ELM || 
         el->elem.gfa.info.nblocks >= MAX_GFA_BLOCKS ) {
        return;
    }
    

/*
 *  Calculate the size of a single block.
 */         
    blk_size = sizeof(char) * STD_STRLEN;
    
    
/*
 *  Allocate memory for one more block. 
 */         
    nblks = G_MAX ( el->elem.gfa.info.nblocks, 0 );    
    el->elem.gfa.info.blockPtr[nblks] = malloc ( blk_size );
    
    if ( !el->elem.gfa.info.blockPtr[nblks] ) {
        return;
    }
    
    
/*
 *  Increase the number of blocks by 1.
 */         
    el->elem.gfa.info.nblocks = nblks + 1;
    
    
/*
 *  Initialize the new space to all '\0'.
 */         
    memset ( el->elem.gfa.info.blockPtr[nblks], 
    			'\0', (size_t)STD_STRLEN );
			
			
/*
 *  Initialize all unused block pointers to NULL.
 */         
    for ( ii = el->elem.gfa.info.nblocks; ii < MAX_GFA_BLOCKS; ii++ ) {
	el->elem.gfa.info.blockPtr[ii] = NULL;                
    }
            

/*
 *  Update the element's record size in the header.
 */         
    el->hdr.recsz = sizeof(VG_HdrStruct) + sizeof(int) * 2 + 
    		    el->elem.gfa.info.nblocks * blk_size +
		    el->elem.gfa.info.npts * sizeof(float) * 2;
        
}
Exemplo n.º 5
0
/* 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);
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
0
void de_srng ( const char *uarg, char *stprm, int *iret )
/************************************************************************
 * de_srng								*
 *									*
 * This subroutine computes the range of its scalar arguments among	*
 * ensemble members. The range is the difference between the maximum	*
 * and the minimum.							*
 *									*
 * de_srng ( uarg, stprm, iret )					*
 *									*
 * Input and parameters:						*
 *	*uarg		const char	Function argument string	*
 *									*
 * Output parameters:							*
 *	*stprm		char		Substitution string		*
 *	*iret		int		Return code			*
 *					  0 = normal return		*
 *					 -8 = cannot parse argument	*
 *					 -9 = ensemble cannot computed	*
 **									*
 * Log:									*
 * R. Tian/SAIC 	 6/05						*
 * R. Tian/SAIC		 1/06	Translated from Fortran			*
 ************************************************************************/
{
    char tname[13], pdum[13], time1[21], time2[21];
    int nsmax, nsmin, num, kxd, kyd, ksub1, ksub2, level1, level2,
        ivcord, nina, one, zero, i, j, ier;
    float *gnsmax, *gnsmin, *gnum, d1, d2, d3;
/*----------------------------------------------------------------------*/
    *iret = 0;
    one = 1;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get new grid numbers for maximum and minimum fields.
     */
    dg_nxts ( &nsmax, iret );
    if ( *iret != 0 ) return;
    dg_nxts ( &nsmin, iret );
    if ( *iret != 0 ) return;

    /*
     * Initialize the output grid.
     */
    dg_getg ( &nsmax, &gnsmax, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &nsmin, &gnsmin, &kxd, &kyd, &ksub1, &ksub2, iret );
    for ( i = ksub1 - 1; i < ksub2; i++ ) {
	gnsmax[i] = -FLT_MAX;
	gnsmin[i] =  FLT_MAX;
    }

    /*
     * Set the number of input arguments.  There is only one argument
     * for DE_SRNG.
     */
    nina = 1;
    for ( i = 0; i < MXARGS; i++ ) {
	_ensdiag.allarg[i][0] = '\0';
    }
    strcpy ( _ensdiag.allarg[0], uarg );

    /*
     * Scan the allarg array.
     */
    de_scan ( &nina, iret );
    if ( *iret != 0 ) return;

    /*
     * Loop over number of members set by DE_SCAN.
     */
    for ( i = 0; i < _ensdiag.nummbr; i++ ) {
	de_mset ( &i, iret );
	dg_pfun ( _ensdiag.allarg[0], iret );
	if ( *iret != 0 ) {
	    er_wmsg ( "DG", iret, " ", &ier, strlen("DG"), strlen(" ") );
	    *iret = -8;
	    return;
	}
	dg_driv ( &one, iret );
	if ( *iret != 0 ) {
	    er_wmsg ( "DG", iret, _ensdiag.allarg[0], &ier,
	        strlen("DG"), strlen(_ensdiag.allarg[0]) );
	    *iret = -9;
	    return;
	}

	/*
	 * Retrieve the output grid from the stack.  Check that the 
	 * output is a scalar.
	 */
	dg_tops ( tname, &num, time1, time2, &level1, &level2,
	    &ivcord, pdum, iret );
	dg_getg ( &num, &gnum, &kxd, &kyd, &ksub1, &ksub2, iret );

	/*
	 * Compute the maximum and minimum.
	 */
	for ( j = ksub1 - 1; j < ksub2; j++ ) {
	    d1 = gnum[j];
	    d2 = gnsmax[j];
	    d3 = gnsmin[j];
	    if ( ERMISS ( d1 ) ) {
		gnsmax[j] = RMISSD;
		gnsmin[j] = RMISSD;
	    } else {
		if ( ! ERMISS ( d2 ) ) {
		    gnsmax[j] = G_MAX ( d1, d2 );
		}
		if ( ! ERMISS ( d2 ) ) {
		    gnsmin[j] = G_MIN ( d1, d3 );
		}
	    }
	}
	dg_frig ( &num, &ier );
    }

    /*
     * Compute the range.
     */
    for ( i = ksub1 - 1; i < ksub2; i++ ) {
	d1 = gnsmax[i];
	d2 = gnsmin[i];
	if ( ERMISS ( d1 ) || ERMISS ( d2 ) ) {
	    gnsmax[i] = RMISSD;
	} else {
	    gnsmax[i] = d1 - d2;
	}
    }
    dg_frig ( &nsmin, &ier );

    /*
     * Reset DGCMN.CMN and set internal grid identifier.
     */
    de_rset ( iret );
    dg_udig ( "EXX_", &nsmax, &zero, &_ensdiag.idgens, stprm, iret );
    dg_esub ( &nsmax, &zero, &zero, &zero, &ier );
    if ( ier != 0 )  *iret = ier;

    return;
}
Exemplo n.º 8
0
static int pgdel_deleteElms ( void )
/************************************************************************
 * pgdel_deleteElms                                                     *
 *                                                                      *
 * This function deletes all the currently selected elements.           *
 *                                                                      *
 * static void pgdel_deleteElms ( )   	                                *
 *                                                                      *
 * Input parameters:                                                    *
 * Output parameters:                                                   *
 *      none                                                            *
 *                                                                      *
 * Return:                                                              *
 *      		int	number of deleted elements		*
 **                                                                     *
 * Log:                                                                 *
 * E. Safford/GSC	04/04	initial coding				*
 * B. Yin/SAIC          08/04   Added code to free TCA memory           *
 * B. Yin/SAIC          08/04   Changed pgtca_freeBkpts to cvg_freeBkpts*
 * J. Wu/SAIC           10/04   free GFA block pointers			*
 * S. Danz/AWC		07/06	Added new cvg_delet placement argument	*
 ***********************************************************************/
{
    int         num      = 0,  ier      = 0, found, update_crg; 
    int		grpnum   = 0,  ii       = 0, 	nelm   = 0;
    int		curIndex = -1, selIndex = 0, 	selLoc = 0;
    int		iret     = 0,  *inxarry = NULL, count  = 0;
    char        grptyp   = '0';
    float       llx = 0, lly = 0, urx = 0, ury = 0, inf_bbox[4];
    VG_DBStruct el;
/*---------------------------------------------------------------------*/

    pghdlb_getNextIndex( curIndex, &selIndex, &selLoc, &iret );

    update_crg = 0;
    while ( iret >= 0 ) {

/*
 *  If this is the first deletion, start the undo step
 */
	if( count == 0 ) {
            pgundo_newStep();	    
        }

        crg_getinx(selLoc, &num, &ier); 
        crg_ggrp (num, &grptyp, &grpnum, &ier);

/*
 *  If deleting _by_ group, process the whole group 
 */
        if (grptyp && grpnum && (grptyp == GRPTYP_COMSYM || 
	    grptyp == GRPTYP_CCF || pgpalw_getMode() == TYPE_GRP)) {

            crg_ggbnd (grptyp, grpnum, &llx, &urx, &ury, &lly, &ier);
	    llx -= EXTRA;
	    lly -= EXTRA;
	    urx += EXTRA;
	    ury += EXTRA;

            crg_ggnel(grptyp, grpnum, &nelm, &ier);

            inxarry = (int *)malloc(nelm*sizeof(int));
            crg_gginx(grptyp, grpnum, nelm, inxarry, &nelm, &ier);

            for ( ii = 0; ii < nelm; ii++ ) {

/*
 * Mark elements in placement that are effected by
 * the delete, and get the area of influence back
 */
                cvg_rdrec ( cvg_getworkfile(), selLoc, &el, &ier );
                cvg_checkplace(&el, 1, selLoc, &found, inf_bbox, &ier);
                if (found > 0) {

/*
 * Update the refresh extent if the area impacted by placement is bigger
 */
                    llx = G_MIN(llx, inf_bbox[0]);
                    lly = G_MIN(lly, inf_bbox[2]);
                    urx = G_MAX(urx, inf_bbox[1]);
                    ury = G_MAX(ury, inf_bbox[3]);

                    update_crg = 1;
                }

/*
 * Free TCA break point/GFA block memory
 */
                if ( el.hdr.vg_type == TCA_ELM ) {
                    cvg_freeBkpts ( &el );
                }
	        else if ( el.hdr.vg_type == GFA_ELM ) {
                    cvg_freeElPtr ( &el );
                }

                crg_goffset(inxarry[ii], &selLoc, &ier);
	        pgundo_storeThisLoc(selLoc, UNDO_DEL, &ier);
	        cvg_delet(cvg_getworkfile(), selLoc, TRUE, &ier);

		count++;
	        crg_clear (inxarry[ii], &ier);
            }
            free(inxarry);
            xpgpaste(llx, lly, urx, ury, &ier);

/*
 *  The deleted elements are deselected here so we won't 
 *  try to process them again in the outer while loop.
 */
	    pghdlb_deselectEl (num, TRUE);
	    cvg_rfrsh(NULL, llx, lly, urx, ury, &ier);
        }
        else {				/* non-group mode */
            pgutls_prepNew (selLoc, &el, &llx, &lly, &urx, &ury, &ier);
            pgundo_storeThisLoc(selLoc, UNDO_DEL, &ier);

/*
 * Free TCA break point/GFA block memory
 */
            if ( el.hdr.vg_type == TCA_ELM ) {
               cvg_freeBkpts ( &el );
            }
	    else if ( el.hdr.vg_type == GFA_ELM ) {
               cvg_freeElPtr ( &el );
            }

	    count++;
        }

/*
 *  Check for the next selected element
 */
	curIndex = selIndex;
        pghdlb_getNextIndex( curIndex, &selIndex, &selLoc, &iret );
    }

    if( count > 0 ) {
        pgundo_endStep();
        pglayer_setChngMade( pglayer_getCurLayer(), TRUE );
        pgactv_clearActv();
    }

/*
 * If we may have impacted other elements with placement
 * we will need to rebuild the range records
 */
    if (update_crg) {
        crg_rebuild();
    }

    return ( count );
}
Exemplo n.º 9
0
void clo_from ( int vgtype, int reorder, int npin, int flag, float *lat, 
			float *lon, int maxchar, char *str, int *iret )
/************************************************************************
 * clo_from                                                    		*
 *                                                                      *
 * This function returns a "from" line given a series of lat-lon	*
 * coordinates.  The format of the "from" line is determined by vgtype.	*
 * The parameter reorder is an indicator whether the points consist of	*
 * an area which is closed and the points should be re-ordered in a	*
 * clockwise fashion, if necessary, and that the first point listed in	*
 * the "from" line is the northernmost point.  The flag parameter 	*
 * indicates whether lat-lon coordinates in International SIGMETs are to*
 * be formatted with direction prepended (flag==0) or with direction	*
 * postpended (flag==1)	or as VOR (flag==2).				*
 *                                                                      *
 * clo_from ( vgtype, reorder, npin, flag, lat, lon, maxchar,           *
 * 	      str, iret )						*
 *                                                                      *
 * Input parameters:                                                    *
 *	vgtype		int		VG type of "from" line		*
 *	reorder		int		VG reorder of "from" line	*
 *	npin		int		Number of points		*
 *	flag		int		Flag for coordinate format	*
 *	*lat		float		Latitudes			*
 *	*lon		float		Longitudes			*
 *	maxchar		int		Maximum number of chars in str	*
 *									*
 * Output parameters:                                                   *
 *	*str		char		"From" line string		*
 *	*iret		int		Return value			*
 *					=  0 - OK			*
 *									*
 **                                                                     *
 * Log:                                                                 *
 * D.W.Plummer/NCEP	 7/99	Create					*
 * D.W.Plummer/NCEP	 8/99	Add CONVSIG, NCONVSIG, CONVOLK & AIRMET	*
 * D.W.Plummer/NCEP	 9/99	Sort area types northernmost & clockwise*
 * M. Li/GSC		10/99	Modified clo_direct and clo_compass code*
 * A. Hardy/GSC         12/99   Added flag for lat/lon                  *
 * D.W.Plummer/NCEP	12/99	Added processing for WSM_ELM vgtype	*
 * F. J. Yen/NCEP	 8/00	Made intl sig lat/lon at least 4 digits *
 * D.W.Plummer/NCEP	 2/01	Changed units of WSM from NM to SM	*
 * D.W.Plummer/NCEP	 5/01	Simplified conversion of DD to DM	*
 * D.W.Plummer/NCEP	 5/01	Added chk of pt order for SIGTYP_LINE	*
 * D.W.Plummer/NCEP	 6/01	Change criteria for line point ordering	*
 * D.W.Plummer/NCEP	10/01	Change meaning of flag for intl sigmets	*
 * 				from dd or dms to pre or post ordinate	*
 * m.gamazaychikov/SAIC  9/02 	remove portion of the code duplicating  *
 *				function clo_reorder;			*
 *				add call to clo_reorder			*
 * S. Jacobs/NCEP	10/02	Increased np for area type		*
 * F. J. Yen/NCEP	 1/04	Handled VOR format for intl SIGMETs.	*
 *				Updated and corrected prolog about flag.*
 * J. Lewis/AWC		 3/05   Added chk for new from line format      *
 * J. Lewis/AWC		 6/05   remove reference to LLMXPT		*
 * B. Yin/SAIC		 6/05	increase indx size by 1 besause of np++	*
 * D.W.Plummer/NCEP	 7/05	Add NEW_VAA_LATLON_FORMAT and VAA type	*
 * S. Jacobs/NCEP	 9/05	Add break to WSM case before VAA	*
 * B. Yin/SAIC		10/05	Add separator flags for GFAs		*
 * B. Yin/SAIC		 1/06	remove the space around hyphen		*
 * D.W.Plummer/NCEP	11/06	Explicit processing for GFAs		*
 * D.W.Plummer/NCEP	01/07	clo_tmatch for GFAs, not clo_tclosest	*
 * K. Tyle/UAlbany      11/10   Increased dimension of prefs_tag	*	
 ***********************************************************************/
{
int	ii, jj, idist, np, ier, icmp;
float	dist, dir, minlat, maxlat, dlat;
char	tstr[8], id[9], dir16[4], prefs_tag[22];
char	vaafmt[20], vaasep[8];
int	*indx;
int     lattmp, lontmp;
int	line_order, reverse, format_type;
Boolean newcoord, newvaacoord;
int	n_nms, nclose;
char	nm[17];
float	GFAtol=GFA_TOL;

/*---------------------------------------------------------------------*/
 
	*iret = 0;

	str[0] = '\0';

	/*
	 * Check if the new coordinate format is to be used.
	 */
	strcpy ( prefs_tag, "NEW_LATLON_FORMAT" );
	ctb_pfbool ( prefs_tag, &newcoord, &ier );

	strcpy ( prefs_tag, "NEW_VAA_LATLON_FORMAT" );
	ctb_pfbool ( prefs_tag, &newvaacoord, &ier );
	
	/*
	 *  Allocate memory.
	 */
	G_MALLOC ( indx, int, npin + 1, "CLO_FROM" );

	np = npin;
	for ( jj = 0; jj < np; jj++ )  indx[jj] = jj;

	if ( reorder == SIGTYP_AREA )  {
            clo_reorder( np, lat, lon, indx, iret );
	    np++;
	}
	else if ( reorder == SIGTYP_LINE )  {

	    /*
	     *  If reorder is a line, re-order processing of
	     *  points to do either west-to-east or north-to-south.
	     *  West-to-east defined as all points within W2ELIM
	     *  degrees of one another.
	     */

            minlat = lat[0];
            maxlat = minlat;
            for ( jj = 1; jj < np; jj++ )  {
                minlat = G_MIN ( minlat, lat[jj] );
                maxlat = G_MAX ( maxlat, lat[jj] );
            }
            dlat = G_ABS( maxlat - minlat );

            line_order = N2S;
            if ( dlat <= W2ELIM )  line_order = W2E;

            reverse = G_FALSE;
            if ( line_order == N2S && lat[0] < lat[np-1] )
                reverse = G_TRUE;
            if ( line_order == W2E && lon[0] > lon[np-1] )
                reverse = G_TRUE;

            if ( reverse )  {
                for ( jj = 0; jj < np; jj++ )  indx[jj] = np-1-jj;
            }

	}

	/*
	 *  Set format_type.
	 */

	if ( vgtype == SIGINTL_ELM ) {
	    /*
	     *	International SIGMET
	     */
	    if ( flag != 2 )
		format_type = LATLON;
	      else
		format_type = VOR_FMT;
	  }
	  else if ( vgtype == SIGNCON_ELM || vgtype == SIGCONV_ELM ||
	    	    vgtype == SIGOUTL_ELM || vgtype == SIGAIRM_ELM )
	    /*
	     *	Non-Convective SIGMET, Convective SIGMET,
	     *	Convective Outlook
	     */
	    format_type = VOR_FMT;
	  else if ( vgtype == GFA_ELM )
	    /*
	     *	AIRMET
	     */
	    format_type = GFA_FMT;
	  else if ( vgtype == WSM_ELM )
	    /*
	     *	Watch Status Message
	     */
	    format_type = WSM;
	  else if ( vgtype == VOLC_ELM || vgtype == ASHCLD_ELM )
	    /*
	     *	VAA volcano and ash clouds.
	     */
	    format_type = VAA;
	  else
	    format_type = IMISSD;

	/*
	 *  Loop through all the points using the indx array.
	 */
		
	for ( jj = 0; jj < np; jj++ )  {

	    ii = indx[jj];

	    switch ( format_type )  {

		case	LATLON:		/* latitude/longitude display */
					/* eg., 3913N7705W 4134N8120W */
					/* eg., N3913W07705 N4134W08120 */

		    if ( jj != 0 )  strcat ( str, " " );

		    if ( flag == 0 ) {

		        if ( ( newcoord == G_TRUE ) && ( jj != 0 ) ) strcat ( str, "- " );
		        if ( lat[ii] >= 0.0F )
			    strcat ( str, "N" );
		        else
		            strcat ( str, "S" );

	                /*
	                 *  Convert degree, decimal to degree, minutes.
	                 */
		        lattmp = DDTODM ( G_ABS( lat[ii] ) );
		        sprintf( tstr, "%04d", lattmp );

		        strcat ( str, tstr );
		        if ( newcoord == G_TRUE )  strcat ( str, " " );

		        if ( lon[ii] >= 0.0F )
			    strcat ( str, "E" );
		        else
		            strcat ( str, "W" );

	                /*
	                 *  Convert degree, decimal to degree, minutes.
	                 */
		        lontmp = DDTODM ( G_ABS( lon[ii] ) );
		        sprintf( tstr, "%05d", lontmp );

		        strcat ( str, tstr );


		    }
		    else  {

	                /*
	                 *  Convert degree, decimal to degree, minutes.
	                 */
		        lattmp = DDTODM ( G_ABS( lat[ii] ) );

		        sprintf( tstr, "%04d", lattmp );

		        strcat ( str, tstr );

		        if ( lat[ii] >= 0.0F )
			    strcat ( str, "N" );
		        else
		            strcat ( str, "S" );

	                /*
	                 *  Convert degree, decimal to degree, minutes.
	                 */
		        lontmp = DDTODM ( G_ABS( lon[ii] ) );
		        sprintf( tstr, "%05d", lontmp );

		        strcat ( str, tstr );

		        if ( lon[ii] >= 0.0F )
			    strcat ( str, "E" );
		        else
		            strcat ( str, "W" );

		    }

		    break;

		case	VOR_FMT:	/* distance and 16-pt compass   */
					/* to closest VOR point		*/
					/* eg., 20SSW EMI TO 20ENE CLE	*/

		    clo_tdirect( "VOR", lat[ii], lon[ii], id, 
				 &dist, &dir, &ier );

		    clo_compass ( &dir, dir16, &icmp, &ier );

		    /*
		     *  Round distance to the nearest 10 nautical miles;
		     *  If convective outlook and less than 30 nm, set to 0.
		     */
		    idist = G_NINT ( dist * M2NM / 10.0F ) * 10;
		    if ( vgtype == SIGOUTL_ELM && idist < 30 )  idist = 0;

		    if ( jj > 0 )  {
			/*
			 *  Different separators for different products.
			 */
			if ( vgtype == SIGCONV_ELM || vgtype == SIGOUTL_ELM ||
			     vgtype == SIGINTL_ELM ) 
			    strcat ( str, "-" );
		        else if ( vgtype == SIGAIRM_ELM || vgtype == SIGNCON_ELM )
			    strcat ( str, " TO " );
		    }

		    if ( idist != 0 )  {
			sprintf( tstr, "%d", idist );
			strcat ( str, tstr );
			if ( vgtype == SIGINTL_ELM ) strcat ( str, " " );
			strcat ( str, dir16 );
		        strcat ( str, " " );
		    }

		    strcat ( str, id );

		    break;

		case	GFA_FMT:	/* closest SNAP point		*/

		    /*
		     * Use clo_tmatch since all points are already snapped
		     */
		    clo_tmatch( "SNAP", lat[ii], lon[ii], GFAtol, &ier );

		    if ( ier != 0 )  {
			nclose = 1;
			clo_tclosest( "SNAP", lat[ii], lon[ii], nclose, &ier );
		    }

		    clo_tgnm ( "SNAP", 1, (sizeof(nm)-1), &n_nms, nm, &ier );

		    cst_rpst ( nm, "_", " ", nm, &ier );

		    if ( jj > 0 )  {
		        if ( flag == SEPARATOR_TO )  {
			    strcat ( str, " TO " );
		        }
		        else if ( flag == SEPARATOR_DASH )  {
			    strcat ( str, "-" );
		        }
		    }

		    strcat ( str, nm );

		    break;

		case	WSM:		/* Watch status messages	*/
					/* SM distance and 16-pt compass*/
					/* to closest ANCHOR point	*/
					/* eg., 10 N DCA TO 20 NW HGR	*/

		    clo_tdirect( "ANCHOR", lat[ii], lon[ii], id, 
				 &dist, &dir, &ier );

		    clo_compass ( &dir, dir16, &icmp, &ier );

		    /*
		     *  Round distance to the nearest 5 statute miles.
		     */
		    idist = G_NINT ( dist * M2SM / 5.0F ) * 5;

		    if ( jj > 0 )  strcat ( str, " TO " );

		    if ( idist != 0 )  {
			sprintf( tstr, "%d ", idist );
			strcat ( str, tstr );
			strcat ( str, dir16 );
		        strcat ( str, " " );
		    }

		    strcat ( str, id );

		    break;

		case	VAA:		/* VAA volcano and ash clouds	*/

		    if ( newvaacoord == G_FALSE )  {
			strcpy ( vaafmt, "%s%04d%s%05d" );
			strcpy ( vaasep, " - " );
		    }
		    else if ( newvaacoord == G_TRUE )  {
			strcpy ( vaafmt, "%s%04d %s%05d" );
			strcpy ( vaasep, " - " );
		    }

	            /*
	             *  Convert degree, decimal to degree, minutes.
	             */
		    lattmp = DDTODM ( G_ABS( lat[ii] ) );
		    lontmp = DDTODM ( G_ABS( lon[ii] ) );
		    sprintf( tstr, vaafmt, 
			    ( lat[ii] >= 0.0F ) ? "N" : "S", lattmp,
			    ( lon[ii] >= 0.0F ) ? "E" : "W", lontmp );

		    strcat ( str, tstr );
		    if ( jj < (np-1) )  strcat ( str, vaasep );

		    break;

	    }

	}
        
	G_FREE ( indx, int );
	
	return;

}
Exemplo n.º 10
0
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);

    }

}
Exemplo n.º 11
0
void db_setsubgnav ( float lllat, float lllon, float urlat, float urlon, int *iret )
/************************************************************************
 * db_setsubgnav                                                        *
 *                                                                      *
 * This subroutine initializes internal sub grid navigation.            *
 * dgc_setsubgnav (lllat, lllon, urlat, urlon, irer )                   *
 * Input parameters:                                                    * 
 * 		lllat     float     Lower left latitude                 *
 *              lllon     float     Lower left Longitude               *
 *              urlat     float     Upper right latitude                *
 *              urlon     float     Upper right Longitude              *
 * Output parameters:                                                   *
 *             *iret      int        Return code                        *
 *                                        0 = normal return             *
 *                                      -46 = invalid grid point        *
 **                                                                     *
 * Log:                                                                 *
 * X. Guo       12/04               Initial                             *
 ***********************************************************************/  
{
     int nc,ier;
     char gprj[5];
     float rltmin, rlnmin, rltmax, rlnmax;
     float  dlatll, dlonll, dlatur, dlonur;
/*----------------------------------------------------------------------*/
     *iret = 0;
     cst_itos ( (int *)&_dgsubg.refnav[1], 1, &nc, gprj, &ier );
     cst_rmbl ( gprj, gprj, &nc, &ier );
     /*
      * Define sub-grid area
      */
    rltmin = G_MIN ( lllat, urlat );
    rlnmin = G_MIN ( lllon, urlon );
    rltmax = G_MAX ( lllat, urlat );
    rlnmax = G_MAX ( lllon, urlon );
    /*
     * Take care of the sub-grid area across the date-line
     */
    if ( ( rlnmax - rlnmin ) > 180. ) {
        dlatll = rltmin;
        dlonll = rlnmax;
        dlatur = rltmax;
        dlonur = rlnmin;
    } else {
        dlatll = rltmin;
        dlonll = rlnmin;
        dlatur = rltmax;
        dlonur = rlnmax;
    }

    /*
     * *Set internal sub-grid navigation
     */
    gsmprj ( gprj, &_dgsubg.refnav[10], &_dgsubg.refnav[11], &_dgsubg.refnav[12],
        &dlatll, &dlonll, &dlatur, &dlonur, &ier, strlen(gprj) );
    /*
     * IF set sub-grid navigation fail, change center longitude
     */
    if ( ier != 0 ) {
        *iret = -46;
    }   
}
Exemplo n.º 12
0
void cgr_segintwn (  float *xin1, float *yin1, 
		     float *xin2, float *yin2,
		     float *xint, float *yint, 
		     int *intrsct, int *iret )
/************************************************************************
 * cgr_segintwn								*
 *									*
 * This function accepts two line segments and determines if they	*
 * intersect one another.  Note that if two line segments are extended	*
 * as lines, they will always intersect (unless they are parallel, ie.	*
 * their slopes are equal).  This intersecting point is returned	*
 * regardless of whether it falls on the segments themselves.  If the	*
 * segments are parallel, the intersecting point is (RMISSD,RMISSD).	*
 *									*
 * This is simply a copy of cgr_segint without the use of normalized    *
 * coordinates.  Output is in sys_M, inputs are assumed to be sys_M as  *
 * well.  If they are in any other coordinate system the results will   *
 * be undefined.							*
 *									*
 * cgr_segint ( xin1, yin1, xin2, yin2, xint, yint, intrsct, iret )	*
 *									*
 * Input parameters:							*
 *	*xin1	float	X-coordinate of endpoints for segment #1	*
 *	*yin1	float	Y-coordinate of endpoints for segment #1	*
 *	*xin2	float	X-coordinate of endpoints for segment #2	*
 *	*yin2	float	Y-coordinate of endpoints for segment #2	*
 *									*
 * Output parameters:							*
 *	*xint	float	X-coordinate of intersecting point		*
 *	*yint	float	Y-coordinate of intersecting point		*
 *	*intrsct int	Result: 					*
 *			0-FALSE (the segments do not intersect),	*
 *			1-TRUE (the segments intersect)			*
 *	*iret	 int	Return code					*
 **									*
 * Log:									*
 * E. Safford/SAIC	09/06	copied from cgr_segint 			*
 * E. Safford/SAIC	10/06	make internal variables double to       *
 *				 ensure same results on all platforms   *
 ***********************************************************************/
{
double	x, y, m1, b1, m2, b2;
double	x1[2], y1[2], x2[2], y2[2];
/*---------------------------------------------------------------------*/

    *iret = 0;
    *intrsct = 0;
    *xint = RMISSD;
    *yint = RMISSD;

    x = RMISSD;
    y = RMISSD;


    /*
     *  Make local copies of the inputs.
     */    
    x1[0] = xin1[0]; x1[1] = xin1[1];
    y1[0] = yin1[0]; y1[1] = yin1[1];
  
    x2[0] = xin2[0]; x2[1] = xin2[1];
    y2[0] = yin2[0]; y2[1] = yin2[1];


    /*
     *  Check for vertical first segment and compute (x,y) intersect.
     */

    if ( G_DIFF(x1[0], x1[1]) ) {

	x = x1[0];
	if ( G_DIFF(x2[0], x2[1]) ) return; 
	m2 = (y2[1]-y2[0]) / (x2[1]-x2[0]);
	b2 = y2[0] - m2 * x2[0];
	y = m2 * x + b2;

    }

    /*
     *  Check for vertical second segment and compute (x,y) intersect.
     */

    else if ( G_DIFF(x2[0], x2[1]) ) {

	x = x2[0];
	if ( G_DIFF(x1[0], x1[1]) ) return;
	m1 = (y1[1]-y1[0]) / (x1[1]-x1[0]);
	b1 = y1[0] - m1 * x1[0];
	y = m1 * x + b1;

    }

    /*
     *  Finally compute (x,y) intersect for all other cases.
     */

    else {

    	m1 = (y1[1]-y1[0]) / (x1[1]-x1[0]);
    	b1 = y1[0] - m1 * x1[0];

    	m2 = (y2[1]-y2[0]) / (x2[1]-x2[0]);
    	b2 = y2[0] - m2 * x2[0];

	if ( G_DIFF(m1, m2) )  {
	    x = RMISSD;
	    y = RMISSD;
	}
	else  {
	    if ( G_DIFF(m1, 0.0F) )  {
	        x = ( b2 - y1[0] ) / ( - m2 );
	        y = y1[0];
	    }
	    else if ( G_DIFF(m2, 0.0F) )  {
	        x = ( y2[0] - b1 ) / ( m1 );
	        y = y2[0];
	    }
	    else  {
	        x = ( b2 - b1 ) / ( m1 - m2 );
	        y = m1 * x + b1;
	    }
	}

    }

    /*
     *  Check if intersecting point is within each segment's bounds.
     */

    if ( ERMISS(x) || ERMISS(y) ) return;

    *xint = x;
    *yint = y;

    if ( x < G_MIN(x1[0],x1[1]) || x > G_MAX(x1[0],x1[1]) )  return;
    if ( x < G_MIN(x2[0],x2[1]) || x > G_MAX(x2[0],x2[1]) )  return;
    if ( y < G_MIN(y1[0],y1[1]) || y > G_MAX(y1[0],y1[1]) )  return;
    if ( y < G_MIN(y2[0],y2[1]) || y > G_MAX(y2[0],y2[1]) )  return;

    *intrsct = 1;

    return;
}
Exemplo n.º 13
0
void pd_hans ( const float *tc1, const float *tc2, const float *dwpc,
               const int *np, const int *type, float *haines, int *iret )
/************************************************************************
 * pd_hans								*
 *									*
 * This subroutine computes low, middle, and high elevation Haines 	*
 * Indices from TMPC and DWPC.						*
 *									*
 * pd_hans ( tc1, tc2, dwpc, np, type, haines, iret )			*
 *									*
 * Input parameters:							*
 *	*tc1		const float	Temperature in Celsius		*
 *	*tc2		const float	Temperature in Celsius		*
 *	*dwpc		const float	Dewpoint in Celsius		*
 *	*np		const int	Number of points		*
 *	*type		const int	Type of Haines index		*
 *					  1 = Low			*
 *					  2 = Middle			*
 *					  3 = High			*
 *									*
 * Output parameters:							*
 *	*haines		float		Haines index			*
 *	*iret		int		Return code			*
 *					  0 = normal return		*
 **									*
 * Log:									*
 * T. Lee/SAIC		 6/03	Created					*
 * R. Tian/SAIC		 9/05	Translated from FORTRAN			*
 ************************************************************************/
{
    float a, b;
    int i, npt, itype;    
/*----------------------------------------------------------------------*/
    *iret = 0;
    npt = *np;
    itype = *type;

    /*
     * Loop through all the points.
     */
    for ( i = 0; i < npt; i++ ) {
        /*
         * Check for missing data.
         */
        if ( ( ERMISS ( tc1 [i] ) ) || ( ERMISS ( tc2 [i] ) ) ||
     	     ( ERMISS ( dwpc [i] ) ) ) {
	    haines [i] = RMISSD;
        } else {
            /*
             * Compute the Haines index.
             */
	    if ( itype == 1 ) {
	        a = ( ( tc2 [i] -  tc1 [i] ) - 3.0F ) * (2.0F/5.0F) + 1.0F;
		b = ( ( tc1 [i] - dwpc [i] ) - 5.0F ) * (2.0F/5.0F) + 1.0F;
            } else if ( itype == 2 ) {
	        a = ( ( tc1 [i] -  tc2 [i] ) - 5.0F ) * (2.0F/6.0F) + 1.0F;
		b = ( ( tc1 [i] - dwpc [i] ) - 5.0F ) * (2.0F/8.0F) + 1.0F;
            } else if ( itype == 3 ) {
	        a = ( ( tc1 [i] -  tc2 [i] ) - 17.0F) * (2.0F/5.0F) + 1.0F;
		b = ( ( tc1 [i] - dwpc [i] ) - 14.0F) * (2.0F/7.0F) + 1.0F;
            }
	    a = G_MAX ( a, 0.9F );
	    a = G_MIN ( a, 3.1F );
	    b = G_MAX ( b, 0.9F );
	    b = G_MIN ( b, 3.1F );
	    haines [i] = a + b;
        }
    }
    
    return;
}
Exemplo n.º 14
0
void rscnfll ( int *np, int ix[], int iy[], int *iret )
/************************************************************************
 * rscnfll								*
 *									*
 * This function draws a filled polygon on a raster bitmap.		*
 *									*
 * void rscnfll ( np, ix, iy, iret )					*
 *									*
 * Input parameters:							*
 *	*np		int		Number of points in the polygon	*
 *	ix []		int		Array of x coordinates		*
 *	iy []		int		Array of y coordinates		*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 **									*
 * Log:									*
 * E. Wehner/EAi	 4/96	Created					*
 * E. Safford/GSC	 3/97	Modified to use new cgr_ routintes 	*
 * E. Wehner/EAi	 3/97	change xsize/ysize to scanlines		*
 * M. Linda/GSC		 7/97	Added a call to RLINE following fill	*
 * S. Jacobs/NCEP	 7/97	Cleaned up header files and global vars	*
 * D.W.Plummer/NCEP	 8/97	Rewrite					*
 ***********************************************************************/
{

	int	npts, *ixarr, *iyarr, iymin, iymax, i, j, index,
		nx1, nx2, ny2;
	float	tau, xout[100];

/*---------------------------------------------------------------------*/

	*iret = G_NORMAL;

/*
 *	Get the number of points and make sure that the polygon
 *	is closed.
 */
	npts = *np;
	if ( ix[0] != ix[npts-1] || iy[0] != iy[npts-1] )  npts++;

/*
 *	Allocate space for the working arrays.
 */
	ixarr = (int *) malloc ( npts * sizeof(int) );
	iyarr = (int *) malloc ( npts * sizeof(int) );

	iymin =  INT_MAX;
	iymax = -INT_MAX;

/*
 *	Double the dimensions for easier computations. Find the min
 *	and max in the Y direction.
 */
	for ( i = 0; i < npts-1; i++ )  {
	    ixarr[i] = ix[i] * 2;
	    iyarr[i] = iy[i] * 2;
	    iymin = G_MIN ( iyarr[i], iymin );
	    iymax = G_MAX ( iyarr[i], iymax );
	}

	ixarr[npts-1] = ixarr[0];
	iyarr[npts-1] = iyarr[0];

/*
 *	For each scan line, compute intersections and fill.
 */
	for ( j = iymin+1; j < iymax; j = j+2 )  {
	
	    index = 0;

	    for ( i = 0; i < npts-1; i++ )  {

		if  ( iyarr[i] != iyarr[i+1] )  {

		    tau = (float) ( j - iyarr[i] ) /
			  (float) ( iyarr[i+1] - iyarr[i] );

		    if ( tau >= 0.0 && tau <= 1.0 ) {

			xout[index] = tau * ( ixarr[i+1] - ixarr[i] ) +
				      ixarr[i];
			index++;

		    }
		}
	    }

/*
 *	    Sort the values of the X coordinate.
 *  Added (int(*)(const void*, const void*)) cast to satisfy qsort
 */
	    qsort ( xout, index, sizeof(float), 
		    (int(*)(const void*, const void*))_cmp_xout );

/*
 *	    Loop over all the scan lines, filling the pixels
 *	    in the pattern.
 */
	    for ( i = 0; i < index; i=i+2 ) {
		ny2 = j / 2;
		nx1 = xout[i  ] / 2;
		nx2 = xout[i+1] / 2;
		fillScan ( ny2, nx1, nx2, iret );
	    }

	}

/*
 *	Free the working arrays.
 */
	free ( ixarr );
	free ( iyarr );

}
Exemplo n.º 15
0
void dg_g2gc ( const int *inttyp, const int *glbwi, const int *kxi,
               const int *kyi, const float *grdi, const int *kxo,
	       const int *kyo, float *gixo, float *giyo, float *grdo,
	       int *iret )
/************************************************************************
 * dg_g2gc								*
 *									*
 * This subroutine remaps cosines of data from one grid to another grid.*
 *									*
 * A globe-wrapping grid must be configured so that the last column	*
 * and first column are identical.					*
 *									*
 * If INTTYP=0, the code determines automatically whether to use a	*
 * simple bi-linear interpolation or an area average preserving re-	*
 * mapping of data.  The method is determined locally and may vary	*
 * across the grid.  The transition to area average preserving remap-	*
 * ping occurs when one output grid box contains approximately four (4)	*
 * or more input grid boxes.  Since bilinear interpolation preserves	*
 * the area average when grid resolutions are comparable or when the	*
 * input grid is coarse compared to the output grid, this method always *
 * preserves area averages.						*
 *									*
 * If INTTYP=1, the code performs nearest neighbor assignment.		*
 * If INTTYP=2, the code performs only bi-linear interpolation.		*
 *									*
 * dg_g2gc ( inttyp, glbwi, kxi, kyi, grdi, kxo, kyo, gixo, giyo, grdo,	*
 *	     iret )							*
 *									*
 * Input parameters:							*
 *	*inttyp		const int	Remapping type			*
 *					 = 0 area average preserving	*
 *					 = 1 nearest point assignment	*
 *					 = 2 bi-linear interpolation	*
 *	*glbwi		const int	Flg for globe-wrapping input grd*
 *	*kxi		const int	Number of x pts on input grid	*
 *	*kyi		const int	Number of y pts on input grid	*
 *	*grdi		const float	Input grid			*
 *	*kxo		const int	Number of x pts on output grid	*
 *	*kyo		const int	Number of y pts on output grid	*
 *	*gixo		flaot		Input grd rltv x on output grid *
 *	*giyo		float		Input grd rltv y on output grid *
 *									*
 * Output parameters:							*
 *	*grdo		float		Output grid of results		*
 *	*iret		int		Return code			*
 *					  0 = normal return		*
 *					-68 = INTTYP is not valid	*
 *					-69 = grid rel position error	*
 **									*
 * Log:									*
 * K. Brill/HPC		 3/04	Created from DG_G2GI			*
 * K. Brill/HPC		 4/04	IF (k==0) k=1; add .005 to rad		*
 * R. Tian/SAIC		 2/06	Recoded from Fortran			*
 ************************************************************************/
{
    float rkio2, rdtst, xchk, rad2m, dx, dy, d2, x, y, xi, omx, omy,
        rad, rad2, radx2, sum, sumw, ri, r2, dr2, dr22, wt, tmp;
    int ir[4], jr[4], kio2, ityp, cidx, cidx1, i, j, k, io, jo, in, jn,
        idx1, idx2, idx3, idx4, ip, ib, jb, ie, je, ii, jj, jdif, npts;
    int rflct;
/*----------------------------------------------------------------------*/
    *iret  = 0;
    if ( (*inttyp) < 0 || (*inttyp) > 2 ) {
	*iret = -68;
	return;
    }

    kio2 = (*kxi) / 2;
    rkio2 = (float)kio2;
    rdtst = 4. / PI;

    if ( (*inttyp) == 0 && (*glbwi) == G_TRUE && ( (*kxi) % 2 ) == 1 ) {
	/*
	 * Check to relect points across the pole of a global grid.
	 * All points along bottom and top rows must be identical.
	 */
	rflct = G_TRUE;
	for ( j = 1; j <= (*kyi); j += (*kyi) - 1 ) {
	    cidx = (j - 1 ) * (*kxi);
	    xchk = cos ( grdi[cidx] );
	    i = 2;
	    while ( i <= (*kxi) && rflct == G_TRUE ) {
	        cidx = ( j - 1 ) * (*kxi) + i - 1;
		rflct = ( ! ERMISS ( grdi[cidx] ) ) ? G_TRUE : G_FALSE;
		if ( rflct == G_TRUE ) {
		    if ( G_ABS ( xchk - cos ( grdi[cidx] ) ) < RDIFFD ) {
		        rflct = G_FALSE;
		    }
		}
		i++;
	    }
	}
    } else {
	rflct = G_FALSE;
    }

    /*
     * Loop over all output grid points.
     */
    rad2m = -9999.;
    for ( jo = 1; jo <= (*kyo); jo++ ) {
	for ( io = 1; io <= (*kxo); io++ ) {
	    cidx = ( jo - 1 ) * (*kxo) + io - 1;
	    grdo[cidx] = RMISSD;
	    if ( ERMISS ( gixo[cidx] ) || ERMISS ( giyo[cidx] ) ) {
		ityp = 2;
	    } else if ( (*inttyp) == 1 ) {
		/*
		 * Assign value at nearest point.
		 */
		ityp = 2;
		in = G_NINT ( gixo[cidx] );
		if ( (*glbwi) == G_TRUE ) {
		    if ( in > (*kxi) ) in = in - (*kxi) + 1;
		    if ( in < 1 ) in = in + (*kxi) - 1;
		}
		jn = G_NINT ( giyo[cidx] );
		if ( in >= 1 && in <= (*kxi) &&
		     jn >= 1 && jn <= (*kyi) ) {
		    /*
		     * Nearest point value assignment.
		     */
		    cidx1 = ( jn - 1 ) * (*kxi) + in - 1;
		    grdo[cidx] = cos ( grdi[cidx1] );
		}
	    } else if ( (*inttyp) == 2 ) {
		ityp = 1;
	    } else {
		ityp = 0;

		/*
		 * Get radius in input grid units of the circle
		 * circumscribing the the diamond formed by the
		 * four points closest to the current point on
		 * the output grid.
		 */
                rad2 = -1.1E31;
                ir[0] = io - 1;
                jr[0] = jo;
                ir[1] = io;
                jr[1] = jo - 1;
                ir[2] = io + 1;
                jr[2] = jo;
                ir[3] = io;
                jr[3] = jo + 1;

                for ( ip = 0; ip < 4; ip++ ) {
                    cidx1 = ( jr[ip] - 1 ) * (*kxo) + ir[ip] - 1;
                    if ( ir[ip] >= 1 && ir[ip] <= (*kxo) &&
                         jr[ip] >= 1 && jr[ip] <= (*kyo) &&
                         ! ERMISS ( gixo[cidx1] ) &&
                         ! ERMISS ( giyo[cidx1] ) ) {
                        dx = gixo[cidx1] - gixo[cidx];
                        if ( (*glbwi) == G_TRUE && G_ABS (dx) > rkio2 ) {
                            /*
                             * Skip this point.
                             */
                        } else if ( G_ABS (dx) > rkio2 ) {
                            *iret = -69;
                            return;
                        } else {
                            dy = giyo[cidx1] - giyo[cidx];
                            d2 = dx * dx + dy * dy;
                            rad2 = G_MAX ( d2, rad2 );
                        }
                    }
                }

                /*
                 * Since RAD2 is the square of the radius of the
                 * circle circumscribing the output grid diamond
                 * in input grid units, multiply by .5 to get the
                 * the square of the radius of the inscribed circle.
                 * This circle circumscribes the output grid box.
                 */
                if ( rad2 > -1.0E30 ) {
                    rad2 *= .5;

                    /*
                     * If the radius is much larger than that at the
                     * adjacent point, then reduce it.
                     */
                    if ( rad2m > 0.0 && rad2 > 1.5 * rad2m ) {
                        rad2 = 1.5 * rad2m;
                    }
                    rad2m = rad2;
                } else {
                    rad2m = -9999.;
                }

                /*
                 * If the squared radius of the inscribed circle is
                 * small enough (4/PI), then there are less than four
                 * input grid boxes per output grid box and linear
                 * interpolation will suffice.
                 */
                if ( rad2 < rdtst ) {
                    ityp = 1;
                }
            }

            if ( ityp == 1 ) {
                /*
                 * Do bi-linear interpolation.
                 */
                i = (int)gixo[cidx];
                if ( (*glbwi) == G_TRUE ) {
                    if ( i >= (*kxi) ) {
                        i = i - (*kxi) + 1;
                        xi = gixo[cidx] - (float)(*kxi) + 1;
                    } else if ( i < 1 ) {
                        i = i + (*kxi) - 1;
                        xi = gixo[cidx] + (float)(*kxi) - 1;
                        if ( gixo[cidx] < 0.0 ) i--;
                    } else {
                        xi = gixo[cidx];
                    }
                } else {
                    xi = gixo[cidx];
                }

                j = (int)giyo[cidx];
                if ( i >= 1 && i <= (*kxi) &&
                     j >= 1 && j <= (*kyi) ) {
                    if ( i == (*kxi) ) i--;
                    if ( j == (*kyi) ) j--;
                    idx1 = ( j - 1 ) * (*kxi) + i - 1;
                    idx2 = ( j - 1 ) * (*kxi) + i;
                    idx3 = j * (*kxi) + i - 1;
                    idx4 = j * (*kxi) + i;
                    if ( ! ERMISS ( grdi[idx1] ) &&
                         ! ERMISS ( grdi[idx2] ) &&
                         ! ERMISS ( grdi[idx3] ) &&
                         ! ERMISS ( grdi[idx4] ) ) {
                        x = xi - (float)i;
                        y = giyo[cidx] - (float)j;
                        omx = 1. - x;
                        omy = 1. - y;
                        grdo[cidx] = ( cos ( grdi[idx1] ) * omx +
                                       cos ( grdi[idx2] ) * x ) * omy +
                                     ( cos ( grdi[idx3] ) * omx +
                                       cos ( grdi[idx4] ) * x ) * y;
                    }
                }
            } else if ( ityp == 0 ) {
                /*
                 * Do area average preserving interpolation.
                 *
                 * This integer truncation acts to pull the
                 * output grid box circumscribing circle in
                 * just a bit.
                 */
                tmp = sqrt ( rad2 );
                k = (int)tmp;
                if ( k == 0 ) k = 1;

                /*
                 * Reset rad2 accordingly.
                 */
                rad = (float)k + .005;
                rad2 = rad * rad;
                radx2 = 1. / ( 2. * rad );

                ib = G_NINT ( gixo[cidx] ) - k;
                jb = G_NINT ( giyo[cidx] ) - k;
                ie = G_NINT ( gixo[cidx] ) + k;
                je = G_NINT ( giyo[cidx] ) + k;
                sum = 0.0;
                sumw = 0.0;
                npts = 0;

                for ( j = jb; j <= je; j++ ) {
                    for ( i = ib; i <= ie; i++ ) {
                        jj = j;
                        ii = i;
                        ri = (float)i;
                        if ( (*glbwi) == G_TRUE ) {
                            if ( i > (*kxi) ) ii = i - (*kxi) + 1;
                            if ( i < 1 ) ii = i + (*kxi) - 1;
                        }

                        dx = ri - gixo[cidx];
                        dy = (float)j - giyo[cidx];
                        r2 = dx * dx + dy * dy;

                        if ( rflct == G_TRUE ) {
                            if ( j > (*kyi) ) {
                                jdif = j - (*kyi);
                                jj = (*kyi) - jdif;
                                if ( ii <= kio2 ) {
                                    ii += kio2;
                                } else {
                                    ii -= kio2;
                                }
                            } else if ( j < 1 ) {
                                jdif = 1 - j;
                                jj = 1 + jdif;
                                if ( ii <= kio2 ) {
                                    ii += kio2;
                                } else {
                                    ii -= kio2;
                                }
                            }
                        }

                        if ( r2 <= rad2 ) {
                            if ( ii >= 1 && ii <= (*kxi) &&
                                 jj >= 1 && jj <= (*kyi) ) {
                                cidx1 = ( jj - 1 ) * (*kxi) + ii - 1;
                                if ( ! ERMISS (grdi[cidx1] ) ) {
                                    /*
                                     * Compute a weighting factor based
                                     * on an estimate of how much of
                                     * the area of the input grid box
                                     * is contributing to the area
                                     * covered by the output grid box.
                                     * The criterion is (rad-r) < .5.
                                     * Using the approximation that
                                     * rad ~ r, then (rad2-r2) is nearly
                                     * equal to 2*rad(rad-r).  Substi-
                                     * tute into above inequality and
                                     * rearrange to get this criterion:
                                     * (rad2-r2)**2<rad2.  The weight is
                                     * either 1 or [.5+(rad2-r2)/rad*2].
                                     * The .5 is added on because a
                                     * point on the circle has about
                                     * half of its area inside.
                                     */
                                    dr2 = rad2 - r2;
                                    dr22 = dr2 * dr2;
                                    if ( dr22 < rad2 ) {
                                        wt = .5 + dr2 * radx2;
                                    } else {
                                        wt = 1.0;
                                    }
                                    sum += wt * cos ( grdi[cidx1] );
                                    sumw += wt;
                                    npts++;
                                }
                            }
                        }
                    }
                }

                if ( sumw >= 2.0 && npts >= 4 ) {
                    /*
                     * The value 2.0 is used as the criterion here
                     * because at least 4 points must contribute
                     * at least a half.
                     */
                    grdo[cidx] = sum / sumw;
                } else {
                    /*
                     * Perform linear interpolation, which itself
                     * preserves area averages when grid resolutions
                     * are comparable.
                     */
                    i = (int)gixo[cidx];
                    if ( (*glbwi) == G_TRUE ) {
                        if ( i >= (*kxi) ) {
                            i = i - (*kxi) + 1;
                            xi = gixo[cidx] - (float)(*kxi) + 1;
                        } else if ( i < 1 ) {
                            i = i + (*kxi) - 1;
                            xi = gixo[cidx] + (float)(*kxi) - 1;
                            if ( gixo[cidx] < 0.0 ) i--;
                        } else {
                            xi = gixo[cidx];
                        }
                    } else {
                        xi = gixo[cidx];
                    }

                    j = (int)giyo[cidx];
                    if ( i >= 1 && i <= (*kxi) && j >= 1 && j <= (*kyi) ) {
                        if ( i == (*kxi) ) i--;
                        if ( j == (*kyi) ) j--;
                        idx1 = ( j - 1 ) * (*kxi) + i - 1;
                        idx2 = ( j - 1 ) * (*kxi) + i;
                        idx3 = j * (*kxi) + i - 1;
                        idx4 = j * (*kxi) + i;
                        if ( ! ERMISS ( grdi[idx1] ) &&
                             ! ERMISS ( grdi[idx2] ) &&
                             ! ERMISS ( grdi[idx3] ) &&
                             ! ERMISS ( grdi[idx4] ) ) {
                            x = xi - (float)i;
                            y = giyo[cidx] - (float)j;
                            omx = 1. - x;
                            omy = 1. - y;
                            grdo[cidx] = ( cos ( grdi[idx1] ) * omx +
                                           cos ( grdi[idx2] ) * x ) * omy +
                                         ( cos ( grdi[idx3] ) * omx +
                                           cos ( grdi[idx4] ) * x ) * y;
                        }
                    }
                }
            }
        }
    }

    return;
}