Line | Count | Source (jump to first uncovered line) |
1 | | /* Convert radian argument to DMS ascii format */ |
2 | | |
3 | | #include <math.h> |
4 | | #include <stddef.h> |
5 | | #include <stdio.h> |
6 | | #include <string.h> |
7 | | |
8 | | #include "proj.h" |
9 | | #include "proj_internal.h" |
10 | | |
11 | | /* |
12 | | ** RES is fractional second figures |
13 | | ** RES60 = 60 * RES |
14 | | ** CONV = 180 * 3600 * RES / PI (radians to RES seconds) |
15 | | */ |
16 | | static double RES = 1000., RES60 = 60000., CONV = 206264806.24709635516; |
17 | | static char format[50] = "%dd%d'%.3f\"%c"; |
18 | | static int dolong = 0; |
19 | 0 | void set_rtodms(int fract, int con_w) { |
20 | 0 | int i; |
21 | |
|
22 | 0 | if (fract >= 0 && fract < 9) { |
23 | 0 | RES = 1.; |
24 | | /* following not very elegant, but used infrequently */ |
25 | 0 | for (i = 0; i < fract; ++i) |
26 | 0 | RES *= 10.; |
27 | 0 | RES60 = RES * 60.; |
28 | 0 | CONV = 180. * 3600. * RES / M_PI; |
29 | 0 | if (!con_w) |
30 | 0 | (void)snprintf(format, sizeof(format), "%%dd%%d'%%.%df\"%%c", |
31 | 0 | fract); |
32 | 0 | else |
33 | 0 | (void)snprintf(format, sizeof(format), "%%dd%%02d'%%0%d.%df\"%%c", |
34 | 0 | fract + 2 + (fract ? 1 : 0), fract); |
35 | 0 | dolong = con_w; |
36 | 0 | } |
37 | 0 | } |
38 | 0 | char *rtodms(char *s, size_t sizeof_s, double r, int pos, int neg) { |
39 | 0 | int deg, min, sign; |
40 | 0 | char *ss = s; |
41 | 0 | double sec; |
42 | 0 | size_t sizeof_ss = sizeof_s; |
43 | |
|
44 | 0 | if (r < 0) { |
45 | 0 | r = -r; |
46 | 0 | if (!pos) { |
47 | 0 | if (sizeof_s == 1) { |
48 | 0 | *s = 0; |
49 | 0 | return s; |
50 | 0 | } |
51 | 0 | sizeof_ss--; |
52 | 0 | *ss++ = '-'; |
53 | 0 | sign = 0; |
54 | 0 | } else |
55 | 0 | sign = neg; |
56 | 0 | } else |
57 | 0 | sign = pos; |
58 | 0 | r = floor(r * CONV + .5); |
59 | 0 | sec = fmod(r / RES, 60.); |
60 | 0 | r = floor(r / RES60); |
61 | 0 | min = (int)fmod(r, 60.); |
62 | 0 | r = floor(r / 60.); |
63 | 0 | deg = (int)r; |
64 | |
|
65 | 0 | if (dolong) |
66 | 0 | (void)snprintf(ss, sizeof_ss, format, deg, min, sec, sign); |
67 | 0 | else if (sec != 0.0) { |
68 | 0 | char *p, *q; |
69 | | /* double prime + pos/neg suffix (if included) + NUL */ |
70 | 0 | size_t suffix_len = sign ? 3 : 2; |
71 | |
|
72 | 0 | (void)snprintf(ss, sizeof_ss, format, deg, min, sec, sign); |
73 | | /* Replace potential decimal comma by decimal point for non C locale */ |
74 | 0 | for (p = ss; *p != '\0'; ++p) { |
75 | 0 | if (*p == ',') { |
76 | 0 | *p = '.'; |
77 | 0 | break; |
78 | 0 | } |
79 | 0 | } |
80 | 0 | if (suffix_len > strlen(ss)) |
81 | 0 | return s; |
82 | 0 | for (q = p = ss + strlen(ss) - suffix_len; *p == '0'; --p) |
83 | 0 | ; |
84 | 0 | if (*p != '.') |
85 | 0 | ++p; |
86 | 0 | if (++q != p) |
87 | 0 | (void)memmove(p, q, suffix_len); |
88 | 0 | } else if (min) |
89 | 0 | (void)snprintf(ss, sizeof_ss, "%dd%d'%c", deg, min, sign); |
90 | 0 | else |
91 | 0 | (void)snprintf(ss, sizeof_ss, "%dd%c", deg, sign); |
92 | 0 | return s; |
93 | 0 | } |