main.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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/G3d.h>
  22. #include <grass/glocale.h>
  23. #include <grass/config.h>
  24. /*- params and global variables -----------------------------------------*/
  25. typedef struct
  26. {
  27. struct Option *input, *output;
  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, G3D_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 (!G3d_closeCell(map))
  49. G3d_fatalError(_("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. G3d_fatalError(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.mask = G_define_flag();
  67. param.mask->key = 'm';
  68. param.mask->description = _("Use G3D mask (if exists) with output map");
  69. }
  70. /* ************************************************************************* */
  71. /* Write the raster maps into one G3D map ********************************** */
  72. /* ************************************************************************* */
  73. void raster_to_g3d(void *map, G3D_Region region, int *fd)
  74. {
  75. int x, y, z;
  76. int rows, cols, depths;
  77. void *rast;
  78. void *ptr;
  79. FCELL fvalue;
  80. DCELL dvalue;
  81. rows = region.rows;
  82. cols = region.cols;
  83. depths = region.depths;
  84. rast = G_allocate_raster_buf(globalRastMapType);
  85. G_debug(3, "raster_to_g3d: Writing %i raster maps with %i rows %i cols.",
  86. depths, rows, cols);
  87. /*Every Rastermap */
  88. for (z = 0; z < depths; z++) { /*From the bottom to the top */
  89. G_debug(4, "Writing g3d slice %i", z + 1);
  90. for (y = 0; y < rows; y++) {
  91. G_percent(y, rows - 1, 10);
  92. if (!G_get_raster_row(fd[z], rast, y, globalRastMapType))
  93. fatal_error(map, fd, depths, _("Could not get raster row"));
  94. for (x = 0, ptr = rast; x < cols; x++,
  95. ptr =
  96. G_incr_void_ptr(ptr, G_raster_size(globalRastMapType))) {
  97. if (globalRastMapType == CELL_TYPE) {
  98. if (G_is_null_value(ptr, globalRastMapType)) {
  99. G3d_setNullValue(&dvalue, 1, DCELL_TYPE);
  100. }
  101. else {
  102. dvalue = *(CELL *) ptr;
  103. }
  104. if (G3d_putValue
  105. (map, x, y, z, (char *)&dvalue, DCELL_TYPE) < 0)
  106. fatal_error(map, fd, depths,
  107. "Error writing double data");
  108. }
  109. else if (globalRastMapType == FCELL_TYPE) {
  110. if (G_is_null_value(ptr, globalRastMapType)) {
  111. G3d_setNullValue(&fvalue, 1, FCELL_TYPE);
  112. }
  113. else {
  114. fvalue = *(FCELL *) ptr;
  115. }
  116. if (G3d_putValue
  117. (map, x, y, z, (char *)&fvalue, FCELL_TYPE) < 0)
  118. fatal_error(map, fd, depths,
  119. "Error writing float data");
  120. }
  121. else if (globalRastMapType == DCELL_TYPE) {
  122. if (G_is_null_value(ptr, globalRastMapType)) {
  123. G3d_setNullValue(&dvalue, 1, DCELL_TYPE);
  124. }
  125. else {
  126. dvalue = *(DCELL *) ptr;
  127. }
  128. if (G3d_putValue
  129. (map, x, y, z, (char *)&dvalue, DCELL_TYPE) < 0)
  130. fatal_error(map, fd, depths,
  131. "Error writing double data");
  132. }
  133. }
  134. }
  135. G_debug(2, "\nDone\n");
  136. }
  137. if (rast)
  138. G_free(rast);
  139. }
  140. /* ************************************************************************* */
  141. /* Main function, open the raster maps and create the G3D raster map ******* */
  142. /* ************************************************************************* */
  143. int main(int argc, char *argv[])
  144. {
  145. G3D_Region region;
  146. struct Cell_head window2d;
  147. struct GModule *module;
  148. void *map = NULL; /*The 3D Rastermap */
  149. int i = 0;
  150. int *fd = NULL; /*The filehandler array for the 2D inputmaps */
  151. int cols, rows, opencells;
  152. char *name;
  153. int changemask = 0;
  154. int maptype_tmp, nofile = 0;
  155. /* Initialize GRASS */
  156. G_gisinit(argv[0]);
  157. module = G_define_module();
  158. module->keywords = _("raster, volume, conversion");
  159. module->description =
  160. _("Converts 2D raster map slices to one 3D raster volume map.");
  161. /* Get parameters from user */
  162. set_params();
  163. /* Have GRASS get inputs */
  164. if (G_parser(argc, argv))
  165. exit(EXIT_FAILURE);
  166. /*Check for output */
  167. if (param.output->answer == NULL)
  168. G3d_fatalError(_("No output map"));
  169. /* Figure out the region from the map */
  170. G3d_initDefaults();
  171. G3d_getWindow(&region);
  172. /*Check if the g3d-region is equal to the 2d rows and cols */
  173. rows = G_window_rows();
  174. cols = G_window_cols();
  175. G_debug(2, "Check the 2d and 3d region settings");
  176. /*If not equal, set the 2D windows correct */
  177. if (rows != region.rows || cols != region.cols) {
  178. G_message(_("The 2d and 3d region settings are different. I will use the g3d settings to adjust the 2d region."));
  179. G_get_set_window(&window2d);
  180. window2d.ns_res = region.ns_res;
  181. window2d.ew_res = region.ew_res;
  182. window2d.rows = region.rows;
  183. window2d.cols = region.cols;
  184. G_set_window(&window2d);
  185. }
  186. /*prepare the filehandler */
  187. fd = (int *)G_malloc(region.depths * sizeof(int));
  188. if (fd == NULL)
  189. fatal_error(map, NULL, 0, _("Out of memory"));
  190. name = NULL;
  191. globalRastMapType = DCELL_TYPE;
  192. globalG3dMapType = DCELL_TYPE;
  193. maptype_tmp = DCELL_TYPE;
  194. opencells = 0; /*Number of opened maps */
  195. /*Loop over all output maps! open */
  196. for (i = 0; i < region.depths; i++) {
  197. /*Open only existing maps */
  198. if (nofile == 0 && param.input->answers[i])
  199. name = param.input->answers[i];
  200. else
  201. nofile = 1;
  202. /*if only one map is given, open it depths - times */
  203. G_message(_("Open raster map %s - one time for each depth (%d/%d)"),
  204. name, i + 1, region.depths);
  205. fd[i] = open_input_raster_map(name);
  206. opencells++;
  207. maptype_tmp = G_get_raster_map_type(fd[i]);
  208. /*maptype */
  209. if (i == 0)
  210. globalRastMapType = maptype_tmp;
  211. if (maptype_tmp != globalRastMapType) {
  212. fatal_error(map, fd, opencells,
  213. _("Input maps have to be from the same type. CELL, FCELL or DCELL!"));
  214. }
  215. }
  216. G_message(_("Creating 3D raster map"));
  217. map = NULL;
  218. if (globalRastMapType == CELL_TYPE) {
  219. map =
  220. G3d_openCellNew(param.output->answer, DCELL_TYPE,
  221. G3D_USE_CACHE_DEFAULT, &region);
  222. globalG3dMapType = DCELL_TYPE;
  223. }
  224. else if (globalRastMapType == FCELL_TYPE) {
  225. map =
  226. G3d_openCellNew(param.output->answer, FCELL_TYPE,
  227. G3D_USE_CACHE_DEFAULT, &region);
  228. globalG3dMapType = FCELL_TYPE;
  229. }
  230. else if (globalRastMapType == DCELL_TYPE) {
  231. map =
  232. G3d_openCellNew(param.output->answer, DCELL_TYPE,
  233. G3D_USE_CACHE_DEFAULT, &region);
  234. globalG3dMapType = DCELL_TYPE;
  235. }
  236. if (map == NULL)
  237. fatal_error(map, fd, opencells, _("Error opening 3d raster map"));
  238. /*if requested set the Mask on */
  239. if (param.mask->answer) {
  240. if (G3d_maskFileExists()) {
  241. changemask = 0;
  242. if (G3d_maskIsOff(map)) {
  243. G3d_maskOn(map);
  244. changemask = 1;
  245. }
  246. }
  247. }
  248. /*Create the G3D Rastermap */
  249. raster_to_g3d(map, region, fd);
  250. /*We set the Mask off, if it was off before */
  251. if (param.mask->answer) {
  252. if (G3d_maskFileExists())
  253. if (G3d_maskIsOn(map) && changemask)
  254. G3d_maskOff(map);
  255. }
  256. /*Loop over all output maps! close */
  257. for (i = 0; i < region.depths; i++)
  258. close_input_raster_map(fd[i]);
  259. if (fd)
  260. G_free(fd);
  261. /* Close files and exit */
  262. if (!G3d_closeCell(map))
  263. G3d_fatalError(_("Error closing 3d raster map"));
  264. map = NULL;
  265. G_debug(2, "Done\n");
  266. return (EXIT_SUCCESS);
  267. }
  268. /* ************************************************************************* */
  269. /* Open the raster input map *********************************************** */
  270. /* ************************************************************************* */
  271. int open_input_raster_map(const char *name)
  272. {
  273. int fd;
  274. G_debug(3, "Open Raster file %s", name);
  275. /* open raster map */
  276. fd = G_open_cell_old(name, "");
  277. if (fd < 0)
  278. G_fatal_error(_("Unable to open raster map <%s>"), name);
  279. return fd;
  280. }
  281. /* ************************************************************************* */
  282. /* Close the raster input map ********************************************** */
  283. /* ************************************************************************* */
  284. void close_input_raster_map(int fd)
  285. {
  286. if (G_close_cell(fd) < 0)
  287. G_fatal_error(_("Unable to close input map"));
  288. }