ll_scan.c

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

Generated on Fri Nov 21 11:02:18 2008 for GRASS by  doxygen 1.5.1