void gb2_gdtlamb( float *navblk, int *igdtmpl, int *iret )
/************************************************************************
 * gb2_gdtlamb								*
 *                                                                      *
 * This routine converts a LCC Gempak grid navigation block to a        *
 * GRIB2 Grid Definition Template 3.30.					*
 *                                                                      *
 * gb2_gdtlamb ( navblk, igdtmpl, iret )				*
 *									*
 * Input parameters:                                                    *
 *  *navblk   		float       Decoded GRIB2 structure             *
 *									*
 * Output parameters:                                                   *
 *  *igdtmpl            int        GDT 3.30 values 			*
 *  *iret               int        Return code                          *
 *                                    -36 = Projection not LCC		*
 **                                                                     *
 * Log:                                                                 *
 * S. Gilbert/NCEP          08/05    Calculations taken from GDS_LCC    *
 * S. Gilbert/NCEP          03/06    Chngs to remove compiler warnings  *
 ***********************************************************************/
{
        int        ier;

        double     rlon, rlov, phi1, phi2, trult1, trult2;
        double     sign, rnx, rny, psi1, psi2;
        double     rlat1, rlon1, rlat2, rlon2, clon;
        double     re, cc, tan1, tan2, dlon1, dlon2;
        double     x1, y1, x2, y2, alfa, dx, dy;

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

        /*
         *  ensure grid navigation block is LCC
         */
        if ( strncmp( (char *)(navblk+1), "LCC", 3) != 0 ) {
           *iret=-36;
           ER_WMSG("GB", iret, (char *)(navblk+1), &ier, 2, 4 );
        }

        /*
         *  Compute the grid increments.
         */
        rnx=navblk[4];
        rny=navblk[5];
        rlat1 = navblk[6];
        rlon1 = navblk[7];
        rlat2 = navblk[8];
        rlon2 = navblk[9];
        phi1 = navblk[10];
        rlov = navblk[11];
        phi2 = navblk[12];

        if ( fabs(phi1) > fabs(phi2) ) {
           trult1 = phi1;
           trult2 = phi2;
           if ( phi1 > 0.0 ) sign = -1.0;
           else sign = 1.0;
        }
        if ( fabs(phi2) > fabs(phi1) ) {
           trult1 = phi2;
           trult2 = phi1;
           if ( phi2 > 0.0 ) sign = -1.0;
           else sign = 1.0;
        }
        else {
           trult1 = phi1;
           trult2 = phi2;
           if ( phi1 > 0.0 ) sign = -1.0;
           else sign = 1.0;
        }

        rlat1 = rlat1 * DTR / 2.;
        rlat2 = rlat2 * DTR / 2.;
        rlon1 = rlon1 * DTR;
        rlon2 = rlon2 * DTR;
        clon = rlov * DTR;

        /*
         *  Compute the cone constant
         */
        psi1 = HALFPI + sign * phi1 * DTR;
        psi2 = HALFPI + sign * phi2 * DTR;
        if ( G_DIFF (phi1, phi2) ) 
            cc = cos ( psi1 );
        else {
            cc = log ( sin ( psi2 ) / sin ( psi1 ) );
            cc = cc / log ( tan ( psi2 / 2. ) / tan ( psi1 / 2. ) );
        }

        re = RADIUS / cc;
        tan1 = pow ( tan ( PI4TH + sign * rlat1 ) , cc);
        tan2 = pow ( tan ( PI4TH + sign * rlat2 ) , cc);
        dlon1 = ( rlon1 - clon ) * cc;
        dlon2 = ( rlon2 - clon ) * cc;
        x1 = re * tan1 * sin ( dlon1 );
        y1 = sign * re * tan1 * cos ( dlon1 );
        x2 = re * tan2 * sin ( dlon2 );
        y2 = sign * re * tan2 * cos ( dlon2 );
        alfa = sin ( psi1 ) / pow( tan ( psi1 / 2. ) , cc );
        dx = ( x2 - x1 ) * alfa / ( rnx - 1. );
        dy = ( y2 - y1 ) * alfa / ( rny - 1. );

        /*
         *  Set Grid Definition Template
         */

        igdtmpl[0] = 1;                       /* Earth Assumed Spherical */
        igdtmpl[1] = 0;                       /* Radius scale factor     */
        igdtmpl[2] = G_NINT( RADIUS );        /* Radius of Earth         */
        igdtmpl[3] = 0;                       /* Oblate info     n/a     */
        igdtmpl[4] = 0;                       /* Oblate info     n/a     */
        igdtmpl[5] = 0;                       /* Oblate info     n/a     */
        igdtmpl[6] = 0;                       /* Oblate info     n/a     */
        igdtmpl[7] = G_NINT( navblk[4] );     /* Kx                      */
        igdtmpl[8] = G_NINT( navblk[5] );     /* Kx                      */
        igdtmpl[9] = G_NINT(navblk[6]*1000000.0);    
                                              /* Lat of 1st grid point   */
        rlon = navblk[7];   
        if ( rlon < 0.0 ) rlon += 360.0;
        igdtmpl[10] = G_NINT(rlon*1000000.0);   
                                              /* Lon of 1st grid point   */
        igdtmpl[11] = 8;                      /* Res and Comp flags      */

        igdtmpl[12] = G_NINT(trult1*1000000.0);
                                              /* LaD                     */
        rlov = navblk[11];   
        if ( rlov < 0.0 ) rlov += 360.0;
        igdtmpl[13] = G_NINT(rlov*1000000.0);
                                              /* LoV                     */
        igdtmpl[14] = G_NINT( dx*1000.0 );    /* Dx                      */
        igdtmpl[15] = G_NINT( dy*1000.0 );    /* Dy                      */
        if ( sign < 0.0 ) igdtmpl[16] = 0;
        else igdtmpl[16] = 128;               /* Projection center flag  */
        igdtmpl[17] = 64;                     /* Scanning mode           */
        igdtmpl[18] = G_NINT( trult1*1000000.0);
                                              /* Lat intrsect 1          */
        igdtmpl[19] = G_NINT( trult2*1000000.0);
                                              /* Lat intrsect 2          */
        igdtmpl[20] = -90000000;              /* Lat of South Pole       */
        igdtmpl[21] = 0;                      /* Lon of South Pole       */

}
void gb2_gdtpstr( float *navblk, int *igdtmpl, int *iret )
/************************************************************************
 * gb2_gdtpstr								*
 *                                                                      *
 * This routine converts a STR Gempak grid navigation block to a        *
 * GRIB2 Grid Definition Template 3.20.					*
 *                                                                      *
 * gb2_gdtpstr ( navblk, igdtmpl, iret )				*
 *									*
 * Input parameters:                                                    *
 *  *navblk   		float       Decoded GRIB2 structure             *
 *									*
 * Output parameters:                                                   *
 *  *igdtmpl            int        GDT 3.20 values 			*
 *  *iret               int        Return code                          *
 *                                    -36 = Projection not STR		*
 **                                                                     *
 * Log:                                                                 *
 * S. Gilbert/NCEP          08/05    Calculations taken from GDS_STR    *
 * S. Gilbert/NCEP          03/06    Chngs to remove compiler warnings  *
 ***********************************************************************/
{

        double     rlat1, rlon1, rlat2, rlon2, dx, dy, polat, rlov;
        double     rnx, rny, sign, clon, re, x1, y1, x2, y2;
        double     tlat1, tlon1;
        double     tan1, tan2, dlon1, dlon2;

        int        ier;
        int        nx, ny;

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

        /*
         *  ensure grid navigation block is STR
         */
        if ( strncmp( (char *)(navblk+1), "STR", 3) != 0 ) {
           *iret=-36;
           er_wmsg("GB", iret, (char *)(navblk+1), &ier, 2, 4 );
        }

        nx = G_NINT(navblk[4]);
        ny = G_NINT(navblk[5]);
        rlat1 = navblk[6];
        rlon1 = navblk[7];
        rlat2 = navblk[8];
        rlon2 = navblk[9];
        polat = navblk[10];
        rlov = navblk[11];

        /*
         *  compute the grid increments
         */
        if ( polat > 0.0 ) sign = -1.0;
        else sign = 1.0;
        rnx = navblk[4];
        rny = navblk[5];
        tlat1 = rlat1 * DTR / 2.;
        rlat2 = rlat2 * DTR / 2.;
        tlon1 = rlon1 * DTR;
        rlon2 = rlon2 * DTR;
        clon = rlov * DTR;
        re = RADIUS;
        tan1 = tan ( PI4TH + sign * tlat1 );
        tan2 = tan ( PI4TH + sign * rlat2 );
        dlon1 = tlon1 - clon;
        dlon2 = rlon2 - clon;
        x1 = re * tan1 * sin ( dlon1 );
        y1 = sign * re * tan1 * cos ( dlon1 );
        x2 = re * tan2 * sin ( dlon2 );
        y2 = sign * re * tan2 * cos ( dlon2 );
        dx = ( x2 - x1 ) * 1.8660254 / ( rnx - 1. );
        dy = ( y2 - y1 ) * 1.8660254 / ( rny - 1. );

        /*
         *  Set Grid Definition Template
         */

        igdtmpl[0] = 1;                       /* Earth Assumed Spherical */
        igdtmpl[1] = 0;                       /* Radius scale factor     */
        igdtmpl[2] = G_NINT(RADIUS);          /* Radius of Earth         */
        igdtmpl[3] = 0;                       /* Oblate info     n/a     */
        igdtmpl[4] = 0;                       /* Oblate info     n/a     */
        igdtmpl[5] = 0;                       /* Oblate info     n/a     */
        igdtmpl[6] = 0;                       /* Oblate info     n/a     */
        igdtmpl[7] = nx;                      /* Kx                      */
        igdtmpl[8] = ny;                      /* Kx                      */
        igdtmpl[9] = G_NINT(rlat1*1000000.0);
                                              /* Lat of 1st grid point   */
        if ( rlon1 < 0.0 ) rlon1 += 360.0;
        igdtmpl[10] = G_NINT(rlon1*1000000.0);   
                                              /* Lon of 1st grid point   */
        igdtmpl[11] = 56;                     /* Res and Comp flags      */
        igdtmpl[12] = 60000000;               /* Lat where Dx,Dy true    */
        if ( rlov < 0.0 ) rlov += 360.0;
        igdtmpl[13] = G_NINT(rlov*1000000.0);   
                                              /* Lon of Orientation      */


        igdtmpl[14] = G_NINT(dx*1000.0);      /* Dx                      */
        igdtmpl[15] = G_NINT(dy*1000.0);      /* Dy                      */
        igdtmpl[16] = 0;
        if ( polat < 0.0 ) igdtmpl[16] = 128; /* Projection center flag  */
        igdtmpl[17] = 64;                     /* Scanning mode           */

}
Exemple #3
0
void df_nmax ( int *iret )
/************************************************************************
 * df_nmax								*
 *									*
 * This subroutine computes NMAX (S,ROI), the neigborhood maximum	*
 * value of a scalar field (S) within some radius of influence    	*
 * (ROI; meters). Masking could be used [e.g., SGT(S1,S2)] to subset *
 * and filter the grid beforehand to allow for faster processing.      	*
 *									*
 * df_nmax ( iret )							*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * C. Melick/SPC	06/12						*
 ************************************************************************/
{
    int num1, num2, num3, num, kxd, kyd, ksub1, ksub2, zero, indx, ier;
    int ixmscl, iymscl, jgymin, jgymax, jgxmin, jgxmax, idglat, idglon;
    int row, col, ibeg, iend, jbeg, jend, ibox, jbox, boxindx, nval;
    float  gddx, gddy, gdspdx, gdspdy, radius;
    float *gnum1, *gnumn, *gkxms, *gkyms, *gnumroi, *glat, *glon, *dist;
    /*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Compute map scale factors.
     */
    dg_mscl ( iret );
    if ( *iret != 0 ) return;

    /*
     * Query DGCMN.CMN idglat/idglon.
    */

    nval = 1;
    dg_iget ( "IDGLAT", &nval, &idglat, iret );
    if ( *iret != 0 ) return;
    dg_iget ( "IDGLON", &nval, &idglon, iret );
    if ( *iret != 0 ) return;

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

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

    dg_qmsl ( &ixmscl, &iymscl, &gddx, &gddy, &ier );
    dg_qbnd ( &jgxmin, &jgxmax, &jgymin, &jgymax, &ier );
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &num,  &gnumn,  &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &ixmscl, &gkxms, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &iymscl, &gkyms, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &num2, &gnumroi, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &idglat, &glat, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &idglon, &glon, &kxd, &kyd, &ksub1, &ksub2, &ier );
    dg_getg ( &num3, &dist, &kxd, &kyd, &ksub1, &ksub2, &ier );

    radius = gnumroi[0];

    /*  QC check on lower and upper bounds of radius of influence.  */

    if ( radius < 0 ) {
        radius = 0.0;
        printf ("\n WARNING : RADIUS value less than zero.  "
                "Resetting to zero.\n");
    }

    if ( radius > 0.5*gddx*(float)(kxd)) {
        radius = 0.5*gddx*(float)(kxd);
        printf ("\n WARNING : RADIUS value too high.  "
                "Resetting to half the distance in X (%f meters).\n",radius);
    }

    /*
     * Loop over all grid points to initialize output grid.
     */
    for ( row = jgymin; row <= jgymax; row++ ) {
        for ( col = jgxmin; col <= jgxmax; col++ ) {
            indx=(row-1)*kxd+(col-1);
            if ( ERMISS ( gnum1[indx] ) ) {
                gnumn[indx] = RMISSD;
            } else {
                gnumn[indx] = gnum1[indx];
            }
        }
    }

    /*
     * Loop over all grid points to determine neighborhood maximum for each grid point.
     */

    for ( row = jgymin; row <= jgymax; row++ ) {
        for ( col = jgxmin; col <= jgxmax; col++ ) {
            indx=(row-1)*kxd+(col-1);
            if ( ! ERMISS ( gnum1[indx] ) ) {
                gdspdx= gddx / gkxms[indx];
                gdspdy= gddy / gkyms[indx];

                /*  Constructing box for each grid point */
                ibeg = col- G_NINT(radius / gdspdx);
                iend = col+ G_NINT(radius / gdspdx);
                jbeg = row- G_NINT(radius / gdspdy);
                jend = row+ G_NINT(radius / gdspdy);
                if (ibeg < jgxmin) {
                    ibeg = jgxmin;
                }
                if (iend > jgxmax) {
                    iend = jgxmax;
                }
                if (jbeg < jgymin) {
                    jbeg = jgymin;
                }
                if (jend > jgymax) {
                    jend = jgymax;
                }
                for ( ibox = ibeg; ibox <= iend; ibox++ ) {
                    for ( jbox = jbeg; jbox <= jend; jbox++ ) {
                        boxindx=(jbox-1)*kxd+(ibox-1);
                        if ((glat[indx] == glat[boxindx]) && (glon[indx] == glon[boxindx])) {
                            dist[boxindx]=0.0;
                        } else {
                            /* Great Circle Distance calculation */
                            dist[boxindx] = acos(sin(glat[boxindx])*sin(glat[indx]) + cos(glat[boxindx])*cos(glat[indx])*cos((glon[boxindx])-(glon[indx])));
                            dist[boxindx] = RADIUS * dist[boxindx];
                        }
                        /* Check maximum value if neighboring point is defined and within radius of influence. */
                        if ( (dist[boxindx] <= radius) && (! ERMISS ( gnum1[boxindx] ) ) ) {
                            if ( gnum1[boxindx] > gnumn[indx] ) {
                                gnumn[indx] = gnum1[boxindx];
                            }
                        }
                    }
                }
                for ( ibox = ibeg; ibox <= iend; ibox++ ) {
                    for ( jbox = jbeg; jbox <= jend; jbox++ ) {
                        boxindx=(jbox-1)*kxd+(ibox-1);
                        /* Spreading the response around to surrounding undefined values */
                        if ( ERMISS ( gnum1[boxindx] ) ) {
                            if (dist[boxindx] <= radius) {
                                if ( ERMISS ( gnumn[boxindx] ) ) {
                                    gnumn[boxindx] = gnumn[indx];
                                } else if ( gnum1[indx] > gnumn[boxindx] ) {
                                    gnumn[boxindx] = gnum1[indx];
                                }
                            }
                        }
                    }
                }
            }
        }
    }

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

    return;
}
Exemple #4
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 #5
0
void gb2_vcrd ( char *wmolvltbl, char *lcllvltbl, Gribmsg *cmsg, 
                int *levels, int *vcord, int *iret )
