/* * r3.out.v5d - * * Copyright Jaro Hofierka * GeoModel,s.r.o., Bratislava, 1999 * hofierka@geomodel.sk * * Improvements: * - added true coordinates support Markus Neteler 1/2001 * - Region sensivity by MN 1/2001 * - Fixed coordinate being reversed MN 1/2001 * * BUGS: see BUG file */ #include #include #include #include #include "binio.h" #include "v5d.h" #include #include #include #define MAX(a,b) (a > b ? a : b) /* structs */ typedef struct { struct Option *input, *output; } paramType; /* protos */ void fatalError(char *errorMsg); void setParams(); void getParams(char **input, char **output, int *decim); void convert(char *fileout, int, int, int, int); /* globals */ void *map = NULL; paramType param; G3D_Region region; /*---------------------------------------------------------------------------*/ /* Simple error handling routine, will eventually replace this with * G3D_fatalError. */ void fatalError(char *errorMsg) { if (map != NULL) { /* should unopen map here! */ if (!G3d_closeCell (map)) fatalError ("Error closing g3d file"); } G3d_fatalError (errorMsg); } /*---------------------------------------------------------------------------*/ /* Convenient way to set up the arguments we are expecting */ void setParams() { param.input = G_define_option(); param.input->key = "input"; param.input->type = TYPE_STRING; param.input->required = YES; param.input->gisprompt = "old,grid3,3d-raster"; param.input->multiple = NO; param.input->description = _("3dcell map to be converted to Vis5d (v5d) file"); param.output = G_define_option(); param.output->key = "output"; param.output->type = TYPE_STRING; param.output->gisprompt = "new_file,file,output"; param.output->required = YES; param.output->description = _("Name for v5d output file"); /* param.null_val = G_define_option(); param.null_val->key = "null"; param.null_val->type = TYPE_STRING; param.null_val->required = NO; param.null_val->description = "Char string to represent no data cell"; param.null_val->answer = "*"; */ } /*---------------------------------------------------------------------------*/ /* Set up the input and output file names from the user's responses */ void getParams(char **input, char **output, int *decim) { *input = param.input->answer; *output = param.output->answer; } /*---------------------------------------------------------------------------*/ /* Opens the output v5d file and writes the header. * Returns the file handle for the output file. */ void convert(char *fileout, int rows, int cols, int depths, int trueCoords) { int NumTimes=1; /* number of time steps */ int NumVars=1; /* number of variables */ int Nl[MAXVARS]; /* size of 3-D grids */ char VarName[MAXVARS][10]; /* names of variables */ int TimeStamp[MAXTIMES]; /* real times for each time step */ int DateStamp[MAXTIMES]; /* real dates for each time step */ float NorthLat; /* latitude of north bound of box */ float LatInc; /* spacing between rows in degrees */ float WestLon; /* longitude of west bound of box */ float LonInc; /* spacing between columns in degs */ float BottomHgt; /* height of bottom of box in km */ float HgtInc; /* spacing between grid levels in km */ int Projection; float ProjArgs[100]; int Vertical; float VertArgs[MAXLEVELS]; int CompressMode; float *g; int cnt; double d1 = 0; double *d1p; float *f1p; int x, y, z; int typeIntern; /*AV*/ /* BEGIN OF ORIGINAL CODE WHICH IS NOT NECESSARY FOR ME, COMMENTED IT */ /* values of global variables are passed as function's arguments at line 345 */ /* / * copy setting from global variables MN 1/2001 * / rows = region.rows; cols=region.cols; depths=region.depths; */ /* END OF ORIGINAL CODE WHICH IS NOT NECESSARY FOR ME, COMMENTED IT */ typeIntern = G3d_tileTypeMap (map); G_debug(3, "cols: %i rows: %i depths: %i\n", cols, rows, depths); /* see v5d.h */ if (cols > MAXCOLUMNS) G_fatal_error(_("Viz5D allows %d cols, you have %d cols"), MAXCOLUMNS, cols); if (rows > MAXROWS) G_fatal_error(_("Viz5D allows %d rows, you have %d rows"), MAXROWS, rows); Nl[0]=depths; /* ********* */ /* BUG: vis5d display one row/col/depth less that volume * * Note: The coordinate system of Vis5D is really odd! */ strcpy(VarName[0], "S"); TimeStamp[0] = DateStamp[0] = 0; CompressMode = 4; if(trueCoords) { /* use map coordinates */ Projection = 0; /*linear, rectangular, generic units*/ ProjArgs[0] = region.north; /*North boundary of 3-D box*/ ProjArgs[1] = region.west; /*West boundary of 3-D box */ ProjArgs[2] = region.ns_res; /*Increment between rows */ ProjArgs[3] = region.ew_res * (-1); /*Increment between columns, reverse direction*/ Vertical = 0; /*equally spaced levels in generic units*/ VertArgs[0] = region.bottom; /*height of bottom level*/ VertArgs[1] = region.tb_res; /*spacing between levels*/ } else { /* xyz coordinates */ Projection = 0; /*linear, rectangular, generic units*/ ProjArgs[0] = 0.0; /*North boundary of 3-D box*/ ProjArgs[1] = 0.0; /*West boundary of 3-D box */ ProjArgs[2] = 1.0; /*Increment between rows */ ProjArgs[3] = 1.0; /*Increment between columns*/ Vertical = 0; /*equally spaced levels in generic units*/ VertArgs[0] = 0.0; /*height of bottom level*/ VertArgs[1] = 1.0; /*spacing between levels*/ } /* put here some g3d functions */ /* required ? */ LatInc = 1.0; LonInc = 1.0; HgtInc = 1.0; NorthLat = 50.0; WestLon = 90.0; BottomHgt = 0.0; /****************/ g = (float *) G_malloc ( rows * cols * Nl[0] * sizeof(float) ); if (!g) G_fatal_error(_("Out of memory")); d1p = &d1; f1p = (float *) &d1; cnt=0; /* originally written in 1999. Bug: displays reversed in Vis5D: for (z = 0; z < depths; z++) { G_percent(z, depths, 1); for (y = 0; y < rows; y++) { for (x = 0; x < cols; x++) { */ /* taken from r3.out.ascii: but modified x and y order MN 1/2001. Now results comparable to r3.showdspf but for loops are different to r3.out.ascii and r3.to.sites - hmpf */ /*AV*/ /* IT WORKS WHIT A PARTICULAR FOR LOOP PROBABLY BECAUSE THE DATA ARE NOT STORED IN A 3D MATRIX [z,y,x] BUT IN A POINTER MANAGED AS (z,x,y) */ for (z = 0; z < depths; z++) { G_percent(z, depths, 1); for (x = 0; x < cols; x++) { for (y = 0; y < rows; y++) { /* north to south */ G3d_getValueRegion (map, x, y, z, d1p, typeIntern); if (typeIntern == G3D_FLOAT) { if (G3d_isNullValueNum(f1p, G3D_FLOAT)) { g[cnt] = MISSING; cnt++; } else { g[cnt] = *f1p; cnt++; } } else { /*double*/ if (G3d_isNullValueNum(d1p, G3D_DOUBLE)){ g[cnt]= MISSING; cnt++; } else { g[cnt] = (float) *d1p; cnt++; } } } } } /************/ /* Create the output v5d file */ /*AV*/ if (!v5dCreate(fileout, NumTimes, NumVars, rows, cols, Nl, VarName, TimeStamp, DateStamp,CompressMode, Projection, ProjArgs, Vertical, VertArgs )) G_fatal_error(_("Error: couldn't create %s"), fileout); /* Write the v5d file */ if (!v5dWrite(1,1, g )) G_fatal_error(_("Error while writing grid. Disk full?")); /* Close the v5d file */ v5dClose(); } /*---------------------------------------------------------------------------*/ /* Main function: open the input and output files, then call * G3dtoascii. */ int main (int argc, char *argv[]) { char *input, *output; int decim; struct Flag *coords; int trueCoords; struct GModule *module; /* Initialize GRASS */ G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("raster3d, voxel"); module->description = _("Export of GRASS 3D raster file to 3-dimensional Vis5D file."); /* Get parameters from user */ setParams(); coords = G_define_flag (); coords->key = 'm'; coords->description = _("Use map coordinates instead of xyz coordinates"); /* Have GRASS get inputs */ if (G_parser(argc, argv)) exit(-1); /* Parse input parameters */ getParams(&input, &output, &decim); trueCoords=coords->answer; if(NULL == G_find_grid3(input, "")) G3d_fatalError(_("Requested g3d file not found")); map = G3d_openCellOld(input, G_find_grid3(input, ""), G3D_DEFAULT_WINDOW, G3D_TILE_SAME_AS_FILE, G3D_NO_CACHE); if (map == NULL) G3d_fatalError("Error opening g3d file"); /* Use default region */ /* G3d_getRegionStructMap(map, ®ion); */ /* Figure out the region from current settings:*/ G3d_getWindow(®ion); G_debug(3, "cols: %i rows: %i layers: %i\n", region.cols, region.rows, region.depths); convert(output, region.rows, region.cols, region.depths, trueCoords); /* Close files and exit */ if (!G3d_closeCell (map)) fatalError ("Error closing g3d file"); map = NULL; return (0); } /*---------------------------------------------------------------------------*/