/**************************************************************************** * * MODULE: r3.to.rast * * AUTHOR(S): Original author * Soeren Gebbert soerengebbert@gmx.de * 08 01 2005 Berlin * PURPOSE: Converts 3D raster maps to 2D raster maps * * COPYRIGHT: (C) 2005 by the GRASS Development Team * * This program is free software under the GNU General Public * License (>=v2). Read the file COPYING that comes with GRASS * for details. * *****************************************************************************/ #include #include #include #include #include #include /*- Parameters and global variables -----------------------------------------*/ typedef struct { struct Option *input, *output; struct Flag *mask; struct Flag *res; /*If set, use the same resolution as the input map */ } paramType; paramType param; /*Parameters */ /*- prototypes --------------------------------------------------------------*/ void fatalError(void *map, int *fd, int depths, char *errorMsg); /*Simple Error message */ void setParams(); /*Fill the paramType structure */ void G3dToRaster(void *map, G3D_Region region, int *fd); /*Write the raster */ int open_output_map(const char *name, int res_type); /*opens the outputmap */ void close_output_map(int fd); /*close the map */ /* ************************************************************************* */ /* Error handling ********************************************************** */ /* ************************************************************************* */ void fatalError(void *map, int *fd, int depths, char *errorMsg) { int i; /* Close files and exit */ if (map != NULL) { if (!G3d_closeCell(map)) G3d_fatalError(_("Could not close the g3d map")); } if (fd != NULL) { for (i = 0; i < depths; i++) G_unopen_cell(fd[i]); } G3d_fatalError(errorMsg); exit(EXIT_FAILURE); } /* ************************************************************************* */ /* 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->description = _("3dcell map(s) to be converted to 2D raster slices"); param.output = G_define_option(); param.output->key = "output"; param.output->type = TYPE_STRING; param.output->required = YES; param.output->description = _("Basename for resultant raster slice maps"); param.output->gisprompt = "new,cell,raster"; param.mask = G_define_flag(); param.mask->key = 'm'; param.mask->description = _("Use G3D mask (if exists) with input map"); param.res = G_define_flag(); param.res->key = 'r'; param.res->description = _ ("Use the same resolution as the input G3D map for the 2d output maps, independently from the current region settings."); } /* ************************************************************************* */ /* Write the slices to seperate raster maps ******************************** */ /* ************************************************************************* */ void G3dToRaster(void *map, G3D_Region region, int *fd) { double d1 = 0, f1 = 0; int x, y, z, check = 0; int rows, cols, depths, typeIntern, pos = 0; FCELL *fcell = NULL; DCELL *dcell = NULL; rows = region.rows; cols = region.cols; depths = region.depths; G_debug(2, _("G3dToRaster: Writing %i raster maps with rows %i cols."), depths, rows, cols); typeIntern = G3d_tileTypeMap(map); if (typeIntern == G3D_FLOAT) fcell = G_allocate_f_raster_buf(); else if (typeIntern == G3D_DOUBLE) dcell = G_allocate_d_raster_buf(); pos = 0; /*Every Rastermap */ for (z = 0; z < depths; z++) { /*From the bottom to the top */ G_debug(3, _("Writing raster map %i\n"), z + 1); for (y = 0; y < rows; y++) { G_percent(y, rows - 1, 10); for (x = 0; x < cols; x++) { if (typeIntern == G3D_FLOAT) { G3d_getValue(map, x, y, z, &f1, typeIntern); if (G3d_isNullValueNum(&f1, G3D_FLOAT)) G_set_null_value(&fcell[x], 1, FCELL_TYPE); else fcell[x] = (FCELL) f1; } else { G3d_getValue(map, x, y, z, &d1, typeIntern); if (G3d_isNullValueNum(&d1, G3D_DOUBLE)) G_set_null_value(&dcell[x], 1, DCELL_TYPE); else dcell[x] = (DCELL) d1; } } if (typeIntern == G3D_FLOAT) { check = G_put_f_raster_row(fd[pos], fcell); if (check != 1) fatalError(map, fd, depths, _("Could not write raster row")); } if (typeIntern == G3D_DOUBLE) { check = G_put_d_raster_row(fd[pos], dcell); if (check != 1) fatalError(map, fd, depths, _("Could not write raster row")); } } G_debug(3, _("\nDone\n")); pos++; } if (dcell) G_free(dcell); if (fcell) G_free(fcell); } /* ************************************************************************* */ /* Main function, open the G3D map and create the raster maps ************** */ /* ************************************************************************* */ int main(int argc, char *argv[]) { G3D_Region region; struct Cell_head region2d; struct GModule *module; void *map = NULL; /*The 3D Rastermap */ int i = 0, changemask = 0; int *fd = NULL, output_type, cols, rows; char *RasterFileName; /* Initialize GRASS */ G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("raster3d, voxel"); module->description = _("Converts 3D raster maps to 2D raster maps"); /* Get parameters from user */ setParams(); /* Have GRASS get inputs */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_debug(3, _("Open g3d map <%s>"), param.input->answer); if (NULL == G_find_grid3(param.input->answer, "")) G3d_fatalError(_("Requested g3d map <%s> not found"), param.input->answer); /*Set the defaults */ G3d_initDefaults(); /*Set the resolution of the output maps */ if (param.res->answer) { /*Open the map with default region */ map = G3d_openCellOld(param.input->answer, G_find_grid3(param.input->answer, ""), G3D_DEFAULT_WINDOW, G3D_TILE_SAME_AS_FILE, G3D_USE_CACHE_DEFAULT); if (map == NULL) G3d_fatalError(_("Error opening g3d map <%s>"), param.input->answer); /*Get the region of the map */ G3d_getRegionStructMap(map, ®ion); /*set this region as current 3d window for map */ G3d_setWindowMap(map, ®ion); /*Set the 2d region appropriate */ G3d_extract2dRegion(®ion, ®ion2d); /*Make the new 2d region the default */ G_set_window(®ion2d); } else { /* Figure out the region from the map */ G3d_getWindow(®ion); /*Check if the g3d-region is equal to the 2d rows and cols */ rows = G_window_rows(); cols = G_window_cols(); /*If not equal, set the 3D window correct */ if (rows != region.rows || cols != region.cols) { G_message (_("The 2d and 3d region settings are different. I will use the 2d window settings to adjust the 2d part of the 3d region.")); G_get_set_window(®ion2d); region.ns_res = region2d.ns_res; region.ew_res = region2d.ew_res; region.rows = region2d.rows; region.cols = region2d.cols; G3d_setWindow(®ion); } /*Open the g3d map */ map = G3d_openCellOld(param.input->answer, G_find_grid3(param.input->answer, ""), ®ion, G3D_TILE_SAME_AS_FILE, G3D_USE_CACHE_DEFAULT); if (map == NULL) G3d_fatalError(_("Error opening g3d map <%s>"), param.input->answer); } /*Get the output type */ output_type = G3d_fileTypeMap(map); /*prepare the filehandler */ fd = (int *)G_malloc(region.depths * sizeof(int)); if (fd == NULL) fatalError(map, NULL, 0, _("out of memory!")); if (G_legal_filename(param.output->answer) < 0) fatalError(map, NULL, 0, _("Illegal output file name")); G_message(_("Creating %i raster maps\n"), region.depths); /*Loop over all output maps! open */ for (i = 0; i < region.depths; i++) { /*Create the outputmaps */ G_asprintf(&RasterFileName, "%s_%i", param.output->answer, i + 1); G_message(_("Raster map %i Filename: %s\n"), i + 1, RasterFileName); if (G_find_cell2(RasterFileName, "")) G_message(_ ("Raster map %i Filename: %s already exists. Will be overwritten!\n"), i + 1, RasterFileName); if (output_type == G3D_FLOAT) fd[i] = open_output_map(RasterFileName, FCELL_TYPE); else if (output_type == G3D_DOUBLE) fd[i] = open_output_map(RasterFileName, DCELL_TYPE); } /*if requested set the Mask on */ if (param.mask->answer) { if (G3d_maskFileExists()) { changemask = 0; if (G3d_maskIsOff(map)) { G3d_maskOn(map); changemask = 1; } } } /*Create the Rastermaps */ G3dToRaster(map, region, fd); /*Loop over all output maps! close */ for (i = 0; i < region.depths; i++) close_output_map(fd[i]); /*We set the Mask off, if it was off before */ if (param.mask->answer) { if (G3d_maskFileExists()) if (G3d_maskIsOn(map) && changemask) G3d_maskOff(map); } /*Cleaning */ if (RasterFileName) G_free(RasterFileName); if (fd) G_free(fd); /* Close files and exit */ if (!G3d_closeCell(map)) fatalError(map, NULL, 0, _("Error closing g3d file")); map = NULL; return (EXIT_SUCCESS); } /* ************************************************************************* */ /* Open the raster output map ********************************************** */ /* ************************************************************************* */ int open_output_map(const char *name, int res_type) { int fd; fd = G_open_raster_new((char *)name, res_type); if (fd < 0) G_fatal_error(_("cannot create output map [%s]"), name); return fd; } /* ************************************************************************* */ /* Close the raster output map ********************************************* */ /* ************************************************************************* */ void close_output_map(int fd) { if (G_close_cell(fd) < 0) G_fatal_error(_("unable to close output map")); }