GRASS Programmer's Manual  6.4.1(2011)
ll_scan.c
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003  G_lat_scan (buf, lat)
00004      char *buf;
00005      double *lat;
00006 
00007  G_lon_scan (buf, lon)
00008      char *buf;
00009      double *lon;
00010 
00011  G_llres_scan (buf, res)
00012      char *buf;
00013      double *res;
00014 
00015  Convert ascii string representations of latitude/longitude to a double.
00016  The string format is:
00017 
00018        dd:mm:ss.ffh
00019 
00020  where:
00021        dd is degrees, 0-90 for latitude, 0-180 for longitude
00022        mm is minutes, 0-59
00023        ss is seconds, 0-59
00024        ff is fractions of a second, >= 0
00025        h  is 'n' or 's' for latitude,
00026              'e' or 'w' for longitude.
00027              missing for resolution
00028 
00029  lat (or lon) is set to the double value for the lat/lon represented in buf.
00030 
00031  lat is always in the range  -90 thru  90,
00032  lon is always in the range -180 thru 180.
00033 
00034  note: southern latitude and western longitude are returned as negative values.
00035 
00036  returns 1 if input format is ok, 0 otherwise.
00037 ******************************************************************************/
00038 #include <grass/gis.h>
00039 
00040 static int scan_ll(const char *, const char *, double *, int);
00041 static int check_minutes(const char *);
00042 static int check_seconds(const char *);
00043 
00044 int G_lat_scan(const char *buf, double *lat)
00045 {
00046     return scan_ll(buf, "sn", lat, 90);
00047 }
00048 
00049 int G_lon_scan(const char *buf, double *lon)
00050 {
00051     return scan_ll(buf, "we", lon, 180);
00052 }
00053 
00054 int G_llres_scan(const char *buf, double *res)
00055 {
00056     char tbuf[100];
00057 
00058     sprintf(tbuf, "%se", buf);
00059     return scan_ll(tbuf, "we", res, 0);
00060 }
00061 
00062 #define MARKER 1
00063 static int scan_ll(const char *buf, const char *dir, double *result, int max)
00064 {
00065     char h[100];
00066     int d, m, s;
00067     char ps[20], *pps;
00068     double p, f;
00069     double pm = 0.0;
00070     char tbuf[100];
00071 
00072     sprintf(tbuf, "%s%c", buf, MARKER); /* add a marker at end of string */
00073     buf = tbuf;
00074 
00075     if (sscanf(buf, "%d:%d:%d.%[0123456789]%[^\n]", &d, &m, &s, ps, h) == 5) {
00076         p = 0.0;
00077         f = .1;
00078         for (pps = ps; *pps; pps++) {
00079             p += (*pps - '0') * f;
00080             f /= 10.0;
00081         }
00082     }
00083     else if (sscanf(buf, "%d:%d:%d%[^\n]", &d, &m, &s, h) == 4) {
00084         p = 0.0;
00085     }
00086     else if (sscanf(buf, "%d:%d.%[0123456789]%[^\n]", &d, &m, ps, h) == 4) {
00087         s = 0;
00088         p = 0.0;
00089         f = .1;
00090         for (pps = ps; *pps; pps++) {
00091             pm += (*pps - '0') * f;
00092             f /= 10.0;
00093         }
00094     }
00095     else if (sscanf(buf, "%d:%d%[^\n]", &d, &m, h) == 3) {
00096         p = 0.0;
00097         s = 0;
00098     }
00099     else if (sscanf(buf, "%d%[^\n]", &d, h) == 2) {
00100         p = 0.0;
00101         s = m = 0;
00102     }
00103     else
00104         return 0;
00105 
00106     if (d < 0)
00107         return 0;
00108     if (m < 0 || m >= 60)
00109         return 0;
00110     if (s < 0 || s >= 60)
00111         return 0;
00112 
00113     if (max) {
00114         if (d > max)
00115             return 0;
00116         if (d == max && (m > 0 || s > 0 || p > 0.0))
00117             return 0;
00118     }
00119 
00120     if (m && !check_minutes(buf))
00121         return 0;
00122     if (s && !check_seconds(buf))
00123         return 0;
00124 
00125     *result = d + (m + pm) / 60.0 + (s + p) / 3600.0;
00126 
00127     G_strip(h);
00128 
00129     if (*result == 0.0 && *h == MARKER)
00130         return (1);
00131 
00132     if (*h >= 'A' && *h <= 'Z')
00133         *h += 'a' - 'A';
00134 
00135     if (*h != dir[0] && *h != dir[1])
00136         return 0;
00137 
00138     if (h[1] != MARKER)
00139         return 0;
00140 
00141     if (*h == dir[0] && *result != 0.0)
00142         *result = -(*result);
00143 
00144     return 1;
00145 }
00146 
00147 static int check_minutes(const char *buf)
00148 {
00149     /* skip over degrees */
00150     while (*buf != ':')
00151         if (*buf++ == 0)
00152             return 1;
00153     buf++;
00154 
00155     /* must have 2 digits for minutes */
00156     if (*buf < '0' || *buf > '9')
00157         return 0;
00158     buf++;
00159     if (*buf < '0' || *buf > '9')
00160         return 0;
00161     buf++;
00162     return (*buf < '0' || *buf > '9');
00163 }
00164 
00165 static int check_seconds(const char *buf)
00166 {
00167     /* skip over degrees */
00168     while (*buf != ':')
00169         if (*buf++ == 0)
00170             return 1;
00171     buf++;
00172     /* skip over minutes */
00173     while (*buf != ':')
00174         if (*buf++ == 0)
00175             return 1;
00176     buf++;
00177 
00178     /* must have 2 digits for seconds */
00179     if (*buf < '0' || *buf > '9')
00180         return 0;
00181     buf++;
00182     if (*buf < '0' || *buf > '9')
00183         return 0;
00184     buf++;
00185     return (*buf < '0' || *buf > '9');
00186 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines