N_arrays_io.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /*****************************************************************************
  2. *
  3. * MODULE: Grass PDE Numerical Library
  4. * AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
  5. * soerengebbert <at> gmx <dot> de
  6. *
  7. * PURPOSE: IO array managment functions
  8. * part of the gpde library
  9. *
  10. * COPYRIGHT: (C) 2000 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. *****************************************************************************/
  17. #include <math.h>
  18. #include <grass/N_pde.h>
  19. #include <grass/raster.h>
  20. #include <grass/glocale.h>
  21. /* ******************** 2D ARRAY FUNCTIONS *********************** */
  22. /*!
  23. * \brief Read a raster map into a N_array_2d structure
  24. *
  25. * The raster map will be opened in the current region settings.
  26. * If no N_array_2d structure is provided (NULL pointer), a new structure will be
  27. * allocated with the same data type as the raster map and the size of the current region.
  28. * The array offset will be set to 0.
  29. * <br><br>
  30. * If a N_array_2d structure is provided, the values from the raster map are
  31. * casted to the N_array_2d type. The array must have the same size
  32. * as the current region.
  33. * <br><br>
  34. * The new created or the provided array are returned.
  35. * If the reading of the raster map fails, G_fatal_error() will
  36. * be invoked.
  37. *
  38. * \param name * char - the name of an existing raster map
  39. * \param array * N_array_2d - an existing array or NULL
  40. * \return N_array_2d * - the existing or new allocated array
  41. * */
  42. N_array_2d *N_read_rast_to_array_2d(char *name, N_array_2d * array)
  43. {
  44. int map; /*The rastermap */
  45. int x, y, cols, rows, type;
  46. void *rast;
  47. void *ptr;
  48. struct Cell_head region;
  49. N_array_2d *data = array;
  50. if (NULL == G_find_cell2(name, ""))
  51. G_fatal_error(_("Raster map <%s> not found"), name);
  52. /* Get the active region */
  53. G_get_set_window(&region);
  54. /*set the rows and cols */
  55. rows = region.rows;
  56. cols = region.cols;
  57. /*open the raster map */
  58. map = Rast_open_old(name, G_find_cell2(name, ""));
  59. if (map < 0)
  60. G_fatal_error(_("Unable to open raster map <%s>"), name);
  61. type = Rast_get_map_type(map);
  62. /*if the array is NULL create a new one with the data type of the raster map */
  63. /*the offset is 0 by default */
  64. if (data == NULL) {
  65. if (type == DCELL_TYPE) {
  66. data = N_alloc_array_2d(cols, rows, 0, DCELL_TYPE);
  67. }
  68. if (type == FCELL_TYPE) {
  69. data = N_alloc_array_2d(cols, rows, 0, FCELL_TYPE);
  70. }
  71. if (type == CELL_TYPE) {
  72. data = N_alloc_array_2d(cols, rows, 0, CELL_TYPE);
  73. }
  74. }
  75. else {
  76. /*Check the array sizes */
  77. if (data->cols != cols)
  78. G_fatal_error
  79. ("N_read_rast_to_array_2d: the data array size is different from the current region settings");
  80. if (data->rows != rows)
  81. G_fatal_error
  82. ("N_read_rast_to_array_2d: the data array size is different from the current region settings");
  83. }
  84. rast = Rast_allocate_buf(type);
  85. G_message(_("Reading raster map <%s> into memory"), name);
  86. for (y = 0; y < rows; y++) {
  87. G_percent(y, rows - 1, 10);
  88. if (!Rast_get_row(map, rast, y, type)) {
  89. Rast_close(map);
  90. G_fatal_error(_("Could not get raster row"));
  91. }
  92. for (x = 0, ptr = rast; x < cols;
  93. x++, ptr = G_incr_void_ptr(ptr, Rast_cell_size(type))) {
  94. if (type == CELL_TYPE) {
  95. if (Rast_is_c_null_value(ptr)) {
  96. N_put_array_2d_value_null(data, x, y);
  97. }
  98. else {
  99. if (data->type == CELL_TYPE)
  100. N_put_array_2d_c_value(data, x, y,
  101. (CELL) * (CELL *) ptr);
  102. if (data->type == FCELL_TYPE)
  103. N_put_array_2d_f_value(data, x, y,
  104. (FCELL) * (CELL *) ptr);
  105. if (data->type == DCELL_TYPE)
  106. N_put_array_2d_d_value(data, x, y,
  107. (DCELL) * (CELL *) ptr);
  108. }
  109. }
  110. if (type == FCELL_TYPE) {
  111. if (Rast_is_f_null_value(ptr)) {
  112. N_put_array_2d_value_null(data, x, y);
  113. }
  114. else {
  115. if (data->type == CELL_TYPE)
  116. N_put_array_2d_c_value(data, x, y,
  117. (CELL) * (FCELL *) ptr);
  118. if (data->type == FCELL_TYPE)
  119. N_put_array_2d_f_value(data, x, y,
  120. (FCELL) * (FCELL *) ptr);
  121. if (data->type == DCELL_TYPE)
  122. N_put_array_2d_d_value(data, x, y,
  123. (DCELL) * (FCELL *) ptr);
  124. }
  125. }
  126. if (type == DCELL_TYPE) {
  127. if (Rast_is_d_null_value(ptr)) {
  128. N_put_array_2d_value_null(data, x, y);
  129. }
  130. else {
  131. if (data->type == CELL_TYPE)
  132. N_put_array_2d_c_value(data, x, y,
  133. (CELL) * (DCELL *) ptr);
  134. if (data->type == FCELL_TYPE)
  135. N_put_array_2d_f_value(data, x, y,
  136. (FCELL) * (DCELL *) ptr);
  137. if (data->type == DCELL_TYPE)
  138. N_put_array_2d_d_value(data, x, y,
  139. (DCELL) * (DCELL *) ptr);
  140. }
  141. }
  142. }
  143. }
  144. /* Close file */
  145. if (Rast_close(map) < 0)
  146. G_fatal_error(_("Unable to close input map"));
  147. return data;
  148. }
  149. /*!
  150. * \brief Write a N_array_2d struct to a raster map
  151. *
  152. * A new raster map is created with the same type as the N_array_2d.
  153. * The current region is used to open the raster map.
  154. * The N_array_2d must have the same size as the current region.
  155. If the writing of the raster map fails, G_fatal_error() will
  156. * be invoked.
  157. * \param array N_array_2d *
  158. * \param name char * - the name of the raster map
  159. * \return void
  160. *
  161. * */
  162. void N_write_array_2d_to_rast(N_array_2d * array, char *name)
  163. {
  164. int map; /*The rastermap */
  165. int x, y, cols, rows, count, type;
  166. CELL *rast = NULL;
  167. FCELL *frast = NULL;
  168. DCELL *drast = NULL;
  169. struct Cell_head region;
  170. if (!array)
  171. G_fatal_error(_("N_array_2d * array is empty"));
  172. /* Get the current region */
  173. G_get_set_window(&region);
  174. rows = region.rows;
  175. cols = region.cols;
  176. type = array->type;
  177. /*Open the new map */
  178. map = Rast_open_new(name, type);
  179. if (map < 0)
  180. G_fatal_error(_("Unable to create raster map <%s>"), name);
  181. if (type == CELL_TYPE)
  182. rast = Rast_allocate_buf(type);
  183. if (type == FCELL_TYPE)
  184. frast = Rast_allocate_buf(type);
  185. if (type == DCELL_TYPE)
  186. drast = Rast_allocate_buf(type);
  187. G_message(_("Write 2d array to raster map <%s>"), name);
  188. count = 0;
  189. for (y = 0; y < rows; y++) {
  190. G_percent(y, rows - 1, 10);
  191. for (x = 0; x < cols; x++) {
  192. if (type == CELL_TYPE)
  193. rast[x] = N_get_array_2d_c_value(array, x, y);
  194. if (type == FCELL_TYPE)
  195. frast[x] = N_get_array_2d_f_value(array, x, y);
  196. if (type == DCELL_TYPE)
  197. drast[x] = N_get_array_2d_d_value(array, x, y);
  198. }
  199. if (type == CELL_TYPE)
  200. if (!Rast_put_c_raster_row(map, rast)) {
  201. Rast_unopen(map); /*unopen the new raster map */
  202. G_fatal_error(_("Unable to write raster row %i"), y);
  203. }
  204. if (type == FCELL_TYPE)
  205. if (!Rast_put_f_raster_row(map, frast)) {
  206. Rast_unopen(map); /*unopen the new raster map */
  207. G_fatal_error(_("Unable to write raster row %i"), y);
  208. }
  209. if (type == DCELL_TYPE)
  210. if (!Rast_put_d_raster_row(map, drast)) {
  211. Rast_unopen(map); /*unopen the new raster map */
  212. G_fatal_error(_("Unable to write raster row %i"), y);
  213. }
  214. }
  215. /* Close file */
  216. if (Rast_close(map) < 0)
  217. G_fatal_error(_("Unable to close input map"));
  218. return;
  219. }
  220. /* ******************** 3D ARRAY FUNCTIONS *********************** */
  221. /*!
  222. * \brief Read a volume map into a N_array_3d structure
  223. *
  224. * The volume map is opened in the current region settings.
  225. * If no N_array_3d structure is provided (NULL pointer), a new structure will be
  226. * allocated with the same data type as the volume map and the size of the current region.
  227. * The array offset will be set to 0.
  228. * <br><br>
  229. *
  230. * If a N_array_3d structure is provided, the values from the volume map are
  231. * casted to the N_array_3d type. The array must have the same size
  232. * as the current region.
  233. * <br><br>
  234. *
  235. * The new created or the provided array is returned.
  236. * If the reading of the volume map fails, G3d_fatalError() will
  237. * be invoked.
  238. *
  239. * \param name * char - the name of an existing volume map
  240. * \param array * N_array_3d - an existing array or NULL
  241. * \param mask int - 0 = false, 1 = ture : if a mask is presenent, use it with the input volume map
  242. * \return N_array_3d * - the existing or new allocated array
  243. * */
  244. N_array_3d *N_read_rast3d_to_array_3d(char *name, N_array_3d * array,
  245. int mask)
  246. {
  247. void *map = NULL; /*The 3D Rastermap */
  248. int changemask = 0;
  249. int x, y, z, cols, rows, depths, type;
  250. double d1 = 0, f1 = 0;
  251. N_array_3d *data = array;
  252. G3D_Region region;
  253. /*get the current region */
  254. G3d_getWindow(&region);
  255. cols = region.cols;
  256. rows = region.rows;
  257. depths = region.depths;
  258. if (NULL == G_find_grid3(name, ""))
  259. G3d_fatalError(_("Requested g3d map <%s> not found"), name);
  260. /*Open all maps with default region */
  261. map =
  262. G3d_openCellOld(name, G_find_grid3(name, ""), G3D_DEFAULT_WINDOW,
  263. G3D_TILE_SAME_AS_FILE, G3D_USE_CACHE_DEFAULT);
  264. if (map == NULL)
  265. G3d_fatalError(_("Error opening g3d map <%s>"), name);
  266. type = G3d_tileTypeMap(map);
  267. /*if the array is NULL create a new one with the data type of the volume map */
  268. /*the offset is 0 by default */
  269. if (data == NULL) {
  270. if (type == FCELL_TYPE) {
  271. data = N_alloc_array_3d(cols, rows, depths, 0, FCELL_TYPE);
  272. }
  273. if (type == DCELL_TYPE) {
  274. data = N_alloc_array_3d(cols, rows, depths, 0, DCELL_TYPE);
  275. }
  276. }
  277. else {
  278. /*Check the array sizes */
  279. if (data->cols != cols)
  280. G_fatal_error
  281. ("N_read_rast_to_array_3d: the data array size is different from the current region settings");
  282. if (data->rows != rows)
  283. G_fatal_error
  284. ("N_read_rast_to_array_3d: the data array size is different from the current region settings");
  285. if (data->depths != depths)
  286. G_fatal_error
  287. ("N_read_rast_to_array_3d: the data array size is different from the current region settings");
  288. }
  289. G_message(_("Read g3d map <%s> into the memory"), name);
  290. /*if requested set the Mask on */
  291. if (mask) {
  292. if (G3d_maskFileExists()) {
  293. changemask = 0;
  294. if (G3d_maskIsOff(map)) {
  295. G3d_maskOn(map);
  296. changemask = 1;
  297. }
  298. }
  299. }
  300. for (z = 0; z < depths; z++) { /*From the bottom to the top */
  301. G_percent(z, depths - 1, 10);
  302. for (y = 0; y < rows; y++) {
  303. for (x = 0; x < cols; x++) {
  304. if (type == FCELL_TYPE) {
  305. G3d_getValue(map, x, y, z, &f1, type);
  306. if (Rast_is_f_null_value((void *)&f1)) {
  307. N_put_array_3d_value_null(data, x, y, z);
  308. }
  309. else {
  310. if (data->type == FCELL_TYPE)
  311. N_put_array_3d_f_value(data, x, y, z, f1);
  312. if (data->type == DCELL_TYPE)
  313. N_put_array_3d_d_value(data, x, y, z, (double)f1);
  314. }
  315. }
  316. else {
  317. G3d_getValue(map, x, y, z, &d1, type);
  318. if (Rast_is_d_null_value((void *)&d1)) {
  319. N_put_array_3d_value_null(data, x, y, z);
  320. }
  321. else {
  322. if (data->type == FCELL_TYPE)
  323. N_put_array_3d_f_value(data, x, y, z, (float)d1);
  324. if (data->type == DCELL_TYPE)
  325. N_put_array_3d_d_value(data, x, y, z, d1);
  326. }
  327. }
  328. }
  329. }
  330. }
  331. /*We set the Mask off, if it was off before */
  332. if (mask) {
  333. if (G3d_maskFileExists())
  334. if (G3d_maskIsOn(map) && changemask)
  335. G3d_maskOff(map);
  336. }
  337. /* Close files and exit */
  338. if (!G3d_closeCell(map))
  339. G3d_fatalError(map, NULL, 0, _("Error closing g3d file"));
  340. return data;
  341. }
  342. /*!
  343. * \brief Write a N_array_3d struct to a volume map
  344. *
  345. * A new volume map is created with the same type as the N_array_3d.
  346. * The current region is used to open the volume map.
  347. * The N_array_3d must have the same size as the current region.
  348. * If the writing of the volume map fails, G3d_fatalError() will
  349. * be invoked.
  350. *
  351. *
  352. * \param array N_array_3d *
  353. * \param name char * - the name of the volume map
  354. * \param mask int - 1 = use a 3d mask, 0 do not use a 3d mask
  355. * \return void
  356. *
  357. * */
  358. void N_write_array_3d_to_rast3d(N_array_3d * array, char *name, int mask)
  359. {
  360. void *map = NULL; /*The 3D Rastermap */
  361. int changemask = 0;
  362. int x, y, z, cols, rows, depths, count, type;
  363. double d1 = 0.0, f1 = 0.0;
  364. N_array_3d *data = array;
  365. G3D_Region region;
  366. /*get the current region */
  367. G3d_getWindow(&region);
  368. cols = region.cols;
  369. rows = region.rows;
  370. depths = region.depths;
  371. type = data->type;
  372. /*Check the array sizes */
  373. if (data->cols != cols)
  374. G_fatal_error
  375. ("N_write_array_3d_to_rast3d: the data array size is different from the current region settings");
  376. if (data->rows != rows)
  377. G_fatal_error
  378. ("N_write_array_3d_to_rast3d: the data array size is different from the current region settings");
  379. if (data->depths != depths)
  380. G_fatal_error
  381. ("N_write_array_3d_to_rast3d: the data array size is different from the current region settings");
  382. /*Open the new map */
  383. if (type == DCELL_TYPE)
  384. map =
  385. G3d_openCellNew(name, DCELL_TYPE, G3D_USE_CACHE_DEFAULT, &region);
  386. else if (type == FCELL_TYPE)
  387. map =
  388. G3d_openCellNew(name, FCELL_TYPE, G3D_USE_CACHE_DEFAULT, &region);
  389. if (map == NULL)
  390. G3d_fatalError(_("Error opening g3d map <%s>"), name);
  391. G_message(_("Write 3d array to g3d map <%s>"), name);
  392. /*if requested set the Mask on */
  393. if (mask) {
  394. if (G3d_maskFileExists()) {
  395. changemask = 0;
  396. if (G3d_maskIsOff(map)) {
  397. G3d_maskOn(map);
  398. changemask = 1;
  399. }
  400. }
  401. }
  402. count = 0;
  403. for (z = 0; z < depths; z++) { /*From the bottom to the top */
  404. G_percent(z, depths - 1, 10);
  405. for (y = 0; y < rows; y++) {
  406. for (x = 0; x < cols; x++) {
  407. if (type == FCELL_TYPE) {
  408. f1 = N_get_array_3d_f_value(data, x, y, z);
  409. G3d_putFloat(map, x, y, z, f1);
  410. }
  411. else if (type == DCELL_TYPE) {
  412. d1 = N_get_array_3d_d_value(data, x, y, z);
  413. G3d_putDouble(map, x, y, z, d1);
  414. }
  415. }
  416. }
  417. }
  418. /*We set the Mask off, if it was off before */
  419. if (mask) {
  420. if (G3d_maskFileExists())
  421. if (G3d_maskIsOn(map) && changemask)
  422. G3d_maskOff(map);
  423. }
  424. /* Close files and exit */
  425. if (!G3d_closeCell(map))
  426. G3d_fatalError(map, NULL, 0, _("Error closing g3d file"));
  427. return;
  428. }