rd_cellhd.c 10 KB

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