Example #1
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;
}
Example #2
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;

}