/* dms.c COPYRIGHT (c) 1991 Kapteyn Astronomical Institute University of Groningen - 9700 AV Groningen, The Netherlands #> dms.dc2 Function: DMS Purpose: Convert degrees to a string containing the degrees, minutes and seconds. Category: COORDINATES File: dms.c Author: Fred Lahuis Use: CALL DMS( DEGREES, Input double STRING, Output char*(*) COOR, Output double array (n = 3) PRECISION Input integer OUTPUT) Input integer DEGREES Input value in degrees STRING Output string, format xxd~xxm~xx.xxs or xxdxx'xx" (see OUTPUT). COOR Array of size 3 to receive the degrees, minutes and seconds. Omitted if coor is equal to NULL. PRECISION Indicates the precision in which the seconds are printed. OUTPUT Type of output 0 --> with d m s 1 --> with d ' ", for use with pgplot Updates: Jul 15, 1991: FL, Creation date. Feb 12, 1992: MV, New calculation of minuts to avoid rounding errors. Oct 19, 1992: FL, Output string changed for 0s. Nov 9, 1992: FL, Error for negative zero degree removed. Nov 13, 1992: FL, Proper handling of 60s, 60m and 360d. Sep 17, 1993: FL, Error in length convstr. #< Fortran to C interface: @ subroutine dms( double precision, character, double precision, integer, integer ) */ #include "ctype.h" #include "stdio.h" #include "stdlib.h" #include "gipsyc.h" #include "math.h" #include "string.h" #include "anyout.h" #define width(w) ((int)((w)?(3+w):2)) #define nint(a) (int)((a)+0.5) #define MAXTEXTLEN 30 void dms_c( double *deg, fchar convstr, double *coor, fint *prec, fint *output ) { fint l0, l1, l2, n , negative ; fint degree , minut ; double second ; double deg_in ; char cstring[MAXTEXTLEN] ; deg_in = *deg ; if( deg_in < 0.0 ){ negative = 1 ; deg_in = -deg_in ; } else negative = 0 ; degree = (int) deg_in ; minut = (int) ( deg_in*60.0 - (double)(degree*60) ); minut = abs(minut) ; second = ( (deg_in - (double)degree - (double)(minut/60.0))*3600.0 ) ; second = fabs( second ) ; if( coor != NULL ){ coor[0] = (double)degree ; if( negative ) coor[0] = -coor[0] ; coor[1] = (double)minut ; if( coor[0] == 0.0 && negative ) coor[1] = -coor[1] ; coor[2] = second ; } if( !*prec && nint(second) == 60 ){ second -= 60.0 ; minut += 1 ; } if( minut == 60 || minut == 61 ){ minut -= 60 ; degree += 1 ; } if( degree == 360 ) degree = 0 ; if( negative ) l0 = sprintf( cstring, "-" ) ; else l0 = sprintf( cstring, "" ) ; if( *output == 0 ){ l1 = sprintf( cstring, "%s%dd %2dm", cstring, degree, minut ) ; if( !*prec && second < 0.5 ) l2 = sprintf( cstring, "%s 00s", cstring ) ; else l2 = sprintf( cstring, "%s %*.*fs", cstring, width(*prec), (int)(*prec), second ) ; } else{ l1 = sprintf( cstring, "%s%d\\uo\\d%2d\\u'\\d", cstring, degree, minut ) ; if( !*prec && second < 0.5 ) l2 = sprintf( cstring, "%s00\\u\"\\d", cstring ) ; else l2 = sprintf( cstring, "%s%*.*f\\u\"\\d", cstring, width(*prec), (int)(*prec), second ) ; } for( n = 0 ; n < l2 && n < convstr.l ; n++ )convstr.a[n] = cstring[n] ; for( ; n < convstr.l ; convstr.a[n++] = ' ' ) ; return ; } #if defined(TESTBED) #define fmake(fchar, size) { \ static char buff[size+1] ; \ int i ; \ for( i = 0 ; i < size ; buff[i++] = ' ' ) ; \ buff[i] = 0 ; \ fchar.a = buff ; \ fchar.l = size ; \ } void main() { double degree ; double coor[3] ; fint output ; fint prec ; fchar Fstring ; fmake( Fstring, 30 ) ; degree = 359. + 59.0/60.0 + 59.8/3600.0 ; degree = -degree ; for( output = 0 ; output <= 1 ; output++ ){ for( prec = 0 ; prec <= 3 ; prec++ ){ dms_c( °ree, Fstring, coor, &prec, &output ) ; printf( "%s\n", Fstring.a ) ; printf( "coor: %d %d %.3f\n", (int)coor[0] , (int)coor[1] , coor[2] ) ; } } } #endif