main.c 9.2 KB

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