/************************************************************************
 * gb2_vcrd								*
 *									*
 * This routine computes the vertical coordinate level/layer values     *
 * from the GRIB2 PDS.	Also, the GEMPAK vertical coordinate type is    *
 * obtained from the appropriate GRIB2 vertical coordinate table.       *
 *									*
 * If either wmolvltbl or lcllvltbl are NULL, the default tables are    *
 * read.                                                                *
 *									*
 * gb2_vcrd ( wmolvltbl, lcllvltbl, cmsg, levels, vcord, iret )		*
 *									*
 * Input parameters:							*
 *      *wmolvltbl      char            WMO vertical coordinate table   *
 *      *lcllvltbl      char            Local vertical coordinate table *
 *	*cmsg  	    struct Gribmsg      GRIB2  message structure        *
 *									*
 * Output parameters:							*
 *      levels[2]       int             lower/upper level/layer values  *
 *	*vcord		int		GEMPAK vertical goordinate type *
 *	*iret		int		return code			*
 *                                        -27 = Unrecognized PDT number *
 **									*
 * Log:									*
 * S. Gilbert/NCEP      11/04                                           *
 * S. Gilbert/NCEP      10/05           Use new routines to read tables *
 * S. Gilbert/NCEP          03/06    Chngs to remove compiler warnings  *
 ***********************************************************************/
{
    int     ret, ier, lvl1, lvl2, iver, lclver;
    G2level g2lev;
    G2lvls  *g2lvltbl;
    char    vparm[12], ctemp[20];
    float   rlevel[2];
    double  sfact;

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

    *iret = 0;

    /* 
     *  Get Level into from vertical coordinate table(s).
     */
    iver=cmsg->gfld->idsect[2];
    lclver=cmsg->gfld->idsect[3];
    lvl1=cmsg->gfld->ipdtmpl[9];
    lvl2=cmsg->gfld->ipdtmpl[12];

    if ( ( lvl1 < 192 || lvl1 == 255 ) && 
         ( lvl2 < 192 || lvl2 == 255 ) ) {
       /* 
        *  Get WMO vertical coordinate table.
        */
        gb2_gtwmolvltbl( wmolvltbl, iver, &g2lvltbl, &ier);
        if ( ier == 0 ) {
           /* 
            *  Get Level into from WMO vertical coordinate table.
            */
            gb2_sklvl( lvl1, lvl2, g2lvltbl, &g2lev, &ier);
        }
    }
    else {
       /* 
        *  Get Local vertical coordinate table.
        */
        gb2_gtlcllvltbl( lcllvltbl, cmsg->origcntr, lclver, &g2lvltbl, &ier);
        if ( ier == 0 ) {
           /* 
            *  Get Level into from Local vertical coordinate table.
            */
            gb2_sklvl( lvl1, lvl2, g2lvltbl, &g2lev, &ier);
        }
    }
    if ( ier != 0 ) {
        *iret=ier;
        if ( ier == -30 ) {
            sprintf(ctemp,"%d|%d", lvl1, lvl2);
            er_wmsg("GB",&ier,ctemp,&ret,2,strlen(ctemp));
        }
        return;
    }

    /* 
     *  Calculate GEMPAK vertical coordinate type
     */
    lv_cord ( g2lev.abbrev, vparm, vcord, &ier, 4, 12);
    if ( ier != 0 ) {
        *iret=-7;
        return;
    }

    /* 
     *  Extract vertical coordinate levels from GRIB2 PDS
     */
    gb2_vlev ( cmsg->gfld, rlevel, &ier );
    if ( ier != 0 ) {
        *iret=ier;
        return;
    }

    /* 
     *  Scale level values by scale factor found in vertical 
     *  coordinate table.
     */
    sfact=pow((double)10.0,g2lev.scale);
    levels[0] = G_NINT( rlevel[0] * sfact );
    if  ( G_DIFF ( -1.0, rlevel[1] ) )  {
        levels[1] = -1;
    }
    else {
        levels[1] = G_NINT( rlevel[1] * sfact );
    }

    if ( lvl1 == 1 ) {          /*  Surface  */
        levels[0] = 0;
        levels[1] = -1;
    }


}
Exemple #6
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 #7
0
void wsatim ( char *imgnam, int *xispace0, int *yispace0,
			int *xispace1, int *yispace1, int *ist,
			int *inum, int *iret )
