ll_scan.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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. static int scan_ll(const char *, const char *, double *, int);
  30. static int check_minutes(const char *);
  31. static int check_seconds(const char *);
  32. int G_lat_scan(const char *buf, double *lat)
  33. {
  34. return scan_ll(buf, "sn", lat, 90);
  35. }
  36. int G_lon_scan(const char *buf, double *lon)
  37. {
  38. return scan_ll(buf, "we", lon, 180);
  39. }
  40. int G_llres_scan(const char *buf, double *res)
  41. {
  42. char tbuf[100];
  43. sprintf(tbuf, "%se", buf);
  44. return scan_ll(tbuf, "we", res, 0);
  45. }
  46. #define MARKER 1
  47. static int scan_ll(const char *buf, const char *dir, double *result, int max)
  48. {
  49. char h[100];
  50. int d, m, s;
  51. char ps[20], *pps;
  52. double p, f;
  53. double pm = 0.0;
  54. char tbuf[100];
  55. sprintf(tbuf, "%s%c", buf, MARKER); /* add a marker at end of string */
  56. buf = tbuf;
  57. if (sscanf(buf, "%d:%d:%d.%[0123456789]%[^\n]", &d, &m, &s, ps, h) == 5) {
  58. p = 0.0;
  59. f = .1;
  60. for (pps = ps; *pps; pps++) {
  61. p += (*pps - '0') * f;
  62. f /= 10.0;
  63. }
  64. }
  65. else if (sscanf(buf, "%d:%d:%d%[^\n]", &d, &m, &s, h) == 4) {
  66. p = 0.0;
  67. }
  68. else if (sscanf(buf, "%d:%d.%[0123456789]%[^\n]", &d, &m, ps, h) == 4) {
  69. s = 0;
  70. p = 0.0;
  71. f = .1;
  72. for (pps = ps; *pps; pps++) {
  73. pm += (*pps - '0') * f;
  74. f /= 10.0;
  75. }
  76. }
  77. else if (sscanf(buf, "%d:%d%[^\n]", &d, &m, h) == 3) {
  78. p = 0.0;
  79. s = 0;
  80. }
  81. else if (sscanf(buf, "%d%[^\n]", &d, h) == 2) {
  82. p = 0.0;
  83. s = m = 0;
  84. }
  85. else
  86. return 0;
  87. if (d < 0)
  88. return 0;
  89. if (m < 0 || m >= 60)
  90. return 0;
  91. if (s < 0 || s >= 60)
  92. return 0;
  93. if (max) {
  94. if (d > max)
  95. return 0;
  96. if (d == max && (m > 0 || s > 0 || p > 0.0))
  97. return 0;
  98. }
  99. if (m && !check_minutes(buf))
  100. return 0;
  101. if (s && !check_seconds(buf))
  102. return 0;
  103. *result = d + (m + pm) / 60.0 + (s + p) / 3600.0;
  104. G_strip(h);
  105. if (*result == 0.0 && *h == MARKER)
  106. return (1);
  107. if (*h >= 'A' && *h <= 'Z')
  108. *h += 'a' - 'A';
  109. if (*h != dir[0] && *h != dir[1])
  110. return 0;
  111. if (h[1] != MARKER)
  112. return 0;
  113. if (*h == dir[0] && *result != 0.0)
  114. *result = -(*result);
  115. return 1;
  116. }
  117. static int check_minutes(const char *buf)
  118. {
  119. /* skip over degrees */
  120. while (*buf != ':')
  121. if (*buf++ == 0)
  122. return 1;
  123. buf++;
  124. /* must have 2 digits for minutes */
  125. if (*buf < '0' || *buf > '9')
  126. return 0;
  127. buf++;
  128. if (*buf < '0' || *buf > '9')
  129. return 0;
  130. buf++;
  131. return (*buf < '0' || *buf > '9');
  132. }
  133. static int check_seconds(const char *buf)
  134. {
  135. /* skip over degrees */
  136. while (*buf != ':')
  137. if (*buf++ == 0)
  138. return 1;
  139. buf++;
  140. /* skip over minutes */
  141. while (*buf != ':')
  142. if (*buf++ == 0)
  143. return 1;
  144. buf++;
  145. /* must have 2 digits for seconds */
  146. if (*buf < '0' || *buf > '9')
  147. return 0;
  148. buf++;
  149. if (*buf < '0' || *buf > '9')
  150. return 0;
  151. buf++;
  152. return (*buf < '0' || *buf > '9');
  153. }