io.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. #include "io.h"
  2. /* all in ram functions section */
  3. int ram_create_map(MAP * map, RASTER_MAP_TYPE data_type)
  4. {
  5. /*
  6. * allocates 0 filled nrows*ncols map of type void;
  7. * map parameters are stored in structure;
  8. * map: map to be created;
  9. * map type to be created must be CELL, FCELL, DCELL;
  10. * */
  11. int r;
  12. if (data_type < 0 || data_type > 2)
  13. G_fatal_error(_("Unable to create raster map of unrecognised type"));
  14. map->data_type = data_type;
  15. map->map_name = NULL;
  16. map->nrows = Rast_window_rows();
  17. map->ncols = Rast_window_cols();
  18. map->data_size = Rast_cell_size(data_type);
  19. /* preparing internal map */
  20. switch (map->data_type) {
  21. case CELL_TYPE:
  22. map->map = G_calloc(map->nrows, sizeof(CELL *));
  23. break;
  24. case FCELL_TYPE:
  25. map->map = G_calloc(map->nrows, sizeof(FCELL *));
  26. break;
  27. case DCELL_TYPE:
  28. map->map = G_calloc(map->nrows, sizeof(DCELL *));
  29. break;
  30. }
  31. for (r = 0; r < map->nrows; ++r)
  32. (map->map)[r] = G_calloc(map->ncols, map->data_size);
  33. return 0;
  34. }
  35. int ram_read_map(MAP * map, char *input_map_name, int check_res,
  36. RASTER_MAP_TYPE check_data_type)
  37. {
  38. /*
  39. * Function read external map and put it in MAP structure (created with create_map)
  40. * map: map to be read can be of any data type, read map is converted to target map if necessary.
  41. * input_map_name: name of the map to be read;
  42. * map pointer to map structure (created with create_map);
  43. * check_res: [1]: check res correspondence between region and map [0 no check];
  44. * check_data_type [CELL, FCELL, DCELL] check if reading map is of particular type, [-1] no check;
  45. */
  46. int r, c;
  47. char *mapset;
  48. struct Cell_head cellhd, this_window;
  49. char *maptypes[] = { "CELL", "FCELL", "DCELL" };
  50. int input_map_fd;
  51. RASTER_MAP_TYPE input_data_type;
  52. size_t input_data_size;
  53. void *input_buffer = NULL;
  54. void *input_pointer;
  55. /* checking if map exist */
  56. mapset = (char *)G_find_raster2(input_map_name, "");
  57. if (mapset == NULL)
  58. G_fatal_error(_("Raster map <%s> not found"), input_map_name);
  59. /* checking if region and input are the same */
  60. G_get_window(&this_window);
  61. Rast_get_cellhd(input_map_name, mapset, &cellhd);
  62. if (check_res)
  63. if (this_window.ew_res != cellhd.ew_res ||
  64. this_window.ns_res != cellhd.ns_res)
  65. G_fatal_error(_("Region resolution and raster map <%s> resolution differs. "
  66. "Run 'g.region rast=%s' to set proper region resolution."),
  67. input_map_name, input_map_name);
  68. /* checking if input map is of required type */
  69. if (check_data_type != map->data_type)
  70. G_debug(1,
  71. "ram_open:required map type and internal map type differs: conversion forced!");
  72. input_data_type = Rast_map_type(input_map_name, mapset);
  73. if (check_data_type != -1)
  74. if (input_data_type != check_data_type)
  75. G_fatal_error(_("Raster map <%s> is not of type '%s'"),
  76. input_map_name, maptypes[check_data_type]);
  77. input_map_fd = Rast_open_old(input_map_name, mapset);
  78. input_data_size = Rast_cell_size(input_data_type);
  79. { /* reading range */
  80. struct Range map_range;
  81. struct FPRange map_fp_range;
  82. int min, max;
  83. if (input_data_type == CELL_TYPE) {
  84. Rast_init_range(&map_range);
  85. Rast_read_range(input_map_name, mapset, &map_range);
  86. Rast_get_range_min_max(&map_range, &min, &max);
  87. map->min = (double)min;
  88. map->max = (double)max;
  89. }
  90. else {
  91. Rast_init_fp_range(&map_fp_range);
  92. Rast_read_fp_range(input_map_name, mapset, &map_fp_range);
  93. Rast_get_fp_range_min_max(&map_fp_range, &(map->min),
  94. &(map->max));
  95. }
  96. }
  97. /* end opening and checking */
  98. input_buffer = Rast_allocate_buf(input_data_type);
  99. /* start reading */
  100. G_message(_("Reading raster map <%s>..."), input_map_name);
  101. for (r = 0; r < map->nrows; ++r) {
  102. G_percent(r, map->nrows, 2);
  103. Rast_get_row(input_map_fd, input_buffer, r, input_data_type);
  104. input_pointer = input_buffer;
  105. for (c = 0; c < map->ncols; ++c)
  106. if (!Rast_is_null_value
  107. (input_pointer + c * input_data_size, input_data_type))
  108. switch (map->data_type) {
  109. case CELL_TYPE:
  110. ((CELL **) map->map)[r][c] =
  111. Rast_get_c_value(input_pointer + c * input_data_size,
  112. input_data_type);
  113. break;
  114. case FCELL_TYPE:
  115. ((FCELL **) map->map)[r][c] =
  116. Rast_get_f_value(input_pointer + c * input_data_size,
  117. input_data_type);
  118. break;
  119. case DCELL_TYPE:
  120. ((DCELL **) map->map)[r][c] =
  121. Rast_get_d_value(input_pointer + c * input_data_size,
  122. input_data_type);
  123. break;
  124. default:
  125. G_fatal_error(_("Wrong internal data type"));
  126. break;
  127. }
  128. } /*end for r */
  129. G_free(input_buffer);
  130. G_percent(r, map->nrows, 2);
  131. Rast_close(input_map_fd);
  132. return 0;
  133. } /* end create floating point map */
  134. int ram_reset_map(MAP * map, int value)
  135. {
  136. /*
  137. * set all cells in the map to value
  138. */
  139. int r;
  140. for (r = 0; r < map->nrows; ++r)
  141. memset((map->map)[r], value, map->ncols * map->data_size);
  142. return 0;
  143. }
  144. int ram_write_map(MAP * map, char *output_map_name,
  145. RASTER_MAP_TYPE output_data_type, int convert_to_null,
  146. double value)
  147. {
  148. /*
  149. * write map to disk with output_map_name and output_data_type [CELL, FCELL, DCELL];
  150. * if output_data_type = -1 than internal map type is used for output;
  151. * if output map != -1 and types differ data_type, conversion is forced
  152. * convert to null: check if convert to null a particular value in dataset;
  153. */
  154. int r, c;
  155. int output_fd = 0;
  156. struct History history;
  157. void *row;
  158. /* check for output format */
  159. if (output_data_type == -1)
  160. output_data_type = map->data_type;
  161. if (output_data_type != map->data_type)
  162. G_debug(1,
  163. "ram_write:required map type and internal map type differs: conversion forced!");
  164. G_message(_("Writing raster map <%s>..."), output_map_name);
  165. output_fd = Rast_open_new(output_map_name, output_data_type);
  166. /* writing */
  167. for (r = 0; r < map->nrows; ++r) {
  168. G_percent(r, map->nrows, 2);
  169. if (convert_to_null) {
  170. row = map->map[r];
  171. switch (map->data_type) {
  172. case CELL_TYPE:
  173. for (c = 0; c < map->ncols; ++c)
  174. if (((CELL *) row)[c] == (CELL) value)
  175. Rast_set_c_null_value(row + c * (map->data_size), 1);
  176. break;
  177. case FCELL_TYPE:
  178. for (c = 0; c < map->ncols; ++c)
  179. if (((FCELL *) row)[c] == (FCELL) value)
  180. Rast_set_f_null_value(row + c * (map->data_size), 1);
  181. break;
  182. case DCELL_TYPE:
  183. for (c = 0; c < map->ncols; ++c)
  184. if (((DCELL *) row)[c] == (DCELL) value)
  185. Rast_set_d_null_value(row + c * (map->data_size), 1);
  186. break;
  187. default:
  188. G_debug(1, "ram_null:Cannot convert to null at: %d %d", r, c);
  189. }
  190. }
  191. Rast_put_row(output_fd, (map->map)[r], output_data_type);
  192. }
  193. G_percent(r, map->nrows, 2);
  194. Rast_close(output_fd);
  195. Rast_short_history(output_map_name, "raster", &history);
  196. Rast_command_history(&history);
  197. Rast_write_history(output_map_name, &history);
  198. /* G_message(_("<%s> Done"), output_map_name); */
  199. return 0;
  200. }
  201. int ram_release_map(MAP *map)
  202. {
  203. /*
  204. * free memory allocated for map, set pointer to null;
  205. */
  206. int r;
  207. for (r = 0; r < map->nrows; ++r)
  208. G_free((map->map)[r]);
  209. G_free(map->map);
  210. map = NULL;
  211. return 0;
  212. }
  213. /* memory swap functions section */
  214. int seg_create_map(SEG * seg, int srows, int scols, int number_of_segs,
  215. RASTER_MAP_TYPE data_type)
  216. {
  217. /* create segment and returns pointer to it;
  218. * seg must be declared first;
  219. * parameters are stored in structure;
  220. * seg: segment to be created;
  221. * srows, scols segment size
  222. * number of segs max number of segs stored in memory
  223. * data_type to be created must be CELL, FCELL, DCELL;
  224. */
  225. char *filename;
  226. int fd;
  227. int local_number_of_segs;
  228. seg->fd = -1;
  229. seg->filename = NULL;
  230. seg->map_name = NULL;
  231. seg->mapset = NULL;
  232. seg->data_type = data_type;
  233. seg->nrows = Rast_window_rows();
  234. seg->ncols = Rast_window_cols();
  235. local_number_of_segs =
  236. (seg->nrows / srows + 1) * (seg->ncols / scols + 1);
  237. number_of_segs =
  238. (number_of_segs >
  239. local_number_of_segs) ? local_number_of_segs : number_of_segs;
  240. G_debug(3, "seg_creat:number of segments %d", number_of_segs);
  241. switch (seg->data_type) {
  242. case CELL_TYPE:
  243. seg->data_size = sizeof(CELL);
  244. break;
  245. case FCELL_TYPE:
  246. seg->data_size = sizeof(FCELL);
  247. break;
  248. case DCELL_TYPE:
  249. seg->data_size = sizeof(DCELL);
  250. break;
  251. default:
  252. G_fatal_error(_("Unrecognisable data type"));
  253. }
  254. filename = G_tempfile();
  255. fd = creat(filename, 0666);
  256. if (0 >
  257. segment_format(fd, seg->nrows, seg->ncols, srows, scols,
  258. seg->data_size)) {
  259. close(fd);
  260. unlink(filename);
  261. G_fatal_error(_("Unable to format segment"));
  262. }
  263. close(fd);
  264. if (0 > (fd = open(filename, 2))) {
  265. unlink(filename);
  266. G_fatal_error(_("Unable to re-open file '%s'"), filename);
  267. }
  268. if (0 > (fd = segment_init(&(seg->seg), fd, number_of_segs))) {
  269. unlink(filename);
  270. G_fatal_error(_("Unable to init segment file or out of memory"));
  271. }
  272. seg->filename = G_store(filename);
  273. seg->fd = fd;
  274. return 0;
  275. }
  276. int seg_read_map(SEG * seg, char *input_map_name, int check_res,
  277. RASTER_MAP_TYPE check_data_type)
  278. {
  279. /*
  280. * Function read external map and put it in SEG structure (created with seg_create_map)
  281. * map to be read can be of any data type, read map is converted if necessary.
  282. * input_map_name: name of the map to be read;
  283. * seg: pointer to map structure (created with create_map);
  284. * check_res: [1]: check res correspondence between region and map [0 no check];
  285. * check_data_type [CELL, FCELL, DCELL] check if reading map is of particular type, [-1] no check;
  286. */
  287. int input_fd;
  288. int r, c;
  289. char *mapset;
  290. struct Cell_head cellhd, this_window;
  291. char *maptypes[] = { "CELL", "FCELL", "DCELL" };
  292. RASTER_MAP_TYPE input_data_type;
  293. size_t input_data_size;
  294. void *input_buffer = NULL;
  295. void *target_buffer = NULL;
  296. void *input_pointer = NULL;
  297. /* checking if map exist */
  298. mapset = (char *)G_find_raster2(input_map_name, "");
  299. if (mapset == NULL)
  300. G_fatal_error(_("Raster map <%s> not found"),
  301. input_map_name);
  302. seg->mapset = mapset;
  303. /* checking if region and input are the same */
  304. G_get_window(&this_window);
  305. Rast_get_cellhd(input_map_name, mapset, &cellhd);
  306. /* check resolution equal any integer check; equal 0 no check */
  307. if (check_res)
  308. if (this_window.ew_res != cellhd.ew_res ||
  309. this_window.ns_res != cellhd.ns_res)
  310. G_fatal_error(_("Region resolution and raster map <%s> resolution differs. "
  311. "Run 'g.region rast=%s' to set proper region resolution."),
  312. input_map_name, input_map_name);
  313. if (check_data_type != seg->data_type)
  314. G_debug(1,
  315. "ram_open:required map type and internal map type differs: conversion forced!");
  316. input_data_type = Rast_map_type(input_map_name, mapset);
  317. if (check_data_type != -1)
  318. if (input_data_type != check_data_type)
  319. G_fatal_error(_("Raster map <%s> is not of type '%s'"),
  320. input_map_name, maptypes[check_data_type]);
  321. input_fd = Rast_open_old(input_map_name, mapset);
  322. input_data_size = Rast_cell_size(input_data_type);
  323. { /* reading range */
  324. struct Range map_range;
  325. struct FPRange map_fp_range;
  326. int min, max;
  327. if (input_data_type == CELL_TYPE) {
  328. Rast_init_range(&map_range);
  329. Rast_read_range(input_map_name, mapset, &map_range);
  330. Rast_get_range_min_max(&map_range, &min, &max);
  331. seg->min = (double)min;
  332. seg->max = (double)max;
  333. }
  334. else {
  335. Rast_init_fp_range(&map_fp_range);
  336. Rast_read_fp_range(input_map_name, mapset, &map_fp_range);
  337. Rast_get_fp_range_min_max(&map_fp_range, &(seg->min),
  338. &(seg->max));
  339. }
  340. }
  341. /* end opening and checking */
  342. G_message(_("Reading raster map <%s>..."), input_map_name);
  343. input_buffer = Rast_allocate_buf(input_data_type);
  344. target_buffer = Rast_allocate_buf(seg->data_type);
  345. for (r = 0; r < seg->nrows; ++r) {
  346. G_percent(r, seg->nrows, 2);
  347. Rast_get_row(input_fd, input_buffer, r, input_data_type);
  348. input_pointer = input_buffer;
  349. memset(target_buffer, 0, seg->ncols * seg->data_size);
  350. for (c = 0; c < seg->ncols; ++c)
  351. if (!Rast_is_null_value
  352. (input_pointer + c * input_data_size, input_data_type)) {
  353. switch (seg->data_type) {
  354. case CELL_TYPE:
  355. ((CELL *) target_buffer)[c] =
  356. Rast_get_c_value(input_pointer + c * input_data_size,
  357. input_data_type);
  358. break;
  359. case FCELL_TYPE:
  360. ((FCELL *) target_buffer)[c] =
  361. Rast_get_f_value(input_pointer + c * input_data_size,
  362. input_data_type);
  363. break;
  364. case DCELL_TYPE:
  365. ((DCELL *) target_buffer)[c] =
  366. Rast_get_d_value(input_pointer + c * input_data_size,
  367. input_data_type);
  368. break;
  369. default:
  370. G_fatal_error(_("Wrong internal data type"));
  371. break;
  372. }
  373. }
  374. if (0 > segment_put_row(&(seg->seg), target_buffer, r)) {
  375. G_free(input_buffer);
  376. G_free(target_buffer);
  377. Rast_close(input_fd);
  378. G_fatal_error(_("seg_read: Cannot segment put row %d for map %s"),
  379. r, input_map_name);
  380. }
  381. } /* end for row */
  382. G_percent(r, seg->nrows, 2);
  383. Rast_close(input_fd);
  384. G_free(input_buffer);
  385. G_free(target_buffer);
  386. seg->map_name = G_store(input_map_name);
  387. seg->mapset = G_store(mapset);
  388. return 0;
  389. }
  390. int seg_reset_map(SEG * seg, int value)
  391. {
  392. /*
  393. * set all cells in the map to value
  394. */
  395. int r, c;
  396. for (r = 0; r < seg->nrows; ++r)
  397. for (c = 0; c < seg->ncols; ++c)
  398. segment_put(&(seg->seg), &value, r, c);
  399. return 0;
  400. }
  401. int seg_write_map(SEG * seg, char *output_map_name,
  402. RASTER_MAP_TYPE output_data_type, int convert_to_null,
  403. double value)
  404. {
  405. /*
  406. * write seg to disk with output_map_name and output_data_type [CELL, FCELL, DCELL];
  407. * if output_data_type = -1 than internal map type is used for output;
  408. * if output map != -1 and types differ data_type, conversion is forced
  409. * convert to null: check if convert to null a particular value in dataset;
  410. */
  411. int output_fd;
  412. int r, c;
  413. void *output_buffer;
  414. void *row;
  415. struct History history;
  416. /* check for output format */
  417. if (output_data_type == -1)
  418. output_data_type = seg->data_type;
  419. if (output_data_type != seg->data_type)
  420. G_debug(1,
  421. "ram_write:required map type and internal map type differs: conversion forced!");
  422. G_message(_("Writing raster map <%s>..."), output_map_name);
  423. output_fd = Rast_open_new(output_map_name, output_data_type);
  424. output_buffer = Rast_allocate_buf(output_data_type);
  425. segment_flush(&(seg->seg));
  426. /* writing */
  427. for (r = 0; r < seg->nrows; ++r) {
  428. G_percent(r, seg->nrows, 2);
  429. if (0 > segment_get_row(&(seg->seg), output_buffer, r))
  430. G_warning(_("Unable to segment read row %d for raster map <%s>"),
  431. r, output_map_name);
  432. if (convert_to_null) {
  433. row = output_buffer;
  434. switch (seg->data_type) {
  435. case CELL_TYPE:
  436. for (c = 0; c < seg->ncols; ++c)
  437. if (((CELL *) output_buffer)[c] == (CELL) value)
  438. Rast_set_c_null_value(row + c * (seg->data_size), 1);
  439. break;
  440. case FCELL_TYPE:
  441. for (c = 0; c < seg->ncols; ++c)
  442. if (((FCELL *) output_buffer)[c] == (FCELL) value)
  443. Rast_set_f_null_value(row + c * (seg->data_size), 1);
  444. break;
  445. case DCELL_TYPE:
  446. for (c = 0; c < seg->ncols; ++c)
  447. if (((DCELL *) output_buffer)[c] == (DCELL) value)
  448. Rast_set_d_null_value(row + c * (seg->data_size), 1);
  449. break;
  450. default:
  451. G_warning(_("Unable to convert to NULL at: %d %d"), r,
  452. c);
  453. }
  454. }
  455. Rast_put_row(output_fd, output_buffer, output_data_type);
  456. }
  457. G_percent(r, seg->nrows, 2);
  458. G_free(output_buffer);
  459. Rast_close(output_fd);
  460. Rast_short_history(output_map_name, "raster", &history);
  461. Rast_command_history(&history);
  462. Rast_write_history(output_map_name, &history);
  463. /* G_message(_("%s Done"), output_map_name); */
  464. return 0;
  465. }
  466. int seg_release_map(SEG * seg)
  467. {
  468. /*
  469. * release segment close files, set pointers to null;
  470. */
  471. segment_release(&(seg->seg));
  472. close(seg->fd);
  473. unlink(seg->filename);
  474. if (seg->map_name)
  475. G_free(seg->map_name);
  476. if (seg->mapset)
  477. G_free(seg->mapset);
  478. return 0;
  479. }