Exemple #1
0
void utl_tomin ( float *anclat, float *anclon, float *newlat, 
                 float *newlon, int *iret )
/************************************************************************
 * utl_tomin								*
 *                                                                      *
 * This function converts lat/lon decimal to lat/lon minutes.    	*
 *                                                                      *
 * utl_tomin ( anclat, anclon, newlat, newlon, iret )                   *
 *                                                                      *
 * Input parameters:                                                    *
 *      *anclat		 float						*
 *	*anclon		 float						*
 *                                                                      *
 * Output parameters:                                                   *
 *	*newlat		 float						*
 *	*newlon		 float						*
 *      *iret            int            Return Code                     *
 *									*
 *					   -3 = Latitude not in range	*
 *					   -4 = Longitude not in range	*
 **                                                                     *
 * Log:                                                                 *
 * A. Hardy/NCEP	 5/03		Copied from VFTOMIN		*
 ***********************************************************************/
{
    int     lattmp, lontmp;
/*-------------------------------------------------------------------*/
    *iret  = 0;

   /*
    * Check for valid latitude and longitude values.
    */

    if ( ( *anclat< -90.0 ) || ( *anclat > 90.0 ) ) {
        *iret = -3;
	return;
    }

    if ( ( *anclon < -180.0 ) || ( *anclon > 180.0 ) ) {
	*iret = -4;
	return;
    }

   /*
    * Convert latitude from decimal to minutes.
    */

     lattmp = DDTODM ( G_ABS( *anclat ) );
    *newlat = (float)lattmp / 100.0F;

   /*
    * Convert longitude from decimal to minutes.
    */

     lontmp = DDTODM ( G_ABS( *anclon ) );
    *newlon = (float)lontmp / 100.0F;
}
Exemple #2
0
void dg_adcl ( int *iret )
/************************************************************************
 * dg_adcl                                                              *
 *                                                                      *
 * This subroutine adds a column to a grid.                             *
 *                                                                      *
 * dg_adcl ( iret )  				                        *
 *                                                                      *
 * Input parameters:                                                    *
 *                                                                      *
 * Output parameters:                                                   *
 *      *iret		int		Return code                     *
 *                                        0 = normal return             *
 **                                                                     *
 * Log:                                                                 *
 * R. Tian/SAIC         10/03                                           *
 * K. Brill/HPC		 2/04	Initialize gwrapg and addcol		*
 * R. Tian/SAIC		 5/04	Removed check for addcol		*
 * R. Tian/SAIC		 2/06	Recoded from Fortran			*
 * K. Brill/HPC         11/11   Remove check for exceeding LLMXTG	*
 ************************************************************************/
{
    float rgx[2], rgy[2];
    int np, ier, ier2;
/*----------------------------------------------------------------------*/
    *iret   = 0;

    _dgsubg.gwrapg = G_FALSE;
    _dgfile.addcol = G_FALSE;
    grc_rnav ( _dgsubg.refnav, _dgfile.cprj, &_dgfile.kxd, &_dgfile.kyd, &ier );
    if ( ( strcmp ( _dgfile.cprj, "MER" ) == 0 ) || 
         ( strcmp ( _dgfile.cprj, "CED" ) == 0 ) ) {
/*	if ( ( _dgfile.kyd * (_dgfile.kxd+1) ) > LLMXTG ) return; */
	rgx[0] = 1.;
	rgy[0] = 1.;
	rgx[1] = (float)( _dgfile.kxd + 1 );
	rgy[1] = 1.;
	np = 2;
	gtrans ( sys_G, sys_M, &np, rgx, rgy, rgx, rgy, &ier,
	    strlen(sys_G), strlen(sys_M) );
	if ( G_ABS ( rgy[0] - rgy[1] ) < 0.01 ||
	    ( G_ABS ( rgy[0] + 180. ) < 0.01 &&
	      G_ABS ( rgy[1] - 180. ) < 0.01 ) ) {
	    _dgfile.kxd += 1;
	    _dgfile.kxyd = _dgfile.kxd * _dgfile.kyd;
	    _dggrid.maxdgg = NDGRD;
	    gsgprj ( _dgfile.cprj, &_dgsubg.refnav[10], &_dgsubg.refnav[11], 
	        &_dgsubg.refnav[12], &_dgfile.kxd, &_dgfile.kyd,
		&_dgsubg.refnav[6], &_dgsubg.refnav[7], &_dgsubg.refnav[8],
		&_dgsubg.refnav[7], &ier, strlen(_dgfile.cprj) );
	    if ( ier != 0 ) {
		er_wmsg ( "GEMPLT", &ier, " ", &ier2,
		    strlen("GEMPLT"), strlen(" ") );
		*iret = -7;
	    }
	    _dgfile.addcol = G_TRUE;

	    /*
	     * Free all existing grids since grid size is changed.
	     */
	    dg_fall ( &ier );
	}
    } else {
	_dgfile.addcol = G_FALSE;
    }

    if ( ( strcmp ( _dgfile.cprj, "MER" ) == 0 ) ||
         ( strcmp ( _dgfile.cprj, "MCD" ) == 0 ) ||
    	 ( strcmp ( _dgfile.cprj, "CED" ) == 0 ) ) {
	/*
	 * Set GWRAPG flag for globe wrapping grid.
	 */
	rgx[0] = 1.;
	rgy[0] = 1.;
	rgx[1] = (float)_dgfile.kxd;
	rgy[1] = 1.;
	np = 2;
	gtrans ( sys_G, sys_M, &np, rgx, rgy, rgx, rgy, &ier,
	    strlen(sys_G), strlen(sys_M) );
	if ( G_ABS ( rgy[0] - rgy[1] ) < 0.01 ||
	    ( G_ABS ( rgy[0] + 180. ) < 0.01 &&
	      G_ABS ( rgy[1] - 180. ) < 0.01 ) ) {
	    _dgsubg.gwrapg = G_TRUE;
	}
    }

    return;
}
Exemple #3
0
void dg_tadc ( int *iret )
/************************************************************************
 * dg_tadc                                                              *
 *                                                                      *
 * This subroutine determines if an added column is required for the	*
 * transfer navigation.							*
 *                                                                      *
 * This subroutine sets the adcltg and gwrptg flags in the HINTRP block *
 * of DGCMN.CMN								*
 *                                                                      *
 * The transfer navigation is assumed to be set in GPLT.		*
 *                                                                      *
 * dg_tadc ( iret ) 		 		                        *
 *                                                                      *
 * Input parameters:                                                    *
 *                                                                      *
 * Output parameters:                                                   *
 *      *iret		int		Return code                     *
 *                                        0 = normal return             *
 **                                                                     *
 * Log:                                                                 *
 * K. Brill/HPC		 3/04	Created from DG_ADCL			*
 * R. Tian/SAIC		 2/06	Recoded from Fortran			*
 * K. Brill/HPC         11/11   Remove check for exceeding LLMXTG	*
 ************************************************************************/
{
    char gprj[5];
    float rgx[2], rgy[2];
    int mx, my, two, ier, ier2;
/*----------------------------------------------------------------------*/
    *iret   = 0;
    two = 2;

    _hintrp.gwrptg = G_FALSE;
    _hintrp.adcltg = G_FALSE;
    grc_rnav ( _hintrp.tfrnav, gprj, &mx, &my, &ier );
    if ( strcmp ( gprj, "MER" ) == 0 || strcmp ( gprj, "CED" ) == 0 ) {
/*	if ( ( my * (mx+1) ) > LLMXTG ) return; */
	rgx[0] = 1.;
	rgy[0] = 1.;
	rgx[1] = (float)( mx + 1 );
	rgy[1] = 1.;
	gtrans ( sys_G, sys_M, &two, rgx, rgy, rgx, rgy, &ier,
	         strlen(sys_G), strlen(sys_M) );
	if ( G_ABS ( rgy[0] - rgy[1] ) < 0.005 ||
	    ( G_ABS ( rgy[0] + 180. ) < 0.005 &&
	      G_ABS ( rgy[1] - 180. ) < 0.005 ) ) {
	    mx += 1;
	    gsgprj ( gprj, &_hintrp.tfrnav[10], &_hintrp.tfrnav[11],
		&_hintrp.tfrnav[12], &mx, &my, &_hintrp.tfrnav[6],
		&_hintrp.tfrnav[7], &_hintrp.tfrnav[8], &_hintrp.tfrnav[7],
		&ier, strlen(gprj) );
	    if ( ier != 0 ) {
		er_wmsg ( "GEMPLT", &ier, " ", &ier2,
		    strlen("GEMPLT"), strlen(" " ) );
		*iret = -7;
	    }
	    _hintrp.adcltg = G_TRUE;
	    _hintrp.gwrptg = G_TRUE;
	    return;
	} else {
	    _hintrp.adcltg = G_FALSE;
	}
    }

    if ( ( strcmp ( gprj, "MER" ) == 0 ) || ( strcmp ( gprj, "MCD" ) == 0 ) ||
	 ( strcmp ( gprj, "CED" ) == 0 ) ) {
	/*
	 * Set GWRAPG flag for globe wrapping grid.
	 */
	rgx[0] = 1.;
	rgy[0] = 1.;
	rgx[1] = (float)mx;
	rgy[1] = 1.;
	gtrans ( sys_G, sys_M, &two, rgx, rgy, rgx, rgy, &ier,
	         strlen(sys_G), strlen(sys_M) );
	if ( G_ABS ( rgy[0] - rgy[1] ) < 0.005 ||
	    ( G_ABS ( rgy[0] + 180. ) < 0.005 &&
	      G_ABS ( rgy[1] - 180. ) < 0.005 ) )  _hintrp.gwrptg = G_TRUE;
    }

    return;
}
Exemple #4
0
void df_ne ( int *iret )
/************************************************************************
 * df_ne								*
 *									*
 * This function is invoked as  NE ( S1, S2, S3 ).  It returns 1 	*
 * if |S1-S2| > S3; otherwise 0.					*
 *									*
 * df_ne ( iret )							*
 *									*
 * Input parameters:							*
 *									*
 * Output parameters:							*
 	*iret		int		Return code			*
 *					0 - normal return 		*
 **									*
 * Log:									*
 * m.gamazaychikov/SAIC	09/05						*
 * R. Tian/SAIC		11/05	Recoded from Fortran			*
 ************************************************************************/
{
    int num1, num2, num3, num, kxd, kyd, ksub1, ksub2, i, im1, zero, ier;
    float *gnum1, *gnum2, *gnum3, *gnum, dg1, dg2, dg3;
/*----------------------------------------------------------------------*/
    *iret = 0;

    dg_ssub ( iret );

    /*
     * Get three grids from the stack.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num2, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num3, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid number and check the grids.
     */ 
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    /*
     * Grid number to grid.
     */
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num2, &gnum2, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num3, &gnum3, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num,  &gnum,  &kxd, &kyd, &ksub1, &ksub2, iret );

    for ( i = ksub1; i <= ksub2; i++ ) {
	im1 = i - 1;
	dg1 = gnum1[im1];
	dg2 = gnum2[im1];
	dg3 = gnum3[im1];
	if ( ERMISS ( dg1 ) || ERMISS ( dg2 ) || ERMISS ( dg3 ) ) {
	    gnum[im1] = RMISSD;
	} else {
	    if ( G_ABS ( dg1 - dg2 ) > dg3 ) {
		gnum[im1] = 1.0;
	    } else {
		gnum[im1] = 0.0;
	    }
	}
    }

    /*
     * Get a name of the form 'NE'//S1//S2 and update header;
     * update stack.
     */
    dg_updh ( "NE", &num, &num1, &num2, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Exemple #5
0
void clo_ddenc ( char *type, int format, float lat, float lon, char *str,
                 int *iret )
/************************************************************************
 * clo_ddenc                                                    	*
 *                                                                      *
 * This function returns gets the string for the seek and location      *
 * structure indicating which entry matches the input CLO name for the  *
 * given latitude and longitude. The format code is in a 4-5 digit      *
 * format (Eg. 5212 or 10212).  The columns are formatted as follows : 	*
 *					       				*
 *									*
 *   ROUNDING        UNITS        DIRECTION     DISPLAY			*
 *                                              			*
 *  5 - nearest 5    0 - omit     0 - omit      0 - degrees		*
 * 10 - nearest 10   1 - NM       1 - 16 point  1 - decimal/minutes   	*
 *                   2 - SM       2 - degrees   2 - 1st column		*
 *                   3 - KM             	4 - 3rd column		*
 *									*
 * For DISPLAY, the 1st column is usually the station id and the 3rd    *
 * column is the name of the station, city or county.			*
 *                                                                      *
 * clo_ddenc ( type, format, lat, lon, str, iret)                       *
 *                                                                      *
 * Input parameters:                                                    *
 *	*type		char		Name of CLO parameter		*
 *	format		int		Indicator of format to use      *
 *      lat            float            Latitude point                  *
 *      lon            float            Longitude point                 *
 *									*
 * Output parameters:                                                   *
 *	*str		char		Character string location       *
 *	*iret		int		Return value			*
 *					=  < 0 - String not created	*
 *									*
 **                                                                     *
 * Log:                                                                 *
 * A. Hardy/GSC		01/00	Create					*
 * A. Hardy/GSC		01/00	Added new format display option         *
 * A. Hardy/GSC		01/00	Added length chk of str;changed rounding*
 * A. Hardy/GSC		02/00	modified for all variations of formats  *
 * A. Hardy/GSC		02/00	reworked string display; city locations *
 * D.W.Plummer/NCEP	 8/00	changes for clo_ redesign		*
 * A. Hardy/GSC		 8/00   renamed from clo_format			*
 * T. Piper/GSC		 3/01	Fixed IRIX6 compiler warnings		*
 * D.W.Plummer/NCEP	 8/01	Repl clo_bqinfo w/ cst_gtag		*
 * D.W.Plummer/NCEP	 6/05	Tens digit sets # decimals for lat,lon	*
 ***********************************************************************/
{
    int		idist, icmp, nh, ier;
    int		ilat, ilon, imnt, imnn, isit, isin;
    char	stn[80], idx[80], *pidx, sdir[4];
    float	dist, dir;
    int         ione, itens, ihund, irnd, which, inlen;
    int         isln, iwidth, ilftovr;
    char        sdirc[5], sdist[5];
    char	info[128], fmt[20];
    /*---------------------------------------------------------------------*/
    *iret = 0;
    strcpy ( str, "NULL" );
    iwidth = 16;

    /*
     * Parse out format into it's components.
     */

    ione  = format % 10;
    itens = (int) (format/10) % 10;
    ihund = (int) (format/100) % 10;
    irnd  = format / 1000;

    /*
     * Check one's place for lat-lon or deg-min.
     */

    if ( ione == 0 ) {	/* show lat/lon */
        /*
         * Tens digit controls the number of decimal digits for the
         * lat,lon display. The default is 2 digits.
         */
        if ( itens == 0 )  itens = 2;
        sprintf(fmt,"%%.%df, %%.%df", itens, itens );
        sprintf(str, fmt, lat, lon);
    }
    else if ( ione == 1 ) {   /* show lat/lon as deg-min */
        isit = ( lat < 0.0F ) ? '-' : ' ';
        ilat = (int) G_ABS ( lat );
        imnt = G_NINT ( ( G_ABS(lat) - (float)ilat ) * 60.0F );
        if  ( imnt >= 60 )  {
            imnt = imnt % 60;
            ilat += 1;
        }

        isin = ( lon < 0.0F ) ? '-' : ' ';
        ilon = (int) G_ABS ( lon );
        imnn = G_NINT ( ( G_ABS(lon) - (float)ilon ) * 60.0F );
        if  ( imnn >= 60 )  {
            imnn = imnn % 60;
            ilon += 1;
        }

        sprintf ( str, "%c%3d:%02d, %c%3d:%02d",
                  isit, ilat, imnt, isin, ilon, imnn );
    }

    else {   /* show city/county/stn  */
        which = clo_which ( type );

        if ( clo.loc[which].format == 1 ) { 		/* show bound */

            clo_tqbnd ( type, lat, lon, idx, &ier);
            pidx = idx;

            /*
             *   Find and save the county FIPS id.
            */

            if ( ione == 2) {

                if (strcmp ( pidx,"-") != 0 ) {
                    clo_bginfo ( type, 0, info, &ier );
                    cst_gtag ( "FIPS", info, "?", str, &ier );
                }
                else {
                    cst_split (pidx, ' ', 14, str, &ier);
                }
            }
            if ( ione == 4) {  /* Save the bound name */
                cst_split (pidx, ' ', 14, str, &ier);
            }
        }


        else {
            if ( clo.loc[which].format == 0 ) { 	/* show station */

                /*
                 *  get station ID, distance and direction.
                 */
                clo_tdirect ( type, lat, lon, stn, &dist, &dir, &ier );

                if ( ione == 4 ) {
                    /*
                     *  Replace station ID w/ station name.
                     */
                    clo_tgnm ( type, 1, sizeof(stn), &nh, stn, &ier );
                }
            }

            if ( ihund == 0 ) {
                strcpy ( sdirc, "" );
            }
            else {
                if ( ihund == 1 ) {           /* get nautical miles */
                    dist *= M2NM;
                }
                else if ( ihund == 2 ) {      /* get statute miles */
                    dist *= M2SM;
                }
                else if ( ihund == 3 ) {      /* get kilometers */
                    dist /= 1000.0F;
                }

                if ( irnd > 0 ) {
                    idist = G_NINT ( dist / (float)irnd ) * irnd;
                    sprintf ( sdirc, "%i ", idist);
                }
                else if ( irnd < 0 ) {
                    irnd = 1;
                    idist = G_NINT ( dist / (float)irnd ) * irnd;
                    sprintf ( sdirc, "%i ", idist);
                }
                else if ( irnd == 0 ) {
                    strcpy ( sdirc, "" );
                }

            }

            if ( itens == 0 ) {  /* omit the direction */
                strcpy ( sdist, "" );
            }
            else {
                if ( itens == 1 ) {      /* use 16 point dir. */
                    clo_compass ( &dir, sdir, &icmp, &ier );
                    sprintf ( sdist, "%s", sdir );
                }
                else if  ( itens == 2 ) {      /* use degrees  */
                    sprintf ( sdist, "%.0f", dir );
                }
            }

            sprintf(str, "%s %s",sdirc, sdist);

            /*
             * If the stn name is longer than 4 chars, print
             */

            inlen = (int)strlen(stn);
            isln = (int)strlen(str);
            ilftovr = iwidth - isln;

            if (inlen > 4 )  {
                sprintf ( str, "%*s %.*s", isln, str, ilftovr, stn );
            }
            else {
                sprintf ( str, "%s %3s", str, stn );
            }

            if ( (ihund == 0 ) && ( itens == 0 ) ) {
                sprintf ( str, "%.*s", ilftovr, stn );
            }
        }
    }
    if ( strcmp ( str, "NULL") != 0 ) *iret = -1;
}
Exemple #6
0
int main ( int argc, char *argv[] )
/************************************************************************
 * sigavgf                                                              *
 *                                                                      *
 * This program reads Significant Weather ASCII files and encodes the   *
 * information into a VG file format.   	                        *
 *                                                                      *
 * command line:                                                        *
 *      sigavgf dattim hh                                               *
 *              dattim      GEMPAK date/time string                     *
 *              hh          Valid time (hours) - must be 18 or 24       *
 **                                                                     *
 * Log:                                                                 *
 * A. Hardy/SAIC     3/02      Created					* 
 * A. Hardy/SAIC     5/02      Added optional input file name; changed  *
 * 			       default input file name			*
 * M. Li/SAIC	     7/04      Removed grpch from sigajet		*
 * M. Li/SAIC	     9/04      Add idcent, chbase and chtop to cas_rdhdr*
 * M. Li/SAIC	     1/05      Process SWM 				*
 * M. Li/SAIC	    10/05      Checked for new format of jet info	*
 ***********************************************************************/
{
    int 	ier, numerr, leverr, pagflg, grpid, iret;
    int         itime[5], jtime[5], idcent;
    float	chbase, chtop;
    int         numtrp, rnum, lnum, hnum, membx, memhi, memlo;
    int         memcld, memmcld, memfrt, memjet, memstm, memtur, memvlr;
    int         numcld, nummcld, numfrt, numjet, numstm, numtur, numvlr;

    char 	fhour [3], fname[256], gtstr[12], grpch, chlvl[10];
    char	errgrp[8], cc[50], casgrp[4];
    char	path[256];
    char	newflvl[10];
    long	size;


    cloud_t     *ptrc, *head,  *ptr2;
    mcloud_t    *ptrm, *headm, *ptr2m;
    jets_t      *ptrj, *headj, *ptr2j;
    front_t     *ptrf, *headf, *ptr2f;
    turb_t      *ptrb, *headb, *ptr2b;
    storm_t     *ptrs, *heads, *ptr2s;
    volrad_t    *ptrv, *headv, *ptr2v;
    trop_t      *ptrr, *headr, *ptr2r;
    trophi_t    *ptrh, *headh, *ptr2h;
    troplo_t    *ptrl, *headl, *ptr2l;

    Boolean     readflg;

    FILE *ifpout;
    /*---------------------------------------------------------------------*/
 
    iret    = 0;
    leverr  = 0;
    readflg = True;
    ifpout  = NULL;

    strcpy ( errgrp, "SIGAVGF" );
    strcpy ( casgrp, "CAS");
    strcpy ( cc, " " );

    rnum   = lnum   = hnum   = 0;
    membx  = memhi  = memlo  = 0;
    memcld = memmcld = memfrt = memjet = memstm = memtur = memvlr = 0;
    numcld = nummcld = numfrt = numjet = numstm = numtur = numvlr = 0;

    ptrc   =  NULL;
    ptrm   =  NULL;
    ptrj   =  NULL;
    ptrf   =  NULL;
    ptrb   =  NULL;
    ptrs   =  NULL;
    ptrv   =  NULL;
    ptrr   =  NULL;
    ptrh   =  NULL;
    ptrl   =  NULL;

    in_bdta ( &ier );

   /*
    * If the forecast hour is not on the command line, print help 
    * and exit.
    */

    if ( argc < 3 ) {
        pagflg = G_FALSE;
        ip_help ( errgrp, &pagflg, &ier, 
                  strlen(errgrp) );
        numerr = -1;
        er_lmsg ( &leverr, errgrp, &numerr, cc, &ier,
                  strlen(errgrp), strlen(cc) );
        exit (1);
    }

    strcpy ( fhour, argv[2] );
    if  ( strcmp ( fhour, "24") != 0 ) { 
        if ( strcmp ( fhour, "18") != 0 ) {
            numerr = -2;
            er_lmsg ( &leverr, errgrp, &numerr, fhour, &ier,
                      strlen(errgrp), strlen(fhour) );
            exit (1);
	}
    }

   /*
    *  Check for input file.
    */

    if ( argv[3] != NULL ) {
        strcpy ( fname, argv[3] );
    }
    else {
       
       /*
	* If an input file is not specified, check for the existence of 
	* either SIGWXHI.txt or SIGWXMID.txt.
	*/

        sprintf ( fname, "SIGWXHI.txt" );
	cfl_inqr ( fname, NULL, &size, path, &ier );
	if ( ier != 0 ) {
	    sprintf ( fname, "SIGWXMID.txt" );
            cfl_inqr ( fname, NULL, &size, path, &ier );
	    if ( ier != 0 ) {
		numerr = -3;
                er_lmsg ( &leverr, errgrp, &numerr, fname, &ier,
                          strlen(errgrp), strlen(fname) );
                exit (1);
            }
	}

    }
    ifpout = cas_open ( fname, readflg, &ier );

   /*
    * If input ASCII file failed to open, exit program.
    */

    if ( ier != 0 ) {
         numerr = -3;
         er_lmsg ( &leverr, errgrp, &numerr, fname, &ier,
                      strlen(errgrp), strlen(fname) );
         exit (1);
    }

   /*
    * Read in the input ASCII file into the CAS structures.
    */

    cas_rdhdr ( ifpout, itime, jtime, &idcent, &chbase, &chtop, &ier );

    rewind (ifpout);
    if ( G_ABS ( HI_BASE - chbase ) < 0.5F &&
         G_ABS ( HI_TOP  - chtop  ) < 0.5F ) {
	strcpy ( chlvl, "SWH" );
        cas_rdcld ( ifpout, &numcld, &ptrc, &memcld, &ier );
    } else if ( G_ABS ( MID_BASE - chbase ) < 0.5F &&
                G_ABS ( MID_TOP  - chtop  ) < 0.5F ) {
        strcpy ( chlvl, "SWM" );
   	cas_rdmcld ( ifpout, &nummcld, &ptrm, &memmcld, &ier );
    }

    rewind (ifpout);
    cas_rdjets ( ifpout, &numjet, &ptrj, &memjet, &ier );

    rewind (ifpout);
    cas_rdturb ( ifpout, &numtur, &ptrb, &memtur, &ier );

    rewind (ifpout);
    cas_rdfrt ( ifpout, &numfrt, &ptrf, &memfrt, &ier);

    rewind (ifpout);
    cas_rdtrop ( ifpout, &numtrp, &ptrr, &membx, &rnum,
                 &ptrl, &memlo, &lnum, &ptrh, &memhi,
		 &hnum, &ier );

    rewind (ifpout);
    cas_rdstm ( ifpout, &numstm, &ptrs, &memstm, &ier );

    rewind (ifpout);
    cas_rdvlrd ( ifpout, &numvlr, &ptrv, &memvlr, &ier );

   /*
    * Close input file.
    */

    cas_clos ( ifpout, &ier );
    
   /*
    * If ASCII file failed to close, write error message.
    */

    if ( ier != 0 ) {
         numerr = -4;
         er_lmsg ( &leverr, casgrp, &numerr, fname, &ier,
                      strlen(casgrp), strlen(fname) );
    }

   /*
    * Initialize the group type table.
    */

    ces_gtrtbl ( &iret );

   /*
    * Call appropriate VG file encoding subroutines.
    *
    * Create cloud VG file.
    */

    strcpy ( gtstr, "CLOUD");
    ces_gtgid (gtstr, &grpid, &ier);
    grpch = (char) grpid;
    if ( strcmp ( chlvl, "SWH" ) == 0 ) {
        sigacld ( fhour, numcld, ptrc, itime, grpch, &ier );
    }
    else {
	sigamcld ( fhour, nummcld, ptrm, itime, grpch, &ier );
    }

   /*
    * Create jets VG file.
    */

    ctb_rdprf ( "prefs.tbl", "config", "SIGWX_FLIGHT_LEVELS", newflvl, &ier );
    sigajet ( fhour, numjet, ptrj, itime, chlvl, newflvl, &ier );

   /*
    * Create turbulence VG file.
    */

    strcpy ( gtstr, "TURB");
    ces_gtgid (gtstr, &grpid, &ier);
    grpch = (char) grpid;
    sigatur ( fhour, numtur, ptrb, itime, grpch, chlvl, &ier );

   /*
    * Create front VG file.
    */

    strcpy ( gtstr, "FRONT");
    ces_gtgid (gtstr, &grpid, &ier);
    grpch = (char) grpid;
    sigafrt ( fhour, numfrt, ptrf, itime, grpch, chlvl, &ier );

   /*
    * Create tropopause VG file.
    */

    sigatrp ( fhour, rnum, ptrr, hnum, ptrh, lnum, ptrl, 
	      itime, chlvl, &ier );

   /*
    * Create symbol VG file.
    */

    strcpy ( gtstr, "LABEL");
    ces_gtgid (gtstr, &grpid, &ier);
    grpch = (char) grpid;
    sigavts ( fhour, numstm, ptrs, numvlr, ptrv, 
                       itime, grpch, chlvl, &ier );

   /*
    *  Free all created linked lists.
    */

    /* Free cloud */
    if ( memcld ) {
        head = ptrc;
        ptr2 = head -> next;
        while ( ptr2 != NULL ) {
            free (head);
            head = ptr2;
            ptr2 = ptr2 -> next;
        }
        free ( head );
    }

    /* Free mcloud */
    if ( memmcld ) {
        headm = ptrm;
        ptr2m = headm -> next;
        while ( ptr2m != NULL ) {
            free (headm);
            headm = ptr2m;
            ptr2m = ptr2m -> next;
        }
        free ( headm );
    }


    /* Free jet */
    if ( memjet ) {
        headj = ptrj;
        ptr2j = headj -> next;
        while ( ptr2j != NULL ) {
            free (headj);
            headj = ptr2j;
            ptr2j = ptr2j -> next;
        }
        free ( headj );
    }

    /* Free turb */
    if ( memtur ) {
        headb = ptrb;
        ptr2b = headb -> next;
        while ( ptr2b != NULL ) {
            free (headb);
            headb = ptr2b;
            ptr2b = ptr2b -> next;
        }
        free ( headb );
    }

    /* Free front*/
    if ( memfrt ) {
        headf = ptrf;
        ptr2f = headf -> next;
        while ( ptr2f != NULL ) {
            free (headf);
            headf = ptr2f;
            ptr2f = ptr2f -> next;
        }
        free ( headf );
    }
    /* Free trop*/
    if ( membx ) {
        headr = ptrr;
        ptr2r = headr -> next;
        while ( ptr2r != NULL ) {
            free ( headr );
            headr = ptr2r;
            ptr2r = ptr2r -> next;
        }
        free ( headr );
    }
    if ( memhi ) {
        headh = ptrh;
        ptr2h = headh -> next;
        while ( ptr2h != NULL ) {
            free ( headh );
            headh = ptr2h;
            ptr2h = ptr2h -> next;
        }
        free ( headh );
    }
    if ( memlo ) {
        headl = ptrl;
        ptr2l = headl -> next;
        while ( ptr2l != NULL ) {
            free ( headl );
            headl = ptr2l;
            ptr2l = ptr2l -> next;
        }
        free ( headl );
    }

    if ( memstm ) {
        heads = ptrs;
        ptr2s = heads -> next;
        while ( ptr2s != NULL ) {
            free ( heads );
            heads = ptr2s;
            ptr2s = ptr2s -> next;
        }
        free ( heads );
    }
    if ( memvlr ) {
        headv = ptrv;
        ptr2v = headv -> next;
        while ( ptr2v != NULL ) {
            free ( headv );
            headv = ptr2v;
            ptr2v = ptr2v -> next;
        }
        free ( headv );
    }

    return 0;
}
Exemple #7
0
void dgc_subg ( const char *ijskip, int *maxgrid, int *imll, int *jmll, 
                int *imur, int *jmur, int *iret )
/************************************************************************
 * dgc_subg								*
 *									*
 * This subroutine sets the internal subset grid given the reference	*
 * grid navigation set in GPLT and the map projection set in GPLT.	*
 * If the reference grid is globe wrapping with the addition of an	*
 * extra grid column, then the navigation set in GPLT must be that for	*
 * the grid with the extra column.					*
 * 									*
 * The subset grid is larger by five grid points than that strictly	*
 * needed to cover the map projection area.  This extension permits	*
 * more accurate computation of derivatives.  The subset grid relative	*
 * coordinates of the region strictly needed for the map are returned.	*
 * 									*
 *									*
 * IJSKIP is parsed by IN_GSKP.  IJSKIP information is entered using	*
 * the following format, where items in square brackets are optional:	*
 *									*
 *	IJSKIP = Iskip[;Istart][;Iend][/Jskip[;Jstart][;Jend]],		*
 *									*
 *	IJSKIP=Y[ES], or IJSKIP=N[O]					*
 *									*
 * The following rules apply in using IJSKIP input:			*
 *									*
 * 1.  If only Iskip is entered, then I and J skips are Iskip.  The	*
 *     beginning points and ending points are determined by querying	*
 *     the display projection to find the area on the reference grid	*
 *     needed to cover it.						*
 *									*
 * 2.  If any bounding value is omitted, it is determined automatically *
 *     by querying the display projection as in 1 above.		*
 *									*
 * 3.  If IJSKIP is blank or NO, skipping is not used to determine the	*
 *     internal grid navigation.					*
 * 									*
 * 4.  If IJSKIP is YES, all skip parameters are determined		*
 *     automatically.							*
 * 									*
 * dgc_subg ( ijskip, maxgrid, imll, jmll, imur, jmru, iret )		*
 *									*
 * Input parameters:							*
 *	*ijskip		const char	User input for skip subsetting	*
 *	*maxgrid	int		Maximum grid size               *
 *									*
 * Output parameters:							*
 *	*IMLL		int		Lower left map I bound		*
 *	*JMLL		int		Lower left map J bound		*
 *	*IMUR		int		Upper right map I bound		*
 *	*JMUR		int		Upper right map J bound		*
 * 	*IRET		int		Return code			*
 *					  0 = normal return		*
 *					-37 = no ref grid navigation set*
 *					-38 = glb wrap grd inconsistency*
 *					-39 = map projection is not set *
 *					-40 = subset grd bound error	*
 *					-41 = subset grid is too big	*
 *					-43 = cannot rearrange grid	*
 *					-44 = error set subset grid nav	*
 *					-48 = both I bounds required	*
 **									*
 * Log:									*
 * K. Brill/HPC		08/02						*
 * K. Brill/HPC		 9/02	Also initialize gparmd () to blank	*
 * S. Jacobs/NCEP	11/02	Added check for current nav vs saved nav*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * K. Brill/HPC		12/02	Use IJSKIP input for subset by skipping *
 * R. Tian/SAIC		 3/04	Add check for outflg			*
 * R. Tian/SAIC		 5/04	Added call to DG_CONE			*
 * R. Tian/SAIC		 2/06	Recoded from Fortran			*
 * S. Gilbert/NCEP	 5/07	Added maxgrid argument                  *
 ************************************************************************/
{
    char gprj[5], cnum[5];
    float aglt1, agln1, aglt2, agln2, ag1, ag2, ag3, rimn, rjmn, rimx,
        rjmx, rglt[2], rgln[2], tnav[LLNNAV];
    double a, b, c;
    int lmx, mx, my, imn, jmn, imx, jmx, nx, ny, ix1, ix2, nsx, iy1, iy2,
        nsy, n, idx, idy, ichk, iadlx, iadly, iadrx, iadry, kxsg, kysg,
	kxysg, nu, mxnu, imn2, jmn2, imx2, jmx2, iadd, navsz;
    int nc, tobig, autos, angflg, navflg, done, ishf, ier, ierr, iir, i, k;

   /*
    * timing vars
    */
    struct   timeb t_gsgprj1, t_gsgprj2, t_gsgprj3, t_gqgprj1, t_gqgprj2, 
             t_gsgprj4, t_setr, t_gqbnd, t_gskp, t_gtrans1, t_mnav, t_cnav, 
             t_cone, t_current;
/*----------------------------------------------------------------------*/
    *iret = 0;
    _dgsubg.dgsubg = G_TRUE;

    for ( i = 0; i < NGDFLS; i++ ) {
	if ( _nfile.outflg[i] == G_TRUE ) {
	    *iret = -63;
	    return;
	}
    }

    /*
     * Set LMX to maximum allowed threshold for ijskip=yes
     */
    lmx = LLMXTH;

    /*
     * Set the reference grid navigation in GPLT.
     */
    cst_itos ( (int *)(&_dgsubg.refnav[1]), 1, &nc, gprj, &ier );
    cst_rmbl ( gprj, gprj, &nc, &ier );
    mx = G_NINT ( _dgsubg.refnav[4] );
    my = G_NINT ( _dgsubg.refnav[5] );
    agln1 = _dgsubg.refnav[7];
    if ( _dgfile.addcol == G_TRUE ) {
	mx += 1;
	agln2 = _dgsubg.refnav[7];
    } else {
	agln2 = _dgsubg.refnav[9];
    }
    ftime(&t_gsgprj1);
    gsgprj ( gprj, &_dgsubg.refnav[10], &_dgsubg.refnav[11], 
             &_dgsubg.refnav[12], &mx, &my, &_dgsubg.refnav[6],
	     &_dgsubg.refnav[7], &_dgsubg.refnav[8], &agln2, &ier,
	     strlen(gprj) );
    ftime(&t_current);
    if ( ier != 0 ) {
	er_wmsg ( "GEMPLT", &ier, " ", &ierr, strlen("GEMPLT"), strlen(" ") );
	*iret = -37;
	return;
    } else if ( _dgsubg.gwrapg == G_TRUE &&
        ( ! COMPAR ( agln1, agln2 ) && ! COMPAR ( (agln1+360.), agln2 ) ) ) {
	*iret = -38;
	return;
    }

    /*
     * Get the shift for re-arranging any globe wrapping grid.
     * ISHIFT is stored in DGCMN.CMN.
     */
    ftime(&t_setr);
    grc_setr ( &mx, &my, &_dgsubg.ishift, &ier );
    ftime(&t_current);
    if ( ier == -22 ) {
	*iret = -39;
	return;
    } else if ( ier != 0 ) {
	*iret = -43;
	return;
    }
    ftime(&t_gqgprj1);
    gqgprj ( gprj, &ag1, &ag2, &ag3, &mx, &my, &aglt1, &agln1, &aglt2,
             &agln2, &ier, sizeof(gprj) );
    ftime(&t_current);
    gprj[4] = '\0';
    cst_lstr ( gprj, &nc, &ier );
    gprj[nc] = '\0';

    /*
     * Get the grid index bounds for the subset grid.
     */
    ftime(&t_gqbnd);
    gqbnd ( sys_G, &rimn, &rjmn, &rimx, &rjmx, &ier, strlen(sys_D) );
    ftime(&t_current);
    if ( ier != 0 ) {
	er_wmsg ( "GEMPLT", &ier, " ", &ierr, strlen("GEMPLT"), strlen(" ") );
	*iret = -40;
	return;
    }
    imn = (int)rimn;
    jmn = (int)rjmn;
    imx = G_NINT ( rimx + .5 );
    if ( G_DIFFT((float)((int)rimx), rimx, GDIFFD) ) imx = (int)rimx;
    jmx = G_NINT ( rjmx + .5 );
    if ( G_DIFFT((float)((int)rjmx), rjmx, GDIFFD) ) jmx = (int)rjmx;
    if ( imn < 1 ) imn = 1;
    if ( jmn < 1 ) jmn = 1;
    if ( imx > mx ) imx = mx;
    if ( jmx > my ) jmx = my;
    nx = imx - imn + 1;
    ny = jmx - jmn + 1;
    if ( nx * ny > lmx ) {
        tobig = G_TRUE;
    } else {
        tobig = G_FALSE;
    }

    /*
     * Check for subsetting by skipping.
     *
     * The bounds are returned from IN_GSKP as IMISSD if
     * not provided.  The skip value returned is converted
     * to a stride value by adding one, i.e. IDX=1 means
     * no skipping, IDX=2 means skip one point.
     *
     * The mathematical relationship stating that the
     * original number of grid points from IMN to IMX must
     * equal the number of points skipped plus the number
     * kept is this:
     *
     *	    (IMX - IMN + 1) = N + (N - 1) * nskip
     *
     * where N is the number of points remaining after
     * skipping and nskip is the number of points skipped
     * between the points that are kept.
     *
     * This equation appears a number of times in various
     * forms below.
     */
    ftime(&t_gskp);
    in_gskp ( ijskip, &ix1, &ix2, &nsx, &iy1, &iy2, &nsy, &autos, &ier );
    ftime(&t_current);
    if ( ier != 0 ) {
	er_wmsg ( "IN", &ier, " ", &iir, strlen("IN"), strlen(" ") );
	*iret = -40;
	return;
    }
    if ( ix2 > mx ) {
	ier = -49;
	er_wmsg ( "DG", &ier, "I", &iir, strlen("DG"), strlen("I") );
	*iret = -40;
	return;
    } else if ( iy2 > my ) {
	ier = -49;
	er_wmsg ( "DG", &ier, "J", &iir, strlen("DG"), strlen("J") );
	*iret = -40;
	return;
    }
    if ( autos == G_TRUE && tobig == G_TRUE ) {
	a = (double)( lmx - 1 );
	b = (double)( nx + ny - 2 * lmx );
	c = (double)( lmx - nx * ny );
	n = (int)( ( b + sqrt ( b * b - 4. * a * c ) ) / ( 2. * a ) );
	nsx = n + 1;
	nsy = nsx;
	cst_inch ( nsx, cnum, &ier );
	ier = 7;
	er_wmsg ( "DG", &ier, cnum, &iir, strlen("DG"), strlen(cnum) );
    }
    idx = nsx + 1;
    idy = nsy + 1;
    if ( nsx > 0 ) {
	ichk = nx / nsx;
	if ( ichk <= 4 ) {
	    ier = 6;
	    er_wmsg ( "DG", &ier, "I", &iir, strlen("DG"), strlen("I") );
	}
    }
    if ( nsy > 0 ) {
	ichk = ny / nsy;
	if ( ichk <= 4 ) {
	    ier = 6;
	    er_wmsg ( "DG", &ier, "J", &iir, strlen("DG"), strlen("J") );
	}
    }

    /*
     * Extend the grid bounds if possible.
     */
    iadlx = 0;
    iadly = 0;
    iadrx = 0;
    iadry = 0;
    imn2 = imn;
    jmn2 = jmn;
    imx2 = imx;
    jmx2 = jmx;
    iadd = 0;
    done = G_FALSE;
    while ( done == G_FALSE && iadd < 5 ) {
	iadd += 1;
	if ( imn2 > idx ) {
	    imn2 -= idx;
	    iadlx += idx;
	}
	if ( jmn2 > idy ) {
	    jmn2 -= idy;
	    iadly += idy;
	}
	if ( imx2 < ( mx - idx ) ) {
	    imx2 += idx;
	    iadrx += idx;
	}
	if ( jmx2 < ( my - idy ) ) {
	    jmx2 += idy;
	    iadry += idy;
	}
	kxsg = G_NINT ( (float)( imx2 - imn2 + 1 + nsx ) / (float)( 1 + nsx ) );
	kysg = G_NINT ( (float)( jmx2 - jmn2 + 1 + nsy ) / (float)( 1 + nsy ) );
	kxysg = kxsg * kysg;
	if ( (kxysg > *maxgrid) && (*maxgrid != IMISSD) ) {
	    done = G_TRUE;
	    if ( imn != imn2 ) {
		imn = imn2 + idx;
		iadlx -= idx;
	    }
	    if ( jmn != jmn2 ) {
		jmn = jmn2 + idy;
		iadly -= idy;
	    }
	    if ( imx != imx2 ) {
		imx = imx2 - idx;
		iadrx -= idx;
	    }
	    if ( jmx != jmx2 ) {
		jmx = jmx2 - idy;
		iadry -= idy;
	    }
	} else {
	    imn = imn2;
	    jmn = jmn2;
	    imx = imx2;
	    jmx = jmx2;
	}
    }

    /*
     * Adjust extend margins using the stride values.
     */
    iadlx = iadlx / idx;
    iadrx = iadrx / idx;
    iadly = iadly / idy;
    iadry = iadry / idy;

    /*
     * Set the I dimension extraction bounds.  No shifting
     * is done if the user provides these bounds.  No
     * extend region is allowed if user provides bounds.
     */
    ishf = _dgsubg.ishift;
    if ( ix1 > 0 ) {
	_dgsubg.ishift = 0;
	iadlx = 0;
	imn = ix1;
    }
    if ( ix2 > 0 ) {
	_dgsubg.ishift = 0;
	iadrx = 0;
	imx = ix2;
    }
    if ( ishf != _dgsubg.ishift ) {
	if ( ix1 < 0 || ix2 < 0 ) {
	    *iret = -48;
	    return;
	}

	/*
	 * Reset the grid projection in GPLT.
	 */
	mx = G_NINT ( _dgsubg.refnav[4] );
	my = G_NINT ( _dgsubg.refnav[5] );
	agln1 = _dgsubg.refnav[7];
	if ( _dgfile.addcol == G_TRUE ) {
	    mx += 1;
	    agln2 = _dgsubg.refnav[7];
	} else {
	    agln2 = _dgsubg.refnav[9];
	}
    ftime(&t_gsgprj2);
	gsgprj ( gprj, &_dgsubg.refnav[10], &_dgsubg.refnav[11], 
	    &_dgsubg.refnav[12], &mx, &my, &_dgsubg.refnav[6],
	    &_dgsubg.refnav[7], &_dgsubg.refnav[8], &agln2, &ier,
	    strlen(gprj) );
    ftime(&t_current);
    ftime(&t_gqgprj2);
	gqgprj ( gprj, &ag1, &ag2, &ag3, &mx, &my, &aglt1, &agln1, 
	    &aglt2, &agln2, &ier, sizeof(gprj) );
    ftime(&t_current);
    if ( diagClbkPtr != NULL )
	gprj[4] = '\0';
	cst_lstr ( gprj, &nc, &ier );
	gprj[nc] = '\0';
	ierr = 5;
	er_wmsg ( "DG", &ierr, " ", &ier, strlen("DG"), strlen(" ") );
    }

    /*
     * Adjust IMX and IMN for skipping.
     */
    if ( idx > 1 ) {
	nu = G_NINT ( (float)( imx - imn + 1 + nsx ) / (float)( 1 + nsx ) );
	mxnu = nu * ( 1 + nsx ) + imn - 1 - nsx;
	if ( mxnu > ( mx - idx ) && mxnu != ix2 ) {
	    mxnu = mx;
	    imn = mxnu - nu * ( 1 + nsx ) + 1 + nsx;
	    if ( imn < 1 ) {
		/*
		 * Start at 1 when full range is needed.
		 */
		imn = 1;
		nu = ( mxnu - imn + 1 + nsx ) / ( 1 + nsx );
		mxnu = nu * ( 1 + nsx ) + imn - 1 - nsx;
	    }
	}
	imx = mxnu;
	if ( ( ix2 > 0 && imx != ix2 ) || 
	     ( ix1 > 0 && imn != ix1 ) ) {
	    ierr = 4;
	    er_wmsg ( "DG", &ierr, "I", &ier, strlen("DG"), strlen("I") );
	}
    }

    /*
     * Set the J dimension extraction bounds. No extend
     * region is allowed if user provides bounds.
     */
    if ( iy1 > 0 ) {
	iadly = 0;
	jmn = iy1;
    }
    if ( iy2 > 0 ) {
	iadry = 0;
	jmx = iy2;
    }

    /*
     * Adjust JMX and JMN for skipping.
     */
    if ( idy > 1 ) { 
	nu = G_NINT ( (float)( jmx - jmn + 1 + nsy ) / (float)( 1 + nsy ) );
	mxnu = nu * ( 1 + nsy ) + jmn - 1 - nsy;
	if ( mxnu > ( my - idy ) && mxnu != iy2 ) {
	    mxnu = my;
	    jmn = mxnu - nu * ( 1 + nsy ) + 1 + nsy;
	    if ( jmn < 1 ) {
		/*
		 * Start at 1 when full range is needed.
		 */
		jmn = 1;
		nu = ( mxnu - jmn + 1 + nsy ) / ( 1 + nsy );
		mxnu = nu * ( 1 + nsy ) + jmn - 1 - nsy;
	    }
	}
	jmx = mxnu;
	if ( ( iy2 > 0 && jmx != iy2 ) || ( iy1 > 0 && jmn != iy1 ) ) {
	    ierr = 4;
	    er_wmsg ( "DG", &ierr, "J", &ier, strlen("DG"), strlen("J") );
	}
    }

    /*
     * Compute subset grid final dimensions.
     */
    kxsg = ( imx - imn + 1 + nsx ) / ( 1 + nsx );
    kysg = ( jmx - jmn + 1 + nsy ) / ( 1 + nsy );
    if ( kxsg <= 0 || kysg <= 0 ) {
	*iret = -40;
	return;
    }
    kxysg = kxsg * kysg;
	

    /*
     * Set common block subset coordinates on reference grid.
     */
    _dgsubg.jsgxmn = imn;
    _dgsubg.jsgymn = jmn;
    _dgsubg.jsgxmx = imx;
    _dgsubg.jsgymx = jmx;
    _dgsubg.jsgxsk = idx;
    _dgsubg.jsgysk = idy;

    /*
     * Set DG_HILO area bounds on subset grid.
     */
    _dgarea.kgxmin = iadlx + 1;
    _dgarea.kgymin = iadly + 1;
    _dgarea.kgxmax = kxsg - iadrx;
    _dgarea.kgymax = kysg - iadry;

    /*
     * Strict map bounds are same as above.
     */
    *imll = _dgarea.kgxmin;
    *jmll = _dgarea.kgymin;
    *imur = _dgarea.kgxmax;
    *jmur = _dgarea.kgymax;

    /*
     * Set the DGAREA common grid bounds calculation flag.
     */
    _dgarea.jgxmin = 1;
    _dgarea.jgxmax = kxsg;
    _dgarea.jgymin = 1;
    _dgarea.jgymax = kysg;
    _dgarea.ksub1 = 1;
    _dgarea.ksub2 = kxysg;

    /*
     * Compute grid size and maximum number of internal grids
     * for the common block.
     */
    if ( (kxysg > *maxgrid) && (*maxgrid != IMISSD) ) {
	/*
	 * Here is the future location to set up some other
	 * remapping.
	 */
	*iret = -41;
	return;
    }

    _dgfile.kxd = kxsg;
    _dgfile.kyd = kysg;
    _dgfile.kxyd = kxysg;
    _dggrid.maxdgg = NDGRD;

    /*
     * Compute the navigation of the internal (subset) grid.
     */
    strcpy ( _dgfile.cprj, gprj );
    rglt[0] = _dgsubg.jsgxmn;
    rgln[0] = _dgsubg.jsgymn;
    rglt[1] = _dgsubg.jsgxmx;
    rgln[1] = _dgsubg.jsgymx;
    nc = 2;
    ftime(&t_gtrans1);
    gtrans ( sys_G, sys_M, &nc, rglt, rgln, rglt, rgln, &ier,
        strlen(sys_G), strlen(sys_M) );
    ftime(&t_current);
    if ( G_ABS ( rgln[0] - 180. ) < .01 || G_ABS ( rgln[0] + 180. ) < .01 )
        rgln[0] = -180.;
    if ( G_ABS ( rgln[1] - 180. ) < .01 || G_ABS ( rgln[1] + 180. ) < .01 )
        rgln[0] = 180.;
    if ( G_ABS ( rgln[0] - rgln[1]) < 0.01 )
        rgln[1] = rgln[0];
    ftime(&t_gsgprj3);
    gsgprj ( _dgfile.cprj, &ag1, &ag2, &ag3, &_dgfile.kxd, &_dgfile.kyd, 
        &rglt[0], &rgln[0], &rglt[1], &rgln[1], &ier, strlen(_dgfile.cprj) );
    ftime(&t_current);
    if ( ier != 0 ) {
	if ( _dgsubg.gwrapg == G_TRUE) {
	    ag2 += 180.;
	    if ( ag2 >= 360. ) ag2 -= 360.;
    ftime(&t_gsgprj4);
	    gsgprj ( _dgfile.cprj, &ag1, &ag2, &ag3, &_dgfile.kxd, &_dgfile.kyd,
		&rglt[0], &rgln[0], &rglt[1], &rgln[1], &ier,
		strlen(_dgfile.cprj) ) ;
    ftime(&t_current);
	if ( ier != 0 ) {
		*iret = -44;
		return;
	    }
	} else {
	    *iret = -44;
	    return;
	}
    }
    angflg = G_TRUE;
    ftime(&t_mnav);
    grc_mnav ( _dgfile.cprj, &_dgfile.kxd, &_dgfile.kyd, &rglt[0], &rgln[0],
	&rglt[1], &rgln[1], &ag1, &ag2, &ag3, &angflg, tnav, &ier );
    ftime(&t_current);

    /*
     * Check the current navigation against the saved navigation.
     * If they are different, then set the navigation flag to False.
     */
    navsz = LLNNAV;
    ftime(&t_cnav);
    grc_cnav ( tnav, _dgfile.snav, &navsz, &navflg, &ier );
    ftime(&t_current);

    /*
     * Save the current navigation.
     */
    for ( k = 0; k < LLNNAV; k++ ) {
	_dgfile.snav[k] = tnav[k];
    }

    db_retsubgcrs (_dgfile.cprj, _dgfile.kxd, _dgfile.kyd, rglt[0], rgln[0],
                       rglt[1], rgln[1],ag1, ag2, ag3,&ier); 
    /*
     * Set the constant of the cone for various projections (code
     * duplicated from UPDCON.FOR in GEMPLT).
     */
    _dgfile.anglr1 = ag1 * DTR;
    _dgfile.anglr2 = ag2 * DTR;
    _dgfile.anglr3 = ag3 * DTR;
    ftime(&t_cone);
    dg_cone ( _dgfile.cprj, &_dgfile.anglr1, &_dgfile.anglr3,
    	      &_dgfile.concon, iret );
    ftime(&t_current);

    /*
     * Set lat/lon,  map scale factor, and rotation matrix
     * internal grid pointers to zero.
     */
    _dgfile.idglat = 0;
    _dgfile.idglon = 0;
    _mapscl.ixmscl = 0;
    _mapscl.iymscl = 0;
    _mapscl.ixmsdy = 0;
    _mapscl.iymsdx = 0;
    _dgrtwd.irtcos = 0;
    _dgrtwd.irtsin = 0;
    _dglndc.lndsea = 0;

    /*
     * Initialize orientation angle.
     */
    _dgovec.ornang = RMISSD;

    /*
     * Free all existing grids since navigation is changed.
     */
    if ( navflg == G_FALSE ) {
        dg_fall ( &ier );
    }

    /*
     * Initialize the origin for M calculation.
     */
    _dgorig.orglat = RMISSD;
    _dgorig.orglon = RMISSD;
    _dgorig.orgxpt = RMISSD;
    _dgorig.orgypt = RMISSD;

    /*
     * Since there were no errors, set flag saying dg package has
     * been initialized.
     */
    _dgfile.dgset = G_TRUE;

    /*
     * Initialize the pointer in the internal grid arrays.
     */
    _dggrid.idglst = 0;

    return;
}
Exemple #8
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;

}
Exemple #9
0
void crg_setsigmet ( VG_DBStruct *el, int joffset, int elnum, int *iret )
/************************************************************************
 * crg_setsigmet                                                        *
 *                                                                      *
 * This function sets the range for a sigmet element.			*
 *                                                                      *
 * crg_setsigmet ( el, joffset, elnum, iret ) 				*
 *                                                                      *
 * Input parameters:                                                    *
 *	*el		VG_DBStruct	Element containing circle	*
 * 	joffset		int		File position of the element	*
 *	elnum		int		Element number			*
 *									*
 * Output parameters:                                                   *
 *      *iret           int             Return code                     *
 **                                                                     *
 * Log:                                                                 *
 * H. Zeng/EAI          07/02   initial coding                          *
 * H. Zeng/EAI          07/02   modified for very large iso. SIGMET     *
 ***********************************************************************/
{
    float	llx, lly, urx, ury, ccx, ccy, dist, ang1, ang2;
    float       new_llx, new_lly, new_urx, new_ury, new_ccx, new_ccy;
    float	lat[MAX_SIGMET*2+3], lon[MAX_SIGMET*2+3];
    float	s1lat[2], s1lon[2], s2lat[2], s2lon[2];
    float	x1[2], y1[2], x2[2], y2[2];
    float	xint, yint, new_dist;
    float	dirs[]= { 0.0F, 180.0F, 90.0F, 270.0F };
    int 	ii, kk, ier, np, npx, vg_subtype, two, intrsct;
    SigmetType  *psig;
    /*---------------------------------------------------------------------*/

    *iret = 0;

    psig       = &(el->elem.sig);
    vg_subtype = psig->info.subtype;
    np         = psig->info.npts;
    dist       = psig->info.distance * NM2M;

    /*
     *  get bounds
     */
    crg_gbnd (sys_M, sys_D, np, &(psig->latlon[0]),
              &(psig->latlon[np]), &llx, &lly, &urx, &ury,
              &ccx, &ccy);


    /*
     * For line or isolated SIGMET, range should be expanded
     * because of the distance.
     */
    if ( vg_subtype == SIGTYP_ISOL && !G_DIFFT(dist, 0.0F, GDIFFD) ) {

        npx = 4;
        for ( ii = 0; ii < npx; ii++ ) {
            clo_dltln ( &(psig->latlon[0]), &(psig->latlon[np]),
                        &dist, &(dirs[ii]), &(lat[ii]), &(lon[ii]), &ier );

        }
        crg_gbnd (sys_M, sys_D, npx, &(lat[0]), &(lon[0]),
                  &new_llx, &new_lly, &new_urx, &new_ury,
                  &new_ccx, &new_ccy );

        /*
         * Calculate the distance between (new_ccx, new_ccy) and
         * (new_llx, new_lly).
         */
        new_dist = (float)sqrt( (double)((new_ccx - new_llx) * (new_ccx - new_llx)
                                         + (new_ccy - new_lly) * (new_ccy - new_lly) ) );

        /*
         * modify the range according to new_dist.
         */
        llx = new_ccx - new_dist;
        urx = new_ccx + new_dist;
        ury = new_ccy + new_dist;
        lly = new_ccy - new_dist;

    }
    else if ( vg_subtype == SIGTYP_LINE && !G_DIFFT(dist, 0.0F, GDIFFD) ) {

        switch ( psig->info.sol )  {

        case    SIGLINE_NOF:
        case    SIGLINE_SOF:
        case    SIGLINE_EOF:
        case    SIGLINE_WOF:

            npx = 0;
            for ( ii = 0; ii < np; ii++ )  {
                clo_dltln ( &(psig->latlon[ii]), &(psig->latlon[ii+np]),
                            &dist, &(dirs[psig->info.sol-1]),
                            &(lat[npx]), &(lon[npx]), &ier );
                npx++;
            }
            crg_gbnd (sys_M, sys_D, npx, &(lat[0]), &(lon[0]),
                      &new_llx, &new_lly, &new_urx, &new_ury,
                      &new_ccx, &new_ccy );

            break;

        case    SIGLINE_ESOL:

            lat[0] = psig->latlon[0];
            lon[0] = psig->latlon[np];

            clo_direct ( &(psig->latlon[1]), &(psig->latlon[np+1]),
                         &(psig->latlon[0]), &(psig->latlon[np  ]),
                         &ang1, &ier );

            ang1 -= 90.0F;
            clo_dltln ( &(psig->latlon[0]), &(psig->latlon[np]), &dist,
                        &ang1, &(lat[2*np+1]), &(lon[2*np+1]), &ier );
            ang1 = ang1 - 180.0F;
            clo_dltln ( &(psig->latlon[0]), &(psig->latlon[np]), &dist,
                        &ang1, &(lat[1]), &(lon[1]), &ier );

            ang2 = ang1;

            two = 2;
            for ( ii = 1; ii < np-1; ii++ )  {

                clo_direct ( &(psig->latlon[ii-1]), &(psig->latlon[np+ii-1]),
                             &(psig->latlon[ii]), &(psig->latlon[np+ii]),
                             &ang1, &ier );
                ang1 = (float)fmod ( ((double)ang1+270.0), 360.0);
                clo_dltln ( &(psig->latlon[ii]), &(psig->latlon[np+ii]),
                            &dist, &ang1, &(s1lat[1]), &(s1lon[1]), &ier );
                clo_direct ( &(psig->latlon[ii+1]), &(psig->latlon[np+ii+1]),
                             &(psig->latlon[ii]), &(psig->latlon[np+ii]),
                             &ang2, &ier );
                ang2 = (float)fmod ( ((double)ang2+90.0), 360.0);
                clo_dltln ( &(psig->latlon[ii]), &(psig->latlon[np+ii]),
                            &dist, &ang2, &(s2lat[0]), &(s2lon[0]), &ier );

                if ( G_ABS(ang1-ang2) > 1.F )  {

                    clo_dltln ( &(psig->latlon[ii-1]), &(psig->latlon[np+ii-1]),
                                &dist, &ang1, &(s1lat[0]), &(s1lon[0]), &ier );
                    clo_dltln ( &(psig->latlon[ii+1]), &(psig->latlon[np+ii+1]),
                                &dist, &ang2, &(s2lat[1]), &(s2lon[1]), &ier );

                    gtrans ( sys_M, sys_N, &two, s1lat, s1lon, x1, y1,
                             &ier, strlen(sys_M), strlen(sys_N) );
                    gtrans ( sys_M, sys_N, &two, s2lat, s2lon, x2, y2,
                             &ier, strlen(sys_M), strlen(sys_N) );
                    cgr_segint( sys_N, x1, y1, sys_N, x2, y2,
                                sys_M, &xint, &yint, &intrsct, &ier );

                }
                else  {

                    xint = (s1lat[1] + s2lat[0]) / 2.0F;
                    yint = (s1lon[1] + s2lon[0]) / 2.0F;

                }

                kk = ii + 1;
                lat[kk] = xint;
                lon[kk] = yint;

                ang1 = (float)fmod ( ((double)ang1+180.0), 360.0 );
                ang2 = (float)fmod ( ((double)ang2+180.0), 360.0 );

                clo_dltln ( &(psig->latlon[ii]), &(psig->latlon[np+ii]),
                            &dist, &ang1, &(s1lat[1]), &(s1lon[1]), &ier );
                clo_dltln ( &(psig->latlon[ii]), &(psig->latlon[np+ii]),
                            &dist, &ang2, &(s2lat[0]), &(s2lon[0]), &ier );

                if ( G_ABS(ang1-ang2) > 1.F )  {

                    clo_dltln ( &(psig->latlon[ii-1]), &(psig->latlon[np+ii-1]),
                                &dist, &ang1, &(s1lat[0]), &(s1lon[0]), &ier );
                    clo_dltln ( &(psig->latlon[ii+1]), &(psig->latlon[np+ii+1]),
                                &dist, &ang2, &(s2lat[1]), &(s2lon[1]), &ier );

                    gtrans ( sys_M, sys_N, &two, s1lat, s1lon, x1, y1,
                             &ier, strlen(sys_M), strlen(sys_N) );
                    gtrans ( sys_M, sys_N, &two, s2lat, s2lon, x2, y2,
                             &ier, strlen(sys_M), strlen(sys_N) );
                    cgr_segint( sys_N, x1, y1, sys_N, x2, y2,
                                sys_M, &xint, &yint, &intrsct, &ier );

                }
                else  {

                    xint = (s1lat[1] + s2lat[0]) / 2.0F;
                    yint = (s1lon[1] + s2lon[0]) / 2.0F;

                }

                kk = 2*np - ii + 1;
                lat[kk] = xint;
                lon[kk] = yint;

                ang1 = (float)fmod ( ((double)ang1+180.0), 360.0 );
                ang2 = (float)fmod ( ((double)ang2+180.0), 360.0 );

                ang1 = ang2;

            } /* the end of for (... */

            clo_direct ( &(psig->latlon[np-2]), &(psig->latlon[2*np-2]),
                         &(psig->latlon[np-1]), &(psig->latlon[2*np-1]),
                         &ang2, &ier );

            ang2 -= 90.0F;
            clo_dltln ( &(psig->latlon[np-1]), &(psig->latlon[2*np-1]),
                        &dist, &ang2, &(lat[np]), &(lon[np]), &ier );

            ang2 = (float)fmod ( ((double)ang2+180.0), 360.0);
            clo_dltln ( &(psig->latlon[np-1]), &(psig->latlon[2*np-1]),
                        &dist, &ang2, &(lat[np+2]), &(lon[np+2]), &ier );

            lat[np+1] = psig->latlon[np-1];
            lon[np+1] = psig->latlon[2*np-1];

            lat[2*np+2] = lat[0];
            lon[2*np+2] = lon[0];

            npx = 2*np + 3;
            crg_gbnd (sys_M, sys_D, npx, &(lat[0]), &(lon[0]),
                      &new_llx, &new_lly, &new_urx, &new_ury,
                      &new_ccx, &new_ccy );

            break;

        } /* the end of switch ... */

        /*
         * compare two set of ranges and get the union of them.
         */
        llx = ( llx <= new_llx ) ? llx : new_llx;
        urx = ( urx >= new_urx ) ? urx : new_urx;
        ury = ( ury >= new_ury ) ? ury : new_ury;
        lly = ( lly <= new_lly ) ? lly : new_lly;

    } /* the end of else if ... */


    llx -= (float)EXTRA_SM;
    urx += (float)EXTRA_SM;
    ury += (float)EXTRA_SM;
    lly -= (float)EXTRA_SM;

    /*
     *  Store the device coordinates in the range array.
     */
    crg_save(elnum, joffset, llx, lly, urx, ury, &ier);


}
Exemple #10
0
void de_cval ( const char *uarg, char *stprm, int *iret )
/************************************************************************
 * de_cval								*
 *									*
 * This function determines the value of the function defined by PARM 	*
 * for which the probability is PRB that the observed value is less 	*
 * than or equal to that computed value based on an idealized ensemble 	*
 * forecast.								*
 *									*
 * GFUNC syntax: ENS_CVAL ( PARM & PRB & LWRBND & UPRBND )		*
 *									*
 * de_cval ( uarg, stprm, iret )					*
 *									*
 * Input and parameters:						*
 *	*uarg		const char	Function argument string	*
 *									*
 * Output parameters:							*
 *	*stprm		char		Substitution string		*
 *	*iret		int		Return code			*
 *					 +3 = Percentile < 0		*
 *					 +1 = Percentile > 100		*
 *					  0 = normal return		*
 *					 -8 = cannot parse argument	*
 *					 -9 = ensemble cannot computed	*
 * 					-15 = Incorrect # of arguments	*
 **									*
 * Log:									*
 * M. Li/SAIC 		10/06						*
 * M. Li/SAIC 		10/06 	Added a check for missing value		*
 * K. Brill/HPC      20080131   Add intrinsic weight computations; fix	*
 *   				eliminate duplicates coding error	*
 * K. Brill/HPC      20101118   Check for single value order stats case *
 ************************************************************************/
{
    char tname[13], pdum[13], time1[21], time2[21];
    char **argu;
    int igo, igp, num, kxd, kyd, ksub1, ksub2, nina, narg, level1, level2,
        ivcord, zero, one, ii, jj, kk, ll, mm, nn, ier;
    int iswflg, istop;
    float *gigo, *gigp, *gnum, data, swpbuf, psum;
    float *gilwr, *giupr, *tmpwt, wtbuf, tol;
    float *zwts, *zfreq;
    float zsum;
    float vn, qlt, qrt, fta, cta, aa, bb, cc;
    Boolean ibreak;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;
    one = 1;

    dg_ssub ( iret );

    /*
     * Get a new grid number.
     */
    dg_nxts ( &igo, iret );
    if ( *iret != 0 ) return;

    /*
     * Initialize the output grid.
     */
    dg_getg ( &igo, &gigo, &kxd, &kyd, &ksub1, &ksub2, iret );
    for ( ii = ksub1 - 1; ii < ksub2; ii++ ) {
	gigo[ii] = RMISSD;
    }

    /*
     * Set the number of input arguments.  There are up to four arguments
     * for DE_CVAL.
     */
    for ( ii = 0; ii < MXARGS; ii++ ) {
	_ensdiag.allarg[ii][0] = '\0';
    }
    nina = 4;
    argu = (char **)cmm_malloc2d ( 4, MXFLSZ+1, sizeof(char), &ier );
    cst_clst ( (char *)uarg, '&', " ", nina, MXFLSZ, argu, &narg, &ier );
    for ( ii = 0; ii < narg; ii++ ) {
        strcpy ( _ensdiag.allarg[ii], argu[ii] );
	if ( ii > 0 && strcmp(argu[ii], " ") == 0 ) {
	    cst_rlch ( RMISSD, 1, _ensdiag.allarg[ii], &ier );
	}
    }

    if ( narg == 2 ) {
	cst_rlch ( RMISSD, 1, _ensdiag.allarg[2], &ier );
	cst_rlch ( RMISSD, 1, _ensdiag.allarg[3], &ier );
    }
    if ( narg == 3 ) {
        cst_rlch ( RMISSD, 1, _ensdiag.allarg[3], &ier );
    }

    cmm_free2d ( (void **) argu, &ier );
    if ( narg < 2 ) {
	*iret = -15;
	return;
    }

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

    /*
     * Evaluate the static arguments.
     */
    for ( ii = 2; ii < nina; ii++ ) {
	dg_pfun ( _ensdiag.allarg[ii], iret );
        dg_driv ( &one, iret );
	dg_tops ( tname, &igp, time1, time2, &level1, &level2,
                  &ivcord, pdum, iret );
	if ( ii == 2 ) {
            dg_getg ( &igp, &gilwr, &kxd, &kyd, &ksub1, &ksub2, iret );
	}
 	else {
            dg_getg ( &igp, &giupr, &kxd, &kyd, &ksub1, &ksub2, iret );
	}
    }
    
    dg_pfun ( _ensdiag.allarg[1], 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[1], &ier,
	    strlen("DG"), strlen(_ensdiag.allarg[1]) );
	*iret = -9;
	return;
    }

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

    /*
     * Loop over number of members set by DE_SCAN.
     */
    for ( ii = 0; ii < _ensdiag.nummbr; ii++ ) {
	de_mset ( &ii, 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 and store the
	 * grid number.
	 */
	dg_tops ( tname, &num, time1, time2, &level1, &level2,
	    &ivcord, pdum, iret );
	_ensdiag.iglist[ii] = num;
    }

    /*
     * Get memory for intrinsic weights (zwts), intrinsic weight
     * frequency (zfreq), and temporary weights.
     */
    G_MALLOC ( zwts, float, _ensdiag.nummbr+1, "x" );
    G_MALLOC ( zfreq, float, _ensdiag.nummbr+1, "x" );
    G_MALLOC ( tmpwt, float, _ensdiag.nummbr+2, "x" );

    for ( ll = ksub1 - 1; ll < ksub2; ll++ ) {

	if ( ERMISS(gigp[ll]) ) continue;	

        if ( gigp[ll] < 0.0F || gigp[ll] > 1.0F ) continue;

	for ( ii = 0; ii < _ensdiag.nummbr; ii++ ) {
	    ibreak = False;
	    num = _ensdiag.iglist[ii];
	    dg_getg ( &num, &gnum, &kxd, &kyd, &ksub1, &ksub2, iret );
	    data = gnum[ll];
	    if ( ! ERMISS ( data ) ) {
	        _ensdiag.emvalu[ii+1] = data;
		tmpwt[ii+1] = _ensdiag.enswts[ii];

	        if ( ii == _ensdiag.nummbr - 1 ) {
	            /*
		     * Bubble sorting the grid values in emvalu with 
		     * emvalue (1) lowest and emvalu (nummbr) highest.
		     */
	            iswflg = 1;
	            istop = _ensdiag.nummbr;
		    while ( iswflg != 0 && istop > 0 ) {
		        iswflg = 0;
		        for ( kk = 1; kk < istop; kk++ ) {
		            if ( _ensdiag.emvalu[kk] > _ensdiag.emvalu[kk+1] ) {
		                iswflg = 1;
			        swpbuf = _ensdiag.emvalu[kk];
				wtbuf = tmpwt[kk];
			        _ensdiag.emvalu[kk] = _ensdiag.emvalu[kk+1];
				tmpwt[kk] = tmpwt[kk+1];
			        _ensdiag.emvalu[kk+1] = swpbuf;
			        tmpwt[kk+1] = wtbuf;
		            }
		        }
		        istop--;
		    }

		    /*
		     * Check for identical values and compute intrinsic weight
      		     * frequency (zfreq).
		     */
		    mm = _ensdiag.nummbr;
		    nn = mm;
		    /*
                     * Initialize intrinsic weight frequency array.
                     */
                    for (kk = 1; kk <= nn; kk++){
                        zfreq[kk] = 1.0F;
                    }
		    tol = 0.001F * (_ensdiag.emvalu[mm]-_ensdiag.emvalu[1]) / mm;
		    for (kk = 1; kk < mm; kk++) {
			if ( G_ABS(_ensdiag.emvalu[kk] - _ensdiag.emvalu[kk+1]) <= tol ) {
			    tmpwt[kk] += tmpwt[kk+1];
			    zfreq[kk] = zfreq[kk] + 1.0F;
			    mm--;
			    for (jj = kk+1; jj <= mm; jj++) {
				_ensdiag.emvalu[jj] = _ensdiag.emvalu[jj+1];
				tmpwt[jj] = tmpwt[jj+1];
			    } 
			    /* This algorithm was originally coded incorrectly.  The value
			     * of kk must also be held back to correctly eliminate three
			     * or more identical values.
			     */
			    kk--;
			}
		    } 

		    /*
		     * Fabricate order statistics if it has collapsed to a single value.            
		     */
		    if ( mm == 1 ) {
		    	if ( G_DIFF(_ensdiag.emvalu[1], 0.0F) ) {
			    _ensdiag.emvalu[1] = -0.00001F;
			    _ensdiag.emvalu[2] = 0.00001F;
			}
			else {
                            _ensdiag.emvalu[2] = _ensdiag.emvalu[1] + 0.00001F * G_ABS(_ensdiag.emvalu[1]);
			    _ensdiag.emvalu[1] -= 0.00001F * G_ABS(_ensdiag.emvalu[1]);
			}

			tmpwt[1] = 0.5F;
		        tmpwt[2] = 0.5F;
			mm = 2;
			zfreq[1] = 1.0F;
			zfreq[2] = 1.0F;
		    }
		    /*
		     *Compute and sum intrinsic weights.
		    */
		    zwts[1] = zfreq[1] / ( _ensdiag.emvalu[2] - _ensdiag.emvalu[1] );
		    zsum = zwts[1];
		    for (kk=2; kk < mm; kk++){
			zwts[kk] = ( zfreq[kk] * 2.0F ) / ( _ensdiag.emvalu[kk+1] - _ensdiag.emvalu[kk-1] );
			zsum = zsum + zwts[kk];
		    }
		    zwts[mm] = zfreq[mm] / ( _ensdiag.emvalu[mm] - _ensdiag.emvalu[mm-1] );
		    zsum = zsum + zwts[mm];
		    /*
		     * Scale external weights by normalized intrinsic weights and
		     * normalize.
		     */
 		    psum = 0.0F;
		    for (kk=1; kk <= mm; kk++ ){
			tmpwt[kk] = ( zwts[kk] / zsum ) * tmpwt[kk];
			psum = psum + tmpwt[kk];
		    }
		    for (kk=1; kk <= mm; kk++ ){
			tmpwt[kk] = tmpwt[kk] / psum;
		    }
	        } /*End "if" for all members ready check.*/
	    }
	    else {
		ibreak = True;
		break;
	    } /*End "if" for check for non-missing value.*/
	} /*End "for" loop over members.*/

	if ( ibreak ) continue;

	/*
         * Compute Qun, the area; Vn, the normalized value; 
	 * w(), normalized weight; and qlt, qrt.
         */
        vn = 0.0F;
        for ( kk = 2; kk <= mm; kk++ ) {
            vn += 0.5 * (tmpwt[kk] + tmpwt[kk-1]) * (_ensdiag.emvalu[kk] - _ensdiag.emvalu[kk-1]);
        }
	/*
	 * If the distribution is a Dirac spike over a single value, then set the result to
         * that single value.
	 */
	if ( G_DIFF ( vn, 0.0 ) ) {
	    gigo[ll] = _ensdiag.emvalu[1];
	    continue;
	}
        vn = vn / (1.0F - 2.0F / (nn+1));

        for ( kk = 1; kk <= mm; kk++ ) {
            tmpwt[kk] = tmpwt[kk] / vn;
        }

        qlt = _ensdiag.emvalu[1] - 2.0F / (tmpwt[1] * (nn + 1));
        qrt = _ensdiag.emvalu[mm] + 2.0F / (tmpwt[mm] * (nn + 1));

        tmpwt[0] = 0.0F;
        tmpwt[mm+1] = 0.0F;
        _ensdiag.emvalu[0] = qlt;
        _ensdiag.emvalu[mm+1] = qrt;

 	psum = 0.0F;
	for ( kk = 1; kk <= mm + 1; kk++ ) {

	    /*
	     * Compute CTA.
	     */
	    cta = 0.5F * (tmpwt[kk] + tmpwt[kk-1]) * (_ensdiag.emvalu[kk] - _ensdiag.emvalu[kk-1]);
	    psum += cta;
	    if ( kk == mm + 1 ) psum = 1.0F;

	    /*
	     * If psum = PRB, assign q[i] to output grid and move on to next grid point.
	     * (This was coded incorrectly and fixed on 20080205 -KB.)
	     */
	    if ( G_DIFF ( gigp[ll], psum ) ) {
		gigo[ll] = _ensdiag.emvalu[kk];
		break;
	    }

	    /*
	     * If psum > PRB. Solve the quadratic equation.
	     */
	    if ( psum > gigp[ll] ) {
	    	psum -= cta;
	    	fta = gigp[ll] - psum;
	    	aa = (tmpwt[kk] - tmpwt[kk-1]) / (_ensdiag.emvalu[kk] - _ensdiag.emvalu[kk-1]); 
	    	bb = 2.0F * tmpwt[kk-1];
	    	cc = 2.0F * fta;

	    	if ( G_DIFF ( aa, 0.0F ) ) {
	   	    gigo[ll] = _ensdiag.emvalu[kk-1] + cc / bb;
	    	}
 	    	else {
		    gigo[ll] = _ensdiag.emvalu[kk-1] + (sqrt(bb * bb + 4 * aa * cc) - bb) / (2 * aa);
	        }
	        
		if ( ! ERMISS(gilwr[ll]) && gigo[ll] < gilwr[ll] ) gigo[ll] = gilwr[ll];
		if ( ! ERMISS(giupr[ll]) && gigo[ll] > giupr[ll] ) gigo[ll] = giupr[ll];
	        
	        break;
	    }

	}

    }

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

    return;
}
void cgr_centroid ( float x[], float y[], int *np, float *xcent, 
				float *ycent, float *area, int *iret )
