GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
ll_scan.c
Go to the documentation of this file.
1/******************************************************************************
2 G_lat_scan (buf, lat)
3 char *buf;
4 double *lat;
5
6 G_lon_scan (buf, lon)
7 char *buf;
8 double *lon;
9
10 G_llres_scan (buf, res)
11 char *buf;
12 double *res;
13
14 Convert ascii string representations of latitude/longitude to a double.
15 The string format is:
16
17 dd:mm:ss.ffh
18
19 where:
20 dd is degrees, 0-90 for latitude, 0-180 for longitude
21 mm is minutes, 0-59
22 ss is seconds, 0-59
23 ff is fractions of a second, >= 0
24 h is 'n' or 's' for latitude,
25 'e' or 'w' for longitude.
26 missing for resolution
27
28 lat (or lon) is set to the double value for the lat/lon represented in buf.
29
30 lat is always in the range -90 thru 90,
31 lon is always in the range -180 thru 180.
32
33 note: southern latitude and western longitude are returned as negative values.
34
35 returns 1 if input format is ok, 0 otherwise.
36******************************************************************************/
37#include <grass/gis.h>
38
39#define LL_TOLERANCE 10
40
41static int scan_ll(const char *, const char *, double *, int);
42static int check_minutes(const char *);
43static int check_seconds(const char *);
44
45int G_lat_scan(const char *buf, double *lat)
46{
47 return scan_ll(buf, "sn", lat, 90 + LL_TOLERANCE);
48}
49
50int G_lon_scan(const char *buf, double *lon)
51{
52 return scan_ll(buf, "we", lon, 360 + LL_TOLERANCE);
53}
54
55int G_llres_scan(const char *buf, double *res)
56{
57 char tbuf[100];
58
59 sprintf(tbuf, "%se", buf);
60 return scan_ll(tbuf, "we", res, 0);
61}
62
63#define MARKER 1
64static int scan_ll(const char *buf, const char *dir, double *result, int max)
65{
66 char h[100];
67 int d, m, s;
68 char ps[20], *pps;
69 double p, f;
70 double pm = 0.0;
71 char tbuf[100];
72
73 sprintf(tbuf, "%s%c", buf, MARKER); /* add a marker at end of string */
74 buf = tbuf;
75
76 if (sscanf(buf, "%d:%d:%d.%[0123456789]%[^\n]", &d, &m, &s, ps, h) == 5) {
77 p = 0.0;
78 f = .1;
79 for (pps = ps; *pps; pps++) {
80 p += (*pps - '0') * f;
81 f /= 10.0;
82 }
83 }
84 else if (sscanf(buf, "%d:%d:%d%[^\n]", &d, &m, &s, h) == 4) {
85 p = 0.0;
86 }
87 else if (sscanf(buf, "%d:%d.%[0123456789]%[^\n]", &d, &m, ps, h) == 4) {
88 s = 0;
89 p = 0.0;
90 f = .1;
91 for (pps = ps; *pps; pps++) {
92 pm += (*pps - '0') * f;
93 f /= 10.0;
94 }
95 }
96 else if (sscanf(buf, "%d:%d%[^\n]", &d, &m, h) == 3) {
97 p = 0.0;
98 s = 0;
99 }
100 else if (sscanf(buf, "%d%[^\n]", &d, h) == 2) {
101 p = 0.0;
102 s = m = 0;
103 }
104 else
105 return 0;
106
107 if (d < 0)
108 return 0;
109 if (m < 0 || m >= 60)
110 return 0;
111 if (s < 0 || s >= 60)
112 return 0;
113
114 if (max) {
115 if (d > max)
116 return 0;
117 if (d == max && (m > 0 || s > 0 || p > 0.0))
118 return 0;
119 }
120
121 if (m && !check_minutes(buf))
122 return 0;
123 if (s && !check_seconds(buf))
124 return 0;
125
126 *result = d + (m + pm) / 60.0 + (s + p) / 3600.0;
127
128 G_strip(h);
129
130 if (*result == 0.0 && *h == MARKER)
131 return (1);
132
133 if (*h >= 'A' && *h <= 'Z')
134 *h += 'a' - 'A';
135
136 if (*h != dir[0] && *h != dir[1])
137 return 0;
138
139 if (h[1] != MARKER)
140 return 0;
141
142 if (*h == dir[0] && *result != 0.0)
143 *result = -(*result);
144
145 return 1;
146}
147
148static int check_minutes(const char *buf)
149{
150 /* skip over degrees */
151 while (*buf != ':')
152 if (*buf++ == 0)
153 return 1;
154 buf++;
155
156 /* must have 2 digits for minutes */
157 if (*buf < '0' || *buf > '9')
158 return 0;
159 buf++;
160 if (*buf < '0' || *buf > '9')
161 return 0;
162 buf++;
163 return (*buf < '0' || *buf > '9');
164}
165
166static int check_seconds(const char *buf)
167{
168 /* skip over degrees */
169 while (*buf != ':')
170 if (*buf++ == 0)
171 return 1;
172 buf++;
173 /* skip over minutes */
174 while (*buf != ':')
175 if (*buf++ == 0)
176 return 1;
177 buf++;
178
179 /* must have 2 digits for seconds */
180 if (*buf < '0' || *buf > '9')
181 return 0;
182 buf++;
183 if (*buf < '0' || *buf > '9')
184 return 0;
185 buf++;
186 return (*buf < '0' || *buf > '9');
187}
#define LL_TOLERANCE
Definition adj_cellhd.c:19
#define MARKER
Definition ll_scan.c:63
int G_lat_scan(const char *buf, double *lat)
Definition ll_scan.c:45
int G_lon_scan(const char *buf, double *lon)
Definition ll_scan.c:50
int G_llres_scan(const char *buf, double *res)
Definition ll_scan.c:55
#define max(a, b)
struct ps_state ps
void G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition strings.c:300