ll_scan.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /******************************************************************************
  2. G_lat_scan (buf, lat)
  3. char *buf;
  4. double *lat;
  5. G_lon_scan (buf, lon)
  6. char *buf;
  7. double *lon;
  8. G_llres_scan (buf, res)
  9. char *buf;
  10. double *res;
  11. Convert ascii string representations of latitude/longitude to a double.
  12. The string format is:
  13. dd:mm:ss.ffh
  14. where:
  15. dd is degrees, 0-90 for latitude, 0-180 for longitude
  16. mm is minutes, 0-59
  17. ss is seconds, 0-59
  18. ff is fractions of a second, >= 0
  19. h is 'n' or 's' for latitude,
  20. 'e' or 'w' for longitude.
  21. missing for resolution
  22. lat (or lon) is set to the double value for the lat/lon represented in buf.
  23. lat is always in the range -90 thru 90,
  24. lon is always in the range -180 thru 180.
  25. note: southern latitude and western longitude are returned as negative values.
  26. returns 1 if input format is ok, 0 otherwise.
  27. ******************************************************************************/
  28. #include <grass/gis.h>
  29. #define LL_TOLERANCE 10
  30. static int scan_ll(const char *, const char *, double *, int);
  31. static int check_minutes(const char *);
  32. static int check_seconds(const char *);
  33. int G_lat_scan(const char *buf, double *lat)
  34. {
  35. return scan_ll(buf, "sn", lat, 90 + LL_TOLERANCE);
  36. }
  37. int G_lon_scan(const char *buf, double *lon)
  38. {
  39. return scan_ll(buf, "we", lon, 360 + LL_TOLERANCE);
  40. }
  41. int G_llres_scan(const char *buf, double *res)
  42. {
  43. char tbuf[100];
  44. sprintf(tbuf, "%se", buf);
  45. return scan_ll(tbuf, "we", res, 0);
  46. }
  47. #define MARKER 1
  48. static int scan_ll(const char *buf, const char *dir, double *result, int max)
  49. {
  50. char h[100];
  51. int d, m, s;
  52. char ps[20], *pps;
  53. double p, f;
  54. double pm = 0.0;
  55. char tbuf[100];
  56. sprintf(tbuf, "%s%c", buf, MARKER); /* add a marker at end of string */
  57. buf = tbuf;
  58. if (sscanf(buf, "%d:%d:%d.%[0123456789]%[^\n]", &d, &m, &s, ps, h) == 5) {
  59. p = 0.0;
  60. f = .1;
  61. for (pps = ps; *pps; pps++) {
  62. p += (*pps - '0') * f;
  63. f /= 10.0;
  64. }
  65. }
  66. else if (sscanf(buf, "%d:%d:%d%[^\n]", &d, &m, &s, h) == 4) {
  67. p = 0.0;
  68. }
  69. else if (sscanf(buf, "%d:%d.%[0123456789]%[^\n]", &d, &m, ps, h) == 4) {
  70. s = 0;
  71. p = 0.0;
  72. f = .1;
  73. for (pps = ps; *pps; pps++) {
  74. pm += (*pps - '0') * f;
  75. f /= 10.0;
  76. }
  77. }
  78. else if (sscanf(buf, "%d:%d%[^\n]", &d, &m, h) == 3) {
  79. p = 0.0;
  80. s = 0;
  81. }
  82. else if (sscanf(buf, "%d%[^\n]", &d, h) == 2) {
  83. p = 0.0;
  84. s = m = 0;
  85. }
  86. else
  87. return 0;
  88. if (d < 0)
  89. return 0;
  90. if (m < 0 || m >= 60)
  91. return 0;
  92. if (s < 0 || s >= 60)
  93. return 0;
  94. if (max) {
  95. if (d > max)
  96. return 0;
  97. if (d == max && (m > 0 || s > 0 || p > 0.0))
  98. return 0;
  99. }
  100. if (m && !check_minutes(buf))
  101. return 0;
  102. if (s && !check_seconds(buf))
  103. return 0;
  104. *result = d + (m + pm) / 60.0 + (s + p) / 3600.0;
  105. G_strip(h);
  106. if (*result == 0.0 && *h == MARKER)
  107. return (1);
  108. if (*h >= 'A' && *h <= 'Z')
  109. *h += 'a' - 'A';
  110. if (*h != dir[0] && *h != dir[1])
  111. return 0;
  112. if (h[1] != MARKER)
  113. return 0;
  114. if (*h == dir[0] && *result != 0.0)
  115. *result = -(*result);
  116. return 1;
  117. }
  118. static int check_minutes(const char *buf)
  119. {
  120. /* skip over degrees */
  121. while (*buf != ':')
  122. if (*buf++ == 0)
  123. return 1;
  124. buf++;
  125. /* must have 2 digits for minutes */
  126. if (*buf < '0' || *buf > '9')
  127. return 0;
  128. buf++;
  129. if (*buf < '0' || *buf > '9')
  130. return 0;
  131. buf++;
  132. return (*buf < '0' || *buf > '9');
  133. }
  134. static int check_seconds(const char *buf)
  135. {
  136. /* skip over degrees */
  137. while (*buf != ':')
  138. if (*buf++ == 0)
  139. return 1;
  140. buf++;
  141. /* skip over minutes */
  142. while (*buf != ':')
  143. if (*buf++ == 0)
  144. return 1;
  145. buf++;
  146. /* must have 2 digits for seconds */
  147. if (*buf < '0' || *buf > '9')
  148. return 0;
  149. buf++;
  150. if (*buf < '0' || *buf > '9')
  151. return 0;
  152. buf++;
  153. return (*buf < '0' || *buf > '9');
  154. }