ll_scan.c

Go to the documentation of this file.
00001 #include "gis.h"
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 "gis.h"
00039 
00040 static int scan_ll(char *,char *,double *,int);
00041 static int check_minutes(char *);
00042 static int check_seconds(char *);
00043 
00044 int G_lat_scan ( char *buf, double *lat)
00045 {
00046     return scan_ll (buf, "sn", lat, 90);
00047 }
00048 
00049 int G_lon_scan ( char *buf, double *lon)
00050 {
00051     return scan_ll (buf, "we", lon, 180);
00052 }
00053 
00054 int G_llres_scan ( 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 (
00064     char *buf,
00065     char *dir,
00066     double *result,
00067     int max)
00068 {
00069     char h[100];
00070     int d,m,s;
00071     char ps[20], *pps;
00072     double p, f;
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%[^\n]", &d, &m, h) == 3)
00093     {
00094         p = 0.0;
00095         s = 0 ;
00096     }
00097     else if (sscanf (buf, "%d%[^\n]", &d, h) == 2)
00098     {
00099         p = 0.0;
00100         s = m = 0;
00101     }
00102     else
00103         return 0;
00104 
00105     if (d < 0) return 0;
00106     if (m < 0 || m >= 60) return 0;
00107     if (s < 0 || s >= 60) return 0;
00108     if (max)
00109     {
00110         if (d > max) return 0;
00111         if (d == max && (m > 0 || s > 0 || p > 0.0)) return 0;
00112     }
00113     if (m && !check_minutes(buf)) return 0;
00114     if (s && !check_seconds(buf)) return 0;
00115 
00116     *result = d + m/60.0 + (s + p)/3600.0;
00117 
00118     G_strip (h);
00119 
00120     if (*result == 0.0 && *h == MARKER)
00121         return (1);
00122 
00123     if (*h >= 'A' && *h <= 'Z') *h += 'a' - 'A';
00124     if (*h != dir[0] && *h != dir[1])
00125         return 0;
00126     if (h[1] != MARKER)
00127         return 0;
00128 
00129     if (*h == dir[0] && *result != 0.0)
00130         *result = -(*result);
00131     return 1;
00132 }
00133 
00134 static int check_minutes(char *buf)
00135 {
00136 /* skip over degrees */
00137     while (*buf != ':')
00138         if (*buf++ == 0) return 1;
00139     buf++;
00140 
00141 /* must have 2 digits for minutes */
00142     if (*buf < '0' || *buf > '9') return 0;
00143     buf++;
00144     if (*buf < '0' || *buf > '9') return 0;
00145     buf++;
00146     return (*buf < '0' || *buf > '9');
00147 }
00148 
00149 static int check_seconds(char *buf)
00150 {
00151 /* skip over degrees */
00152     while (*buf != ':')
00153         if (*buf++ == 0) return 1;
00154     buf++;
00155 /* skip over minutes */
00156     while (*buf != ':')
00157         if (*buf++ == 0) return 1;
00158     buf++;
00159 
00160 /* must have 2 digits for seconds */
00161     if (*buf < '0' || *buf > '9') return 0;
00162     buf++;
00163     if (*buf < '0' || *buf > '9') return 0;
00164     buf++;
00165     return (*buf < '0' || *buf > '9');
00166 }

Generated on Sat Jul 22 22:06:15 2006 for GRASS by  doxygen 1.4.7