123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /******************************************************************************
- G_lat_scan (buf, lat)
- char *buf;
- double *lat;
- G_lon_scan (buf, lon)
- char *buf;
- double *lon;
- G_llres_scan (buf, res)
- char *buf;
- double *res;
- Convert ascii string representations of latitude/longitude to a double.
- The string format is:
- dd:mm:ss.ffh
- where:
- dd is degrees, 0-90 for latitude, 0-180 for longitude
- mm is minutes, 0-59
- ss is seconds, 0-59
- ff is fractions of a second, >= 0
- h is 'n' or 's' for latitude,
- 'e' or 'w' for longitude.
- missing for resolution
- lat (or lon) is set to the double value for the lat/lon represented in buf.
- lat is always in the range -90 thru 90,
- lon is always in the range -180 thru 180.
- note: southern latitude and western longitude are returned as negative values.
- returns 1 if input format is ok, 0 otherwise.
- ******************************************************************************/
- #include <grass/gis.h>
- #define LL_TOLERANCE 10
- static int scan_ll(const char *, const char *, double *, int);
- static int check_minutes(const char *);
- static int check_seconds(const char *);
- int G_lat_scan(const char *buf, double *lat)
- {
- return scan_ll(buf, "sn", lat, 90 + LL_TOLERANCE);
- }
- int G_lon_scan(const char *buf, double *lon)
- {
- return scan_ll(buf, "we", lon, 360 + LL_TOLERANCE);
- }
- int G_llres_scan(const char *buf, double *res)
- {
- char tbuf[100];
- sprintf(tbuf, "%se", buf);
- return scan_ll(tbuf, "we", res, 0);
- }
- #define MARKER 1
- static int scan_ll(const char *buf, const char *dir, double *result, int max)
- {
- char h[100];
- int d, m, s;
- char ps[20], *pps;
- double p, f;
- double pm = 0.0;
- char tbuf[100];
- sprintf(tbuf, "%s%c", buf, MARKER); /* add a marker at end of string */
- buf = tbuf;
- if (sscanf(buf, "%d:%d:%d.%[0123456789]%[^\n]", &d, &m, &s, ps, h) == 5) {
- p = 0.0;
- f = .1;
- for (pps = ps; *pps; pps++) {
- p += (*pps - '0') * f;
- f /= 10.0;
- }
- }
- else if (sscanf(buf, "%d:%d:%d%[^\n]", &d, &m, &s, h) == 4) {
- p = 0.0;
- }
- else if (sscanf(buf, "%d:%d.%[0123456789]%[^\n]", &d, &m, ps, h) == 4) {
- s = 0;
- p = 0.0;
- f = .1;
- for (pps = ps; *pps; pps++) {
- pm += (*pps - '0') * f;
- f /= 10.0;
- }
- }
- else if (sscanf(buf, "%d:%d%[^\n]", &d, &m, h) == 3) {
- p = 0.0;
- s = 0;
- }
- else if (sscanf(buf, "%d%[^\n]", &d, h) == 2) {
- p = 0.0;
- s = m = 0;
- }
- else
- return 0;
- if (d < 0)
- return 0;
- if (m < 0 || m >= 60)
- return 0;
- if (s < 0 || s >= 60)
- return 0;
- if (max) {
- if (d > max)
- return 0;
- if (d == max && (m > 0 || s > 0 || p > 0.0))
- return 0;
- }
- if (m && !check_minutes(buf))
- return 0;
- if (s && !check_seconds(buf))
- return 0;
- *result = d + (m + pm) / 60.0 + (s + p) / 3600.0;
- G_strip(h);
- if (*result == 0.0 && *h == MARKER)
- return (1);
- if (*h >= 'A' && *h <= 'Z')
- *h += 'a' - 'A';
- if (*h != dir[0] && *h != dir[1])
- return 0;
- if (h[1] != MARKER)
- return 0;
- if (*h == dir[0] && *result != 0.0)
- *result = -(*result);
- return 1;
- }
- static int check_minutes(const char *buf)
- {
- /* skip over degrees */
- while (*buf != ':')
- if (*buf++ == 0)
- return 1;
- buf++;
- /* must have 2 digits for minutes */
- if (*buf < '0' || *buf > '9')
- return 0;
- buf++;
- if (*buf < '0' || *buf > '9')
- return 0;
- buf++;
- return (*buf < '0' || *buf > '9');
- }
- static int check_seconds(const char *buf)
- {
- /* skip over degrees */
- while (*buf != ':')
- if (*buf++ == 0)
- return 1;
- buf++;
- /* skip over minutes */
- while (*buf != ':')
- if (*buf++ == 0)
- return 1;
- buf++;
- /* must have 2 digits for seconds */
- if (*buf < '0' || *buf > '9')
- return 0;
- buf++;
- if (*buf < '0' || *buf > '9')
- return 0;
- buf++;
- return (*buf < '0' || *buf > '9');
- }
|