123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- /****************************************************************************
- *
- * MODULE: r.to.rast3
- *
- * AUTHOR(S): Original author
- * Soeren Gebbert soerengebbert@gmx.de
- * 08 01 2005 Berlin
- * PURPOSE: Converts 2D raster map slices to one 3D volume map
- *
- * 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 <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <grass/gis.h>
- #include <grass/raster.h>
- #include <grass/raster3d.h>
- #include <grass/glocale.h>
- #include <grass/config.h>
- /*- params and global variables -----------------------------------------*/
- typedef struct {
- struct Option *input, *output, *tilesize;
- struct Flag *mask;
- } paramType;
- paramType param; /*params */
- int globalRastMapType;
- int globalG3dMapType;
- /*- prototypes --------------------------------------------------------------*/
- void fatal_error(void *map, int *fd, int depths, char *errorMsg); /*Simple Error message */
- void set_params(); /*Fill the paramType structure */
- void raster_to_g3d(void *map, RASTER3D_Region region, int *fd); /*Write the raster */
- int open_input_raster_map(const char *name); /*opens the outputmap */
- void close_input_raster_map(int fd); /*close the map */
- /* ************************************************************************* */
- /* Error handling ********************************************************** */
- /* ************************************************************************* */
- void fatal_error(void *map, int *fd, int depths, char *errorMsg)
- {
- int i;
- /* Close files and exit */
- if (map != NULL) {
- /* should unopen map here! but this functionality is not jet implemented */
- if (!Rast3d_close(map))
- Rast3d_fatal_error(_("Could not close the map"));
- }
- if (fd != NULL) {
- for (i = 0; i < depths; i++)
- close_input_raster_map(fd[i]);
- }
- Rast3d_fatal_error(errorMsg);
- exit(EXIT_FAILURE);
- }
- /* ************************************************************************* */
- /* Setg up the arguments we are expecting ********************************** */
- /* ************************************************************************* */
- void set_params()
- {
- param.input = G_define_standard_option(G_OPT_R_INPUTS);
- param.input->description = _("2d raster maps which represent the slices");
- param.output = G_define_standard_option(G_OPT_R3_OUTPUT);
- param.tilesize = G_define_option();
- param.tilesize->description = _("The maximum tile size in kilo bytes. Default is 32KB.");
- param.tilesize->key = "tilesize";
- param.tilesize->answer = "32";
- param.tilesize->type = TYPE_INTEGER;
- param.tilesize->required = NO;
- param.tilesize->multiple = NO;
- param.mask = G_define_flag();
- param.mask->key = 'm';
- param.mask->description = _("Use 3D raster mask (if exists) with output map");
- }
- /* ************************************************************************* */
- /* Write the raster maps into one RASTER3D map ********************************** */
- /* ************************************************************************* */
- void raster_to_g3d(void *map, RASTER3D_Region region, int *fd)
- {
- int x, y, z;
- int rows, cols, depths;
- void *rast;
- void *ptr;
- FCELL fvalue;
- DCELL dvalue;
- rows = region.rows;
- cols = region.cols;
- depths = region.depths;
- rast = Rast_allocate_buf(globalRastMapType);
- G_debug(3, "raster_to_g3d: Writing %i raster maps with %i rows %i cols.",
- depths, rows, cols);
- /*Every Rastermap */
- for (z = 0; z < depths; z++) { /*From the bottom to the top */
- G_percent(z, depths, 1);
- G_debug(4, "Writing g3d slice %i", z + 1);
- for (y = 0; y < rows; y++) { /* From north to south */
- Rast_get_row(fd[z], rast, y, globalRastMapType);
- for (x = 0, ptr = rast; x < cols; x++,
- ptr =
- G_incr_void_ptr(ptr, Rast_cell_size(globalRastMapType))) {
- if (globalRastMapType == CELL_TYPE) {
- if (Rast_is_null_value(ptr, globalRastMapType)) {
- Rast3d_set_null_value(&dvalue, 1, DCELL_TYPE);
- } else {
- dvalue = *(CELL *) ptr;
- }
- if (Rast3d_put_value
- (map, x, y, z, (char *) &dvalue, DCELL_TYPE) < 0)
- fatal_error(map, fd, depths,
- "Error writing double data");
- } else if (globalRastMapType == FCELL_TYPE) {
- if (Rast_is_null_value(ptr, globalRastMapType)) {
- Rast3d_set_null_value(&fvalue, 1, FCELL_TYPE);
- } else {
- fvalue = *(FCELL *) ptr;
- }
- if (Rast3d_put_value
- (map, x, y, z, (char *) &fvalue, FCELL_TYPE) < 0)
- fatal_error(map, fd, depths,
- "Error writing float data");
- } else if (globalRastMapType == DCELL_TYPE) {
- if (Rast_is_null_value(ptr, globalRastMapType)) {
- Rast3d_set_null_value(&dvalue, 1, DCELL_TYPE);
- } else {
- dvalue = *(DCELL *) ptr;
- }
- if (Rast3d_put_value
- (map, x, y, z, (char *) &dvalue, DCELL_TYPE) < 0)
- fatal_error(map, fd, depths,
- "Error writing double data");
- }
- }
- }
- }
- G_percent(1, 1, 1);
- if (rast)
- G_free(rast);
- }
- /* ************************************************************************* */
- /* Main function, open the raster maps and create the RASTER3D raster map ******* */
- /* ************************************************************************* */
- int main(int argc, char *argv[])
- {
- RASTER3D_Region region;
- struct Cell_head window2d;
- struct GModule *module;
- void *map = NULL; /*The 3D Rastermap */
- int i = 0;
- int *fd = NULL; /*The filehandler array for the 2D inputmaps */
- int cols, rows, opencells;
- char *name;
- int changemask = 0;
- int maptype_tmp, nofile = 0;
- int maxSize;
- /* Initialize GRASS */
- G_gisinit(argv[0]);
- module = G_define_module();
- G_add_keyword(_("raster"));
- G_add_keyword(_("conversion"));
- G_add_keyword(_("voxel"));
- module->description =
- _("Converts 2D raster map slices to one 3D raster volume map.");
- /* Get parameters from user */
- set_params();
- /* Have GRASS get inputs */
- if (G_parser(argc, argv))
- exit(EXIT_FAILURE);
- /*Check for output */
- if (param.output->answer == NULL)
- Rast3d_fatal_error(_("No output map"));
- /* Get the tile size */
- maxSize = atoi(param.tilesize->answer);
- /* Figure out the region from the map */
- Rast3d_init_defaults();
- Rast3d_get_window(®ion);
- /*Check if the g3d-region is equal to the 2d rows and cols */
- rows = Rast_window_rows();
- cols = Rast_window_cols();
- G_debug(2, "Check the 2d and 3d region settings");
- /*If not equal, set the 2D windows correct */
- if (rows != region.rows || cols != region.cols) {
- G_message(_("The 2D and 3D region settings are different. I will use the 3D region settings to adjust the 2D region."));
- G_get_set_window(&window2d);
- window2d.ns_res = region.ns_res;
- window2d.ew_res = region.ew_res;
- window2d.rows = region.rows;
- window2d.cols = region.cols;
- Rast_set_window(&window2d);
- }
- /*prepare the filehandler */
- fd = (int *) G_malloc(region.depths * sizeof (int));
- if (fd == NULL)
- fatal_error(map, NULL, 0, _("Out of memory"));
- name = NULL;
- globalRastMapType = DCELL_TYPE;
- globalG3dMapType = DCELL_TYPE;
- maptype_tmp = DCELL_TYPE;
- opencells = 0; /*Number of opened maps */
- /*Loop over all output maps! open */
- for (i = 0; i < region.depths; i++) {
- /*Open only existing maps */
- if (nofile == 0 && param.input->answers[i])
- name = param.input->answers[i];
- else
- nofile = 1;
- /*if only one map is given, open it depths - times */
- G_verbose_message(_("Open raster map %s - one time for each depth (%d/%d)"),
- name, i + 1, region.depths);
- fd[i] = open_input_raster_map(name);
- opencells++;
- maptype_tmp = Rast_get_map_type(fd[i]);
- /*maptype */
- if (i == 0)
- globalRastMapType = maptype_tmp;
- if (maptype_tmp != globalRastMapType) {
- fatal_error(map, fd, opencells,
- _("Input maps have to be from the same type. CELL, FCELL or DCELL!"));
- }
- }
- G_message(_("Creating 3D raster map"));
- map = NULL;
- /* Set the map type depending from the arster maps type */
- if (globalRastMapType == CELL_TYPE || globalRastMapType == DCELL_TYPE)
- globalG3dMapType = DCELL_TYPE;
- else
- globalG3dMapType = FCELL_TYPE;
- map = Rast3d_open_new_opt_tile_size(param.output->answer, RASTER3D_USE_CACHE_XY, ®ion, globalG3dMapType, maxSize);
- if (map == NULL)
- fatal_error(map, fd, opencells, _("Error opening 3D raster map"));
- /*if requested set the Mask on */
- if (param.mask->answer) {
- if (Rast3d_mask_file_exists()) {
- changemask = 0;
- if (Rast3d_mask_is_off(map)) {
- Rast3d_mask_on(map);
- changemask = 1;
- }
- }
- }
- /*Create the RASTER3D Rastermap */
- raster_to_g3d(map, region, fd);
- /*We set the Mask off, if it was off before */
- if (param.mask->answer) {
- if (Rast3d_mask_file_exists())
- if (Rast3d_mask_is_on(map) && changemask)
- Rast3d_mask_off(map);
- }
- /*Loop over all output maps! close */
- for (i = 0; i < region.depths; i++)
- close_input_raster_map(fd[i]);
- if (fd)
- G_free(fd);
- /* Flush all tile */
- if (!Rast3d_flush_all_tiles(map))
- Rast3d_fatal_error("Error flushing tiles with Rast3d_flush_all_tiles");
- /* Close files and exit */
- if (!Rast3d_close(map))
- Rast3d_fatal_error(_("Error closing 3d raster map"));
- map = NULL;
- G_debug(2, "Done\n");
- return (EXIT_SUCCESS);
- }
- /* ************************************************************************* */
- /* Open the raster input map *********************************************** */
- /* ************************************************************************* */
- int open_input_raster_map(const char *name)
- {
- G_debug(3, "Open Raster file %s", name);
- return Rast_open_old(name, "");
- }
- /* ************************************************************************* */
- /* Close the raster input map ********************************************** */
- /* ************************************************************************* */
- void close_input_raster_map(int fd)
- {
- Rast_close(fd);
- }
|