/************************************************************************
 * wsatim								*
 *									*
 * This subroutine displays satellite images for the GIF driver.	*
 * It is capable of displaying raw satellite images and remapped images.*
 *									*
 * wsatim ( imgnam, xispace0, yispace0, xispace1, yispace1,		*
 *	    ist, inum, iret )						*
 *									*
 * Input parameters:							*
 *	*imgnam		char		Name of image file		*
 *	*xispace0	int		Left of image in plot coord	*
 *	*yispace0	int		Top of image in plot coord	*
 *	*xispace1	int		Right of image in plot coord	*
 *	*yispace1	int		Bottom of image in plot coord	*
 *	*ist		int		Starting point of color table	*
 *	*inum		int		Number of colors		*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					G_NORMAL  = normal return	*
 *                      G_NIMGFL  = cannot open image file              *
 *                      G_NFILENM = file name is too long (xslutf)      *
 *                      G_NIMGCOL = not enough image colors      	*
 *			G_NMEMRY  = Memory allocation failure		*
 *			G_NIMCORD = invalid image coordinates		* 
 **									*
 * Log:									*
 * G. Krueger/EAI	12/93	Modify xrest -> xsatim			*
 * G. Krueger/EAI	02/93	Added simplified color alloc scheme	*
 * S. Jacobs/NMC	 3/94	Added std image max/min values		*
 * S. Jacobs/NMC	 7/94	General clean up			*
 * C. Lin/EAI	         7/94	Multi-window, multi-pixmap		*
 * C. Lin/EAI	         8/94	Take clrsalloc into xwcmn.h		*
 * J. Cowie/COMET	 8/94	Added byte swapping for image headers	*
 * D. Himes/COMET	 8/94	Return error code if xcaloc fails	*
 * S. Jacobs/NMC	 8/94	Updated calls to MV_SWP4 to send arrays	*
 * S. Jacobs/NMC	 9/94	Added more optional debug prints	*
 * J. Cowie/COMET	11/94	Handle radar, use default LUT file	*
 * S. Jacobs/NMC	 1/95	Changed to use a radar colors array	*
 * J. Cowie/COMET	 1/95	Fixed index color mapping rounding bug	*
 * J. Cowie/COMET	 1/95	Added image subsetting			*
 * C. Lin/EAI            3/95   Added clearing pixmap                   *
 *                              Used calloc() to clear image_data       *
 *                              Error code; error handling              *
 *                              Use ColorBanks structure                *
 *                              Bug fix: all malloc() calls             *
 * C. Lin/EAI            3/95   Take out normal coordinates input.      *
 *				Rewrite the program.   			*
 * C. Lin/EAI            9/95   Add G_ZEROCB check			*
 * J. Cowie/COMET	10/95	Changed to use icbank value		*
 * J. Nielsen-Gammon/TAMU2/96	Disabled pixmap clearing		*
 * J. Nielsen-Gammon/TAMU12/96	Modified for GIF driver			*
 * J. Nielsen-Gammon/TAMU9/98	Gempak 5.4 version			*
 * T. Lee/GSC		 7/00	Renamed x*.c to w*.c			*
 * R. Curtis/EAI	 8/00   Updated for NetCDF files                *
 * S. Chiswell/Unidata	11/00	Updated for ZLIB compressed NIDS files	*
 * R. Tian/SAIC		05/02	Modified to display fax image		*
 * D.W.Plummer/NCEP	 3/03	Changes for 10-bit GVAR imagery		*
 * S. Danz/AWC 		11/03	Changed to not clear background data	*
 * A. Hardy/NCEP	 4/04	Modified to display 10-bit VIS imagery	*
 * T. Piper/SAIC	10/05	Dynamically allocate coltrans & rowtrans*
 * T. Piper/SAIC	1/06	Change *lenfil from long int to int	*
 * T. Piper/SAIC	08/06	Moved byte swapping to crarea		*
 * T. Piper/SAIC        11/06   Restore coltrans[0] back to original    *
 * T. Piper/SAIC	03/07	Fixed flaw in row processing		*
 * X. Guo/CWS           04/10   Added codes to support 94 product       *
 * X. Guo/CWS           05/10   Added IFHINIDS to process 8 bit product *
 ***********************************************************************/
{
    int                 *coltrans, drange, element_size, ier, ii;
    int                 imghght, imgwdth, indx, isGVARRAW, iwdth;
    int                 linestart, ncolors, *rowtrans, ximage0;
    int                 ximage1, xloc, yimage0, yimage1, yloc;
    char                dev[] = "GIF";
    float               *fpix, *tmpk;
    size_t              imgsize;
    double              dbltmp, doffset, imgratio, plotratio, ratio, sf_hght, sf_wdth;
    unsigned char       datamap[256], *ddptr, *dptr;
    unsigned int        col, linesize, newdim, *pix;
    unsigned int        plothght, plotwdth, remainder, row, xhght, xwdth;

/*---------------------------------------------------------------------*/
/*
 *  Check the input for valid bounds.  Then set the image dimensions.
 */
    if (( imbot <= imtop ) || ( imrght <= imleft ) ||
        ( *xispace1 <= *xispace0) || ( *yispace0 <= *yispace1 )) {
        *iret = G_NIMCORD;
        return;
    }
    imgwdth = (imrght - imleft) + 1;
    imghght = (imbot - imtop) + 1;
/*
 *  Initialize the image data arrays.
 */
    csinit ( &ier );
/*
 *  Read image data file if this is a new file.
 */
    if  ( strcmp ( lastimg.filename, imgnam ) != 0 ) {
/*
 *  Allocate image data space.
 */
	imgsize = (size_t)(imnpix * imnlin * imdpth);

	if  ( ( imgData != (unsigned char *)NULL ) && 
	      ( imgsize <= lastimg.imgsize ) ) {
	    memset ( (unsigned char *)imgData, 0, imgsize );
	}
	else {
	    if  ( imgData != (unsigned char *)NULL ) {
	        free ( imgData );
	    }
	    imgData = (unsigned char *) calloc ( imgsize, 
				     sizeof ( unsigned char ) );
	    if  ( imgData == (unsigned char *)NULL ) {
	        *iret = G_NMEMRY;
	        return;
	    }
        }
/*
 *  Get the image data for the type of image file format.
 */
	switch ( imftyp ) {
	  case IFAREA:  /* Area file */
	    crarea ( imgnam, &ier );
	    break;
		
	  case IFGINI:  /* AWIPS GINI files */
	    crgini ( imgnam, &ier );
	    break;

	  case IFNIDS:  /* NIDS radar files */
          case IFHINIDS: /*Higher Resolution NIDS radar files*/
            crnids (imgnam, &ier );
            break;
	   
	  case IFNOWR:  /* WSI NOWRAD radar files */
	    crnowr ( imgnam, &ier );
	    break;
	    
	  case IFNCDF:  /* NetCDF files */
	    crncdf ( imgnam, &ier );
	    break;

	  case IFNEXZ:  /* ZLIB NEXRAD files */
	    crnexz ( imgnam, &ier );
	    break;

          case IFNFAX:  /* 6-bit FAX product files */
            crnfax ( dev, imgnam, &ier );
               	break;

	  case IFNEX2:  /* NEXRAD Level2 files */
	    crnex2 ( imgnam, &ier );
	    break;

	  default:  /* Error in format */
	    ier = G_NIMGFMT;
	    break;
	}
/*
 *  Check for error.  Set this file as the 'last' one if OK.
 */
	if ( ier != G_NORMAL ) {
	    *iret = ier;
	    return;
	}
	strcpy ( lastimg.filename, imgnam );
	lastimg.imgsize = imgsize;
    }
/*
 *  Check image data range.
 */
    if  ( immxpx == immnpx ) {
        *iret = G_BADPXV;
        return;
    }
/*
 *  Request image area.  Set image scaling.
 */
    imgratio = (double)imghght / (double)imgwdth;
    if  ( ( !G_DIFF(rmxysc, 1.0F) ) && ( rmxysc > MNSCAL ) ) {
	imgratio /= (double)rmxysc;
    }
/*
 *  Compute the plot area.
 */
    plotwdth  = (*xispace1 - *xispace0) + 1; 
    plothght  = (*yispace0 - *yispace1) + 1;
    plotratio = (double)plothght / (double)plotwdth; 
/*
 *  Calculate final image size.
 *  ( ximage0, ximage1, yimage0, yimage1 )
 */
    if  ( plotratio > imgratio ) { 
/*
 *  If the height to width of the space available for the image
 *  is greater than the height to width of the image, width is
 *  the limiting factor, and scale the height to keep the
 *  appropriate aspect ratio.
 */
	ximage0 = *xispace0;
	ximage1 = *xispace1;
/*
 *  Center the image in the plot area.
 */
	newdim    = (unsigned int)((double)plotwdth * imgratio);
	remainder = plothght - newdim;
	yimage0   = G_NINT ( (double)*yispace0 - (double)remainder / 2.0 );
	yimage1   = G_NINT ( (double)*yispace1 + (double)remainder / 2.0 );
    }
    else {
/*
 *  Otherwise, if the height to width of the space available for
 *  the image is less than the height to width of the image,
 *  height is the limiting factor, and scale the width to keep
 *  the appropriate aspect ratio.
 */
	yimage0 = *yispace0;
	yimage1 = *yispace1;
/*
 *  Center the image in the plot area.
 */
        newdim    = (unsigned int)((double)plothght / imgratio);
        remainder = plotwdth - newdim;
        ximage0   = G_NINT ( (double)*xispace0 + (double)remainder / 2.0 );
        ximage1   = G_NINT ( (double)*xispace1 - (double)remainder / 2.0 );
    }
/*
 *  Final image size.
 */
    xwdth = (unsigned int)((ximage1 - ximage0) + 1);
    xhght = (unsigned int)((yimage0 - yimage1) + 1);
/*
 *  Construct the mapping from the image data to the final color
 *  pixel index -- datamap[].
 */
    isGVARRAW = G_FALSE;
    if ( strcmp ( cmstyp, "GVAR" ) == 0 &&
         strcmp ( cmcalb,  "RAW" ) == 0  )  isGVARRAW = G_TRUE;
/*
 * Compute image data range.
 */
    if ( isGVARRAW != G_TRUE ) {
        dbltmp = pow (2.0, (double)(imdpth * 8) );
    }
    else {
/*
 *  Treat GVAR RAW data as 0-255.
 *  (10-bit GVAR count scaled to 8-bit brightness temperature)
 */
        dbltmp = pow(2.0, 8.0);
    }
    drange = (int)dbltmp;
    ncolors = *inum;
    ratio   = (double)(ncolors - 1) / (double)(immxpx - immnpx);
/*
 *  Compute offset for data mapping.
 */
    doffset =  (double)immnpx * ratio - 0.5;

    if  ( imdpth < 2 ||  isGVARRAW == G_TRUE ) {
/*
 *  One byte data.
 */
	for ( ii = 0; ii < drange; ii++ ) {
	    if  ( ii < immnpx )
		datamap[ii] = 0;
	    else if  ( ii > immxpx )
		datamap[ii] = *ist + ncolors - 1;
	    else {
	        if ( ! isGVARRAW == G_TRUE)
		    indx = (int)((double)ii * ratio - doffset);
	        else
		    indx = (int)((double)(ii*(ncolors-1)) / (double)drange - doffset);
	        datamap[ii] = *ist + indx;
	    }
	}
    }
/*
 *  Fill the column translation array with incremental indices
 *  into the original image columns with respect to the previous
 *  column.  Off-image values are set to -1.
 */
    G_MALLOC(coltrans, int, xwdth, "coltrans");
    sf_wdth = (double)(imgwdth - 1) / (double)(xwdth - 1);
    for ( col = 0; col < xwdth; col++ ) {
	coltrans[col] = (imleft - 1) + (int)(sf_wdth * (double)col + 0.5);
	if ( coltrans[col] < 0 || coltrans[col] >= imnpix ) {
	    coltrans[col] = -1;
	}
	else if ( col != 0 && coltrans[col-1] != -1 ) {
	    coltrans[col] -= (imleft - 1) +
				(int)(sf_wdth*(double)(col-1) + 0.5);
	}
    }
/*
 *  Fill the row translation array with indices into the
 *  original image rows.  Set off-image values to -1.
 */
    G_MALLOC(rowtrans, int, xhght, "rowtrans");
    sf_hght = (double)(imghght - 1) / (double)(xhght -1);
    for ( row = 0; row < xhght; row++ ) {
	rowtrans[row] = (imtop - 1) + (int)(sf_hght * (double)row + 0.5);
	if  ( rowtrans[row] < 0  || rowtrans[row] >= imnlin ) {
	    rowtrans[row] = -1;
	}
    }
/*
 *  Construct the final image for display.
 */
    *iret = G_NORMAL;
    element_size = imdpth;
    linesize = (unsigned int)(imnpix * element_size); 
/*
 *  Allocate memory for one row/line of pixel data.
 */
    G_MALLOC(pix, unsigned int, xwdth, "pix");
    if ( imdpth == 2 && isGVARRAW == G_TRUE ) {
	G_MALLOC(tmpk, float, xwdth, "tmpk");
	G_MALLOC(fpix, float, xwdth, "fpix");
        }
Exemple #8
0
void vfwsaw ( int *iret )
/************************************************************************
 * vfwsaw                                                               *
 *                                                                      *
 * This program opens, creates and closes the Weather Watch SAW text    *
 * product file.							*
 *                                                                      *
 * vfwsaw ( iret )                                             		*
 *                                                                      *
 * Input parameters:                                                    *
 *                                                                      *
 * Output parameters:                                                   *
 *      *iret            int            Return Code                     *
 *                                                                      *
 **                                                                     *
 * Log:                                                                 *
 * A. Hardy/GSC          8/99   Created                                 *
 * M. Li/GSC		10/99	Modified output format			*
 * A. Hardy/GSC         11/99   Added replacement watch information     *
 * A. Hardy/GSC		 2/00   Extracted from SPCTXT                   *
 * A. Hardy/GSC		 3/00   Add check for listing replacement states*
 * A. Hardy/GSC		 5/00   Changed cfl_aopn to cfl_wopn; Use       *
 *				AWIPS/WMO header ids.; removed 'NNNN'	*
 * A. Hardy/GSC		10/00   Added ck for '0' dist. anchor/vor points*
 * A. Hardy/GSC		12/00   Removed '&' from iret			*
 * A. Hardy/SAIC	10/01   Added check for old/new WMO header flag *
 * R. Tian/SAIC		06/02	Modified to meet the SPC requirement	*
 * R. Tian/SAIC		04/03	Corrected if(iret == 0) syntax error	*
 * A. Hardy/NCEP	 6/03	Change hail size to string for decimals *
 * A. Hardy/NCEP	10/03	Modified to use utl/wbc libraries and   *
 * 				added 'TEST' if a test watch		*
 * A. Hardy/NCEP	 3/04	Added wbc_mzrm				*
 * G. Grosshans/SPC	10/04	Added ADD_WATCH_APPROX check		*
 * G. Grosshans/SPC	11/05	Added LATLON_SAW_FORMAT tag to turn     *
 *				off lat-lon info at bottom of product.	*
 * S. Jacobs/NCEP	11/05	Fixed array indices for ilat and ilon	*
 * T. Piper/SAIC	12/05	Updated for cst_wrap CSC		*
 * J. Wu/SAIC		04/06	Added parameter in cst_wrap 		*
 ***********************************************************************/
{
    FILE    *ifpsaw;
    char    blank[2]={' '}, ifname[256], wtch_type[20];
    char    cname1[32], cname2[32], sep[5], cpstates[256], states[256];
    char    newname[132], tmpsaw[500], hwmstr[500];
    char    prefs_tag[] = "LATLON_SAW_FORMAT";
    float   xx, yy;
    int     ii, jj, ier, len, ilat[4], ilon[4];
    Boolean useln;
/*-------------------------------------------------------------------*/
    ier = 0;

   /*
    *  Create output file for appending.
    */

    utl_gname ( spcinfo.ancrpt.stn1, spcinfo.ancrpt.stnnam1, 
		spcinfo.ancrpt.stateid1, &ier );
    utl_gname ( spcinfo.ancrpt.stn2, spcinfo.ancrpt.stnnam2, 
		spcinfo.ancrpt.stateid2, &ier );

    sprintf ( ifname, "WW%04d.SAW", spcinfo.wnum );
    ifpsaw = cfl_wopn ( ifname, &ier );

   /*
    * Set up header information.
    */
    if ( strcmp(spcinfo.wtype,"SEVERE THUNDERSTORM" ) == 0 ) 
                strcpy ( wtch_type, "SEVERE TSTM");
    if ( strcmp(spcinfo.wtype,"TORNADO" ) == 0 ) 
                strcpy ( wtch_type, "TORNADO");

    spcinfo.sssnum = spcinfo.wnum % 10;
    fprintf ( ifpsaw, "WWUS30 KWNS %02d%s\n", 
                      spcinfo.itime.day,spcinfo.itime.hour);
    fprintf ( ifpsaw, "SAW%d \n", spcinfo.sssnum);
    fprintf ( ifpsaw, "%cSPC AWW %02d%s\n", CHRS, 
                      spcinfo.itime.day,spcinfo.itime.hour);

   /*
    * Replace underscores in the county names with a space.
    */

    cst_rnan (  spcinfo.ancrpt.stnnam1, cname1, &ier );
    cst_rnan (  spcinfo.ancrpt.stnnam2, cname2, &ier );

   /*
    * Check if watch has been issued as a 'TEST'.
    */ 

    if ( strcmp (spcinfo.status, "TEST") == 0 ) {
        fprintf ( ifpsaw, "WW %d TEST ", spcinfo.wnum); 
    }
    else {
        fprintf ( ifpsaw, "WW %d ", spcinfo.wnum); 
    }

   /*
    * Check for the marine zones which aren't the Great Lakes or
    * coastal water (CW). Remove them, if found.
    */

    strcpy (cpstates, spcinfo.states);
    wbc_mzrm ( cpstates, states, &len, &ier );

   /*
    * Set up rest of section.
    */

    fprintf ( ifpsaw, "%s %s %02d%sZ - %02d%sZ\n",
              wtch_type, states, spcinfo.vtime.day, 
	      spcinfo.vtime.hour, spcinfo.etime.day, spcinfo.etime.hour );
    fprintf ( ifpsaw, "AXIS..%d STATUTE MILES %s OF LINE..\n",
              spcinfo.ancatt.dist, spcinfo.ancatt.dirc );

   /*
    *  Check for zero distance for anchor points.
    */
    if ( (spcinfo.ancrpt.dist1 != 0 ) && ( spcinfo.ancrpt.dist2 != 0 ) ) {
        fprintf ( ifpsaw, "%d%s %s/%s %s/ - %d%s %s/%s %s/\n",
                  spcinfo.ancrpt.dist1, spcinfo.ancrpt.dirct1, spcinfo.ancrpt.stn1,
                  cname1, spcinfo.ancrpt.stateid1,
                  spcinfo.ancrpt.dist2, spcinfo.ancrpt.dirct2, spcinfo.ancrpt.stn2,
                  cname2, spcinfo.ancrpt.stateid2);
    }
    else if  ( ( spcinfo.ancrpt.dist1 == 0 ) && ( spcinfo.ancrpt.dist2 != 0 ) ) {
        fprintf ( ifpsaw, "%s/%s %s/ - %d%s %s/%s %s/\n",
                  spcinfo.ancrpt.stn1, cname1, spcinfo.ancrpt.stateid1,
                  spcinfo.ancrpt.dist2, spcinfo.ancrpt.dirct2, spcinfo.ancrpt.stn2,
                  cname2, spcinfo.ancrpt.stateid2);
    }
    else if  ( ( spcinfo.ancrpt.dist1 != 0 ) && ( spcinfo.ancrpt.dist2 == 0 ) ) {
        fprintf ( ifpsaw, "%d%s %s/%s %s/ - %s/%s %s/\n",
                  spcinfo.ancrpt.dist1, spcinfo.ancrpt.dirct1, spcinfo.ancrpt.stn1,
                  cname1, spcinfo.ancrpt.stateid1, spcinfo.ancrpt.stn2,
                  cname2, spcinfo.ancrpt.stateid2);
    }
    else if  ( ( spcinfo.ancrpt.dist1 == 0 ) && ( spcinfo.ancrpt.dist2 == 0 ) ) {
        fprintf ( ifpsaw, "%s/%s %s/ - %s/%s %s/\n",
                  spcinfo.ancrpt.stn1, cname1, spcinfo.ancrpt.stateid1, 
		  spcinfo.ancrpt.stn2, cname2, spcinfo.ancrpt.stateid2);
    }
   /*
    * Check for zero distance for the vor points.
    */
    if ( (spcinfo.vorrpt.dist1 != 0 ) && ( spcinfo.vorrpt.dist2 != 0 ) ) {
        fprintf ( ifpsaw, "..AVIATION COORDS.. %dNM %s /%d%s %s - %d%s %s/\n",
                  spcinfo.voratt.dist, spcinfo.voratt.dirc,
                  spcinfo.vorrpt.dist1, spcinfo.vorrpt.dirct1, spcinfo.vorrpt.stn1,
                  spcinfo.vorrpt.dist2, spcinfo.vorrpt.dirct2, spcinfo.vorrpt.stn2);
    }
    else if ( (spcinfo.vorrpt.dist1 == 0 ) && ( spcinfo.vorrpt.dist2 != 0 ) ) {
        fprintf ( ifpsaw, "..AVIATION COORDS.. %dNM %s /%s - %d%s %s/\n",
                  spcinfo.voratt.dist, spcinfo.voratt.dirc, spcinfo.vorrpt.stn1, 
		  spcinfo.vorrpt.dist2, spcinfo.vorrpt.dirct2, spcinfo.vorrpt.stn2);
    }
    else if ( (spcinfo.vorrpt.dist1 != 0 ) && ( spcinfo.vorrpt.dist2 == 0 ) ) {
        fprintf ( ifpsaw, "..AVIATION COORDS.. %dNM %s /%d%s %s - %s/\n",
                  spcinfo.voratt.dist, spcinfo.voratt.dirc, spcinfo.vorrpt.dist1, 
		  spcinfo.vorrpt.dirct1, spcinfo.vorrpt.stn1, spcinfo.vorrpt.stn2);
    }
    else if ( (spcinfo.vorrpt.dist1 == 0 ) && ( spcinfo.vorrpt.dist2 == 0 ) ) {
        fprintf ( ifpsaw, "..AVIATION COORDS.. %dNM %s /%s - %s/\n",
                  spcinfo.voratt.dist, spcinfo.voratt.dirc, 
		  spcinfo.vorrpt.stn1, spcinfo.vorrpt.stn2);
    }

   /*
    * Set up hail, wind gusts and lightning section.
    */

    tmpsaw[0] = '\0';
    cst_ncpy ( sep, "TO", 2, &ier );
    len = sizeof(hwmstr);
    wbc_dhwm ( sep, &(spcinfo.hailsz), &(spcinfo.maxgust), 
                &(spcinfo.maxtops), &(spcinfo.motion.deg), 
		&(spcinfo.motion.speed), len, hwmstr, &ier );
    tmpsaw[0] = '\0';
    strcat ( tmpsaw, hwmstr);
    strcat ( tmpsaw, EOL );
    cst_wrap ( tmpsaw, blank, &len, EOL, (char *)NULL, tmpsaw, &ier );
    fprintf ( ifpsaw, tmpsaw);

   /*
    *  If there are replacement watches listed, retrieve the lists of states
    *  for each replacement watch.
    */

    if ( strcmp ( spcinfo.replcnm[0], "NONE") != 0 ) {
	strcpy ( newname, "ww");
	strcat ( newname, spcinfo.replcnm[0] );
	strcat ( newname, ".txt" );
	strcpy ( newinfo.file_info.filnam,newname);
	vfrptxt (newname, iret); 
	if ( *iret == 0 ){
            wbc_mzrm ( newinfo.states, states, &len, &ier );
            fprintf ( ifpsaw, "\nREPLACES WW %d..%s \n",
	          atoi(spcinfo.replcnm[0]), states);
	}
	else {
	    fprintf ( ifpsaw, "         WW %d.. \n", 
	              atoi (spcinfo.replcnm[0]) );
        }
   /*
    *  If there are more that 1 replacement watches listed,
    *  proceed with the loop.
    */
        for(jj = 1; jj <= spcinfo.wwrepnm; jj++) {
	    strcpy ( newname, "ww");
	    strcat ( newname, spcinfo.replcnm[jj] );
	    strcat ( newname, ".txt" );
	    strcpy ( newinfo.file_info.filnam,newname);
  	    vfrptxt (newname, iret); 
	    if ( *iret == 0 ){
            wbc_mzrm ( newinfo.states, states, &len, &ier );
	    fprintf ( ifpsaw, "REPLACES WW %d..%s \n", 
	              atoi (spcinfo.replcnm[jj]), states);
	    }
	    else {
	      fprintf ( ifpsaw, "         WW %d.. \n", 
	              atoi (spcinfo.replcnm[jj]) );
	    }
        }
	fprintf ( ifpsaw, "\n");
    }
    else {
	    fprintf ( ifpsaw, "\n");
    }

    /*
     * Check if the LATLON_SAW_FORMAT flag is TRUE and then
     * add enhanced lat-lon data to the SAW text.
     * Make sure lats and lons are rounded to 
     * 100ths of deg.
     */

    tmpsaw[0] = '\0';
    ctb_pfbool (prefs_tag, &useln, &ier );
    if ( useln == TRUE ) {
	for ( ii = 0 ; ii < 4 ; ii++ ) {
            switch ( ii ) {
                case 0:
                    xx = ((int)(spcinfo.wcpnt1.lat*100.0F)) / 100.0F;
                    yy = ((int)(spcinfo.wcpnt1.lon*-100.0F)) / 100.0F;
                    break;
                case 1:
                    xx = ((int)(spcinfo.wcpnt2.lat*100.0F)) / 100.0F;
                    yy = ((int)(spcinfo.wcpnt2.lon*-100.0F)) / 100.0F;
                    break;
                case 2:
                    xx = ((int)(spcinfo.wcpnt3.lat*100.0F)) / 100.0F;
                    yy = ((int)(spcinfo.wcpnt3.lon*-100.0F)) / 100.0F;
                    break;
                case 3:
                    xx = ((int)(spcinfo.wcpnt4.lat*100.0F)) / 100.0F;
                    yy = ((int)(spcinfo.wcpnt4.lon*-100.0F)) / 100.0F;
                    break;
		default:
                    break;
            } 
            if ( yy >= 100.0F )  yy = yy - 100.0F;
            ilat[ii] = G_NINT(xx*100.0F);
	    ilon[ii] = G_NINT(yy*100.0F);
        }
        fprintf ( ifpsaw, "LAT...LON %4d%04d %4d%04d %4d%04d %4d%04d\n\n",
            ilat[0], ilon[0],
            ilat[1], ilon[1],
            ilat[2], ilon[2],
            ilat[3], ilon[3]);
    }

    /*
     * Check if the approximation verbage needs to be included
     * in the SAW text.
     */
    tmpsaw[0] = '\0';
    strcpy (prefs_tag, "ADD_WATCH_APPROX");
    ctb_pfbool (prefs_tag, &useln, &ier );

    if ( useln == TRUE ) {
       tmpsaw[0] = '\0';
       fprintf(ifpsaw, "THIS IS AN APPROXIMATION TO THE WATCH AREA.  FOR A\n");
       fprintf(ifpsaw, "COMPLETE DEPICTION OF THE WATCH SEE WOUS64 KWNS\n");
       fprintf(ifpsaw, "FOR WOU%d.\n", spcinfo.sssnum);
       fprintf(ifpsaw, "\n");
    }


   /*
    *  Close output file.
    */

    cfl_clos ( ifpsaw, &ier );
}
Exemple #9
0
int main ( int argc, char **argv )
/************************************************************************
 * mdp									*
 *                                                                      *
 * This program generates the mesoscale discussion latlon pairings.	*
 * Pairings will be written to a file whose filename is based on the	*
 * input filename (filename extension, if exists, is replaced w/ "mdp").*
 *                                                                      *
 * Example:								*
 * mdp input_vgf_file.vgf						*
 * Produces latlon pairings in the ASCII file				*
 * output_vgf_file.mdp							*
 *                                                                      *
 * main(argc, argv)                                                     *
 *                                                                      *
 * Input parameters:                                                    *
 *  argc   int      number of parameters of command line                *
 *  argv   char**   parameter array of command line                     *
 *                                                                      *
 * Output parameters:                                                   *
 * Return parameters:                                                   *
 *                      NONE                                            *
 *                                                                      *
 **                                                                     *
 * Log:                                                                 *
 * D.W.Plummer/NCEP	 6/02						*
 * D.W.Plummer/NCEP	 8/02	Bug fix for lons > 99.995 and < 100.0	*
 * m.gamazaychikov/SAIC  3/03	Made mdp work only on scallop lines	*
 *				added WFOs and STATES to output text	*
 * m.gamazaychikov/SAIC  3/03	Made mdp work on lines grouped or not 	*
 *				grouped with WFOs and/or STATES		*
 *				Made MDP exit upon encountering first	*
 *				scallop line in VGF file		*
 * 				Made changes to format of output text	*
 * T. Piper/SAIC	12/05	Updated cst_wrap for CSC		*
 * J. Wu/SAIC		04/06	Added parameter in cst_wrap 		*
 ***********************************************************************/
{
int    	ii, ix, iy, pagflg, ier;
int	ilen, npts;
char	vg_class, vg_type;
char    blank[2]={' '}, errgrp[8], infile[128], ifname[128], outfile[128];
float	x, y;
long	ifilesize;
int	ne1, more1, curpos1;
char	buffer[1024], str[20], *cptr;

int     wrtoutfg, wrtwfofg, wrtsttfg;
int     grpnumbr1, grpnumbr2;
int     lintyp, jj, narea, areatype;
int	ne2, more2, curpos2;
char    strwfo[480], strstt[480], bufferlat[1024];

VG_DBStruct     el;

FILE    *ifptr, *ofptr;
/*---------------------------------------------------------------------*/

    /*
     *  Check if number of input arguments is correct.
     */
    if ( argc < 2 )  {
	pagflg = G_FALSE;
	strcpy ( errgrp, "MDP" );
        ip_help ( errgrp, &pagflg, &ier,
                  strlen(errgrp) );
	exit (0);
    }

    /*
     *  First input on command line is input vgf file name.
     */
    strcpy ( infile, argv[1] );
    cfl_inqr ( infile, NULL, &ifilesize, ifname, &ier );
    ifptr = (FILE *) cfl_ropn(ifname, "", &ier);
    if ( ier != 0 )  {
	printf("Error opening VGF file %s\n", infile );
	exit (0);
    }

    /*
     *  Output filename is input filename w/ "mdp" filename extension.
     */
    strcpy ( outfile, infile );
    cptr = strrchr( outfile, '.' );
    if ( cptr != (char *)NULL )  {
	cptr[0] = '\0';
    }
    strcat( outfile, ".mdp" );

    /*
     *  Loop through all the elements until a line is found.
     */
    ne1 = 0;
    more1 = G_TRUE;
    curpos1 = 0;
    buffer[0] = '\0';
    bufferlat[0] = '\0';
    while ( ne1 < MAX_EDITABLE_ELEMS && more1 == G_TRUE )  {

        wrtoutfg = G_FALSE;
        wrtsttfg = G_FALSE;
        wrtwfofg = G_FALSE;

	cvg_rdrecnoc( ifname, ifptr, curpos1, &el, &ier );

	if ( ier < 0 )  {
	    more1 = G_FALSE;
	}
	else  {


	    curpos1 += el.hdr.recsz;
	    vg_class = el.hdr.vg_class;
	    vg_type  = el.hdr.vg_type;
	    grpnumbr1 = el.hdr.grpnum;

            if ( (int)vg_class == CLASS_LINES )  {
               /*
                *  Open output file.
                */
                ofptr = (FILE *)cfl_wopn ( outfile, &ier );
                if ( ier != 0 )  {
                    printf("Error opening/creating output file %s\n", outfile );
                    exit (0);
                }
                if ((int)vg_type == SPLN_ELM ) {
                   /*
                    * type of special line
                    */
                    lintyp   = el.elem.spl.info.spltyp;
                    if (lintyp == 3 ) {
                       /*
                        * number of points in a line
                        */
		        npts    = el.elem.spl.info.numpts;
		       /*
		        *  Format lats and lons into buffer.
		        */
		        for ( ii = 0; ii < npts; ii++ )  {
		            x = el.elem.spl.latlon[ii];
		            y = -el.elem.spl.latlon[ii+npts];
		           /*
		            *  Make sure lats and lons are rounded to 100ths of deg.
		            */
		            x = ((int)(x*100)) / 100.0F;
		            y = ((int)(y*100)) / 100.0F;
		            if ( y >= 100.0F )  y -= 100.0F;
		            ix = G_NINT(x*100.0F);
		            iy = G_NINT(y*100.0F);

	         	    sprintf( str, "%04d%04d ", ix, iy );
		            strcat ( bufferlat, str );
                            /*
                             * this flag is here to ensure exit as soon
                             * as a line is found
                             */
	                     more1 = G_FALSE;
                            /*
                             * this flag is here to ensure that lat-lon
                             * pairs are written out even without wfo and states 
                             * grouped with it
                             */
                             wrtoutfg = G_TRUE;
                             
		        }

                        ne2 = 0;
                        curpos2 = 0;
	                more2 = G_TRUE;
                        while ( ne2 < MAX_EDITABLE_ELEMS && more2 == G_TRUE )  {
                           cvg_rdrecnoc( ifname, ifptr, curpos2, &el, &ier );
                         if ( ier < 0 )  {
	                  more2 = G_FALSE;
                         }
	                 else  {
                           curpos2 += el.hdr.recsz;
                           vg_class = el.hdr.vg_class;
                           vg_type  = el.hdr.vg_type;
	                   grpnumbr2 = el.hdr.grpnum;
                           if (grpnumbr2 == grpnumbr1 && grpnumbr2 != 0) {
                            if ((int)vg_type == LIST_ELM ) {
                              areatype = 0;
                              areatype = el.elem.lst.info.subtyp;
                              if (areatype == 3) {
                                 wrtwfofg = G_TRUE;
                                 narea = el.elem.lst.data.nitems;
                                 strwfo[0] = '\0';
                                 strcat( strwfo, "ATTN...WFO...");
                                 jj = 0;
                                 for (jj = 0; jj < narea; jj++) {
                                   strcpy (str,    el.elem.lst.data.item[jj]);
                                   strcat (strwfo, str);
                                   strcat (strwfo, "..." );
                                   if ((jj+1)%9 == 0) {
                                     strcat (strwfo, "\n");
                                   }
                                 }
                                 strcat (strwfo, "\n");
                              }
                              if (areatype == 4) {
                                 wrtsttfg = G_TRUE;
                                 narea = el.elem.lst.data.nitems;
                                 strstt[0] = '\0';
                                 jj = 0;
                                 for (jj = 0; jj < narea; jj++) {
                                   strcpy (str,    el.elem.lst.data.item[jj]);
                                   strcat (strstt, str);
                                   strcat (strstt, "Z000-" );
                                 }
                                 strcat (strstt, "\n");
                              }
                            }
		           } 
                         }
	                 ne2++;
                        }
		    } 
		} 
            }
        }
	ne1++;
           /*
            *  Write to output file.
            */
        if (wrtoutfg == G_TRUE) {
          /*
           *  Wrap bufferlat such that only 6 pairs of lat,lons on one line
           */
            ilen = 55;
            cst_wrap( bufferlat, blank, &ilen, "\n", (char *)NULL, bufferlat, &ier );

            if (wrtsttfg == G_TRUE) {
              /*
               *  Wrap strstt such that only 7 STATE IDs on one line
               *  and dump strstt into buffer for further output
               */
              ilen = 49;
              cst_wrap( strstt, blank, &ilen, "\n", (char *)NULL, strstt, &ier );
              strcat ( buffer, strstt );
              strcat ( buffer, "\n");
            }
            if (wrtwfofg == G_TRUE) {
              /*
               *  Wrap strwfo such that only 9 WFOs on one line
               *  and dump strswo into buffer for further output
               */
               ilen = 67;
               cst_wrap( strwfo, blank, &ilen, "\n", (char *)NULL, strwfo, &ier );
               strcat ( buffer, strwfo );
               strcat ( buffer, "\n");
            }

            strcat ( buffer, bufferlat);
            strcat ( buffer, "\n");
            cfl_writ( ofptr, (int)strlen(buffer), (unsigned char *)buffer, &ier );
            bufferlat[0] = '\0';
        }
    }
    /*
     *  If no line is found, close files and exit.
     */
    cfl_clos ( ifptr, &ier );
    cfl_clos ( ofptr, &ier );
    return(0);

}
Exemple #10
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 #11
0
void gb2_gdtmerc( float *navblk, int *igdtmpl, int *iret )
/************************************************************************
 * gb2_gdtmerc								*
 *                                                                      *
 * This routine converts a MER Gempak grid navigation block to a        *
 * GRIB2 Grid Definition Template 3.10.					*
 *                                                                      *
 * gb2_gdtmerc ( navblk, igdtmpl, iret )				*
 *									*
 * Input parameters:                                                    *
 *  *navblk   		float       Decoded GRIB2 structure             *
 *									*
 * Output parameters:                                                   *
 *  *igdtmpl            int        GDT 3.10 values 			*
 *  *iret               int        Return code                          *
 *                                    -36 = Projection not MER		*
 **                                                                     *
 * Log:                                                                 *
 * S. Gilbert/NCEP          08/05    Calculations taken from GDS_MER    *
 * S. Gilbert/NCEP          03/06    Chngs to remove compiler warnings  *
 ***********************************************************************/
{

        double     rlat1, rlon1, rlat2, rlon2, dx, dy;
        double     tlat1, tlon1, tlat2, tlon2;
        double     x1, y1, x2, y2, rnx, rny;

        int        ier;
        int        nx, ny;

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

        /*
         *  ensure grid navigation block is MER
         */
        if ( strncmp( (char *)(navblk+1), "MER", 3) != 0 ) {
           *iret=-36;
           ER_WMSG("GB", iret, (char *)(navblk+1), &ier, 2, 4 );
        }

        nx = G_NINT(navblk[4]);
        ny = G_NINT(navblk[5]);
        rlat1 = navblk[6];
        rlon1 = navblk[7];
        rlat2 = navblk[8];
        rlon2 = navblk[9];

        /*
         *  Calculate grid increments
         */
        rnx = navblk[4];
        rny = navblk[5];
        tlat1 = rlat1 * DTR / 2.;
        tlat2 = rlat2 * DTR / 2.;
        if ( rlon2 <  rlon1 ) tlon2 = rlon2 + 360.;
        else tlon2 = rlon2;
        tlon1 = rlon1 * DTR;
        tlon2 = tlon2 * DTR;
        x1 = 0.0;
        y1 = RADIUS * log ( tan ( PI4TH + tlat1 ) );
        x2 = RADIUS * ( tlon2 - tlon1 );
        y2 = RADIUS * log ( tan ( PI4TH + tlat2 ) );
        dx = ( x2 - x1 ) / ( rnx - 1. );
        dy = ( y2 - y1 ) / ( rny - 1. );

        /*
         *  Set Grid Definition Template
         */

        igdtmpl[0] = 1;                       /* Earth Assumed Spherical */
        igdtmpl[1] = 0;                       /* Radius scale factor     */
        igdtmpl[2] = G_NINT(RADIUS);          /* Radius of Earth         */
        igdtmpl[3] = 0;                       /* Oblate info     n/a     */
        igdtmpl[4] = 0;                       /* Oblate info     n/a     */
        igdtmpl[5] = 0;                       /* Oblate info     n/a     */
        igdtmpl[6] = 0;                       /* Oblate info     n/a     */
        igdtmpl[7] = nx;                      /* Kx                      */
        igdtmpl[8] = ny;                      /* Kx                      */
        igdtmpl[9] = G_NINT(rlat1*1000000.0);
                                              /* Lat of 1st grid point   */
        if ( rlon1 < 0.0 ) rlon1 += 360.0;
        igdtmpl[10] = G_NINT(rlon1*1000000.0);   
                                              /* Lon of 1st grid point   */
        igdtmpl[11] = 48;                     /* Res and Comp flags      */
        igdtmpl[12] = 0;                      /* LaD at equator          */

        igdtmpl[13] = G_NINT(rlat2*1000000.0);
                                              /* Lat of last grid point  */
        if ( rlon2 < 0.0 ) rlon2 += 360.0;
        igdtmpl[14] = G_NINT(rlon2*1000000.0);   
                                              /* Lon of last grid point  */
        igdtmpl[15] = 64;                     /* Scanning mode           */
        igdtmpl[16] = 0;                      /* Orientation of grid     */

        igdtmpl[17] = G_NINT(dx*1000.0);      /* Dx                      */
        igdtmpl[18] = G_NINT(dy*1000.0);      /* Dy                      */

}
Exemple #12
0
void msdatt ( int *iunit, char *filnam, int *lenf, int *itype, 
              float *xsize, float *ysize, int *ileft, int *ibot, 
	      int *iright, int *itop, int *iret )
/************************************************************************
 * msdatt								*
 *									*
 * This subroutine is called to initialize the metafile attributes.	*
 *									*
 * msdatt  ( iunit, filnam, lenf, itype, xsize, ysize,			*
 *           ileft, ibot, iright, itop, iret )                          *
 *									*
 * Input parameters:							*
 *	*iunit		int		Output type (Used for XW only)	*
 *	*filnam		char		Output metafile name		*
 *	*lenf		int		Length of file name		*
 *	*itype		int		Device color type		*
 *	*xsize		float		X size in pixels		*
 *	*ysize		float		Y size in pixels		*
 *									*
 * Output parameters:							*
 *      *ileft          int             Left device coordinate          *
 *      *ibot           int             Bottom device coordinate        *
 *      *iright         int             Right device coordinate         *
 *      *itop           int             Top device coordinate           *
 *	*iret		int		Return code			*
 **									*
 * Log:									*
 * S. Jacobs/NCEP	 2/96						*
 * S. Jacobs/NCEP	 5/96	Added new global variables for queries	*
 * S. Jacobs/NCEP	 2/97	Fixed check for same file name		*
 * R. Tian/SAIC          4/02   Added init of ileft, ibot, iright, itop *
 * M. Li/SAIC		 7/02	Added G_NINT				*
 ***********************************************************************/
{
	int	ier;
	char	tmpfil[MAX_FNLEN];
        int     tmpxz, tmpyz;
	long	flen;
	int	nbin;
	FILE	*fp;

/*---------------------------------------------------------------------*/
	*iret = G_NORMAL;

/*
 *	If the input length is greater than the maximum allowed,
 *	return an error.
 */
	if  ( ( *lenf >= MAX_FNLEN ) || ( *lenf <= 0 ) )  {
	    *iret = G_NOMETA;
	    return;
	}

/*
 *	Copy the file name to a temporary variable and add a NULL.
 */
	strncpy ( tmpfil, filnam, (size_t)*lenf );
	tmpfil[*lenf] = CHNULL;

/*
 *	Compare the input file name to the current file name.  If the
 *	names are different, close the old file.  Otherwise, do nothing.
 */
	if  ( strcmp ( curfil, tmpfil ) != 0 )  {
 	    mclose ( &ier );

/*
 *	    Set the current file name.
 */
	    strcpy ( curfil, tmpfil );
	    *iret = G_NEWWIN;

/*
 *	    Set the global output and color scheme types.
 */
    	    kctype = *itype;
	    kunit  = *iunit;

/*
 *          Check for the existence of the metafile.
 */
	    cfl_inqr(curfil, NULL, &flen, tmpfil, &ier);
            if ( ( ier == 0 ) && ( strcmp ( curfil, "Nmeta" ) != 0 ) ) {
/*
 *          	Get frame size from the existing file
 */
		if ( ( fp = cfl_ropn(curfil, NULL, &ier) ) == NULL ) {
            	    *iret = G_NOMETA;
            	    return;
        	}
		
	        cfl_read(fp, sizeof(nc_file_header), (unsigned char *)&meta_head,
		         &nbin, &ier);
        	if ( ier ) {
            	    *iret = G_NOMETA;
		    cfl_clos(fp, &ier);
            	    return;
        	}
		cfl_clos(fp, &ier);

            	if ( meta_head.version == 2 ) {
/*
 *    	            Set the global CGM frame size
 */
        	    fxsize = meta_head.fxsize;
        	    fysize = meta_head.fysize;

/*
 *      	    ileft  = left device coordinate
 *      	    ibot   = bottom device coordinate
 *      	    iright = right device coordinate
 *      	    itop   = top device coordinate
 */
        	    *ileft  = 0;
        	    *ibot   = 0;
        	    *iright = (int)meta_head.fxsize;
        	    *itop   = (int)meta_head.fysize;
		}

            } else {
/*
 *              The valid range of xsize and ysize is 0.1 ~ 1.0.  If neither
 *              value is 1.0, then set the larger value to be 1.0, and set the
 *              smaller value to be the ratio of the smaller to the larger.
 */
        	tmpxz = G_NINT(*xsize * (float)XY_SCALE);
        	tmpyz = G_NINT(*ysize * (float)XY_SCALE);
        	tmpxz = (tmpxz < 0 || tmpxz > XY_SCALE) ? XY_SCALE : tmpxz;
        	tmpyz = (tmpyz < 0 || tmpyz > XY_SCALE) ? XY_SCALE : tmpyz;
        	if(tmpxz != XY_SCALE && tmpyz != XY_SCALE) {
            	    if(tmpxz > tmpyz) {
                    	tmpyz = G_NINT((((float)tmpyz)/(float)tmpxz)*(float)XY_SCALE);
                    	tmpxz = XY_SCALE;
            	    } else if(tmpxz < tmpyz) {
                    	tmpxz = G_NINT((((float)tmpxz)/(float)tmpyz)*(float)XY_SCALE);
                    	tmpyz = XY_SCALE;
            	    } else {
                    	tmpxz = XY_SCALE;
                    	tmpyz = XY_SCALE;
            	    }
        	}
        	tmpxz = (tmpxz < G_NINT(0.1F*(float)XY_SCALE)) ? G_NINT(0.1F*(float)XY_SCALE) 
						      : tmpxz;
        	tmpyz = (tmpyz < G_NINT(0.1F*(float)XY_SCALE)) ? G_NINT(0.1F*(float)XY_SCALE) 
						      : tmpyz;

/*
 *    	        Set the global CGM frame size
 */
        	fxsize = (unsigned short)tmpxz;
        	fysize = (unsigned short)tmpyz;;

/*
 *      	ileft  = left device coordinate
 *      	ibot   = bottom device coordinate
 *      	iright = right device coordinate
 *      	itop   = top device coordinate
 */
        	*ileft  = 0;
        	*ibot   = 0;
        	*iright = tmpxz;
        	*itop   = tmpyz;
	    }
	}
}
Exemple #13
0
int main ( int argc, char **argv )
/************************************************************************
 * mdp									*
 *                                                                      *
 * This program generates the mesoscale discussion latlon pairings.	*
 * Pairings will be written to a file whose filename is based on the	*
 * input filename (filename extension, if exists, is replaced w/ "mdp").*
 *                                                                      *
 * Example:								*
 * mdp input_vgf_file.vgf						*
 * Produces latlon pairings in the ASCII file				*
 * output_vgf_file.mdp							*
 *                                                                      *
 * main(argc, argv)                                                     *
 *                                                                      *
 * Input parameters:                                                    *
 *  argc   int      number of parameters of command line                *
 *  argv   char**   parameter array of command line                     *
 *                                                                      *
 * Output parameters:                                                   *
 * Return parameters:                                                   *
 *                      NONE                                            *
 *                                                                      *
 **                                                                     *
 * Log:                                                                 *
 * D.W.Plummer/NCEP	 6/02						*
 * D.W.Plummer/NCEP	 8/02	Bug fix for lons > 99.995 and < 100.0	*
 * G. Grosshans/SPC	11/02	Updated to decode multi-scalloped lines *
 * G. Grosshans/SPC	12/02	Updated to compute WFO/State		*
 * S. Jacobs/NCEP	 5/03	Clean up unused variables and headers	*
 * G. Grosshans/SPC     10/03   Updated for precision                   *
 * T. Piper/SAIC	12/05	Updated cst_wrap for CSC		*
 * J. Wu/SAIC		04/06	Added parameter in cst_wrap 		*
 * G. Grosshans/SPC	08/08	Updated for SCN 08-45 to add LAT...LON  *
 * 				and list first point as last point      *
 * 				to indicate a closed polygon.  Add      *
 *				word wrapping for ATTN...WFO...		*
 ***********************************************************************/
{
int		ii, ix, iy, ixfirst, iyfirst, pagflg, ne, ilen,
	        npts, ier, iret, nitems, more, curpos;

long		ifilesize;

float		x, y, flat[MAXLISTITEMS], flon[MAXLISTITEMS];

char		vg_class, vg_type, buffer[2048], bufferfinal[2048],
		bufferfinalwfo[2048],str[20], *cptr, errgrp[12], infile[128],
		ifname[128], outfile[128], info[2048], stpo[4],
		cstl_list[1000], cstl_liststate[1000],
		newLineStr[13]="            "; /* 13 spaces */

char		blank[2]={' '}, device[13], dfilnam[73], pro[80];
int		mode, istat, iunit, itype;
float		xsize, ysize, lllat, lllon, urlat, urlon,
		prjang1, prjang2, prjang3;

VG_DBStruct	el;

FILE		*ifptr, *ofptr;

const int line_len = 66;

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

    /* 
     * Set defaults for gsdeva and gsmprj
     */
    mode = 1;
    strcpy ( device, "GN" );
    iunit = 1;
    strcpy ( dfilnam, "MDPSPC" );
    itype = 1;
    xsize = 500.0F;
    ysize = 500.0F;
    lllat = 10.0F;
    lllon = -120.0F;
    urlat = 50.0F;
    urlon = -50.0F;
    strcpy ( pro, "str" );
    prjang1 =   90.0F;
    prjang2 = -105.0F;
    prjang3 =    0.0F;
    cstl_list[0] = '\0';
    cstl_liststate[0] = '\0';

    in_bdta ( &ier );
    ginitp ( &mode, &istat, &ier);
    gsdeva (device, &iunit, dfilnam, &itype, &xsize, &ysize, &iret,
	    strlen(device), strlen(dfilnam));
    gsmprj ( pro, &prjang1, &prjang2, &prjang3, 
	     &lllat, &lllon, &urlat, &urlon, &iret, strlen(pro));
    clo_init ( &ier );

    /*
     *  Check if number of input arguments is correct.
     */
    if ( argc < 2 )  {
	pagflg = G_FALSE;
	strcpy ( errgrp, "MDPSPC" );
        ip_help ( errgrp, &pagflg, &ier,
                  strlen(errgrp) );
	gendp (&mode, &ier);
	exit (0);
    }

    /*
     *  First input on command line is input vgf file name.
     */
    strcpy ( infile, argv[1] );
    cfl_inqr ( infile, NULL, &ifilesize, ifname, &ier );
    ifptr = (FILE *) cfl_ropn(ifname, "", &ier);
    if ( ier != 0 )  {
	printf("Error opening VGF file %s\n", infile );
	gendp (&mode, &ier);
	exit (0);
    }

    /*
     *  Output filename is input filename w/ "mdp" filename extension.
     */
    strcpy ( outfile, infile );
    cptr = strrchr( outfile, '.' );
    if ( cptr != (char *)NULL )  {
	cptr[0] = '\0';
    }
    strcat( outfile, ".mdp" );
    
    /*
     *  Loop through all the elements until a line is found.
     */
    ne = 0;
    more = G_TRUE;
    curpos = 0;
    buffer[0] = '\0';
    bufferfinal[0] = '\0';
    bufferfinalwfo[0] = '\0';
    strcat ( buffer, "LAT...LON   " );
    while ( ne < MAX_EDITABLE_ELEMS && more == G_TRUE )  {
	cvg_rdrecnoc( ifname, ifptr, curpos, &el, &ier );

	if ( ier < 0 )  {
	    more = G_FALSE;
	}
	else  {

	    curpos += el.hdr.recsz;

	    vg_class = el.hdr.vg_class;
	    vg_type  = el.hdr.vg_type;

            if ( ( (int)vg_class == CLASS_LINES ) &&
	    	 ( el.hdr.vg_type == SPLN_ELM ) &&
		 ( (int)el.elem.spl.info.spltyp == 3 ) )  {

		/*
		 *  Open output file.
		 */
		ofptr = (FILE *)cfl_wopn ( outfile, &ier );
		if ( ier != 0 )  {
		    printf("Error opening/creating output file %s\n",
		    	    outfile );
	            gendp (&mode, &ier);
		    exit (0);
    		}

	       /*
		* Find FIPS bounded by the closed line
		*/

		npts = el.elem.spl.info.numpts;

		/*  FIND WHAT STATES ARE IN MD AREA */

		clo_binpoly ( "CNTY_BNDS", npts, el.elem.spl.latlon,
                              &(el.elem.spl.latlon[npts]), &ier );
		clo_tgltln ( "CNTY_BNDS", MAXLISTITEMS, &nitems,
			      flat, flon, &ier);

		for ( ii = 0; ii < nitems; ii++ )  {
		  clo_bginfo( "CNTY_BNDS", ii, info, &ier );
		  cst_gtag( "STATE", info, "?", stpo, &ier);
		  
		  if (strstr(cstl_liststate, stpo)==NULL) {
		    strcat(cstl_liststate, stpo);
		    strcat(cstl_liststate, " ");		  
		  }
		}


		/*  FIND WHAT WFOs ARE IN MD AREA */
		clo_binpoly ( "CWA_BNDS", npts, el.elem.spl.latlon,
                              &(el.elem.spl.latlon[el.elem.spl.info.numpts]),
			      &ier );
		clo_tgltln ( "CWA_BNDS", MAXLISTITEMS, &nitems,
			      flat, flon, &ier);

		for ( ii = 0; ii < nitems; ii++ )  {
		  clo_bginfo( "CWA_BNDS", ii, info, &ier );
		  cst_gtag( "WFO", info, "?", stpo, &ier);
		  strcat(cstl_list, stpo);
		  strcat(cstl_list, "...");		  
		}

		/*
		 *  Format lats and lons into buffer.
		 */
		if ( (int)vg_type == LINE_ELM )  {
		    npts = el.elem.lin.info.numpts;
		}
		else if ( (int)vg_type == SPLN_ELM )  {
		    npts = el.elem.spl.info.numpts;
		}
		for ( ii = 0; ii < npts; ii++ )  {
		    if ( (int)vg_type == LINE_ELM )  {
		        x = el.elem.lin.latlon[ii];
		        y = -el.elem.lin.latlon[ii+npts];
		    }
		    else if ( (int)vg_type == SPLN_ELM )  {
		        x = el.elem.spl.latlon[ii];
		        y = -el.elem.spl.latlon[ii+npts];
		    }
		    /*
		     * Make sure lats and lons are rounded
		     * to 100ths of deg.
		     */
		    x = ((int)(x*100.0F)) / 100.0F;
		    y = ((int)(y*100.0F)) / 100.0F;
		    if ( y >= 100.0F )  y -= 100.0F;
		    ix = G_NINT(x*100.0F);
		    iy = G_NINT(y*100.0F);
		    sprintf( str, "%04d%04d ", ix, iy );
		    strcat ( buffer, str );
		    if ( ii == 0 ) {
                        ixfirst = ix;
			iyfirst = iy;
                    }
		}
		/*
		 *   Repeat first lat/lon point as last lat/lon point 
		 *   to indicate a closed polygon.
		 */


		sprintf( str, "%04d%04d ", ixfirst, iyfirst);
		strcat ( buffer, str );

		sprintf( str, "\n\n" );
		strcat ( buffer, str );

		/*
		 *  Wrap buffer such that only 6 pairs of lat,lons 
		 *  on one line.
		 *  ilen = 55;
		 *  cst_wrap( buffer, blank, &ilen, "\n", (char *)NULL, buffer, &ier );
		 */
		ilen = 66;
		cst_wrap( buffer, blank, &ilen, "\n", newLineStr, buffer, &ier );

	    }

	}
	ne++;
    }

    /*
     * wrap the ATTN...WFO... line
     */
    strcat ( bufferfinalwfo, "ATTN...WFO..." );
    strcat ( bufferfinalwfo, cstl_list );
    cst_wrap( bufferfinalwfo, "...", &line_len, "\n", (char *)NULL, bufferfinalwfo, &ier );

    /*
     * build the output file string and add the ATTN...WFO... string
     */
    strcat ( bufferfinal,"STATES=" );
    strcat ( bufferfinal, cstl_liststate );
    strcat ( bufferfinal, "\n\n" );
    strcat ( bufferfinal, bufferfinalwfo );
/*
    strcat ( bufferfinal,"ATTN...WFO..." );
    strcat ( bufferfinal, cstl_list );
*/
    strcat ( bufferfinal, "\n\n" );
    strcat ( bufferfinal, buffer );

    /*
     *  Write to output file.
     */
    cfl_writ ( ofptr, (int)strlen(bufferfinal),
    	       (unsigned char *)bufferfinal, &ier );

    /*
     *  close files and exit.
     */
    cfl_clos ( ifptr, &ier );
    cfl_clos ( ofptr, &ier );
    gendp (&mode, &ier);
    return(0);

}
Exemple #14
0
void df_hilo  ( const int *hi, const int *lo, int *iret )
/************************************************************************
 * df_hilo								*
 *									*
 * This subroutine finds the relative extrema over a grid.		*
 *									*
 * df_hilo ( hi, lo, iret )						*
 *									*
 * Input parameters:							*
 *	*hi		const int	Flag for finding highs		*
 *	*lo		const int	Flag for finding lows		*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * K. Brill/NMC          5/93   					*
 * D. Keiser/GSC	 7/95	Changed DC_HILO to DG_HILO		*
 * D. Keiser/GSC	10/95	Add call to write error message after 	*
 *				call to DG_HILO				*
 * T. Lee/GSC		 4/96   Single dimension for dgg		*
 * K. Tyle/GSC           5/96   Moved IGDPT outside do-loop             *
 * T. Piper/GSC		11/98	Updated prolog				*
 * 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			*
 ************************************************************************/
{
    int num1, num2, no, nx, kxd, kyd, kxyd, ksub1, ksub2;
    int krad, nmax, nmin, ixmx, iymx, ivmx, ixmn, iymn, ivmn, intflg,
        nummx, nummn, ii, i, j, nxi,nxj, nxv, index, ier, ier2, izero;
    float *gnum1, *gnum2, *gno, *gnx, fzero;
    char namout[5];
/*----------------------------------------------------------------------*/
    *iret = 0;
    izero = 0;
    fzero = 0.0;

    dg_ssub ( iret );
    strcpy ( namout, "HILO" );

    /*
     * Get the grid to be searched from the stack.
     */
    dg_gets ( &num1, iret );
    if ( *iret != 0 ) return;
    dg_getg ( &num1, &gnum1, &kxd, &kyd, &ksub1, &ksub2, iret );

    /*
     * Get the radius value.
     */
    dg_gets ( &num2, iret );
    if ( *iret != 0 ) return;
    dg_getg ( &num2, &gnum2, &kxd, &kyd, &ksub1, &ksub2, iret );
    krad = G_NINT ( gnum2[0] );

    /*
     * Get a new grid number for the output highs and lows.
     */
    dg_nxts ( &no, iret );
    if ( *iret != 0 ) return;
    dg_getg ( &no, &gno, &kxd, &kyd, &ksub1, &ksub2, iret );

    kxyd = kxd * kyd;
    nmax = kxyd / 6;
    nmin = nmax;

    /*
     * Store the HILO information in the NX grid.
     */
    dg_nxts ( &nx, iret );
    if ( *iret != 0 ) return;
    dg_getg ( &nx, &gnx, &kxd, &kyd, &ksub1, &ksub2, iret );

    ixmx = 1;
    iymx = 1 + nmax;
    ivmx = iymx + nmax;
    ixmn = ivmx + nmin;
    iymn = ixmn + nmin;
    ivmn = iymn + nmin;
    if ( *hi == G_FALSE ) nmax = 0;
    if ( *lo == G_FALSE ) nmin = 0;

    intflg = G_FALSE;
    dg_hilo ( gnum1, &kxd, &kyd, &krad, &intflg, &nmax, &nmin, 
        &fzero, &fzero, &fzero, &fzero,
	&nummx, &gnx[ixmx-1], &gnx[iymx-1], &gnx[ivmx-1],
	&nummn, &gnx[ixmn-1], &gnx[iymn-1], &gnx[ivmn-1], iret );
    if ( *iret < 0 )  return;

    /*
     * Write out error message regarding internal buffers in DG_HILO.
     */
    if ( *iret != 0 ) {
        er_wmsg ( "DG", iret, " ", &ier2, strlen("DG"), strlen(" ") );
    }

    /*
     * Set all grid values to missing.
     */
    for ( ii = ksub1; ii <= ksub2; ii++ ) {
        gno[ii-1] = RMISSD;
    }

    if ( *hi == G_TRUE ) {
        if ( *lo == G_FALSE ) strcpy ( namout, "HIGH" );

	/*
	 * Put the maxima on the grid.
	 */
	for ( ii = 1, nxi = ixmx-1, nxj = iymx-1, nxv = ivmx-1; 
	      ii <= nummx; 
	      ii++, nxi++, nxj++, nxv++ ) {
    	    i = G_NINT ( gnx[nxi] );
    	    j = G_NINT ( gnx[nxj] );
    	    index = ( j - 1 ) * kxd + i;
    	    gno[index-1] = gnx[nxv];
        }
    }

    if ( *lo == G_TRUE ) {
        if ( *hi == G_FALSE ) strcpy ( namout, "LOWS" );

	/*
	 *Put the minima on the grid.
	 */
        for ( ii = 1, nxi = ixmn-1, nxj = iymn-1, nxv = ivmn-1;
	      ii <= nummn;
	      ii++, nxi++, nxj++, nxv++ ) {
    	    i = G_NINT ( gnx[nxi] );
    	    j = G_NINT ( gnx[nxj] );
    	    index = ( j - 1 ) * kxd + i;
    	    gno[index-1] = gnx[nxv];
        }
    }

    /*
     * Get a name of the form NAMOUT //S and update header;
     * update stack.
     */
    dg_updh ( namout, &no, &num1, &izero, iret );
    dg_puts ( &no, iret );
    dg_esub ( &no, &izero, &izero, &izero, &ier );
    if ( ier != 0 ) *iret = ier;

    return;
}
Exemple #15
0
void df_rdfs ( int *iret )
/************************************************************************
 * DF_RDFS (Resolution Dependent Filter for Scalar)			*
 *									*
 * This subroutine smoothes a scalar grid using a moving average	*
 * low-pass filter whose weights are determined by the normal 		*
 * (Gaussian) probability distribution function for two dimensions.	*
 * The weight given to any grid point within the area covered by the	*
 * moving average for a	target grid point is proportional to		*
 *									*
 *		    EXP [ -( D ** 2 ) ],				*
 *									*
 * where D is the distance from	that point to the target point divided	*
 * by the standard deviation of the normal distribution.  The value of	*
 * the standard deviation is determined by the degree of filtering	*
 * requested.  The degree of filtering is specified by giving an 	*
 * effective resolution in km for the output grid.  From this value,	*
 * an integer required as the input for the GWFS function is computed.  *
 *									*
 * See the documentation for the GWFS function for more details.	*
 *									*
 * When this function is invoked, the first argument is the grid to be	*
 * smoothed, the second is the effective resolution as described above:	*
 *									*
 *			RDFS ( S, dx )					* 
 *									*
 * where dx > 0.  If the value of dx is less than the grid spacing	*
 * on the internal grid, no filtering is done.				*
 *									*
 * DF_RDFS  ( IRET )							*
 *									*
 * Output parameters:							*
 *	IRET		INTEGER		Return code			*
 *					As for DG_GETS			*
 **									*
 * Log:									*
 * K. Brill/HPC         05/12   Developed from DF_GWFS			*
 ************************************************************************/
{
    int nnw, kxd, kyd, ksub1, ksub2, zero, ier;
    int jj, ii, indx;
    int ixm, iym, ni, no;
    float *gnnw, *gnost;
    float gdx, gdy, dsg, eres, swl;
/*----------------------------------------------------------------------*/
    *iret = 0;
    zero = 0;

    dg_ssub ( iret );

    /*
     * Compute map scale factors and grid increments.
     */
    dg_mscl ( iret );
    if ( *iret != 0 ) return;

    /*
     * Get the grid spacing values:
     */
    dg_qmsl ( &ixm, &iym, &gdx, &gdy, iret );
    if ( *iret != 0 ) return;
    if ( gdx > gdy ) {
	dsg = gdx;
    } else {
	dsg = gdy;
    }
    dsg = dsg / 1000.0;

    /*printf ("  dsg = %f\n", dsg ); */

    /*
     * Get the input grid number.
     */
    dg_gets ( &ni, iret );
    if ( *iret != 0 ) return;

    /*
     * Get the user specified effective resolution (km).
     */
    dg_gets ( &nnw, iret );
    if ( *iret != 0 ) return;
    dg_getg ( &nnw, &gnnw, &kxd, &kyd, &ksub1, &ksub2, iret );
    eres = gnnw[0];

    if ( eres < dsg ) {
	/*printf ( " No smoothing\n" );*/
        /*
	 *  Do nothing -- return original grid without smoothing.
	 */
        /*
         * Make a name of the form 'RDF'//S and update header;
         * update stack.
         */
        dg_updh ( "RDF", &ni, &ni, &zero, iret );
        dg_puts ( &ni, iret );
        dg_esub ( &ni, &zero, &zero, &zero, &ier );
        if ( ier != 0 ) *iret = ier;
        return;
    } else {
	/*
	 * Call the GWFS program to smooth the grid. The smoother
	   footprint is chosen so as so suppress the 2 delta X
	   wave on the coarse grid to 1/e of the original amplitude.
	 */
	swl = (float)G_NINT ( ( eres / dsg ) * 2.0 );
	/*printf (" Smooth with footprint = %f\n", swl);*/
        /*
         * Get a new grid number for the output.
         */
        dg_nxts ( &no, iret );
        if ( *iret != 0 ) return;
        dg_getg ( &no, &gnost, &kxd, &kyd, &ksub1, &ksub2, iret );
        for ( jj = 1; jj <= kyd; jj++ ) {
            for ( ii = 1; ii <= kxd; ii++ ) {
	        indx = ( jj - 1 ) * kxd + ii;
	        gnost[indx-1] = swl;
	    }
	}
	/*
	 * Put two grids on the stack for the Gaussing weighted filter.
	 */
	dg_puts ( &no, iret );
        if ( *iret != 0 ) return;
	dg_puts ( &ni, iret );
        if ( *iret != 0 ) return;
	df_gwfs ( iret );
    }
    return;
}
Exemple #16
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 #17
0
void psatim ( char *imgnam, int *xispace0, int *yispace0, 
				int *xispace1, int *yispace1, int *iret )
/************************************************************************
 * psatim								*
 *									*
 * This subroutine writes satellite images to the PostScript file.	*
 * It is capable of displaying raw satellite images and remapped images.*
 *									*
 * psatim ( imgnam, xispace0, yispace0, xispace1, yispace1,iret)	*
 *									*
 * Input parameters:							*
 *	*imgnam		char		Name of image file		*
 *	*xispace0	int		Left of image in plot coord	*
 *	*yispace0	int		Top of image in plot coord	*
 *	*xispace1	int		Right of image in plot coord	*
 *	*yispace1	int		Bottom of image in plot coord	*
 *									*
 * Output parameters:							*
 *	*iret		int		Return code			*
 *					G_NORMAL  = normal return	*
 *					G_NIMGFL  = cannot open img file*
 *					G_NMEMRY  = Memory alloc failure*
 *					G_NIMCORD = invalid image coord	*
 *					G_BADPXV  = bad min/max pxl vals*
 **									*
 * Log:									*
 * S. Jacobs/NCEP	12/96	Copied from XSATIM			*
 * S. Jacobs/NCEP	 4/97	Removed #define IMGDEF; Changed imgDpy	*
 *				to imgDpy and reworked malloc		*
 * S. Jacobs/NCEP	 6/99	Added NetCDF file type			*
 * R. Curtis/EAI	 8/00   Updated for NetCDF files                *
 * S. Chiswell/Unidata	11/00	Updated for ZLIB compressed NIDS files	*
 * R. Tian/SAIC		05/02	Updated for fax image			*
 * D.W.Plummer/NCEP	 3/03	Changes for 10-bit GVAR imagery		*
 * A. Hardy/NCEP	 4/04	Modified to display 10-bit VIS imagery	*
 * T. Piper/SAIC	10/05	Dynamically allocate coltrans & rowtrans*
 * T. Piper/SAIC	08/06	Moved byte swapping to crarea		*
 * T. Piper/SAIC        11/06   Restore coltrans[0] back to original    *
 * X. Guo/CWS		04/10   Added codes to support 94 product       *
 * X. Guo/CWS           05/10   Added IFHINIDS to process 8 bit product *
 ***********************************************************************/
{
    int                 *coltrans, drange, element_size, ier, ierr;
    int                 ii, imghght, imgwdth, indx, isGVARRAW;
    int                 iwdth, lenp, linestart, ncolors, *rowtrans;
    int                 ximage0, ximage1, yimage0, yimage1;
    char                buff[80], dev[] = "PS", hdrstr[1024];
    float               *fpix, *tmpk;
    size_t              dpysize, imgsize;
    double              dbltmp, doffset, imgratio, plotratio, ratio, sf_hght, sf_wdth;
    unsigned char       *ddptr, *dptr, *imgptr;
    unsigned char       background, datamap[256], *imgDpy;
    unsigned int        col, jj, linesize, newdim, *pix, plothght, plotwdth;
    unsigned int        remainder, row, xhght, xwdth;

/*---------------------------------------------------------------------*/
/*
 *  Check the input for valid bounds.  Then set the image dimensions.
 */
    if  ( ( imtop <= imbot ) || ( imrght <= imleft ) ||
          ( *xispace1 <= *xispace0 ) || ( *yispace1 <= *yispace0 ) ) {
        *iret = G_NIMCORD;
        return;
    }
    imgwdth = (imrght - imleft) + 1;
    imghght = (imtop - imbot) + 1;
/*
 *  Make sure that plot file is open.  Put terminal in vector mode.
 */
    if  ( ! opnfil ) { 
	psopen ( iret );
	if  ( *iret != G_NORMAL )  return;
    }
    psplot = G_TRUE; 
/*
 *  Initialize the image data arrays.
 */
    csinit ( &ier );
/*
 *  Read image data file if this is a new file.
 */
    if  ( strcmp ( lastimg.filename, imgnam ) != 0 ) {
/*
 *  Allocate image data space.
 */
	imgsize = (size_t)(imnpix * imnlin * imdpth);

	if  ( ( imgData != (unsigned char *)NULL ) && 
	      ( imgsize <= lastimg.imgsize ) ) {
	    memset ( (unsigned char *)imgData, 0, imgsize );
	}
	else {
	    if  ( imgData != (unsigned char *)NULL ) {
	        free ( imgData );
	    }
	    imgData = (unsigned char *) calloc ( imgsize, 
				     sizeof ( unsigned char ) );
	    if  ( imgData == (unsigned char *)NULL ) {
	        *iret = G_NMEMRY;
	        return;
	    }
        }
/*
 *  Get the image data for the type of image file format.
 */
	switch ( imftyp ) {
	  case IFAREA:  /* Area file */
	    crarea ( imgnam, &ier );
	    break;
		
	  case IFGINI:  /* AWIPS GINI files */
	    crgini ( imgnam, &ier );
	    break;

	  case IFNIDS:  /* NIDS radar files */
	        crnids ( imgnam, &ier );
	    break;

          case IFHINIDS: /*Higher Resolution NIDS radar files*/
               crnexbz (imgnam, &ier );
            break;
	   
	  case IFNOWR:  /* WSI NOWRAD radar files */
	    crnowr ( imgnam, &ier );
	    break;
	    
	  case IFNCDF:  /* NetCDF files */
	    crncdf ( imgnam, &ier );
	    break;

	  case IFNEXZ:  /* ZLIB NEXRAD files */
	    crnexz ( imgnam, &ier );
	    break;

          case IFNFAX:  /* 6-bit FAX product files */
            crnfax ( dev, imgnam, &ier );
	    prtfax ( flun, imnpix, imnlin, xsize, ysize, &ier);
            return;

	  case IFNEX2:  /* NEXRAD Level2 files */
	    crnex2 ( imgnam, &ier );
	    break;

	  default:  /* Error in format */
	    ier = G_NIMGFMT;
	    break;
	}
/*
 *  Check for error.  Set this file as the 'last' one if OK.
 */
	if ( ier != G_NORMAL ) {
	    *iret = ier;
	    return;
	}
	strcpy ( lastimg.filename, imgnam );
	lastimg.imgsize = imgsize;
    }
/*
 *  Check image data range.
 */
    if  ( immxpx == immnpx ) {
        *iret = G_BADPXV;
        return;
    }
/*
 *  Request image area.  Set image scaling.
 */
    imgratio = (double)imghght / (double)imgwdth;
    if  ( ( !G_DIFF(rmxysc, 1.0F) ) && ( rmxysc > MNSCAL ) ) {
	imgratio /= (double)rmxysc;
    }
/*
 *  Compute the plot area.
 */
    plotwdth  = (*xispace1 - *xispace0) + 1; 
    plothght  = (*yispace1 - *yispace0) + 1;
    plotratio = (double)plothght / (double)plotwdth; 
/*
 *  Calculate final image size.
 *  ( ximage0, ximage1, yimage0, yimage1 )
 */
    if  ( plotratio > imgratio ) { 
/*
 *  If the height to width of the space available for the image
 *  is greater than the height to width of the image, width is
 *  the limiting factor, and scale the height to keep the
 *  appropriate aspect ratio.
 */
	ximage0 = *xispace0;
	ximage1 = *xispace1;
/*
 *  Center the image in the plot area.
 */
	newdim    = (unsigned int)((double)plotwdth * imgratio);
	remainder = plothght - newdim;
	yimage0   = G_NINT ( (double)*yispace0 - (double)remainder / 2.0 );
	yimage1   = G_NINT ( (double)*yispace1 + (double)remainder / 2.0 );
    }
    else {
/*
 *  Otherwise, if the height to width of the space available for
 *  the image is less than the height to width of the image,
 *  height is the limiting factor, and scale the width to keep
 *  the appropriate aspect ratio.
 */
	yimage0 = *yispace0;
	yimage1 = *yispace1;
/*
 *  Center the image in the plot area.
 */
        newdim    = (unsigned int)((double)plothght / imgratio);
        remainder = plotwdth - newdim;
        ximage0   = G_NINT ( (double)*xispace0 + (double)remainder / 2.0 );
        ximage1   = G_NINT ( (double)*xispace1 - (double)remainder / 2.0 );
    }
/*
 *  Final image size.
 */
    xwdth = G_NINT ( (double)((ximage1 - ximage0) + 1) / 32.0 );
    xhght = G_NINT ( (double)((yimage1 - yimage0) + 1) / 32.0 );
/*
 *  Construct the mapping from the image data to the final color
 *  pixel index -- datamap[].
 */
    isGVARRAW = G_FALSE;
    if ( strcmp ( cmstyp, "GVAR" ) == 0 &&
         strcmp ( cmcalb,  "RAW" ) == 0  )  isGVARRAW = G_TRUE;
/*
 * Compute image data range.
 */
    if ( isGVARRAW != G_TRUE ) {
        dbltmp = pow (2.0, (double)(imdpth * 8) );
    }
    else {
/*
 *  Treat GVAR RAW data as 0-255.
 *  (10-bit GVAR count scaled to 8-bit brightness temperature)
 */
        dbltmp = pow(2.0, 8.0);
    }
    drange = (int)dbltmp;
    ncolors = clrbank[imbank].ncolr;
    ratio   = (double)(ncolors - 1) / (double)(immxpx - immnpx);
/*
 *  Compute offset for data mapping.
 */
    doffset = (double)immnpx * ratio - 0.5;

    if  ( imdpth < 2 ||  isGVARRAW == G_TRUE ) {
/*
 *  One byte data.
 */
	for ( ii = 0; ii < drange; ii++ ) {
	    if  ( ii < immnpx )
		datamap[ii] = 0;
	    else if  ( ii > immxpx )
		datamap[ii] = ncolors - 1;
	    else {
	        if ( ! isGVARRAW == G_TRUE)
		    indx = (int)((double)ii * ratio - doffset);
	        else
		    indx = (int)( (double)(ii * (ncolors-1)) / (double)drange - doffset);
		datamap[ii] = indx;
	    }
	}
    }
/*
 *  Fill the column translation array with incremental indices
 *  into the original image columns with respect to the previous
 *  column.  Off-image values are set to -1.
 */
    G_MALLOC(coltrans, int, xwdth, "coltrans");
    sf_wdth = (double)(imgwdth - 1) / (double)(xwdth - 1);
    for ( col = 0; col < xwdth; col++ ) {
	coltrans[col] = (imleft - 1) + (int)(sf_wdth * (double)col + 0.5);
	if ( coltrans[col] < 0 || coltrans[col] >= imnpix ) {
	    coltrans[col] = -1;
	}
	else if ( col != 0 && coltrans[col-1] != -1 ) {
	    coltrans[col] -= (imleft - 1) +
			     (int)(sf_wdth*(double)(col-1) + 0.5);
	}
    }
/*
 *  Fill the row translation array with indices into the
 *  original image rows.  Set off-image values to -1.
 */
    G_MALLOC(rowtrans, int, xhght, "rowtrans");
    sf_hght = (double)(imghght - 1) / (double)(xhght -1);
    for ( row = 0; row < xhght; row++ ) {
	rowtrans[row] = (imbot - 1) + (int)(sf_hght * (double)row + 0.5);
	if  ( rowtrans[row] < 0  || rowtrans[row] >= imnlin ) {
	    rowtrans[row] = -1;
        }
    }
/*
 *  Construct the final image for display.
 */
    dpysize = xhght * xwdth;
    G_CALLOC(imgDpy, unsigned char, (int)dpysize, "imgDpy");
    if ( imgDpy == (unsigned char *)NULL ) {
	G_FREE ( coltrans, int );
	G_FREE ( rowtrans, int );
	*iret = G_NMEMRY;
	return;
    }
    imgptr = imgDpy;

    background = 255;
    *iret = G_NORMAL;
    element_size = imdpth;
    linesize = (unsigned int)(imnpix * element_size);
/*
 *  Allocate memory for one row/line of pixel data.
 */
    G_MALLOC(pix, unsigned int, xwdth, "pix");
    if ( imdpth == 2 && isGVARRAW == G_TRUE ) {
        G_MALLOC(tmpk, float, xwdth, "tmpk");
	G_MALLOC(fpix, float, xwdth, "fpix");
    }
Exemple #18
0
void dg_snav ( const float *rnav, int *iret )
/************************************************************************
 * dg_snav								*
 *									*
 * This subroutine sets the DGCMN grid navigation related elements for	*
 * the navigation in the input navigation block.			*
 * 									*
 * dg_snav ( rnav, iret )						*
 *									*
 * Input parameters:							*
 *	*rnav		const float	Navigation block		*
 *									*
 * Output parameters:							*
 * 	*iret		int		Return code			*
 *					  0 = normal return		*
 **									*
 * Log:									*
 * K. Brill/HPC		02/04						*
 * R. Tian/SAIC		05/04		Added call to DG_CONE		*
 * R. Tian/SAIC		 2/06		Recoded from Fortran		*
 ************************************************************************/
{
    float ag1, ag2, ag3;
    int nc, ier;
/*----------------------------------------------------------------------*/
    *iret = 0;

    cst_itos ( (int *)(&rnav[1]), 1, &nc, _dgfile.cprj, &ier );
    cst_rmbl ( _dgfile.cprj, _dgfile.cprj, &nc, &ier );
    _dgfile.kxd = G_NINT ( rnav[4] );
    _dgfile.kyd = G_NINT ( rnav[5] );
    _dgfile.kxyd = _dgfile.kxd * _dgfile.kyd;
    ag1 = rnav[10];
    ag2 = rnav[11];
    ag3 = rnav[12];

    /*
     * 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;
    dg_cone ( _dgfile.cprj, &_dgfile.anglr1, &_dgfile.anglr3, 
              &_dgfile.concon, iret );

    /*
     * 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;

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

    return;
}