rd_cellhd.c 10 KB

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