GRASS Programmer's Manual
6.4.2(2012)
|
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 }