main.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /****************************************************************************
  2. *
  3. * MODULE: r.to.rast3
  4. *
  5. * AUTHOR(S): Original author
  6. * Soeren Gebbert soerengebbert@gmx.de
  7. * 08 01 2005 Berlin
  8. * PURPOSE: Converts 2D raster map slices to one 3D volume map
  9. *
  10. * COPYRIGHT: (C) 2005 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 <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <grass/gis.h>
  21. #include <grass/raster.h>
  22. #include <grass/raster3d.h>
  23. #include <grass/glocale.h>
  24. #include <grass/config.h>
  25. /*- params and global variables -----------------------------------------*/
  26. typedef struct {
  27. struct Option *input, *output, *tilesize;
  28. struct Flag *mask;
  29. } paramType;
  30. paramType param; /*params */
  31. int globalRastMapType;
  32. int globalG3dMapType;
  33. /*- prototypes --------------------------------------------------------------*/
  34. void fatal_error(void *map, int *fd, int depths, char *errorMsg); /*Simple Error message */
  35. void set_params(); /*Fill the paramType structure */
  36. void raster_to_g3d(void *map, RASTER3D_Region region, int *fd); /*Write the raster */
  37. int open_input_raster_map(const char *name); /*opens the outputmap */
  38. void close_input_raster_map(int fd); /*close the map */
  39. /* ************************************************************************* */
  40. /* Error handling ********************************************************** */
  41. /* ************************************************************************* */
  42. void fatal_error(void *map, int *fd, int depths, char *errorMsg)
  43. {
  44. int i;
  45. /* Close files and exit */
  46. if (map != NULL) {
  47. /* should unopen map here! but this functionality is not jet implemented */
  48. if (!Rast3d_close(map))
  49. Rast3d_fatal_error(_("Could not close the map"));
  50. }
  51. if (fd != NULL) {
  52. for (i = 0; i < depths; i++)
  53. close_input_raster_map(fd[i]);
  54. }
  55. Rast3d_fatal_error(errorMsg);
  56. exit(EXIT_FAILURE);
  57. }
  58. /* ************************************************************************* */
  59. /* Setg up the arguments we are expecting ********************************** */
  60. /* ************************************************************************* */
  61. void set_params()
  62. {
  63. param.input = G_define_standard_option(G_OPT_R_INPUTS);
  64. param.input->description = _("2d raster maps which represent the slices");
  65. param.output = G_define_standard_option(G_OPT_R3_OUTPUT);
  66. param.tilesize = G_define_option();
  67. param.tilesize->description = _("The maximum tile size in kilo bytes. Default is 32KB.");
  68. param.tilesize->key = "tilesize";
  69. param.tilesize->answer = "32";
  70. param.tilesize->type = TYPE_INTEGER;
  71. param.tilesize->required = NO;
  72. param.tilesize->multiple = NO;
  73. param.mask = G_define_flag();
  74. param.mask->key = 'm';
  75. param.mask->description = _("Use 3D raster mask (if exists) with output map");
  76. }
  77. /* ************************************************************************* */
  78. /* Write the raster maps into one RASTER3D map ********************************** */
  79. /* ************************************************************************* */
  80. void raster_to_g3d(void *map, RASTER3D_Region region, int *fd)
  81. {
  82. int x, y, z;
  83. int rows, cols, depths;
  84. void *rast;
  85. void *ptr;
  86. FCELL fvalue;
  87. DCELL dvalue;
  88. rows = region.rows;
  89. cols = region.cols;
  90. depths = region.depths;
  91. rast = Rast_allocate_buf(globalRastMapType);
  92. G_debug(3, "raster_to_g3d: Writing %i raster maps with %i rows %i cols.",
  93. depths, rows, cols);
  94. /*Every Rastermap */
  95. for (z = 0; z < depths; z++) { /*From the bottom to the top */
  96. G_percent(z, depths, 1);
  97. G_debug(4, "Writing g3d slice %i", z + 1);
  98. for (y = 0; y < rows; y++) { /* From north to south */
  99. Rast_get_row(fd[z], rast, y, globalRastMapType);
  100. for (x = 0, ptr = rast; x < cols; x++,
  101. ptr =
  102. G_incr_void_ptr(ptr, Rast_cell_size(globalRastMapType))) {
  103. if (globalRastMapType == CELL_TYPE) {
  104. if (Rast_is_null_value(ptr, globalRastMapType)) {
  105. Rast3d_set_null_value(&dvalue, 1, DCELL_TYPE);
  106. } else {
  107. dvalue = *(CELL *) ptr;
  108. }
  109. if (Rast3d_put_value
  110. (map, x, y, z, (char *) &dvalue, DCELL_TYPE) < 0)
  111. fatal_error(map, fd, depths,
  112. "Error writing double data");
  113. } else if (globalRastMapType == FCELL_TYPE) {
  114. if (Rast_is_null_value(ptr, globalRastMapType)) {
  115. Rast3d_set_null_value(&fvalue, 1, FCELL_TYPE);
  116. } else {
  117. fvalue = *(FCELL *) ptr;
  118. }
  119. if (Rast3d_put_value
  120. (map, x, y, z, (char *) &fvalue, FCELL_TYPE) < 0)
  121. fatal_error(map, fd, depths,
  122. "Error writing float data");
  123. } else if (globalRastMapType == DCELL_TYPE) {
  124. if (Rast_is_null_value(ptr, globalRastMapType)) {
  125. Rast3d_set_null_value(&dvalue, 1, DCELL_TYPE);
  126. } else {
  127. dvalue = *(DCELL *) ptr;
  128. }
  129. if (Rast3d_put_value
  130. (map, x, y, z, (char *) &dvalue, DCELL_TYPE) < 0)
  131. fatal_error(map, fd, depths,
  132. "Error writing double data");
  133. }
  134. }
  135. }
  136. }
  137. G_percent(1, 1, 1);
  138. if (rast)
  139. G_free(rast);
  140. }
  141. /* ************************************************************************* */
  142. /* Main function, open the raster maps and create the RASTER3D raster map ******* */
  143. /* ************************************************************************* */
  144. int main(int argc, char *argv[])
  145. {
  146. RASTER3D_Region region;
  147. struct Cell_head window2d;
  148. struct GModule *module;
  149. void *map = NULL; /*The 3D Rastermap */
  150. int i = 0;
  151. int *fd = NULL; /*The filehandler array for the 2D inputmaps */
  152. int cols, rows, opencells;
  153. char *name;
  154. int changemask = 0;
  155. int maptype_tmp, nofile = 0;
  156. int maxSize;
  157. /* Initialize GRASS */
  158. G_gisinit(argv[0]);
  159. module = G_define_module();
  160. G_add_keyword(_("raster"));
  161. G_add_keyword(_("conversion"));
  162. G_add_keyword(_("voxel"));
  163. module->description =
  164. _("Converts 2D raster map slices to one 3D raster volume map.");
  165. /* Get parameters from user */
  166. set_params();
  167. /* Have GRASS get inputs */
  168. if (G_parser(argc, argv))
  169. exit(EXIT_FAILURE);
  170. /*Check for output */
  171. if (param.output->answer == NULL)
  172. Rast3d_fatal_error(_("No output map"));
  173. /* Get the tile size */
  174. maxSize = atoi(param.tilesize->answer);
  175. /* Figure out the region from the map */
  176. Rast3d_init_defaults();
  177. Rast3d_get_window(&region);
  178. /*Check if the g3d-region is equal to the 2d rows and cols */
  179. rows = Rast_window_rows();
  180. cols = Rast_window_cols();
  181. G_debug(2, "Check the 2d and 3d region settings");
  182. /*If not equal, set the 2D windows correct */
  183. if (rows != region.rows || cols != region.cols) {
  184. G_message(_("The 2D and 3D region settings are different. I will use the 3D region settings to adjust the 2D region."));
  185. G_get_set_window(&window2d);
  186. window2d.ns_res = region.ns_res;
  187. window2d.ew_res = region.ew_res;
  188. window2d.rows = region.rows;
  189. window2d.cols = region.cols;
  190. Rast_set_window(&window2d);
  191. }
  192. /*prepare the filehandler */
  193. fd = (int *) G_malloc(region.depths * sizeof (int));
  194. if (fd == NULL)
  195. fatal_error(map, NULL, 0, _("Out of memory"));
  196. name = NULL;
  197. globalRastMapType = DCELL_TYPE;
  198. globalG3dMapType = DCELL_TYPE;
  199. maptype_tmp = DCELL_TYPE;
  200. opencells = 0; /*Number of opened maps */
  201. /*Loop over all output maps! open */
  202. for (i = 0; i < region.depths; i++) {
  203. /*Open only existing maps */
  204. if (nofile == 0 && param.input->answers[i])
  205. name = param.input->answers[i];
  206. else
  207. nofile = 1;
  208. /*if only one map is given, open it depths - times */
  209. G_verbose_message(_("Open raster map %s - one time for each depth (%d/%d)"),
  210. name, i + 1, region.depths);
  211. fd[i] = open_input_raster_map(name);
  212. opencells++;
  213. maptype_tmp = Rast_get_map_type(fd[i]);
  214. /*maptype */
  215. if (i == 0)
  216. globalRastMapType = maptype_tmp;
  217. if (maptype_tmp != globalRastMapType) {
  218. fatal_error(map, fd, opencells,
  219. _("Input maps have to be from the same type. CELL, FCELL or DCELL!"));
  220. }
  221. }
  222. G_message(_("Creating 3D raster map"));
  223. map = NULL;
  224. /* Set the map type depending from the arster maps type */
  225. if (globalRastMapType == CELL_TYPE || globalRastMapType == DCELL_TYPE)
  226. globalG3dMapType = DCELL_TYPE;
  227. else
  228. globalG3dMapType = FCELL_TYPE;
  229. map = Rast3d_open_new_opt_tile_size(param.output->answer, RASTER3D_USE_CACHE_XY, &region, globalG3dMapType, maxSize);
  230. if (map == NULL)
  231. fatal_error(map, fd, opencells, _("Error opening 3D raster map"));
  232. /*if requested set the Mask on */
  233. if (param.mask->answer) {
  234. if (Rast3d_mask_file_exists()) {
  235. changemask = 0;
  236. if (Rast3d_mask_is_off(map)) {
  237. Rast3d_mask_on(map);
  238. changemask = 1;
  239. }
  240. }
  241. }
  242. /*Create the RASTER3D Rastermap */
  243. raster_to_g3d(map, region, fd);
  244. /*We set the Mask off, if it was off before */
  245. if (param.mask->answer) {
  246. if (Rast3d_mask_file_exists())
  247. if (Rast3d_mask_is_on(map) && changemask)
  248. Rast3d_mask_off(map);
  249. }
  250. /*Loop over all output maps! close */
  251. for (i = 0; i < region.depths; i++)
  252. close_input_raster_map(fd[i]);
  253. if (fd)
  254. G_free(fd);
  255. /* Flush all tile */
  256. if (!Rast3d_flush_all_tiles(map))
  257. Rast3d_fatal_error("Error flushing tiles with Rast3d_flush_all_tiles");
  258. /* Close files and exit */
  259. if (!Rast3d_close(map))
  260. Rast3d_fatal_error(_("Error closing 3d raster map"));
  261. map = NULL;
  262. G_debug(2, "Done\n");
  263. return (EXIT_SUCCESS);
  264. }
  265. /* ************************************************************************* */
  266. /* Open the raster input map *********************************************** */
  267. /* ************************************************************************* */
  268. int open_input_raster_map(const char *name)
  269. {
  270. G_debug(3, "Open Raster file %s", name);
  271. return Rast_open_old(name, "");
  272. }
  273. /* ************************************************************************* */
  274. /* Close the raster input map ********************************************** */
  275. /* ************************************************************************* */
  276. void close_input_raster_map(int fd)
  277. {
  278. Rast_close(fd);
  279. }