main.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * r3.out.v5d -
  3. *
  4. * Copyright Jaro Hofierka
  5. * GeoModel,s.r.o., Bratislava, 1999
  6. * hofierka@geomodel.sk
  7. *
  8. * Improvements:
  9. * - added true coordinates support Markus Neteler 1/2001
  10. * - Region sensivity by MN 1/2001
  11. * - Fixed coordinate being reversed MN 1/2001
  12. *
  13. * BUGS: see BUG file
  14. */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <math.h>
  19. #include "binio.h"
  20. #include "v5d.h"
  21. #include <grass/gis.h>
  22. #include <grass/raster3d.h>
  23. #include <grass/glocale.h>
  24. /* structs */
  25. typedef struct
  26. {
  27. struct Option *input, *output;
  28. } paramType;
  29. /* protos */
  30. void fatalError(char *errorMsg);
  31. void setParams();
  32. void getParams(char **input, char **output, int *decim);
  33. void convert(char *fileout, int, int, int, int);
  34. /* globals */
  35. void *map = NULL;
  36. paramType param;
  37. RASTER3D_Region region;
  38. /*---------------------------------------------------------------------------*/
  39. /* Simple error handling routine, will eventually replace this with
  40. * RASTER3D_fatalError.
  41. */
  42. void fatalError(char *errorMsg)
  43. {
  44. if (map != NULL) {
  45. /* should unopen map here! */
  46. if (!Rast3d_close(map))
  47. fatalError(_("Unable to close 3D raster map"));
  48. }
  49. Rast3d_fatal_error("%s", errorMsg);
  50. }
  51. /*---------------------------------------------------------------------------*/
  52. /* Convenient way to set up the arguments we are expecting
  53. */
  54. void setParams()
  55. {
  56. param.input = G_define_option();
  57. param.input->key = "input";
  58. param.input->type = TYPE_STRING;
  59. param.input->required = YES;
  60. param.input->gisprompt = "old,grid3,3d-raster";
  61. param.input->multiple = NO;
  62. param.input->description =
  63. _("3D raster map to be converted to Vis5D (V5D) file");
  64. param.output = G_define_standard_option(G_OPT_F_OUTPUT);
  65. param.output->required = YES;
  66. param.output->description = _("Name for V5D output file");
  67. /* param.null_val = G_define_option();
  68. param.null_val->key = "null";
  69. param.null_val->type = TYPE_STRING;
  70. param.null_val->required = NO;
  71. param.null_val->description = "Char string to represent no data cell";
  72. param.null_val->answer = "*";
  73. */
  74. }
  75. /*---------------------------------------------------------------------------*/
  76. /* Set up the input and output file names from the user's responses
  77. */
  78. void getParams(char **input, char **output, int *decim)
  79. {
  80. *input = param.input->answer;
  81. *output = param.output->answer;
  82. }
  83. /*---------------------------------------------------------------------------*/
  84. /* Opens the output v5d file and writes the header.
  85. * Returns the file handle for the output file.
  86. */
  87. void convert(char *fileout, int rows, int cols, int depths, int trueCoords)
  88. {
  89. int NumTimes = 1; /* number of time steps */
  90. int NumVars = 1; /* number of variables */
  91. int Nl[MAXVARS]; /* size of 3-D grids */
  92. char VarName[MAXVARS][10]; /* names of variables */
  93. int TimeStamp[MAXTIMES]; /* real times for each time step */
  94. int DateStamp[MAXTIMES]; /* real dates for each time step */
  95. float NorthLat; /* latitude of north bound of box */
  96. float LatInc; /* spacing between rows in degrees */
  97. float WestLon; /* longitude of west bound of box */
  98. float LonInc; /* spacing between columns in degs */
  99. float BottomHgt; /* height of bottom of box in km */
  100. float HgtInc; /* spacing between grid levels in km */
  101. int Projection;
  102. float ProjArgs[100];
  103. int Vertical;
  104. float VertArgs[MAXLEVELS];
  105. int CompressMode;
  106. float *g;
  107. int cnt;
  108. double d1 = 0;
  109. double *d1p;
  110. float *f1p;
  111. int x, y, z;
  112. int typeIntern;
  113. /*AV*/
  114. /* BEGIN OF ORIGINAL CODE WHICH IS NOT NECESSARY FOR ME, COMMENTED IT */
  115. /* values of global variables are passed as function's arguments at line 345 */
  116. /*
  117. / * copy setting from global variables MN 1/2001 * /
  118. rows = region.rows;
  119. cols=region.cols;
  120. depths=region.depths;
  121. */
  122. /* END OF ORIGINAL CODE WHICH IS NOT NECESSARY FOR ME, COMMENTED IT */
  123. typeIntern = Rast3d_tile_type_map(map);
  124. G_debug(3, "cols: %i rows: %i depths: %i\n", cols, rows, depths);
  125. /* see v5d.h */
  126. if (cols > MAXCOLUMNS)
  127. G_fatal_error(_("Vis5D allows %d columns, %d columns found"), MAXCOLUMNS,
  128. cols);
  129. if (rows > MAXROWS)
  130. G_fatal_error(_("Vis5D allows %d rows, %d rows found"), MAXROWS,
  131. rows);
  132. Nl[0] = depths;
  133. /* ********* */
  134. /* BUG: vis5d display one row/col/depth less that volume
  135. *
  136. * Note: The coordinate system of Vis5D is really odd!
  137. */
  138. strcpy(VarName[0], "S");
  139. TimeStamp[0] = DateStamp[0] = 0;
  140. CompressMode = 4;
  141. if (trueCoords) { /* use map coordinates */
  142. Projection = 0; /*linear, rectangular, generic units */
  143. ProjArgs[0] = region.north; /*North boundary of 3-D box */
  144. ProjArgs[1] = region.west; /*West boundary of 3-D box */
  145. ProjArgs[2] = region.ns_res; /*Increment between rows */
  146. ProjArgs[3] = region.ew_res * (-1); /*Increment between columns, reverse direction */
  147. Vertical = 0; /*equally spaced levels in generic units */
  148. VertArgs[0] = region.bottom; /*height of bottom level */
  149. VertArgs[1] = region.tb_res; /*spacing between levels */
  150. }
  151. else { /* xyz coordinates */
  152. Projection = 0; /*linear, rectangular, generic units */
  153. ProjArgs[0] = 0.0; /*North boundary of 3-D box */
  154. ProjArgs[1] = 0.0; /*West boundary of 3-D box */
  155. ProjArgs[2] = 1.0; /*Increment between rows */
  156. ProjArgs[3] = 1.0; /*Increment between columns */
  157. Vertical = 0; /*equally spaced levels in generic units */
  158. VertArgs[0] = 0.0; /*height of bottom level */
  159. VertArgs[1] = 1.0; /*spacing between levels */
  160. }
  161. /* put here some g3d functions */
  162. /* required ? */
  163. LatInc = 1.0;
  164. LonInc = 1.0;
  165. HgtInc = 1.0;
  166. NorthLat = 50.0;
  167. WestLon = 90.0;
  168. BottomHgt = 0.0;
  169. /****************/
  170. g = (float *)G_malloc(rows * cols * Nl[0] * sizeof(float));
  171. d1p = &d1;
  172. f1p = (float *)&d1;
  173. cnt = 0;
  174. /* originally written in 1999. Bug: displays reversed in Vis5D:
  175. for (z = 0; z < depths; z++) {
  176. G_percent(z, depths, 1);
  177. for (y = 0; y < rows; y++) {
  178. for (x = 0; x < cols; x++) {
  179. */
  180. /* taken from r3.out.ascii: but modified x and y order
  181. MN 1/2001. Now results comparable to r3.showdspf but
  182. for loops are different to r3.out.ascii and r3.to.sites - hmpf */
  183. /*AV*/
  184. /* IT WORKS WHIT A PARTICULAR FOR LOOP PROBABLY BECAUSE THE DATA
  185. ARE NOT STORED IN A 3D MATRIX [z,y,x] BUT IN A POINTER
  186. MANAGED AS (z,x,y) */
  187. for (z = 0; z < depths; z++) {
  188. G_percent(z, depths, 1);
  189. for (x = 0; x < cols; x++) {
  190. for (y = 0; y < rows; y++) { /* north to south */
  191. Rast3d_get_value_region(map, x, y, z, d1p, typeIntern);
  192. if (typeIntern == FCELL_TYPE) {
  193. if (Rast3d_is_null_value_num(f1p, FCELL_TYPE)) {
  194. g[cnt] = MISSING;
  195. cnt++;
  196. }
  197. else {
  198. g[cnt] = *f1p;
  199. cnt++;
  200. }
  201. }
  202. else { /*double */
  203. if (Rast3d_is_null_value_num(d1p, DCELL_TYPE)) {
  204. g[cnt] = MISSING;
  205. cnt++;
  206. }
  207. else {
  208. g[cnt] = (float)*d1p;
  209. cnt++;
  210. }
  211. }
  212. }
  213. }
  214. }
  215. /************/
  216. /* Create the output v5d file */
  217. /*AV*/
  218. if (!v5dCreate(fileout, NumTimes, NumVars, rows, cols, Nl, (const char (*)[10])VarName,
  219. TimeStamp, DateStamp, CompressMode, Projection,
  220. ProjArgs, Vertical, VertArgs))
  221. G_fatal_error(_("Unable to create V5D file <%s>"), fileout);
  222. /* Write the v5d file */
  223. if (!v5dWrite(1, 1, g))
  224. G_fatal_error(_("Failed writing V5D file"));
  225. /* Close the v5d file */
  226. v5dClose();
  227. }
  228. /*---------------------------------------------------------------------------*/
  229. /* Main function: open the input and output files, then call
  230. * G3dtoascii.
  231. */
  232. int main(int argc, char *argv[])
  233. {
  234. char *input, *output;
  235. int decim;
  236. struct Flag *coords;
  237. int trueCoords;
  238. struct GModule *module;
  239. /* Initialize GRASS */
  240. G_gisinit(argv[0]);
  241. module = G_define_module();
  242. G_add_keyword(_("raster3d"));
  243. G_add_keyword(_("export"));
  244. G_add_keyword(_("output"));
  245. G_add_keyword(_("voxel"));
  246. module->description =
  247. _("Exports GRASS 3D raster map to 3-dimensional Vis5D file.");
  248. /* Get parameters from user */
  249. setParams();
  250. coords = G_define_flag();
  251. coords->key = 'm';
  252. coords->description = _("Use map coordinates instead of xyz coordinates");
  253. /* Have GRASS get inputs */
  254. if (G_parser(argc, argv))
  255. exit(EXIT_FAILURE);
  256. /* Parse input parameters */
  257. getParams(&input, &output, &decim);
  258. trueCoords = coords->answer;
  259. if (NULL == G_find_raster3d(input, ""))
  260. Rast3d_fatal_error(_("3D raster map <%s> not found"), input);
  261. map = Rast3d_open_cell_old(input, G_find_raster3d(input, ""), RASTER3D_DEFAULT_WINDOW,
  262. RASTER3D_TILE_SAME_AS_FILE, RASTER3D_NO_CACHE);
  263. if (map == NULL)
  264. Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), input);
  265. /* Use default region */
  266. /* Rast3d_get_region_struct_map(map, &region); */
  267. /* Figure out the region from current settings: */
  268. Rast3d_get_window(&region);
  269. G_debug(3, "cols: %i rows: %i layers: %i\n", region.cols, region.rows,
  270. region.depths);
  271. convert(output, region.rows, region.cols, region.depths, trueCoords);
  272. /* Close files and exit */
  273. if (!Rast3d_close(map))
  274. fatalError(_("Unable to close 3D raster map"));
  275. map = NULL;
  276. return (0);
  277. }
  278. /*---------------------------------------------------------------------------*/