rd_cellhd.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*!
  2. \file lib/gis/rd_cellhd.c
  3. \brief GIS Library - Read cell header or window
  4. (C) 1999-2011 by the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. \author USACERL and others
  8. */
  9. #include <string.h>
  10. #include <grass/gis.h>
  11. #include <grass/glocale.h>
  12. static int scan_item(const char *, char *, char *);
  13. static int scan_int(const char *, int *);
  14. static double scan_double(const char *, double *);
  15. #define F_PROJ 1
  16. #define F_ZONE 2
  17. #define F_NORTH 3
  18. #define F_SOUTH 4
  19. #define F_EAST 5
  20. #define F_WEST 6
  21. #define F_EWRES 7
  22. #define F_NSRES 8
  23. #define F_FORMAT 9
  24. #define F_COMP 10
  25. #define F_COLS 11
  26. #define F_ROWS 12
  27. #define F_EWRES3 13
  28. #define F_NSRES3 14
  29. #define F_COLS3 15
  30. #define F_ROWS3 16
  31. #define F_TOP 17
  32. #define F_BOTTOM 18
  33. #define F_TBRES 19
  34. #define F_DEPTHS 20
  35. #define SET(x) flags|=(1<<x)
  36. #define TEST(x) (flags&(1<<x))
  37. /*!
  38. \brief Read cell header (for internal use only)
  39. \param fp file descriptor
  40. \param[out] cellhd pointer to Cell_head structure
  41. \param is_cellhd ? (unused)
  42. */
  43. void G__read_Cell_head(FILE * fd, struct Cell_head *cellhd, int is_cellhd)
  44. {
  45. int count;
  46. char **array;
  47. char buf[1024];
  48. G_debug(2, "G__read_Cell_head");
  49. /* Count lines */
  50. count = 0;
  51. G_fseek(fd, 0L, 0);
  52. while (G_getl(buf, sizeof(buf), fd))
  53. count++;
  54. array = (char **)G_calloc(count + 1, sizeof(char *));
  55. count = 0;
  56. G_fseek(fd, 0L, 0);
  57. while (G_getl(buf, sizeof(buf), fd)) {
  58. array[count] = G_store(buf);
  59. count++;
  60. }
  61. G__read_Cell_head_array(array, cellhd, is_cellhd);
  62. count = 0;
  63. while (array[count]) {
  64. G_free(array[count]);
  65. count++;
  66. }
  67. G_free(array);
  68. }
  69. /*!
  70. \brief Read window from NULL terminated array of strings (for internal use only)
  71. \param array array of strings
  72. \param[out] cellhd pointer to Cell_head structure
  73. \param is_cellhd ? (unused)
  74. */
  75. void G__read_Cell_head_array(char **array,
  76. struct Cell_head *cellhd, int is_cellhd)
  77. {
  78. char *buf;
  79. char label[200];
  80. char value[200];
  81. int i, line;
  82. int flags;
  83. G_debug(2, "G__read_Cell_head_array");
  84. flags = 0;
  85. /* initialize the cell header */
  86. cellhd->format = 0;
  87. cellhd->rows = 0;
  88. cellhd->rows3 = 0;
  89. cellhd->cols = 0;
  90. cellhd->cols3 = 0;
  91. cellhd->depths = 1;
  92. cellhd->proj = -1;
  93. cellhd->zone = -1;
  94. cellhd->compressed = -1;
  95. cellhd->ew_res = 0.0;
  96. cellhd->ew_res3 = 1.0;
  97. cellhd->ns_res = 0.0;
  98. cellhd->ns_res3 = 1.0;
  99. cellhd->tb_res = 1.0;
  100. cellhd->north = 0.0;
  101. cellhd->south = 0.0;
  102. cellhd->east = 0.0;
  103. cellhd->west = 0.0;
  104. cellhd->top = 1.0;
  105. cellhd->bottom = 0.0;
  106. /* determine projection, zone first */
  107. i = 0;
  108. for (line = 1; (buf = array[i++]); line++) {
  109. if (TEST(F_PROJ) && TEST(F_ZONE))
  110. break;
  111. switch (scan_item(buf, label, value)) {
  112. case -1:
  113. G_fatal_error(_("Syntax error in cell header"));
  114. case 0:
  115. continue;
  116. case 1:
  117. break;
  118. }
  119. if (strncmp(label, "proj", 4) == 0) {
  120. if (TEST(F_PROJ))
  121. G_fatal_error(_("Duplicate projection field"));
  122. if (!scan_int(value, &cellhd->proj))
  123. G_fatal_error(_("Syntax error in cell header"));
  124. SET(F_PROJ);
  125. continue;
  126. }
  127. if (strncmp(label, "zone", 4) == 0) {
  128. if (TEST(F_ZONE))
  129. G_fatal_error(_("Duplicate zone field"));
  130. if (!scan_int(value, &cellhd->zone))
  131. G_fatal_error(_("Syntax error in cell header"));
  132. SET(F_ZONE);
  133. continue;
  134. }
  135. }
  136. if (!TEST(F_PROJ))
  137. G_fatal_error(_("Field <%s> missing"), "projection");
  138. if (!TEST(F_ZONE))
  139. G_fatal_error(_("Field <%s> missing"), "zone");
  140. /* read the other info */
  141. i = 0;
  142. for (line = 1; (buf = array[i++]); line++) {
  143. G_debug(3, "region item: %s", buf);
  144. switch (scan_item(buf, label, value)) {
  145. case -1:
  146. G_fatal_error(_("Syntax error in cell header"));
  147. case 0:
  148. continue;
  149. case 1:
  150. break;
  151. }
  152. if (strncmp(label, "proj", 4) == 0)
  153. continue;
  154. if (strncmp(label, "zone", 4) == 0)
  155. continue;
  156. if (strncmp(label, "nort", 4) == 0) {
  157. if (TEST(F_NORTH))
  158. G_fatal_error(_("Duplicate north field"));
  159. if (!G_scan_northing(value, &cellhd->north, cellhd->proj))
  160. G_fatal_error(_("Syntax error in cell header"));
  161. SET(F_NORTH);
  162. continue;
  163. }
  164. if (strncmp(label, "sout", 4) == 0) {
  165. if (TEST(F_SOUTH))
  166. G_fatal_error(_("Duplicate south field"));
  167. if (!G_scan_northing(value, &cellhd->south, cellhd->proj))
  168. G_fatal_error(_("Syntax error in cell header"));
  169. SET(F_SOUTH);
  170. continue;
  171. }
  172. if (strncmp(label, "east", 4) == 0) {
  173. if (TEST(F_EAST))
  174. G_fatal_error(_("Duplicate east field"));
  175. if (!G_scan_easting(value, &cellhd->east, cellhd->proj))
  176. G_fatal_error(_("Syntax error in cell header"));
  177. SET(F_EAST);
  178. continue;
  179. }
  180. if (strncmp(label, "west", 4) == 0) {
  181. if (TEST(F_WEST))
  182. G_fatal_error(_("Duplicate west field"));
  183. if (!G_scan_easting(value, &cellhd->west, cellhd->proj))
  184. G_fatal_error(_("Syntax error in cell header"));
  185. SET(F_WEST);
  186. continue;
  187. }
  188. if (strncmp(label, "top", 3) == 0) {
  189. if (TEST(F_TOP))
  190. G_fatal_error(_("Duplicate top field"));
  191. if (!scan_double(value, &cellhd->top))
  192. G_fatal_error(_("Syntax error in cell header"));
  193. SET(F_TOP);
  194. continue;
  195. }
  196. if (strncmp(label, "bottom", 6) == 0) {
  197. if (TEST(F_BOTTOM))
  198. G_fatal_error(_("Duplicate bottom field"));
  199. if (!scan_double(value, &cellhd->bottom))
  200. G_fatal_error(_("Syntax error in cell header"));
  201. SET(F_BOTTOM);
  202. continue;
  203. }
  204. if (strncmp(label, "e-w ", 4) == 0 && strlen(label) == 9) {
  205. if (TEST(F_EWRES))
  206. G_fatal_error(_("Duplicate e-w resolution field"));
  207. if (!G_scan_resolution(value, &cellhd->ew_res, cellhd->proj))
  208. G_fatal_error(_("Syntax error in cell header"));
  209. if (cellhd->ew_res <= 0.0)
  210. G_fatal_error(_("Syntax error in cell header"));
  211. SET(F_EWRES);
  212. continue;
  213. }
  214. if (strncmp(label, "e-w resol3", 10) == 0) {
  215. if (TEST(F_EWRES3))
  216. G_fatal_error(_("Duplicate 3D e-w resolution field"));
  217. if (!G_scan_resolution(value, &cellhd->ew_res3, cellhd->proj))
  218. G_fatal_error(_("Syntax error in cell header"));
  219. if (cellhd->ew_res3 <= 0.0)
  220. G_fatal_error(_("Syntax error in cell header"));
  221. SET(F_EWRES3);
  222. continue;
  223. }
  224. if (strncmp(label, "n-s ", 4) == 0 && strlen(label) == 9) {
  225. if (TEST(F_NSRES))
  226. G_fatal_error(_("Duplicate n-s resolution field"));
  227. if (!G_scan_resolution(value, &cellhd->ns_res, cellhd->proj))
  228. G_fatal_error(_("Syntax error in cell header"));
  229. if (cellhd->ns_res <= 0.0)
  230. G_fatal_error(_("Syntax error in cell header"));
  231. SET(F_NSRES);
  232. continue;
  233. }
  234. if (strncmp(label, "n-s resol3", 10) == 0) {
  235. if (TEST(F_NSRES3))
  236. G_fatal_error(_("Duplicate 3D n-s resolution field"));
  237. if (!G_scan_resolution(value, &cellhd->ns_res3, cellhd->proj))
  238. G_fatal_error(_("Syntax error in cell header"));
  239. if (cellhd->ns_res3 <= 0.0)
  240. G_fatal_error(_("Syntax error in cell header"));
  241. SET(F_NSRES3);
  242. continue;
  243. }
  244. if (strncmp(label, "t-b ", 4) == 0) {
  245. if (TEST(F_TBRES))
  246. G_fatal_error(_("Duplicate t-b resolution field"));
  247. if (!scan_double(value, &cellhd->tb_res))
  248. G_fatal_error(_("Syntax error in cell header"));
  249. if (cellhd->tb_res <= 0.0)
  250. G_fatal_error(_("Syntax error in cell header"));
  251. SET(F_TBRES);
  252. continue;
  253. }
  254. if (strncmp(label, "rows", 4) == 0 && strlen(label) == 4) {
  255. if (TEST(F_ROWS))
  256. G_fatal_error(_("Duplicate rows field"));
  257. if (!scan_int(value, &cellhd->rows))
  258. G_fatal_error(_("Syntax error in cell header"));
  259. if (cellhd->rows <= 0)
  260. G_fatal_error(_("Syntax error in cell header"));
  261. SET(F_ROWS);
  262. continue;
  263. }
  264. if (strncmp(label, "rows3", 5) == 0) {
  265. if (TEST(F_ROWS3))
  266. G_fatal_error(_("Duplicate 3D rows field"));
  267. if (!scan_int(value, &cellhd->rows3))
  268. G_fatal_error(_("Syntax error in cell header"));
  269. if (cellhd->rows3 <= 0)
  270. G_fatal_error(_("Syntax error in cell header"));
  271. SET(F_ROWS3);
  272. continue;
  273. }
  274. if (strncmp(label, "cols", 4) == 0 && strlen(label) == 4) {
  275. if (TEST(F_COLS))
  276. G_fatal_error(_("Duplicate cols field"));
  277. if (!scan_int(value, &cellhd->cols))
  278. G_fatal_error(_("Syntax error in cell header"));
  279. if (cellhd->cols <= 0)
  280. G_fatal_error(_("Syntax error in cell header"));
  281. SET(F_COLS);
  282. continue;
  283. }
  284. if (strncmp(label, "cols3", 5) == 0) {
  285. if (TEST(F_COLS3))
  286. G_fatal_error(_("Duplicate 3D cols field"));
  287. if (!scan_int(value, &cellhd->cols3))
  288. G_fatal_error(_("Syntax error in cell header"));
  289. if (cellhd->cols3 <= 0)
  290. G_fatal_error(_("Syntax error in cell header"));
  291. SET(F_COLS3);
  292. continue;
  293. }
  294. if (strncmp(label, "depths", 6) == 0) {
  295. if (TEST(F_DEPTHS))
  296. G_fatal_error(_("Duplicate depths field"));
  297. if (!scan_int(value, &cellhd->depths))
  298. G_fatal_error(_("Syntax error in cell header"));
  299. if (cellhd->depths <= 0)
  300. G_fatal_error(_("Syntax error in cell header"));
  301. SET(F_DEPTHS);
  302. continue;
  303. }
  304. if (strncmp(label, "form", 4) == 0) {
  305. if (TEST(F_FORMAT))
  306. G_fatal_error(_("Duplicate format field"));
  307. if (!scan_int(value, &cellhd->format))
  308. G_fatal_error(_("Syntax error in cell header"));
  309. SET(F_FORMAT);
  310. continue;
  311. }
  312. if (strncmp(label, "comp", 4) == 0) {
  313. if (TEST(F_COMP))
  314. G_fatal_error(_("Duplicate compressed field"));
  315. if (!scan_int(value, &cellhd->compressed))
  316. G_fatal_error(_("Syntax error in cell header"));
  317. SET(F_COMP);
  318. continue;
  319. }
  320. G_fatal_error(_("Syntax error in cell header"));
  321. }
  322. /* check some of the fields */
  323. if (!TEST(F_NORTH))
  324. G_fatal_error(_("Field <%s> missing"), "north");
  325. if (!TEST(F_SOUTH))
  326. G_fatal_error(_("Field <%s> missing"), "south");
  327. if (!TEST(F_WEST))
  328. G_fatal_error(_("Field <%s> missing"), "west");
  329. if (!TEST(F_EAST))
  330. G_fatal_error(_("Field <%s> missing"), "east");
  331. if (!TEST(F_EWRES) && !TEST(F_COLS))
  332. G_fatal_error(_("Field <%s> missing"), "cols");
  333. if (!TEST(F_NSRES) && !TEST(F_ROWS))
  334. G_fatal_error(_("Field <%s> missing"), "rows");
  335. /* This next stmt is commented out to allow wr_cellhd.c to write
  336. * headers that will be readable by GRASS 3.1
  337. if ((TEST(F_ROWS) && TEST(F_NSRES))
  338. || (TEST(F_COLS) && TEST(F_EWRES)))
  339. ERROR ("row/col and resolution information can not both appear ",0);
  340. */
  341. /* 3D defined? */
  342. if (TEST(F_EWRES3) || TEST(F_NSRES3) || TEST(F_COLS3) || TEST(F_ROWS3)) {
  343. if (!TEST(F_EWRES3))
  344. G_fatal_error(_("Field <%s> missing"), "ewres3");
  345. if (!TEST(F_NSRES3))
  346. G_fatal_error(_("Field <%s> missing"), "nsres3");
  347. if (!TEST(F_COLS3))
  348. G_fatal_error(_("Field <%s> missing"), "cols3");
  349. if (!TEST(F_ROWS3))
  350. G_fatal_error(_("Field <%s> missing"), "rows3");
  351. }
  352. else { /* use 2D */
  353. cellhd->ew_res3 = cellhd->ew_res;
  354. cellhd->ns_res3 = cellhd->ns_res;
  355. cellhd->cols3 = cellhd->cols;
  356. cellhd->rows3 = cellhd->rows;
  357. }
  358. /* Adjust and complete the cell header */
  359. G_adjust_Cell_head(cellhd, TEST(F_ROWS), TEST(F_COLS));
  360. }
  361. static int scan_item(const char *buf, char *label, char *value)
  362. {
  363. /* skip blank lines */
  364. if (sscanf(buf, "%1s", label) != 1)
  365. return 0;
  366. /* skip comment lines */
  367. if (*label == '#')
  368. return 0;
  369. /* must be label: value */
  370. if (sscanf(buf, "%[^:]:%[^\n]", label, value) != 2)
  371. return -1;
  372. G_strip(label);
  373. G_strip(value);
  374. return 1;
  375. }
  376. static int scan_int(const char *buf, int *n)
  377. {
  378. char dummy[3];
  379. *dummy = 0;
  380. return (sscanf(buf, "%d%1s", n, dummy) == 1 && *dummy == 0);
  381. }
  382. static double scan_double(const char *buf, double *n)
  383. {
  384. char dummy[3];
  385. *dummy = 0;
  386. return (sscanf(buf, "%lf%1s", n, dummy) == 1 && *dummy == 0);
  387. }