rd_cellhd.c 12 KB

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