/************************************************************************
 * cgr_centroid								*
 *									*
 * This function computes the area and centroid (or center of mass)	*
 * of the given polygon.						*
 *									*
 * Reference:								*
 * Graphics Gems IV, "Centroid of a Polygon", Gerard Bashein and	*
 * Paul R. Detmer, pp 3-5.						*
 *									*
 * cgr_centroid ( x, y, np, xcent, ycent, area, iret )			*
 *									*
 * Input parameters:							*
 *	x [np]		float		X coordinates of polygon	*
 *	y [np]		float		Y coordinates of polygon	*
 *      *np             int             Number of point in polygon      *
 *									*
 * Output parameters:							*
 *	*xcent		float		X coordinate of centroid	*
 *	*ycent		float		Y coordinate of centroid	*
 *	*area		float		Area of polygon			*
 *	*iret		int		Return code			*
 *					  -1 = Not enough points	*
 *					  -2 = Area is zero		*
 *									*
 **									*
 * S. Jacobs/NCEP	11/01	Created					*
 * S. Jacobs/NCEP	12/01	Set return values if not enough points	*
 * M. Li/SAIC		03/04	Prolog change for *area			*
 * D.W.Plummer/NCEP	03/05	Rm relationship between area and cntrd	*
 * M. Li/SAIC		04/05	Output positive area			*
 ***********************************************************************/
{

    register int	i, j;
    float		ai, atmp = 0.0F, xtmp = 0.0F, ytmp = 0.0F;

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

    *iret = 0;

    /*
     * Check for at least 3 points to make a polygon.
     */
    if  ( *np < 3 )  {
	*iret  = -1;
    	*xcent = RMISSD;
    	*ycent = RMISSD;
	*area  = RMISSD;
    	return;
    }

    /*
     * Compute the summation of the area and the first moments.
     */
    for ( i = *(np)-1, j = 0; j < *np; i = j, j++ )  {

    	ai = x[i] * y[j] - x[j] * y[i];
	atmp += ai;
	xtmp += ( x[j] + x[i] ) * ai;
	ytmp += ( y[j] + y[i] ) * ai;
    }

    /*
     * Compute the area of the polygon.
     */
    *area = G_ABS ( atmp / 2.0F );

    /*
     * Compute the location of the centroid of the polygon.
     */
    if  ( !G_DIFF(atmp, 0.0F) )  {
    	*xcent = xtmp / ( 3.0F * atmp );
    	*ycent = ytmp / ( 3.0F * atmp );
    }
    else {
    	*xcent = 0; *ycent = 0;
	for ( i = 0; i < *np; i++ )  {
	    *xcent += x[i]; *ycent += y[i];
	}
	*xcent /= *np; *ycent /= *np;
    	*iret = -2;
    }

}
Exemple #12
0
void df_mass ( int *iret )
/************************************************************************
 * df_mass								*
 *									*
 * This subroutine computes MASS, the mass per unit volume in a layer:	*
 *									*
 *     MASS ( PRES ) = 100 * LDF (PRES) / ( GRAVTY * (level1 - level2) )*
 *									*
 *                     Where: the 100 converts millibars to Pascals	*
 *                            level1, level2 are also converted to	*
 *                              Pascals when VCORD=PRES			*
 *									*
 * The volume is expressed in units of					*
 * meters * meters * (units of vert coord).				*
 *									*
 * df_mass ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * M. Goodman/RDS	12/85						*
 * M. desJardins/GSFC	 7/88	Rewritten so layer can be found		*
 * G. Huffman/GSC	 9/88	Error messages				*
 * K. Brill/GSC		 8/89   Subsetting				*
 * K. Brill/GSC		10/89   Subsetting				*
 * M. desJardins/NMC	 7/93	Changed update scheme			*
 * T. Lee/GSC		 4/96	Single dimension for dgg		*
 * K. Tyle/GSC           5/96   Moved IGDPT outside do-loop             *
 * K. Brill/HPC		 1/02	CALL DG_SSUB and DG_ESUB		*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * R. Tian/SAIC		11/05	Recoded from Fortran			*
 ************************************************************************/
{
    char time1[21], time2[21], gparm[13], gfunc[13];
    int level1, level2, ndp, ivcord, kx, ky, ksub1, ksub2, i, im1, zero,
        ier;
    float dellev, cnst, *gndp, dg;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Pressure is on the stack.  Compute the level difference.
     * Note that this function is called by DG_GETS.  Therefore,
     * it cannot call subroutines which call DG_GETS.
     */
    df_ldf ( iret );
    if ( *iret != 0 )  return;

    /*
     * Get information about the pressure difference grid.
     */
    dg_tops ( gfunc, &ndp, time1, time2, &level1, &level2,
              &ivcord, gparm, iret );
    if ( *iret != 0 )  return;

    /*
     * Compute the layer difference of the vertical coordinate
     */
    dellev = (float)( level1 - level2 );

    /*
     * Convert millibars to pascals when vert. coord. is PRES.
     */
    if ( ivcord == 1 )  dellev *= 100.;

    /*
     * Compute constant for multiplication.
     */
    cnst = -1. / GRAVTY;

    /*
     * Compute the mass grid.
     */
    dg_getg ( &ndp, &gndp, &kx, &ky, &ksub1, &ksub2, iret );

    for ( i = ksub1; i <= ksub2; i++ ) {
        im1 = i - 1;
	if ( ERMISS ( gndp[im1] ) ) {
	    gndp[im1] = RMISSD;
	} else {
	    /*
	     * Convert pressure from millibars to pascals, then 
	     * compute average mass.
  	     */
	    dg = gndp[im1] * 100.;
	    gndp[im1] = G_ABS ( cnst * dg / dellev );
	}
    }

    /*
     * Make a name MASS and update header; the stack is current.
     */
    dg_upsg ( time1, time2, &level1, &level2, &ivcord, &zero, "MASS",
              &ndp, iret );
    dg_esub ( &ndp, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Exemple #13
0
void df_ncdf ( int *iret )
/************************************************************************
 * df_ncdf								*
 *									*
 * This subroutine computes the normal cumulative distribution function *
 * given a particular value, the mean, and standard deviation:		*
 *									*
 *     NCDF (S1, S2, S3) = { INTEGRAL [-inf -> Z] EXP ( -u**2 / 2 ) } /	*
 *				SQRT ( 2 * PI )				*
 *									*
 *     where u = (z - S2) / S3 and Z = (S1 - S2) / S3			*
 *									*
 * This gives the probability of S <= S1.  For the probability of	*
 * S >= S1, subtract this result from one.  For the probability of S	*
 * between two values, take the absolute value of the difference of	*
 * this result for each of the two values.				*
 *									*
 * The standard normal distribution is described and tabulated in Meyer	*
 * (1970).  The numerical integration algorithm is the Simpson Composite*
 * Algorithm described in Burden et. al (1978).				*
 *									*
 * References:								*
 *									*
 * Burden, R. L., J. D. Faires, and A. C. Reynolds, 1978:  NUMERICAL	*
 *     ANALYSIS.  Prindle, Weber & Schmidt, ISBN 0-87150-243-7, 579 pp. *
 *									*
 * Meyer, P. L., 1970:  INTRODUCTORY PROBABILITY AND STATISTICAL	*
 *     APPLICATIONS.  Addison-Wesley Pub. Co., ISBN 0-201-04710-1,	*
 *     367 pp.								*
 *									*
 * df_ncdf ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * K. Brill/HPC		10/02						*
 * K. Brill/HPC		11/02	Eliminate use of the SUBA logical array	*
 * R. Tian/SAIC		11/05	Recoded from Fortran			*
 ************************************************************************/
{
    int num1, num2, num3, num, kxd, kyd, ksub1, ksub2, zero, ier;
    int i, im1, k, kend, m;
    float *gnum1, *gnum2, *gnum3, *gnum, hstep, cnorm, dg1, dg2, dg3;
    float zstop, azstp, sign, x, h, sum;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Get the three input grid numbers.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num2, iret );
    if ( *iret != 0 ) return;
    dg_gets ( &num3, iret );
    if ( *iret != 0 ) return;

    /*
     * Get a new grid number.
     */
    dg_nxts ( &num, iret );
    if ( *iret != 0 ) return;

    /*
     * Grid number to grid.
     */
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num2, &gnum2, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num3, &gnum3, &kxd, &kyd, &ksub1, &ksub2, iret );
    dg_getg ( &num,  &gnum,  &kxd, &kyd, &ksub1, &ksub2, iret );

    /*
     * Set up integration parameters.
     */ 
    hstep = .05;
    cnorm = 1. / ( 3. * sqrt ( 2.0 * PI ) );

    /*
     * Begin calculation.
     */
    for ( i = ksub1; i <= ksub2; i++ ) {
        im1 = i - 1;
	dg1 = gnum1[im1];
	dg2 = gnum2[im1];
	dg3 = gnum3[im1];
	if ( ERMISS (dg1) || ERMISS (dg2) || ERMISS (dg3) ||
	    dg3 < 0.00001 ) {
	    gnum[im1] = RMISSD;
	} else {
	    zstop = ( dg1 - dg2 ) / dg3;
	    azstp = G_ABS ( zstop );
	    if ( azstp < 0.0001 ) {
		gnum[im1] = .500;
	    } else if ( zstop > 7. ) {
		gnum[im1] = 1.0;
	    } else if ( zstop < -7. ) {
		gnum[im1] = 0.0;
	    } else {
		if ( zstop < 0.0 ) {
		    sign = -1.0;
		} else {
		    sign = 1.0;
		}
		m = (int) ( azstp / ( 2. * hstep ) );
		if ( m < 4 ) m = 4;
		h = azstp / ( 2. * m );

		/*
		 * Perform Simpson's Composite Algorithm to integrate.
		 */
		x = 0.;
		sum = 1.;
		kend = 2 * m;
		for ( k = 1; k <= kend; k++ ) {
		    x = x + h;
		    if ( k == kend ) {
			sum += exp ( - x * x / 2. );
		    } else if ( ( k % 2 ) != 0 ) {
			sum += 4. * exp ( - x * x / 2. );
		    } else {
			sum += 2. * exp ( - x * x / 2. );
		    }
		}
		sum *= ( h * cnorm );
		gnum[im1] = .5 + sign * sum;
	    }
	}
    }

    /*
     * Make a name of the form 'NCDF'//S1//S2 and update header;
     * update stack.
     */
    dg_updh ( "NCDF", &num, &num1, &num2, iret );
    dg_puts ( &num, iret );
    dg_esub ( &num, &zero, &zero, &zero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Exemple #14
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;
}
Exemple #15
0
void xopenw ( char win_name[], int win_index, float xsize,
              float ysize, int *ixsize, int *iysize, int *iret )
/************************************************************************
 * xopenw								*
 *									*
 * This subroutine opens one xw window and sets the initial		*
 * graphics context along with basic window attributes.			*
 *									*
 * xopenw ( win_name, win_index, xsize, ysize, ixsize, iysize, iret )	*
 *									*
 * Input parameters:							*
 *	win_name[]	char		window name			*
 *	win_index	int		window index			*
 *	xsize		float		Right edge of window		*
 *	ysize		float		Bottom edge of window		*
 *									*
 * Output parameters:							*
 *	*ixsize		int		Right edge of window		*
 *	*iysize		int		Bottom edge of window		*
 *	*iret		int		Return code			*
 *					G_NORMAL = normal return	*
 **									*
 * Log:									*
 * A. Hardy/GSC          2/01   Copied from the XW driver and           *
 *                              removed size limitations                *
 ***********************************************************************/
{
    int			dhght, dwdth, gemscreen, xpos, ypos, ier;
    unsigned int	xwdth, xhght, xbord, xdpth;
    char		gemname [WNAME_LEN];

    Cursor		curs;
    Window		gwin;
    GC			gemgc;

    XGCValues		 values;
    XSizeHints		 gemhint;
    XSetWindowAttributes gemxswa;
    XColor		 cred;

    Window_str      	*cwin;
    winloop_t		*cloop;
    /*---------------------------------------------------------------------*/

    *iret = G_NORMAL;

    current_window = win_index;

    cwin  = &(gemwindow[current_window]);
    cloop = &(cwin->loop[cwin->curr_loop]);

    strcpy(cwin->name, win_name);

    strcpy(gemname, win_name);

    gemscreen = DefaultScreen( (XtPointer)gemdisplay );

    /*
     * Determine window height and width.
     */

    dwdth = DisplayWidth( (XtPointer)gemdisplay, gemscreen );
    dhght = DisplayHeight( (XtPointer)gemdisplay, gemscreen );

    if ( G_ABS ( xsize - RMISSD ) < RDIFFD )
        gemhint.width = 0.7 * (float) dwdth ;
    else if ( ( xsize > 0.0 ) && ( xsize <= 1.0 ) )
        gemhint.width = (float) dwdth * xsize ;
    else if ( xsize < 100.0 ) gemhint.width = 100 ;
    else gemhint.width = (int) xsize ;

    if ( G_ABS ( ysize - RMISSD ) < RDIFFD )
        gemhint.height = 0.7 * (float) dhght ;
    else if ( ( ysize > 0.0 ) && ( ysize <= 1.0 ) )
        gemhint.height = (float) dhght * ysize ;
    else if ( ysize < 100.0 ) gemhint.height = 100 ;
    else gemhint.height = (int) ysize ;

    if ( gemhint.width  < 100 ) gemhint.width  = 100 ;
    if ( gemhint.height < 100 ) gemhint.height = 100 ;

    /*
     * Determine window location.
     */

    gemhint.x = dwdth - ( gemhint.width ) - ( current_window * 30 ) - 20;
    if ( gemhint.x < 0 ) gemhint.x = 0;

    gemhint.y = ( current_window * 30 );

    gemhint.flags  = USPosition | USSize;

    /*
     * Create the window and set standard properties and attributes.
     */

    gwin = XCreateSimpleWindow( gemdisplay, root, gemhint.x, gemhint.y,
                                gemhint.width, gemhint.height, 5,
                                WhitePixel ( (XtPointer)gemdisplay, gemscreen ),
                                BlackPixel ( (XtPointer)gemdisplay, gemscreen ) );

    cwin->window = gwin;

    XSetStandardProperties( gemdisplay, gwin, gemname, gemname, None,
                            NULL, 0, &gemhint );

    gemxswa.bit_gravity = CenterGravity;

    XChangeWindowAttributes (gemdisplay, gwin, (CWBitGravity), &gemxswa );

    /*
     * Get the geometry and window size information.
     */
    XGetGeometry( gemdisplay, gwin, &root, &xpos,
                  &ypos, &xwdth, &xhght, &xbord, &xdpth );

    cwin->width  = xwdth;
    cwin->height = xhght;
    cwin->depth  = xdpth;

    /*
     * Create graphics contexts.
     */
    gemgc = XCreateGC( gemdisplay, gwin, 0, 0 );

    /*
     * Turn of NoExpose and GraphicsExpose events.  They
     * don't seem to be needed and were causing many events
     * to seen in xxevent().
     */
    values.graphics_exposures = False;
    XChangeGC( gemdisplay, gemgc, GCGraphicsExposures, &values);

    cwin->gc = gemgc;

    /*
     * Set backgound colors.
     */
    XSetBackground( gemdisplay, gemgc,
                    BlackPixel ( (XtPointer)gemdisplay, gemscreen ) ) ;

    /*
     * Set fill rule.
     */
    XSetFillRule ( gemdisplay, gemgc, EvenOddRule );

    /*
     * Create one pixmap.
     */
    cwin->pxms[cwin->curr_loop][0] =
        XCreatePixmap(gemdisplay, root, xwdth, xhght, xdpth);

    cwin->curpxm[cwin->curr_loop] = 0;
    cloop->pxm_wdth	= xwdth;
    cloop->pxm_hght	= xhght;
    cloop->roamflg	= 0;
    cloop->xoffset	= 0;
    cloop->yoffset	= 0;

    cloop->pxm_x	= 0;
    cloop->pxm_y	= 0;
    cwin->area_w	= xwdth;
    cwin->area_h	= xhght;
    cwin->win_x		= 0;
    cwin->win_y		= 0;

    /*
     * return device size
     */
    *ixsize = xwdth;
    *iysize = xhght;

    /*
     * clear the pixmap,
     */
    xclrpxm(&(cwin->curpxm[cwin->curr_loop]), &ier);

    /*
     * Select the events to be processed.
     */
    XSelectInput ( gemdisplay, gwin, ExposureMask );

    /*
     * Set the cursor to be the customary red arrow.
     */
    curs = XCreateFontCursor ( gemdisplay, XC_top_left_arrow );
    XDefineCursor ( gemdisplay, gwin, curs );
    cred.red	= 65535;
    cred.blue	= 0;
    cred.green	= 0;
    cred.flags	= DoRed | DoBlue | DoGreen;
    XRecolorCursor ( gemdisplay, curs, &cred, &cred );

}
Exemple #16
0
void cds_sig ( VG_DBStruct *el, int indx, int *iret )
/************************************************************************
 * cds_sig								*
 *									*
 * This function displays SIGMETs to the output device.			*
 *									*
 * cds_sig (el, indx, iret)						*
 *									*
 * Input parameters:							*
 * 	*el		VG_DBStruct	Pointer to VG record structure	*
 *	indx		int		Index into user attribute table *
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *									*
 **									*
 * Log:									*
 * D.W.Plummer/NCEP	 7/99	Copied from cds_line			*
 * D.W.Plummer/NCEP	 9/99	Compute circle from element distance;	*
 *				Compute line extension area		*
 * H. Zeng/EAI           9/99   Preserve plot attributes                *
 * F. J. Yen/NCEP 	10/99   Handled user attribute table            *
 * M. Li/GSC		10/99	Modified clo_direct and clo_dltln codes	*
 * D.W.Plummer/NCEP	12/99	Added plotting of sequence number	*
 * M. Li/GSC		 1/00	Used string variables in gtrans		*
 * S. Law/GSC		05/00	changed to use MAX_SIGMET for lat/lon	*
 * H. Zeng/EAI          06/00   increased the sizes of lat&lon arrays   *
 * A. Hardy/GSC         11/00   renamed coordinate system declarations	*
 * M. Li/SAIC           01/03   delete vgstruct.h                       *
 * T. Piper/SAIC        12/05   redone with new Setting_t structure     *
 ***********************************************************************/
{
    int		ii, kk, npts, np, intrsct, ier;
    int		mtype, color, width, lintyp, lthw, lwhw, mkhw, two;
    int         iltypx, ilthwx, iwidthx, iwhwx, icolrx, imarkx, imkhwx, imkwidx;
    char	str[4];
    float	lat[MAX_SIGMET*2+3], lon[MAX_SIGMET*2+3];
    float	size, dist, dir, ang1, ang2;
    float	dirs[]={ 0.0F, 180.0F, 90.0F, 270.0F };
    float	s1lat[2], s1lon[2], s2lat[2], s2lon[2];
    float	x1[2], y1[2], x2[2], y2[2];
    float	xint, yint;
    float       szmarkx;
    float	lbllat, lbllon, rotat=0.0F;
    int		ixoff=0, iyoff=2;
    int		itxfn_s, itxhw_s, itxwid_s, ibrdr_s, irrotn_s, ijust_s;
    float	sztext_s;
    int		itxfn, itxhw, itxwid, ibrdr, irrotn, ijust;
    float	sztext;
    SigmetType	*psig;
/*---------------------------------------------------------------------*/

    *iret = 0;

    /*
     *  Save plot attributes.
     */
    gqcolr ( &icolrx, &ier );
    gqline ( &iltypx, &ilthwx, &iwidthx, &iwhwx, &ier );
    gqmrkr ( &imarkx, &imkhwx, &szmarkx, &imkwidx, &ier );
   
    /*
     * setup basic information
     */
    psig  = &(el->elem.sig);
    width =  (int) (( (  cdsUattr[indx].info.sig->linwid == 0 ) ?
		(float)psig->info.linwid :
		(float)cdsUattr[indx].info.sig->linwid) * cdsLineWdth);
    lintyp = (  cdsUattr[indx].info.sig->lintyp == 0 ) ?
		psig->info.lintyp : cdsUattr[indx].info.sig->lintyp;

    lthw  = 0;
    lwhw  = 0;
    mtype = 1;
    mkhw  = 0;
    size  = 1.0F;
    np    = psig->info.npts;

    gsline (&lintyp, &lthw, &width, &lwhw, &ier);

    color = (cdsColor == 0) ? 
       	 ( ( cdsUattr[indx].maj_col == 0 ) ?
	     el->hdr.maj_col : cdsUattr[indx].maj_col ) : cdsColor;
    gscolr (&color, &ier);

    switch ( psig->info.subtype )  {

      case	SIGTYP_ISOL:		/* isolated	*/

	/*
	 *  Plot marker w/ surrounding circle
	 */

        lat[0] = psig->latlon[0];
        lon[0] = psig->latlon[np];
        gsmrkr ( &mtype, &mkhw, &size, &width, &ier );
        gmark ( sys_M, &np, lat, lon, &ier, strlen(sys_M) );

	if ( !G_DIFF(psig->info.distance, 0.0F ) )  {

            dir = ( lat[0] >= 0.F ) ? 180.F : 0.F;
	    dist = psig->info.distance * NM2M;
	    clo_dltln ( &lat[0], &lon[0], &dist, &dir, &(lat[1]), &(lon[1]), &ier );
            np = 18;
            gcircl ( sys_M, lat, lon, &(lat[1]), &(lon[1]), &np, 
		     &ier, strlen(sys_M) );

	}

	break;

      case	SIGTYP_LINE:		/* line		*/

	for ( ii = 0; ii < np; ii++ )  {
	    lat[ii] = psig->latlon[ii];
	    lon[ii] = psig->latlon[ii+np];
	}

	gline ( sys_M, &np, lat, lon, &ier, strlen(sys_M) );

	if ( !G_DIFF(psig->info.distance, 0.0F) )  {

	    lintyp = 2;
    	    gsline (&lintyp, &lthw, &width, &lwhw, &ier);

	    dist = psig->info.distance * NM2M;

	    switch ( psig->info.sol )  {

		case	SIGLINE_NOF:
		case	SIGLINE_SOF:
		case	SIGLINE_EOF:
		case	SIGLINE_WOF:

		    npts = 1;
		    for ( ii = 0; ii < np; ii++ )  {
			clo_dltln ( &(psig->latlon[ii]), &(psig->latlon[ii+np]),
				    &dist, &(dirs[psig->info.sol-1]),
				    &(lat[npts]), &(lon[npts]), &ier );
			npts++;
		    }
		    lat[npts] = psig->latlon[np-1];
		    lon[npts] = psig->latlon[2*np-1];
		    npts++;

		    gline ( sys_M, &npts, lat, lon, &ier, strlen(sys_M) );

		break;

		case	SIGLINE_ESOL:

		    lat[0] = psig->latlon[0];
		    lon[0] = psig->latlon[np];

		    clo_direct ( &(psig->latlon[1]), &(psig->latlon[np+1]),
				 &(psig->latlon[0]), &(psig->latlon[np  ]),
				 &ang1, &ier );

		    ang1 -= 90.0F;
		    clo_dltln ( &(psig->latlon[0]), &(psig->latlon[np]), &dist, 
				&ang1, &(lat[2*np+1]), &(lon[2*np+1]), &ier );
		    ang1 = ang1 - 180.0F;
		    clo_dltln ( &(psig->latlon[0]), &(psig->latlon[np]), &dist, 
				&ang1, &(lat[1]), &(lon[1]), &ier );

		    ang2 = ang1;

		    two = 2;
		    for ( ii = 1; ii < np-1; ii++ )  {

		     clo_direct ( &(psig->latlon[ii-1]), &(psig->latlon[np+ii-1]),
				  &(psig->latlon[ii]), &(psig->latlon[np+ii]), 
				  &ang1, &ier );
		     ang1 = (float)fmod ( ((double)ang1+270.0), 360.0);
		     clo_dltln ( &(psig->latlon[ii]), &(psig->latlon[np+ii]), 
				 &dist, &ang1, &(s1lat[1]), &(s1lon[1]), &ier );
		     clo_direct ( &(psig->latlon[ii+1]), &(psig->latlon[np+ii+1]),
				  &(psig->latlon[ii]), &(psig->latlon[np+ii]),
				  &ang2, &ier );
		     ang2 = (float)fmod ( ((double)ang2+90.0), 360.0);
		     clo_dltln ( &(psig->latlon[ii]), &(psig->latlon[np+ii]), 
				 &dist, &ang2, &(s2lat[0]), &(s2lon[0]), &ier );

		     if ( G_ABS(ang1-ang2) > 1.F )  {

		       clo_dltln ( &(psig->latlon[ii-1]), &(psig->latlon[np+ii-1]), 
				   &dist, &ang1, &(s1lat[0]), &(s1lon[0]), &ier );
		       clo_dltln ( &(psig->latlon[ii+1]), &(psig->latlon[np+ii+1]), 
				   &dist, &ang2, &(s2lat[1]), &(s2lon[1]), &ier );

		       gtrans ( sys_M, sys_N, &two, s1lat, s1lon, x1, y1, 
		                &ier, strlen(sys_M), strlen(sys_N) );
		       gtrans ( sys_M, sys_N, &two, s2lat, s2lon, x2, y2, 
		                &ier, strlen(sys_M), strlen(sys_N) );
		       cgr_segint( sys_N, x1, y1, sys_N, x2, y2,
			           sys_M, &xint, &yint, &intrsct, &ier );

		     }
		     else  {

		       xint = (s1lat[1] + s2lat[0]) / 2.0F;
		       yint = (s1lon[1] + s2lon[0]) / 2.0F;

		     }

		     kk = ii + 1;
		     lat[kk] = xint;
		     lon[kk] = yint;

		     ang1 = (float)fmod ( ((double)ang1+180.0), 360.0 );
		     ang2 = (float)fmod ( ((double)ang2+180.0), 360.0 );

		     clo_dltln ( &(psig->latlon[ii]), &(psig->latlon[np+ii]), 
				 &dist, &ang1, &(s1lat[1]), &(s1lon[1]), &ier );
		     clo_dltln ( &(psig->latlon[ii]), &(psig->latlon[np+ii]), 
				 &dist, &ang2, &(s2lat[0]), &(s2lon[0]), &ier );

		     if ( G_ABS(ang1-ang2) > 1.F )  {

		       clo_dltln ( &(psig->latlon[ii-1]), &(psig->latlon[np+ii-1]), 
				   &dist, &ang1, &(s1lat[0]), &(s1lon[0]), &ier );
		       clo_dltln ( &(psig->latlon[ii+1]), &(psig->latlon[np+ii+1]), 
				   &dist, &ang2, &(s2lat[1]), &(s2lon[1]), &ier );

		       gtrans ( sys_M, sys_N, &two, s1lat, s1lon, x1, y1, 
		                &ier, strlen(sys_M), strlen(sys_N) );
		       gtrans ( sys_M, sys_N, &two, s2lat, s2lon, x2, y2, 
		                &ier, strlen(sys_M), strlen(sys_N) );
		       cgr_segint( sys_N, x1, y1, sys_N, x2, y2,
			           sys_M, &xint, &yint, &intrsct, &ier );

		     }
		     else  {

		       xint = (s1lat[1] + s2lat[0]) / 2.0F;
		       yint = (s1lon[1] + s2lon[0]) / 2.0F;

		     }

		     kk = 2*np - ii + 1;
		     lat[kk] = xint;
		     lon[kk] = yint;

		     ang1 = (float)fmod ( ((double)ang1+180.0), 360.0 );
		     ang2 = (float)fmod ( ((double)ang2+180.0), 360.0 );

		     ang1 = ang2;

		    }

		    clo_direct ( &(psig->latlon[np-2]), &(psig->latlon[2*np-2]),
				 &(psig->latlon[np-1]), &(psig->latlon[2*np-1]),
				 &ang2, &ier );

		    ang2 -= 90.0F;
		    clo_dltln ( &(psig->latlon[np-1]), &(psig->latlon[2*np-1]), 
				&dist, &ang2, &(lat[np]), &(lon[np]), &ier );

		    ang2 = (float)fmod ( ((double)ang2+180.0), 360.0);
		    clo_dltln ( &(psig->latlon[np-1]), &(psig->latlon[2*np-1]), 
				&dist, &ang2, &(lat[np+2]), &(lon[np+2]), &ier );

		    lat[np+1] = psig->latlon[np-1];
		    lon[np+1] = psig->latlon[2*np-1];

		    lat[2*np+2] = lat[0];
		    lon[2*np+2] = lon[0];

		    npts = 2*np + 3;
		    gline ( sys_M, &npts, lat, lon, &ier, strlen(sys_M) );

		break;

	    }

	}

	break;

      case	SIGTYP_AREA:		/* area		*/

	for ( ii = 0; ii < np; ii++ )  {
	    lat[ii] = psig->latlon[ii];
	    lon[ii] = psig->latlon[ii+np];
	}
	lat[np] = psig->latlon[0];
	lon[np] = psig->latlon[np];
	np++;

	gline ( sys_M, &np, lat, lon, &ier, strlen(sys_M) );

	break;

    }

    if ( el->hdr.vg_type == SIGCONV_ELM || el->hdr.vg_type == SIGOUTL_ELM )  {

	if ( el->hdr.vg_type == SIGCONV_ELM ) 
	    sprintf( str, "%d%c", psig->info.seqnum, psig->info.msgid[0] );
	else if ( el->hdr.vg_type == SIGOUTL_ELM )
	    sprintf( str, "%d", psig->info.seqnum );

	np = psig->info.npts;
	lbllat = psig->latlon[0];
	lbllon = psig->latlon[np];
	for ( ii = 1; ii < np; ii++ )  {
	    if ( psig->latlon[ii] > lbllat )  {
	        lbllat = psig->latlon[ii];
	        lbllon = psig->latlon[ii+np];
	    }
	}

	gqtext( &itxfn_s, &itxhw_s, &sztext_s, &itxwid_s, &ibrdr_s, 
		&irrotn_s, &ijust_s, &ier );
	itxfn  = 0;
	itxhw  = 0;
	sztext = 1.5F;
	itxwid = 0;
	ibrdr  = 0;
	irrotn = 0;
	ijust  = 2;
	gstext( &itxfn, &itxhw, &sztext, &itxwid, &ibrdr, &irrotn, &ijust, &ier );
	gtext( sys_M, &lbllat, &lbllon, str, &rotat, &ixoff, &iyoff, &ier, 
	       strlen(sys_M), strlen(str) );
	gstext( &itxfn_s, &itxhw_s, &sztext_s, &itxwid_s, &ibrdr_s, 
		&irrotn_s, &ijust_s, &ier );

    }

    /*
     *  Restore the saved plot attribute values
     */
    gsmrkr ( &imarkx, &imkhwx, &szmarkx, &imkwidx, &ier );
    gsline ( &iltypx, &ilthwx, &iwidthx, &iwhwx, &ier );
    gscolr ( &icolrx, &ier );

}