main.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /****************************************************************************
  2. *
  3. * MODULE: r3.to.rast
  4. *
  5. * AUTHOR(S): Original author
  6. * Soeren Gebbert soerengebbert@gmx.de
  7. * 08 01 2005 Berlin
  8. * PURPOSE: Converts 3D raster maps to 2D raster maps
  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. /*- Parameters and global variables -----------------------------------------*/
  25. typedef struct {
  26. struct Option *input, *output;
  27. struct Flag *mask;
  28. struct Flag *res; /*If set, use the same resolution as the input map */
  29. } paramType;
  30. paramType param; /*Parameters */
  31. /*- prototypes --------------------------------------------------------------*/
  32. void fatal_error(void *map, int *fd, int depths, char *errorMsg); /*Simple Error message */
  33. void set_params(); /*Fill the paramType structure */
  34. void g3d_to_raster(void *map, RASTER3D_Region region, int *fd); /*Write the raster */
  35. int open_output_map(const char *name, int res_type); /*opens the outputmap */
  36. void close_output_map(int fd); /*close the map */
  37. /* ************************************************************************* */
  38. /* Error handling ********************************************************** */
  39. /* ************************************************************************* */
  40. void fatal_error(void *map, int *fd, int depths, char *errorMsg)
  41. {
  42. int i;
  43. /* Close files and exit */
  44. if (map != NULL) {
  45. if (!Rast3d_close(map))
  46. Rast3d_fatal_error(_("Unable to close 3D raster map"));
  47. }
  48. if (fd != NULL) {
  49. for (i = 0; i < depths; i++)
  50. Rast_unopen(fd[i]);
  51. }
  52. Rast3d_fatal_error("%s", errorMsg);
  53. exit(EXIT_FAILURE);
  54. }
  55. /* ************************************************************************* */
  56. /* Set up the arguments we are expecting ********************************** */
  57. /* ************************************************************************* */
  58. void set_params()
  59. {
  60. param.input = G_define_option();
  61. param.input->key = "input";
  62. param.input->type = TYPE_STRING;
  63. param.input->required = YES;
  64. param.input->gisprompt = "old,grid3,3d-raster";
  65. param.input->description =
  66. _("3D raster map(s) to be converted to 2D raster slices");
  67. param.output = G_define_option();
  68. param.output->key = "output";
  69. param.output->type = TYPE_STRING;
  70. param.output->required = YES;
  71. param.output->description = _("Basename for resultant raster slice maps");
  72. param.output->gisprompt = "new,cell,raster";
  73. param.mask = G_define_flag();
  74. param.mask->key = 'm';
  75. param.mask->description = _("Use 3D raster mask (if exists) with input map");
  76. param.res = G_define_flag();
  77. param.res->key = 'r';
  78. param.res->description =
  79. _("Use the same resolution as the input 3D raster map for the 2D output "
  80. "maps, independent of the current region settings");
  81. }
  82. /* ************************************************************************* */
  83. /* Write the slices to seperate raster maps ******************************** */
  84. /* ************************************************************************* */
  85. void g3d_to_raster(void *map, RASTER3D_Region region, int *fd)
  86. {
  87. DCELL d1 = 0;
  88. FCELL f1 = 0;
  89. int x, y, z;
  90. int rows, cols, depths, typeIntern, pos = 0;
  91. FCELL *fcell = NULL;
  92. DCELL *dcell = NULL;
  93. rows = region.rows;
  94. cols = region.cols;
  95. depths = region.depths;
  96. G_debug(2, "g3d_to_raster: Writing %i raster maps with %i rows %i cols.",
  97. depths, rows, cols);
  98. typeIntern = Rast3d_tile_type_map(map);
  99. if (typeIntern == FCELL_TYPE)
  100. fcell = Rast_allocate_f_buf();
  101. else if (typeIntern == DCELL_TYPE)
  102. dcell = Rast_allocate_d_buf();
  103. pos = 0;
  104. /*Every Rastermap */
  105. for (z = 0; z < depths; z++) { /*From the bottom to the top */
  106. G_debug(2, "Writing raster map %d of %d", z + 1, depths);
  107. for (y = 0; y < rows; y++) {
  108. G_percent(y, rows - 1, 10);
  109. for (x = 0; x < cols; x++) {
  110. if (typeIntern == FCELL_TYPE) {
  111. Rast3d_get_value(map, x, y, z, &f1, typeIntern);
  112. if (Rast3d_is_null_value_num(&f1, FCELL_TYPE))
  113. Rast_set_null_value(&fcell[x], 1, FCELL_TYPE);
  114. else
  115. fcell[x] = f1;
  116. } else {
  117. Rast3d_get_value(map, x, y, z, &d1, typeIntern);
  118. if (Rast3d_is_null_value_num(&d1, DCELL_TYPE))
  119. Rast_set_null_value(&dcell[x], 1, DCELL_TYPE);
  120. else
  121. dcell[x] = d1;
  122. }
  123. }
  124. if (typeIntern == FCELL_TYPE)
  125. Rast_put_f_row(fd[pos], fcell);
  126. if (typeIntern == DCELL_TYPE)
  127. Rast_put_d_row(fd[pos], dcell);
  128. }
  129. G_debug(2, "Finished writing map %d.", z + 1);
  130. pos++;
  131. }
  132. if (dcell)
  133. G_free(dcell);
  134. if (fcell)
  135. G_free(fcell);
  136. }
  137. /* ************************************************************************* */
  138. /* Open the raster output map ********************************************** */
  139. /* ************************************************************************* */
  140. int open_output_map(const char *name, int res_type)
  141. {
  142. return Rast_open_new(name, res_type);
  143. }
  144. /* ************************************************************************* */
  145. /* Close the raster output map ********************************************* */
  146. /* ************************************************************************* */
  147. void close_output_map(int fd)
  148. {
  149. Rast_close(fd);
  150. }
  151. /* ************************************************************************* */
  152. /* Main function, open the RASTER3D map and create the raster maps ************** */
  153. /* ************************************************************************* */
  154. int main(int argc, char *argv[])
  155. {
  156. RASTER3D_Region region, inputmap_bounds;
  157. struct Cell_head region2d;
  158. struct GModule *module;
  159. struct History history;
  160. void *map = NULL; /*The 3D Rastermap */
  161. int i = 0, changemask = 0;
  162. int *fd = NULL, output_type, cols, rows;
  163. char *RasterFileName;
  164. int overwrite = 0;
  165. /* Initialize GRASS */
  166. G_gisinit(argv[0]);
  167. module = G_define_module();
  168. G_add_keyword(_("raster3d"));
  169. G_add_keyword(_("conversion"));
  170. G_add_keyword(_("raster"));
  171. G_add_keyword(_("voxel"));
  172. module->description = _("Converts 3D raster maps to 2D raster maps");
  173. /* Get parameters from user */
  174. set_params();
  175. /* Have GRASS get inputs */
  176. if (G_parser(argc, argv))
  177. exit(EXIT_FAILURE);
  178. G_debug(3, "Open 3D raster map <%s>", param.input->answer);
  179. if (NULL == G_find_raster3d(param.input->answer, ""))
  180. Rast3d_fatal_error(_("3D raster map <%s> not found"),
  181. param.input->answer);
  182. /*Set the defaults */
  183. Rast3d_init_defaults();
  184. /*Set the resolution of the output maps */
  185. if (param.res->answer) {
  186. /*Open the map with current region */
  187. map = Rast3d_open_cell_old(param.input->answer,
  188. G_find_raster3d(param.input->answer, ""),
  189. RASTER3D_DEFAULT_WINDOW, RASTER3D_TILE_SAME_AS_FILE,
  190. RASTER3D_USE_CACHE_DEFAULT);
  191. if (map == NULL)
  192. Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
  193. param.input->answer);
  194. /*Get the region of the map */
  195. Rast3d_get_region_struct_map(map, &region);
  196. /*set this region as current 3D window for map */
  197. Rast3d_set_window_map(map, &region);
  198. /*Set the 2d region appropriate */
  199. Rast3d_extract2d_region(&region, &region2d);
  200. /*Make the new 2d region the default */
  201. Rast_set_window(&region2d);
  202. } else {
  203. /* Figure out the region from the map */
  204. Rast3d_get_window(&region);
  205. /*Open the 3d raster map */
  206. map = Rast3d_open_cell_old(param.input->answer,
  207. G_find_raster3d(param.input->answer, ""),
  208. &region, RASTER3D_TILE_SAME_AS_FILE,
  209. RASTER3D_USE_CACHE_DEFAULT);
  210. if (map == NULL)
  211. Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
  212. param.input->answer);
  213. }
  214. /*Check if the g3d-region is equal to the 2D rows and cols */
  215. rows = Rast_window_rows();
  216. cols = Rast_window_cols();
  217. /*If not equal, set the 3D window correct */
  218. if (rows != region.rows || cols != region.cols) {
  219. G_message(_("The 2D and 3D region settings are different. "
  220. "Using the 2D window settings to adjust the 2D part of the 3D region."));
  221. G_get_set_window(&region2d);
  222. region.ns_res = region2d.ns_res;
  223. region.ew_res = region2d.ew_res;
  224. region.rows = region2d.rows;
  225. region.cols = region2d.cols;
  226. Rast3d_adjust_region(&region);
  227. Rast3d_set_window_map(map, &region);
  228. }
  229. /* save the input map region for later use (history meta-data) */
  230. Rast3d_get_region_struct_map(map, &inputmap_bounds);
  231. /*Get the output type */
  232. output_type = Rast3d_file_type_map(map);
  233. /*prepare the filehandler */
  234. fd = (int *) G_malloc(region.depths * sizeof (int));
  235. if (fd == NULL)
  236. fatal_error(map, NULL, 0, _("Out of memory"));
  237. G_message(_("Creating %i raster maps"), region.depths);
  238. /*Loop over all output maps! open */
  239. for (i = 0; i < region.depths; i++) {
  240. /*Create the outputmaps */
  241. G_asprintf(&RasterFileName, "%s_%05d", param.output->answer, i + 1);
  242. G_message(_("Raster map %i Filename: %s"), i + 1, RasterFileName);
  243. overwrite = G_check_overwrite(argc, argv);
  244. if (G_find_raster2(RasterFileName, "") && !overwrite)
  245. G_fatal_error(_("Raster map %d Filename: %s already exists. Use the flag --o to overwrite."),
  246. i + 1, RasterFileName);
  247. if (output_type == FCELL_TYPE)
  248. fd[i] = open_output_map(RasterFileName, FCELL_TYPE);
  249. else if (output_type == DCELL_TYPE)
  250. fd[i] = open_output_map(RasterFileName, DCELL_TYPE);
  251. }
  252. /*if requested set the Mask on */
  253. if (param.mask->answer) {
  254. if (Rast3d_mask_file_exists()) {
  255. changemask = 0;
  256. if (Rast3d_mask_is_off(map)) {
  257. Rast3d_mask_on(map);
  258. changemask = 1;
  259. }
  260. }
  261. }
  262. /*Create the Rastermaps */
  263. g3d_to_raster(map, region, fd);
  264. /*Loop over all output maps! close */
  265. for (i = 0; i < region.depths; i++) {
  266. close_output_map(fd[i]);
  267. /* write history */
  268. G_asprintf(&RasterFileName, "%s_%i", param.output->answer, i + 1);
  269. G_debug(4, "Raster map %d Filename: %s", i + 1, RasterFileName);
  270. Rast_short_history(RasterFileName, "raster", &history);
  271. Rast_set_history(&history, HIST_DATSRC_1, "3D Raster map:");
  272. Rast_set_history(&history, HIST_DATSRC_2, param.input->answer);
  273. Rast_append_format_history(&history, "Level %d of %d", i + 1, region.depths);
  274. Rast_append_format_history(&history, "Level z-range: %f to %f",
  275. region.bottom + (i * region.tb_res),
  276. region.bottom + (i + 1 * region.tb_res));
  277. Rast_append_format_history(&history, "Input map full z-range: %f to %f",
  278. inputmap_bounds.bottom, inputmap_bounds.top);
  279. Rast_append_format_history(&history, "Input map z-resolution: %f",
  280. inputmap_bounds.tb_res);
  281. if (!param.res->answer) {
  282. Rast_append_format_history(&history, "GIS region full z-range: %f to %f",
  283. region.bottom, region.top);
  284. Rast_append_format_history(&history, "GIS region z-resolution: %f",
  285. region.tb_res);
  286. }
  287. Rast_command_history(&history);
  288. Rast_write_history(RasterFileName, &history);
  289. }
  290. /*We set the Mask off, if it was off before */
  291. if (param.mask->answer) {
  292. if (Rast3d_mask_file_exists())
  293. if (Rast3d_mask_is_on(map) && changemask)
  294. Rast3d_mask_off(map);
  295. }
  296. /*Cleaning */
  297. if (RasterFileName)
  298. G_free(RasterFileName);
  299. if (fd)
  300. G_free(fd);
  301. /* Close files and exit */
  302. if (!Rast3d_close(map))
  303. fatal_error(map, NULL, 0, _("Unable to close 3D raster map"));
  304. map = NULL;
  305. return (EXIT_SUCCESS);
  306. }