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; }
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; }