main.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. /****************************************************************************
  2. *
  3. * MODULE: r3.out.vtk
  4. *
  5. * AUTHOR(S): Original author
  6. * Soeren Gebbert soerengebbert at gmx de
  7. * 27 Feb 2006 Berlin
  8. * PURPOSE: Converts 3D raster maps (G3D) into the VTK-Ascii format
  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/G3d.h>
  23. #include <grass/glocale.h>
  24. #include "globalDefs.h"
  25. #include "parameters.h"
  26. #include "writeVTKData.h"
  27. #include "writeVTKHead.h"
  28. #include "errorHandling.h"
  29. paramType param; /*Parameters */
  30. double x_extent;
  31. double y_extent;
  32. /** prototypes ***************************************************************/
  33. /*Open the rgb voxel maps and write the data to the output */
  34. static void open_write_rgb_maps(input_maps * in, G3D_Region region, FILE * fp,
  35. int dp);
  36. /*Open the rgb voxel maps and write the data to the output */
  37. static void open_write_vector_maps(input_maps * in, G3D_Region region,
  38. FILE * fp, int dp);
  39. /*opens a raster input map */
  40. static int open_input_map(const char *name, const char *mapset);
  41. /*Check if all maps are available */
  42. static void check_input_maps(void);
  43. /*Initiate the input maps structure */
  44. static input_maps *create_input_maps_struct(void);
  45. /* ************************************************************************* */
  46. /* Open the raster input map *********************************************** */
  47. /* ************************************************************************* */
  48. input_maps *create_input_maps_struct(void)
  49. {
  50. input_maps *in;
  51. in = (input_maps *) calloc(1, sizeof(input_maps));
  52. in->map = NULL;
  53. in->map_r = NULL;
  54. in->map_g = NULL;
  55. in->map_b = NULL;
  56. in->map_x = NULL;
  57. in->map_y = NULL;
  58. in->map_z = NULL;
  59. in->top = -1;
  60. in->bottom = -1;
  61. in->topMapType = 0;
  62. in->bottomMapType = 0;
  63. in->elevmaps = NULL;
  64. in->elevmaptypes = NULL;
  65. in->numelevmaps = 0;
  66. return in;
  67. }
  68. /* ************************************************************************* */
  69. /* Open the raster input map *********************************************** */
  70. /* ************************************************************************* */
  71. int open_input_map(const char *name, const char *mapset)
  72. {
  73. int fd;
  74. G_debug(3, "Open Raster file %s in Mapset %s", name, mapset);
  75. /* open raster map */
  76. fd = Rast_open_old(name, mapset);
  77. if (fd < 0)
  78. G_fatal_error(_("Could not open map %s"), name);
  79. return fd;
  80. }
  81. /* ************************************************************************* */
  82. /* Check the input maps **************************************************** */
  83. /* ************************************************************************* */
  84. void check_input_maps(void)
  85. {
  86. int i = 0;
  87. const char *mapset, *name;
  88. /*Check top and bottom if surface is requested */
  89. if (param.structgrid->answer) {
  90. if (!param.top->answer || !param.bottom->answer)
  91. G3d_fatalError(_("You have to specify top and bottom map"));
  92. mapset = NULL;
  93. name = NULL;
  94. name = param.top->answer;
  95. mapset = G_find_raster2(name, "");
  96. if (mapset == NULL) {
  97. G3d_fatalError(_("Top cell map <%s> not found"),
  98. param.top->answer);
  99. }
  100. mapset = NULL;
  101. name = NULL;
  102. name = param.bottom->answer;
  103. mapset = G_find_raster2(name, "");
  104. if (mapset == NULL) {
  105. G3d_fatalError(_("Bottom cell map <%s> not found"),
  106. param.bottom->answer);
  107. }
  108. }
  109. /*If input maps are provided, check them */
  110. if (param.input->answers != NULL) {
  111. for (i = 0; param.input->answers[i] != NULL; i++) {
  112. if (NULL == G_find_grid3(param.input->answers[i], ""))
  113. G3d_fatalError(_("Requested 3d raster map <%s> not found"),
  114. param.input->answers[i]);
  115. }
  116. }
  117. /*Check for rgb maps. */
  118. if (param.rgbmaps->answers != NULL) {
  119. for (i = 0; i < 3; i++) {
  120. if (param.rgbmaps->answers[i] != NULL) {
  121. if (NULL == G_find_grid3(param.rgbmaps->answers[i], ""))
  122. G3d_fatalError(_("Requested g3d RGB map <%s> not found"),
  123. param.rgbmaps->answers[i]);
  124. }
  125. else {
  126. G3d_fatalError(_("Please provide three g3d RGB maps"));
  127. }
  128. }
  129. }
  130. /*Check for vector maps. */
  131. if (param.vectormaps->answers != NULL) {
  132. for (i = 0; i < 3; i++) {
  133. if (param.vectormaps->answers[i] != NULL) {
  134. if (NULL == G_find_grid3(param.vectormaps->answers[i], ""))
  135. G3d_fatalError(_("Requested g3d vector map <%s> not found"),
  136. param.vectormaps->answers[i]);
  137. }
  138. else {
  139. G3d_fatalError(_("Please provide three g3d vector maps [x,y,z]"));
  140. }
  141. }
  142. }
  143. if (param.input->answers == NULL && param.rgbmaps->answers == NULL &&
  144. param.vectormaps->answers == NULL) {
  145. G_warning(_("No g3d data, RGB or xyz-vector maps are provided! Will only write the geometry."));
  146. }
  147. return;
  148. }
  149. /* ************************************************************************* */
  150. /* Prepare the VTK RGB voxel data for writing ****************************** */
  151. /* ************************************************************************* */
  152. void open_write_rgb_maps(input_maps * in, G3D_Region region, FILE * fp,
  153. int dp)
  154. {
  155. int i, changemask[3] = { 0, 0, 0 };
  156. void *maprgb = NULL;
  157. if (param.rgbmaps->answers != NULL) {
  158. /*Loop over all input maps! */
  159. for (i = 0; i < 3; i++) {
  160. G_debug(3, _("Open rgb 3d raster map %s"),
  161. param.rgbmaps->answers[i]);
  162. maprgb = NULL;
  163. /*Open the map */
  164. maprgb =
  165. G3d_openCellOld(param.rgbmaps->answers[i],
  166. G_find_grid3(param.rgbmaps->answers[i], ""),
  167. &region, G3D_TILE_SAME_AS_FILE,
  168. G3D_USE_CACHE_DEFAULT);
  169. if (maprgb == NULL) {
  170. G_warning(_("Error opening 3d raster map <%s>"),
  171. param.rgbmaps->answers[i]);
  172. fatal_error(_("No RGB Data will be created."), in);
  173. }
  174. /*if requested set the Mask on */
  175. if (param.mask->answer) {
  176. if (G3d_maskFileExists()) {
  177. changemask[i] = 0;
  178. if (G3d_maskIsOff(maprgb)) {
  179. G3d_maskOn(maprgb);
  180. changemask[i] = 1;
  181. }
  182. }
  183. }
  184. if (i == 0)
  185. in->map_r = maprgb;
  186. if (i == 1)
  187. in->map_g = maprgb;
  188. if (i == 2)
  189. in->map_b = maprgb;
  190. }
  191. G_debug(3, "Writing VTK VoxelData");
  192. write_vtk_rgb_data(in->map_r, in->map_g, in->map_b, fp, "RGB_Voxel",
  193. region, dp);
  194. for (i = 0; i < 3; i++) {
  195. if (i == 0)
  196. maprgb = in->map_r;
  197. if (i == 1)
  198. maprgb = in->map_g;
  199. if (i == 2)
  200. maprgb = in->map_b;
  201. /*We set the Mask off, if it was off before */
  202. if (param.mask->answer) {
  203. if (G3d_maskFileExists())
  204. if (G3d_maskIsOn(maprgb) && changemask[i])
  205. G3d_maskOff(maprgb);
  206. }
  207. /* Close the 3d raster map */
  208. if (!G3d_closeCell(maprgb)) {
  209. fatal_error(_("Error closing g3d rgb map."), in);
  210. }
  211. /*Set the pointer to null so we noe later that these files are already closed */
  212. if (i == 0)
  213. in->map_r = NULL;
  214. if (i == 1)
  215. in->map_g = NULL;
  216. if (i == 2)
  217. in->map_b = NULL;
  218. }
  219. }
  220. return;
  221. }
  222. /* ************************************************************************* */
  223. /* Prepare the VTK vector data for writing ********************************* */
  224. /* ************************************************************************* */
  225. void open_write_vector_maps(input_maps * in, G3D_Region region, FILE * fp,
  226. int dp)
  227. {
  228. int i, changemask[3] = { 0, 0, 0 };
  229. void *mapvect = NULL;
  230. if (param.vectormaps->answers != NULL) {
  231. /*Loop over all input maps! */
  232. for (i = 0; i < 3; i++) {
  233. G_debug(3, "Open vector 3d raster map %s",
  234. param.vectormaps->answers[i]);
  235. mapvect = NULL;
  236. /*Open the map */
  237. mapvect =
  238. G3d_openCellOld(param.vectormaps->answers[i],
  239. G_find_grid3(param.vectormaps->answers[i],
  240. ""), &region,
  241. G3D_TILE_SAME_AS_FILE, G3D_USE_CACHE_DEFAULT);
  242. if (mapvect == NULL) {
  243. G_warning(_("Error opening 3d raster map <%s>"),
  244. param.vectormaps->answers[i]);
  245. fatal_error(_("No vector data will be created."), in);
  246. }
  247. /*if requested set the Mask on */
  248. if (param.mask->answer) {
  249. if (G3d_maskFileExists()) {
  250. changemask[i] = 0;
  251. if (G3d_maskIsOff(mapvect)) {
  252. G3d_maskOn(mapvect);
  253. changemask[i] = 1;
  254. }
  255. }
  256. }
  257. if (i == 0)
  258. in->map_x = mapvect;
  259. if (i == 1)
  260. in->map_y = mapvect;
  261. if (i == 2)
  262. in->map_z = mapvect;
  263. }
  264. G_debug(3, "Writing VTK Vector Data");
  265. write_vtk_vector_data(in->map_x, in->map_y, in->map_z, fp,
  266. "Vector_Data", region, dp);
  267. for (i = 0; i < 3; i++) {
  268. if (i == 0)
  269. mapvect = in->map_x;
  270. if (i == 1)
  271. mapvect = in->map_y;
  272. if (i == 2)
  273. mapvect = in->map_z;
  274. /*We set the Mask off, if it was off before */
  275. if (param.mask->answer) {
  276. if (G3d_maskFileExists())
  277. if (G3d_maskIsOn(mapvect) && changemask[i])
  278. G3d_maskOff(mapvect);
  279. }
  280. /* Close the 3d raster map */
  281. if (!G3d_closeCell(mapvect)) {
  282. fatal_error(_("Error closing g3d vector map."), in);
  283. }
  284. /*Set the pointer to null so we noe later that these files are already closed */
  285. if (i == 0)
  286. in->map_x = NULL;
  287. if (i == 1)
  288. in->map_y = NULL;
  289. if (i == 2)
  290. in->map_z = NULL;
  291. }
  292. }
  293. return;
  294. }
  295. /* ************************************************************************* */
  296. /* Main function, opens most of the input and output files ***************** */
  297. /* ************************************************************************* */
  298. int main(int argc, char *argv[])
  299. {
  300. char *output = NULL;
  301. G3D_Region region;
  302. struct Cell_head window2d;
  303. struct Cell_head default_region;
  304. FILE *fp = NULL;
  305. struct GModule *module;
  306. int dp, i, changemask = 0;
  307. int rows, cols;
  308. const char *mapset, *name;
  309. double scale = 1.0, llscale = 1.0;
  310. input_maps *in;
  311. /* Initialize GRASS */
  312. G_gisinit(argv[0]);
  313. module = G_define_module();
  314. G_add_keyword(_("raster3d"));
  315. G_add_keyword(_("voxel"));
  316. module->description =
  317. _("Converts 3D raster maps (G3D) into the VTK-Ascii format");
  318. /* Get parameters from user */
  319. set_params();
  320. /* Have GRASS get inputs */
  321. if (G_parser(argc, argv))
  322. exit(EXIT_FAILURE);
  323. /*The precision of the output */
  324. if (param.decimals->answer) {
  325. if (sscanf(param.decimals->answer, "%d", &dp) != 1)
  326. G_fatal_error(_("failed to interpret dp as an integer"));
  327. if (dp > 20 || dp < 0)
  328. G_fatal_error(_("dp has to be from 0 to 20"));
  329. }
  330. else {
  331. dp = 8; /*This value is taken from the lib settings in G_format_easting */
  332. }
  333. /*Check the input */
  334. check_input_maps();
  335. /*Correct the coordinates, so the precision of VTK is not hurt :( */
  336. if (param.coorcorr->answer) {
  337. /*Get the default region for coordiante correction */
  338. G_get_default_window(&default_region);
  339. /*Use the center of the current region as extent */
  340. y_extent = (default_region.north + default_region.south) / 2;
  341. x_extent = (default_region.west + default_region.east) / 2;
  342. }
  343. else {
  344. x_extent = 0;
  345. y_extent = 0;
  346. }
  347. /*open the output */
  348. if (param.output->answer) {
  349. fp = fopen(param.output->answer, "w");
  350. if (fp == NULL) {
  351. perror(param.output->answer);
  352. G_usage();
  353. exit(EXIT_FAILURE);
  354. }
  355. }
  356. else
  357. fp = stdout;
  358. /* Figure out the region from the map */
  359. G3d_initDefaults();
  360. G3d_getWindow(&region);
  361. /*initiate the input mpas structure */
  362. in = create_input_maps_struct();
  363. /* read and compute the scale factor */
  364. sscanf(param.elevscale->answer, "%lf", &scale);
  365. /*if LL projection, convert the elevation values to degrees */
  366. if (region.proj == PROJECTION_LL) {
  367. llscale = M_PI / (180) * 6378137;
  368. scale /= llscale;
  369. }
  370. /*Open the top and bottom file */
  371. if (param.structgrid->answer) {
  372. /*Check if the g3d-region is equal to the 2d rows and cols */
  373. rows = G_window_rows();
  374. cols = G_window_cols();
  375. /*If not equal, set the 2D windows correct */
  376. if (rows != region.rows || cols != region.cols) {
  377. G_message(_("The 2d and 3d region settings are different. The g3d settings are used to adjust the 2d region."));
  378. G_get_set_window(&window2d);
  379. window2d.ns_res = region.ns_res;
  380. window2d.ew_res = region.ew_res;
  381. window2d.rows = region.rows;
  382. window2d.cols = region.cols;
  383. Rast_set_window(&window2d);
  384. }
  385. /*open top */
  386. mapset = NULL;
  387. name = NULL;
  388. name = param.top->answer;
  389. mapset = G_find_raster2(name, "");
  390. in->top = open_input_map(name, mapset);
  391. in->topMapType = Rast_get_map_type(in->top);
  392. /*open bottom */
  393. mapset = NULL;
  394. name = NULL;
  395. name = param.bottom->answer;
  396. mapset = G_find_raster2(name, "");
  397. in->bottom = open_input_map(name, mapset);
  398. in->bottomMapType = Rast_get_map_type(in->bottom);
  399. /* Write the vtk-header and the points */
  400. if (param.point->answer) {
  401. write_vtk_structured_grid_header(fp, output, region);
  402. write_vtk_points(in, fp, region, dp, 1, scale);
  403. }
  404. else {
  405. write_vtk_unstructured_grid_header(fp, output, region);
  406. write_vtk_points(in, fp, region, dp, 0, scale);
  407. write_vtk_unstructured_grid_cells(fp, region);
  408. }
  409. if (Rast_close(in->top) < 0) {
  410. G_fatal_error(_("unable to close top raster map"));
  411. }
  412. in->top = -1;
  413. if (Rast_close(in->bottom) < 0) {
  414. G_fatal_error(_("unable to close bottom raster map"));
  415. }
  416. in->bottom = -1;
  417. }
  418. else {
  419. /* Write the structured point vtk-header */
  420. write_vtk_structured_point_header(fp, output, region, dp, scale);
  421. }
  422. /*Write the normal VTK data (cell or point data) */
  423. /*Loop over all 3d input maps! */
  424. if (param.input->answers != NULL) {
  425. for (i = 0; param.input->answers[i] != NULL; i++) {
  426. G_debug(3, "Open 3d raster map %s", param.input->answers[i]);
  427. /*Open the map */
  428. in->map =
  429. G3d_openCellOld(param.input->answers[i],
  430. G_find_grid3(param.input->answers[i], ""),
  431. &region, G3D_TILE_SAME_AS_FILE,
  432. G3D_USE_CACHE_DEFAULT);
  433. if (in->map == NULL) {
  434. G_warning(_("Error opening 3d raster map <%s>"),
  435. param.input->answers[i]);
  436. fatal_error(" ", in);
  437. }
  438. /*if requested set the Mask on */
  439. if (param.mask->answer) {
  440. if (G3d_maskFileExists()) {
  441. changemask = 0;
  442. if (G3d_maskIsOff(in->map)) {
  443. G3d_maskOn(in->map);
  444. changemask = 1;
  445. }
  446. }
  447. }
  448. /* Write the point or cell data */
  449. write_vtk_data(fp, in->map, region, param.input->answers[i], dp);
  450. /*We set the Mask off, if it was off before */
  451. if (param.mask->answer) {
  452. if (G3d_maskFileExists())
  453. if (G3d_maskIsOn(in->map) && changemask)
  454. G3d_maskOff(in->map);
  455. }
  456. /* Close the 3d raster map */
  457. if (!G3d_closeCell(in->map)) {
  458. in->map = NULL;
  459. fatal_error(_("Error closing 3d raster map, the VTK file may be incomplete."),
  460. in);
  461. }
  462. in->map = NULL;
  463. }
  464. }
  465. /*Write the RGB voxel data */
  466. open_write_rgb_maps(in, region, fp, dp);
  467. open_write_vector_maps(in, region, fp, dp);
  468. /*Close the output file */
  469. if (param.output->answer && fp != NULL)
  470. if (fclose(fp))
  471. fatal_error(_("Error closing VTK-ASCII file"), in);
  472. /*close all open maps and free memory */
  473. release_input_maps_struct(in);
  474. return 0;
  475. }