gethead.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <math.h>
  4. #include <grass/gis.h>
  5. #include <grass/raster.h>
  6. #include <grass/glocale.h>
  7. #include "local_proto.h"
  8. #define DOT "." /* for determining data type -tw */
  9. #define INT "int"
  10. #define FLOAT "float"
  11. #define DOUBLE "double"
  12. #define TMPBUFSIZE 8192
  13. static int missing(int, char *);
  14. static int extract(int, char *, char *, void *, int, int (*)());
  15. static int scan_int(char *, int *, int);
  16. const char gs_ascii_flag[5] = { "DSAA" };
  17. int getgrdhead(FILE * fd, struct Cell_head *cellhd)
  18. {
  19. char grd_flag[6];
  20. int nc, nr;
  21. float xmin, xmax, ymin, ymax, zmin, zmax;
  22. /* make sure the input file is positioned at the beginning */
  23. rewind(fd);
  24. /* read and check the flag on the first line */
  25. fgets(grd_flag, sizeof(grd_flag), fd);
  26. if (strncmp(gs_ascii_flag, grd_flag, strlen(gs_ascii_flag))) {
  27. G_warning(_("input file is not a Surfer ascii grid file"));
  28. return 0;
  29. }
  30. /* read the row and column dimensions */
  31. if (fscanf(fd, "%d %d \n", &nc, &nr) != 2) {
  32. G_warning(_("error reading the column and row dimension from the Surfer grid file"));
  33. return 0;
  34. }
  35. /* read the range of x values */
  36. if (fscanf(fd, "%f %f \n", &xmin, &xmax) != 2) {
  37. G_warning(_("error reading the X range from the Surfer grid file"));
  38. return 0;
  39. }
  40. /* read the range of y values */
  41. if (fscanf(fd, "%f %f \n", &ymin, &ymax) != 2) {
  42. G_warning(_("error reading the Y range from the Surfer grid file"));
  43. return 0;
  44. }
  45. /* read the range of z values (not used) */
  46. if (fscanf(fd, "%f %f \n", &zmin, &zmax) != 2) {
  47. G_warning(_("error reading the Z range from the Surfer grid file"));
  48. return 0;
  49. }
  50. /* initialize the cell header */
  51. cellhd->zone = G_zone();
  52. cellhd->proj = G_projection();
  53. cellhd->rows = nr;
  54. cellhd->cols = nc;
  55. cellhd->ew_res = (double)(xmax - xmin) / (nc - 1);
  56. cellhd->ns_res = (double)(ymax - ymin) / (nr - 1);
  57. /* the Surfer grid specifies x,y locations of gridded points. The GRASS raster
  58. specifies an area covered by rectangular cells centerd at gridded points.
  59. That difference requires an adjustment */
  60. cellhd->north = ymax + cellhd->ns_res / 2.;
  61. cellhd->south = ymin - cellhd->ns_res / 2.;
  62. cellhd->east = xmax + cellhd->ew_res / 2.;
  63. cellhd->west = xmin - cellhd->ew_res / 2.;
  64. return 1;
  65. }
  66. int gethead(FILE * fd,
  67. struct Cell_head *cellhd,
  68. RASTER_MAP_TYPE * d_type, DCELL * mult, char **nval)
  69. {
  70. int n, s, e, w, r, c;
  71. char label[100], value[100];
  72. char buf[1024];
  73. int ret, len;
  74. /* rsb fix */
  75. fpos_t p;
  76. n = s = e = w = r = c = 0;
  77. cellhd->zone = G_zone();
  78. cellhd->proj = G_projection();
  79. /* while (n == 0 || s== 0 || e == 0 || w == 0 || r == 0 || c == 0) */
  80. while (1) {
  81. /* rsb fix */
  82. if (fgetpos(fd, &p) != 0)
  83. G_fatal_error(_("error getting file position"));
  84. if (!G_getl2(buf, sizeof(buf), fd))
  85. break;
  86. len = strlen(buf);
  87. *label = *value = '\0';
  88. if (NULL == strstr(buf, ":"))
  89. break;
  90. if (sscanf(buf, "%[^:]:%s", label, value) != 2)
  91. break;
  92. if (*label == '\0')
  93. continue; /* ignore blank lines */
  94. if (strcmp(label, "north") == 0) {
  95. extract(n++, label, value, &cellhd->north, cellhd->proj,
  96. G_scan_northing);
  97. continue;
  98. }
  99. if (strcmp(label, "south") == 0) {
  100. extract(s++, label, value, &cellhd->south, cellhd->proj,
  101. G_scan_northing);
  102. continue;
  103. }
  104. if (strcmp(label, "east") == 0) {
  105. extract(e++, label, value, &cellhd->east, cellhd->proj,
  106. G_scan_easting);
  107. continue;
  108. }
  109. if (strcmp(label, "west") == 0) {
  110. extract(w++, label, value, &cellhd->west, cellhd->proj,
  111. G_scan_easting);
  112. continue;
  113. }
  114. if (strcmp(label, "rows") == 0) {
  115. extract(r++, label, value, &cellhd->rows, cellhd->proj, scan_int);
  116. continue;
  117. }
  118. if (strcmp(label, "cols") == 0) {
  119. extract(c++, label, value, &cellhd->cols, cellhd->proj, scan_int);
  120. continue;
  121. }
  122. /* try to read optional header fields */
  123. if (strcmp(label, "type") == 0) { /* if not exist then the file scan */
  124. if (*d_type < 0) { /* if data type not set on command line */
  125. if (!strncmp(value, INT, strlen(INT)))
  126. *d_type = CELL_TYPE;
  127. else if (!strncmp(value, FLOAT, strlen(FLOAT)))
  128. *d_type = FCELL_TYPE;
  129. else if (!strncmp(value, DOUBLE, strlen(DOUBLE)))
  130. *d_type = DCELL_TYPE;
  131. else {
  132. G_warning(_("illegal type field: using type int"));
  133. *d_type = CELL_TYPE;
  134. }
  135. }
  136. else
  137. G_warning(_("ignoring type filed in header, type is set on command line"));
  138. continue;
  139. }
  140. if (strcmp(label, "multiplier") == 0) {
  141. if (Rast_is_d_null_value(mult)) { /* if mult not set on commant line */
  142. if (sscanf(value, "%lf", mult) != 1) {
  143. G_warning(_("illegal multiplier field: using 1.0"));
  144. *mult = 1.0;
  145. }
  146. }
  147. else
  148. G_warning(_("ignoring multiplier filed in header, multiplier is set on command line"));
  149. continue;
  150. }
  151. if (strcmp(label, "null") == 0) {
  152. if (!(*nval)) /* if null val string not set on command line */
  153. *nval = G_store(value);
  154. else
  155. G_warning(_("ignoring null filed in header, null string is set on command line"));
  156. continue;
  157. }
  158. } /* while */
  159. /* the line read was not a header line, but actually
  160. the first data line, so put it back on the stack and break */
  161. /* rsb fix */
  162. fsetpos(fd, &p);
  163. missing(n, "north");
  164. missing(s, "south");
  165. missing(e, "east");
  166. missing(w, "west");
  167. missing(r, "rows");
  168. missing(c, "cols");
  169. if (!(*nval))
  170. *nval = G_store("*");
  171. if (Rast_is_d_null_value(mult))
  172. *mult = 1.0;
  173. /* if data type is not set, then scan data to find out data type */
  174. if (*d_type < 0) {
  175. ret = file_scan(fd);
  176. if (!ret)
  177. *d_type = DCELL_TYPE;
  178. else if (ret == 1)
  179. *d_type = CELL_TYPE;
  180. else {
  181. G_warning(_("error in ascii data format"));
  182. return 0;
  183. }
  184. }
  185. G_adjust_Cell_head(cellhd, 1, 1);
  186. return 1;
  187. }
  188. static int scan_int(char *s, int *i, int proj)
  189. {
  190. char dummy[3];
  191. *dummy = 0;
  192. if (sscanf(s, "%d%1s", i, dummy) != 1)
  193. return 0;
  194. if (*dummy)
  195. return 0;
  196. if (*i <= 0)
  197. return 0;
  198. return 1;
  199. }
  200. static int extract(int count,
  201. char *label, char *value,
  202. void *data, int proj, int (*scanner) ())
  203. {
  204. if (count) {
  205. G_warning(_("Duplicate \"%s\" field in header"), label);
  206. return 0;
  207. }
  208. if (scanner(value, data, proj))
  209. return 1;
  210. G_warning(_("Illegal \"%s\" value in header: %s"), label, value);
  211. return 0;
  212. }
  213. static int missing(int count, char *label)
  214. {
  215. if (count)
  216. return 0;
  217. G_warning(_("\"%s\" field missing from header"), label);
  218. return 1;
  219. }
  220. /* file_scan(): determine data type in ascii format */
  221. int file_scan(FILE * fd)
  222. {
  223. long curpos;
  224. char tmpbuf[TMPBUFSIZE];
  225. size_t size = TMPBUFSIZE;
  226. if ((curpos = G_ftell(fd)) == -1)
  227. return -1;
  228. while (!feof(fd)) {
  229. if (size != fread(tmpbuf, sizeof(char), size, fd)) {
  230. if (!feof(fd))
  231. return -1;
  232. }
  233. if (strstr(tmpbuf, DOT) != NULL) {
  234. G_fseek(fd, curpos - 1L, SEEK_SET);
  235. return 0;
  236. }
  237. }
  238. G_fseek(fd, curpos - 1L, SEEK_SET);
  239. return 1;
  240. }