Пример #1
0
int main(int argc, char *argv[]) {
	struct GModule *module;
	struct {
		struct Option *input;
		struct Option *output;
		struct Option *null;
		struct Option *bytes;
		struct Option *order;
		struct Option *north;
		struct Option *south;
		struct Option *top;
		struct Option *bottom;
		struct Option *east;
		struct Option *west;
		struct Option *rows;
		struct Option *cols;
		struct Option *depths;
	} parm;
	struct {
		struct Flag *integer_in;
		struct Flag *sign;
		struct Flag *depth;
		struct Flag *row;
	} flag;
	const char *input;
	const char *output;
	int is_integer;
	int is_signed;
	int bytes;
	int order;
	int byte_swap;
	RASTER_MAP_TYPE map_type;
	off_t file_size;
	struct History history;
	off_t expected;
	/* Need to be allocated later */
	in_cell = NULL;

	G_gisinit(argv[0]);

	/* Set description */
	module = G_define_module();
	G_add_keyword(_("raster3d"));
	G_add_keyword(_("import"));
	G_add_keyword(_("voxel"));
	module->description =
			_("Imports a binary raster file into a GRASS 3D raster map.");

	parm.input = G_define_standard_option(G_OPT_F_BIN_INPUT);
	parm.input->description = _("Name of binary 3D raster file to be imported");

	parm.output = G_define_standard_option(G_OPT_R3_OUTPUT);

	parm.bytes = G_define_option();
	parm.bytes->key = "bytes";
	parm.bytes->type = TYPE_INTEGER;
	parm.bytes->required = YES;
	parm.bytes->options = "1,2,4,8";
	parm.bytes->description = _("Number of bytes per cell in binary file");

	parm.order = G_define_option();
	parm.order->key = "order";
	parm.order->type = TYPE_STRING;
	parm.order->required = NO;
	parm.order->options = "big,little,native,swap";
	parm.order->description = _("Byte order in binary file");
	parm.order->answer = "native";

	parm.north = G_define_option();
	parm.north->key = "north";
	parm.north->type = TYPE_DOUBLE;
	parm.north->required = YES;
	parm.north->description =
			_("Northern limit of geographic region (outer edge)");
	parm.north->guisection = _("Bounds");

	parm.south = G_define_option();
	parm.south->key = "south";
	parm.south->type = TYPE_DOUBLE;
	parm.south->required = YES;
	parm.south->description =
			_("Southern limit of geographic region (outer edge)");
	parm.south->guisection = _("Bounds");

	parm.east = G_define_option();
	parm.east->key = "east";
	parm.east->type = TYPE_DOUBLE;
	parm.east->required = YES;
	parm.east->description =
			_("Eastern limit of geographic region (outer edge)");
	parm.east->guisection = _("Bounds");

	parm.west = G_define_option();
	parm.west->key = "west";
	parm.west->type = TYPE_DOUBLE;
	parm.west->required = YES;
	parm.west->description =
			_("Western limit of geographic region (outer edge)");
	parm.west->guisection = _("Bounds");

	parm.bottom = G_define_option();
	parm.bottom->key = "bottom";
	parm.bottom->type = TYPE_DOUBLE;
	parm.bottom->required = YES;
	parm.bottom->description =
			_("Bottom limit of geographic region (outer edge)");
	parm.bottom->guisection = _("Bounds");

	parm.top = G_define_option();
	parm.top->key = "top";
	parm.top->type = TYPE_DOUBLE;
	parm.top->required = YES;
	parm.top->description = _("Top limit of geographic region (outer edge)");
	parm.top->guisection = _("Bounds");

	parm.rows = G_define_option();
	parm.rows->key = "rows";
	parm.rows->type = TYPE_INTEGER;
	parm.rows->required = YES;
	parm.rows->description = _("Number of rows");
	parm.rows->guisection = _("Bounds");

	parm.cols = G_define_option();
	parm.cols->key = "cols";
	parm.cols->type = TYPE_INTEGER;
	parm.cols->required = YES;
	parm.cols->description = _("Number of columns");
	parm.cols->guisection = _("Bounds");

	parm.depths = G_define_option();
	parm.depths->key = "depths";
	parm.depths->type = TYPE_INTEGER;
	parm.depths->required = YES;
	parm.depths->description = _("Number of depths");
	parm.depths->guisection = _("Bounds");

	parm.null = G_define_option();
	parm.null->key = "null";
	parm.null->type = TYPE_DOUBLE;
	parm.null->required = NO;
	parm.null->description = _("Set Value to NULL");

	flag.row = G_define_flag();
	flag.row->key = 'r';
	flag.row->description = _("Switch the row order in output from "
			"north->south to south->north");

	flag.depth = G_define_flag();
	flag.depth->key = 'd';
	flag.depth->description = _("Switch the depth order in output "
			"from bottom->top to top->bottom");

	flag.integer_in = G_define_flag();
	flag.integer_in->key = 'i';
	flag.integer_in->description =
			_("Binary data is of type integer");

	flag.sign = G_define_flag();
	flag.sign->key = 's';
	flag.sign->description = _("Signed data (two's complement)");

	if (G_parser(argc, argv))
		exit(EXIT_FAILURE);

	input = parm.input->answer;
	output = parm.output->answer;

	if (G_strcasecmp(parm.order->answer, "big") == 0)
		order = 0;
	else if (G_strcasecmp(parm.order->answer, "little") == 0)
		order = 1;
	else if (G_strcasecmp(parm.order->answer, "native") == 0)
		order = G_is_little_endian() ? 1 : 0;
	else if (G_strcasecmp(parm.order->answer, "swap") == 0)
		order = G_is_little_endian() ? 0 : 1;

	byte_swap = order == (G_is_little_endian() ? 0 : 1);

	is_signed = !!flag.sign->answer;

	is_integer = 0;
	bytes = 8;

	if (parm.bytes->answer)
		bytes = atoi(parm.bytes->answer);

	if (!flag.integer_in->answer) {
		if (bytes && bytes < 4)
			G_fatal_error(
					_("bytes=%d; must be 4 or 8 in case of floating point input"),
					bytes);
		if (!bytes)
			bytes = 4;
	} else {
		is_integer = 1;
	}

#ifndef HAVE_LONG_LONG_INT
	if (is_integer && bytes > 4)
	G_fatal_error(_("Integer input doesn't support size=8 in this build"));
#endif

	if (bytes != 1 && bytes != 2 && bytes != 4 && bytes != 8)
		G_fatal_error(_("bytes= must be 1, 2, 4 or 8"));

	region.zone = G_zone();
	region.proj = G_projection();
	region.rows = atoi(parm.rows->answer);
	region.cols = atoi(parm.cols->answer);
	region.depths = atoi(parm.depths->answer);
	region.top = atof(parm.top->answer);
	region.bottom = atof(parm.bottom->answer);

	if (!G_scan_northing(parm.north->answer, &region.north, region.proj))
		G_fatal_error(_("Illegal north coordinate <%s>"), parm.north->answer);
	if (!G_scan_northing(parm.south->answer, &region.south, region.proj))
		G_fatal_error(_("Illegal south coordinate <%s>"), parm.south->answer);
	if (!G_scan_easting(parm.east->answer, &region.east, region.proj))
		G_fatal_error(_("Illegal east coordinate <%s>"), parm.east->answer);
	if (!G_scan_easting(parm.west->answer, &region.west, region.proj))
		G_fatal_error(_("Illegal west coordinate <%s>"), parm.west->answer);

	Rast3d_adjust_region(&region);

	expected = (off_t) region.rows * region.cols * region.depths * bytes;

	fp = fopen(input, "rb");
	if (!fp)
		G_fatal_error(_("Unable to open <%s>"), input);

	/* Find File Size in Byte and Check against byte size */
	G_fseek(fp, 0, SEEK_END);
	file_size = G_ftell(fp);
	G_fseek(fp, 0, SEEK_SET);

	if (file_size != expected) {
		G_warning(_("File Size %lld ... Total Bytes %lld"),
				(long long int) file_size, (long long int) expected);
		G_fatal_error(_("Bytes do not match file size"));
	}

	map_type = (bytes > 4 ? DCELL_TYPE : FCELL_TYPE);

	if(is_integer && bytes >= 4)
		map_type = DCELL_TYPE;

	Rast3d_init_defaults();

	/*Open the new 3D raster map */
	map = Rast3d_open_new_opt_tile_size(output, RASTER3D_USE_CACHE_DEFAULT,
			&region, map_type, 32);

	if (map == NULL)
		G_fatal_error(_("Unable to open 3D raster map"));

	in_cell = G_malloc(bytes);

	bin_to_raster3d(parm.null->answer, map_type, is_integer, is_signed, bytes,
			byte_swap, flag.row->answer, flag.depth->answer);

	if (!Rast3d_close(map))
		G_fatal_error(_("Unable to close 3D raster map"));

	/* write input name to map history */
	Rast3d_read_history(output, G_mapset(), &history);
	Rast_set_history(&history, HIST_DATSRC_1, input);
	Rast3d_write_history(output, &history);

	fclose(fp);
	if (in_cell)
		G_free(in_cell);

	return EXIT_SUCCESS;
}
Пример #2
0
int main(int argc, char *argv[])
{
    struct Option *vector_opt, *seed_opt, *flowlines_opt, *flowacc_opt, *sampled_opt,
	*scalar_opt, *unit_opt, *step_opt, *limit_opt, *skip_opt, *dir_opt,
	*error_opt;
    struct Flag *table_fl;
    struct GModule *module;
    RASTER3D_Region region;
    RASTER3D_Map *flowacc, *sampled;
    struct Integration integration;
    struct Seed seed;
    struct Gradient_info gradient_info;
    struct Map_info seed_Map;
    struct line_pnts *seed_points;
    struct line_cats *seed_cats;
    struct Map_info fl_map;
    struct line_cats *fl_cats;	/* for flowlines */
    struct line_pnts *fl_points;	/* for flowlines */
    struct field_info *finfo;
    dbDriver *driver;
    int cat;			/* cat of flowlines */
    int if_table;
    int i, r, c, d;
    char *desc;
    int n_seeds, seed_count, ltype;
    int skip[3];

    G_gisinit(argv[0]);
    module = G_define_module();
    G_add_keyword(_("raster3d"));
    G_add_keyword(_("hydrology"));
    G_add_keyword(_("voxel"));
    module->description =
	_("Computes 3D flow lines and 3D flow accumulation.");


    scalar_opt = G_define_standard_option(G_OPT_R3_INPUT);
    scalar_opt->required = NO;
    scalar_opt->guisection = _("Input");

    vector_opt = G_define_standard_option(G_OPT_R3_INPUTS);
    vector_opt->key = "vector_field";
    vector_opt->required = NO;
    vector_opt->description = _("Names of three 3D raster maps describing "
				"x, y, z components of vector field");
    vector_opt->guisection = _("Input");

    seed_opt = G_define_standard_option(G_OPT_V_INPUT);
    seed_opt->required = NO;
    seed_opt->key = "seed_points";
    seed_opt->description = _("If no map is provided, "
			      "flow lines are generated "
			      "from each cell of the input 3D raster");
    seed_opt->label = _("Name of vector map with points "
			"from which flow lines are generated");
    seed_opt->guisection = _("Input");

    flowlines_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    flowlines_opt->key = "flowline";
    flowlines_opt->required = NO;
    flowlines_opt->description = _("Name for vector map of flow lines");
    flowlines_opt->guisection = _("Output");

    flowacc_opt = G_define_standard_option(G_OPT_R3_OUTPUT);
    flowacc_opt->key = "flowaccumulation";
    flowacc_opt->required = NO;
    flowacc_opt->description =
	_("Name for output flowaccumulation 3D raster");
    flowacc_opt->guisection = _("Output");

    sampled_opt = G_define_standard_option(G_OPT_R3_INPUT);
    sampled_opt->key = "sampled";
    sampled_opt->required = NO;
    sampled_opt->label =
            _("Name for 3D raster sampled by flowlines");
    sampled_opt->description =
            _("Values of this 3D raster will be stored "
              "as attributes of flowlines segments");

    unit_opt = G_define_option();
    unit_opt->key = "unit";
    unit_opt->type = TYPE_STRING;
    unit_opt->required = NO;
    unit_opt->answer = "cell";
    unit_opt->options = "time,length,cell";
    desc = NULL;
    G_asprintf(&desc,
	       "time;%s;"
	       "length;%s;"
	       "cell;%s",
	       _("elapsed time"),
	       _("length in map units"), _("length in cells (voxels)"));
    unit_opt->descriptions = desc;
    unit_opt->label = _("Unit of integration step");
    unit_opt->description = _("Default unit is cell");
    unit_opt->guisection = _("Integration");

    step_opt = G_define_option();
    step_opt->key = "step";
    step_opt->type = TYPE_DOUBLE;
    step_opt->required = NO;
    step_opt->answer = "0.25";
    step_opt->label = _("Integration step in selected unit");
    step_opt->description = _("Default step is 0.25 cell");
    step_opt->guisection = _("Integration");

    limit_opt = G_define_option();
    limit_opt->key = "limit";
    limit_opt->type = TYPE_INTEGER;
    limit_opt->required = NO;
    limit_opt->answer = "2000";
    limit_opt->description = _("Maximum number of steps");
    limit_opt->guisection = _("Integration");

    error_opt = G_define_option();
    error_opt->key = "max_error";
    error_opt->type = TYPE_DOUBLE;
    error_opt->required = NO;
    error_opt->answer = "1e-5";
    error_opt->label = _("Maximum error of integration");
    error_opt->description = _("Influences step, increase maximum error "
			       "to allow bigger steps");
    error_opt->guisection = _("Integration");

    skip_opt = G_define_option();
    skip_opt->key = "skip";
    skip_opt->type = TYPE_INTEGER;
    skip_opt->required = NO;
    skip_opt->multiple = YES;
    skip_opt->description =
	_("Number of cells between flow lines in x, y and z direction");

    dir_opt = G_define_option();
    dir_opt->key = "direction";
    dir_opt->type = TYPE_STRING;
    dir_opt->required = NO;
    dir_opt->multiple = NO;
    dir_opt->options = "up,down,both";
    dir_opt->answer = "down";
    dir_opt->description = _("Compute flowlines upstream, "
			     "downstream or in both direction.");

    table_fl = G_define_flag();
    table_fl->key = 'a';
    table_fl->description = _("Create and fill attribute table");

    G_option_required(scalar_opt, vector_opt, NULL);
    G_option_exclusive(scalar_opt, vector_opt, NULL);
    G_option_required(flowlines_opt, flowacc_opt, NULL);
    G_option_requires(seed_opt, flowlines_opt, NULL);
    G_option_requires(table_fl, flowlines_opt, NULL);
    G_option_requires(sampled_opt, table_fl, NULL);

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    driver = NULL;
    finfo = NULL;

    if_table = table_fl->answer ? TRUE : FALSE;

    check_vector_input_maps(vector_opt, seed_opt);

    Rast3d_init_defaults();
    Rast3d_get_window(&region);

    /* set up integration variables */
    if (step_opt->answer) {
	integration.step = atof(step_opt->answer);
	integration.unit = unit_opt->answer;
    }
    else {
	integration.unit = "cell";
	integration.step = 0.25;
    }
    integration.max_error = atof(error_opt->answer);
    integration.max_step = 5 * integration.step;
    integration.min_step = integration.step / 5;
    integration.limit = atof(limit_opt->answer);
    if (strcmp(dir_opt->answer, "up") == 0)
	integration.direction_type = FLOWDIR_UP;
    else if (strcmp(dir_opt->answer, "down") == 0)
	integration.direction_type = FLOWDIR_DOWN;
    else
	integration.direction_type = FLOWDIR_BOTH;


    /* cell size is the diagonal */
    integration.cell_size = sqrt(region.ns_res * region.ns_res +
				 region.ew_res * region.ew_res +
				 region.tb_res * region.tb_res);

    /* set default skip if needed */
    if (skip_opt->answers) {
	for (i = 0; i < 3; i++) {
	    if (skip_opt->answers[i] != NULL) {
		skip[i] = atoi(skip_opt->answers[i]);
	    }
	    else {
		G_fatal_error(_("Please provide 3 integer values for skip option."));
	    }
	}
    }
    else {
	skip[0] = fmax(1, region.cols / 10);
	skip[1] = fmax(1, region.rows / 10);
	skip[2] = fmax(1, region.depths / 10);

    }

    /* open raster 3D maps of velocity components */
    gradient_info.initialized = FALSE;
    load_input_raster3d_maps(scalar_opt, vector_opt, &gradient_info, &region);


    /* open new 3D raster map of flowacumulation */
    if (flowacc_opt->answer) {
	flowacc = Rast3d_open_new_opt_tile_size(flowacc_opt->answer,
						RASTER3D_USE_CACHE_DEFAULT,
						&region, FCELL_TYPE, 32);


	if (!flowacc)
	    Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
			       flowacc_opt->answer);
	init_flowaccum(&region, flowacc);
    }

    /* open 3D raster map used for sampling */
    if (sampled_opt->answer) {
	sampled = Rast3d_open_cell_old(sampled_opt->answer,
				       G_find_raster3d(sampled_opt->answer, ""),
				       &region, RASTER3D_TILE_SAME_AS_FILE,
				       RASTER3D_USE_CACHE_DEFAULT);
	if (!sampled)
	    Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
			       sampled_opt->answer);
    }
    else
	sampled = NULL;

    /* open new vector map of flowlines */
    if (flowlines_opt->answer) {
	fl_cats = Vect_new_cats_struct();
	fl_points = Vect_new_line_struct();
	if (Vect_open_new(&fl_map, flowlines_opt->answer, TRUE) < 0)
	    G_fatal_error(_("Unable to create vector map <%s>"),
			  flowlines_opt->answer);

	Vect_hist_command(&fl_map);

	if (if_table) {
	    create_table(&fl_map, &finfo, &driver,
			 gradient_info.compute_gradient, sampled ? 1 : 0);
	}
    }

    n_seeds = 0;
    /* open vector map of seeds */
    if (seed_opt->answer) {
	if (Vect_open_old2(&seed_Map, seed_opt->answer, "", "1") < 0)
	    G_fatal_error(_("Unable to open vector map <%s>"),
			  seed_opt->answer);
	if (!Vect_is_3d(&seed_Map))
	    G_fatal_error(_("Vector map <%s> is not 3D"), seed_opt->answer);

	n_seeds = Vect_get_num_primitives(&seed_Map, GV_POINT);
    }
    if (flowacc_opt->answer || (!seed_opt->answer && flowlines_opt->answer)) {
	if (flowacc_opt->answer)
	    n_seeds += region.cols * region.rows * region.depths;
	else {
	    n_seeds += ceil(region.cols / (double)skip[0]) *
		ceil(region.rows / (double)skip[1]) *
		ceil(region.depths / (double)skip[2]);
	}
    }
    G_debug(1, "Number of seeds is %d", n_seeds);

    seed_count = 0;
    cat = 1;
    if (seed_opt->answer) {

	seed_points = Vect_new_line_struct();
	seed_cats = Vect_new_cats_struct();

	/* compute flowlines from vector seed map */
	while (TRUE) {
	    ltype = Vect_read_next_line(&seed_Map, seed_points, seed_cats);
	    if (ltype == -1) {
		Vect_close(&seed_Map);
		G_fatal_error(_("Error during reading seed vector map"));
	    }
	    else if (ltype == -2) {
		break;
	    }
	    else if (ltype == GV_POINT) {
		seed.x = seed_points->x[0];
		seed.y = seed_points->y[0];
		seed.z = seed_points->z[0];
		seed.flowline = TRUE;
		seed.flowaccum = FALSE;
	    }
	    G_percent(seed_count, n_seeds, 1);
	    if (integration.direction_type == FLOWDIR_UP ||
		integration.direction_type == FLOWDIR_BOTH) {
		integration.actual_direction = FLOWDIR_UP;
		compute_flowline(&region, &seed, &gradient_info, flowacc, sampled,
				 &integration, &fl_map, fl_cats, fl_points,
				 &cat, if_table, finfo, driver);
	    }
	    if (integration.direction_type == FLOWDIR_DOWN ||
		integration.direction_type == FLOWDIR_BOTH) {
		integration.actual_direction = FLOWDIR_DOWN;
		compute_flowline(&region, &seed, &gradient_info, flowacc, sampled,
				 &integration, &fl_map, fl_cats, fl_points,
				 &cat, if_table, finfo, driver);
	    }
	    seed_count++;
	}

	Vect_destroy_line_struct(seed_points);
	Vect_destroy_cats_struct(seed_cats);
	Vect_close(&seed_Map);
    }
    if (flowacc_opt->answer || (!seed_opt->answer && flowlines_opt->answer)) {
	/* compute flowlines from points on grid */
	for (r = region.rows; r > 0; r--) {
	    for (c = 0; c < region.cols; c++) {
		for (d = 0; d < region.depths; d++) {
		    seed.x =
			region.west + c * region.ew_res + region.ew_res / 2;
		    seed.y =
			region.south + r * region.ns_res - region.ns_res / 2;
		    seed.z =
			region.bottom + d * region.tb_res + region.tb_res / 2;
		    seed.flowline = FALSE;
		    seed.flowaccum = FALSE;
		    if (flowacc_opt->answer)
			seed.flowaccum = TRUE;

		    if (flowlines_opt->answer && !seed_opt->answer &&
		       (c % skip[0] == 0) && (r % skip[1] == 0) && (d % skip[2] == 0))
			seed.flowline = TRUE;

		    if (seed.flowaccum || seed.flowline) {
			G_percent(seed_count, n_seeds, 1);

			if (integration.direction_type == FLOWDIR_UP ||
			    integration.direction_type == FLOWDIR_BOTH) {
			    integration.actual_direction = FLOWDIR_UP;
			    compute_flowline(&region, &seed, &gradient_info,
					     flowacc, sampled, &integration, &fl_map,
					     fl_cats, fl_points, &cat,
					     if_table, finfo, driver);
			}
			if (integration.direction_type == FLOWDIR_DOWN ||
			    integration.direction_type == FLOWDIR_BOTH) {
			    integration.actual_direction = FLOWDIR_DOWN;
			    compute_flowline(&region, &seed, &gradient_info,
					     flowacc, sampled, &integration, &fl_map,
					     fl_cats, fl_points, &cat,
					     if_table, finfo, driver);
			}
			seed_count++;
		    }
		}
	    }
	}
    }
    G_percent(1, 1, 1);
    if (flowlines_opt->answer) {
	if (if_table) {
	    db_commit_transaction(driver);
	    db_close_database_shutdown_driver(driver);
	}
	Vect_destroy_line_struct(fl_points);
	Vect_destroy_cats_struct(fl_cats);
	Vect_build(&fl_map);
	Vect_close(&fl_map);
    }

    if (flowacc_opt->answer)
	Rast3d_close(flowacc);


    return EXIT_SUCCESS;
}
Пример #3
0
int OUTGR()
{
    void *cf1, *cf2, *cf3, *cf4, *cf5, *cf6, *cf7;
    int read_val;
    FCELL *cell;
    float *data;
    int i, iarc, cnt;
    int bmask = 1;
    int x, y;
    float value;

    if ((cellinp != NULL) && (cellout != NULL)) {
	cell = Rast_allocate_f_buf();

	for (i = 0; i < nsizr; i++) {
	    /* seek to the right row */
	    G_fseek
		(Tmp_fd_cell, ((off_t)(nsizr - 1 - i) * nsizc * sizeof(FCELL)),
		 0);
	    fread(cell, sizeof(FCELL), nsizc, Tmp_fd_cell);
	    Rast_put_f_row(fdcout, cell);
	}
    }

  /*** Initialize output g3d region ***/
    current_region.bottom = z_orig_in;
    current_region.top = nsizl * tb_res_in + z_orig_in;

    if (!(data = (float *)G_malloc(sizeof(float) * nsizr * nsizc * nsizl))) {
	clean();
	G_fatal_error(_("Out of memory"));
    }

  /*** Write elevation results ***/
    if (outz != NULL) {

	cf1 = Rast3d_open_new_opt_tile_size(outz, RASTER3D_USE_CACHE_DEFAULT, &current_region, FCELL_TYPE, 32); 
	if (cf1 == NULL) {
	    clean();
	    G_fatal_error(_("Unable to open %s for writing"), outz);
	}

	/* seek to the beginning */
	G_fseek(Tmp_fd_z, 0L, 0);

	/* Read data in from temp file */
	read_val =
	    fread(data, sizeof(float), nsizr * nsizc * nsizl, Tmp_fd_z);
	if (read_val < 0) {
	    clean();
	    G_fatal_error(_("Unable to read data from temp file"));
	}

	cnt = 0;
	for (iarc = 0; iarc < nsizl; iarc++) {

	    for (y = nsizr - 1; y >= 0; y--) {	/* changed by AV */
		for (x = 0; x < nsizc; x++) {
		    if (maskmap != NULL)
			bmask = BM_get(bitmask, x, nsizr - y - 1);
		    else
			bmask = 1;
		    value = data[cnt];
		    if (!bmask)
			Rast3d_set_null_value(&value, 1, FCELL_TYPE);
		    if (Rast3d_put_float(cf1, x, y, iarc, value) == 0) {
			clean();
			G_fatal_error(
				_("Error writing cell (%d,%d,%d) with value %f"),
				x, y, iarc, value);
		    }

		    cnt++;

		}
	    }
	}

	/* Close the file */
	if (Rast3d_close(cf1) == 0) {
	    clean();
	    G_fatal_error(_("Error closing output file %s"), outz);
	} else
            G_message(_("3D raster map <%s> created"), outz);
    }

  /*** Write out the gradient results ***/
    if (gradient != NULL) {

	cf2 = Rast3d_open_new_opt_tile_size(gradient, RASTER3D_USE_CACHE_DEFAULT, &current_region, FCELL_TYPE, 32); 
	if (cf2 == NULL) {
	    clean();
	    G_fatal_error(_("Unable to open %s for writing"), gradient);
	}

	/* seek to the beginning */
	G_fseek(Tmp_fd_dx, 0L, 0);

	/* Read data in from temp file */
	read_val =
	    fread(data, sizeof(float), nsizr * nsizc * nsizl, Tmp_fd_dx);
	if (read_val < 0) {
	    clean();
	    G_fatal_error(_("Unable to read data from temp file"));
	}

	cnt = 0;
	for (iarc = 0; iarc < nsizl; iarc++) {

	    for (y = nsizr - 1; y >= 0; y--) {	/* changed by AV */
		for (x = 0; x < nsizc; x++) {
		    if (maskmap != NULL)
			bmask = BM_get(bitmask, x, nsizr - y - 1);
		    else
			bmask = 1;
		    value = data[cnt];
		    if (!bmask)
			Rast3d_set_null_value(&value, 1, FCELL_TYPE);
		    if (Rast3d_put_float(cf2, x, y, iarc, value) == 0) {
			clean();
			G_fatal_error(
				_("Error writing cell (%d,%d,%d) with value %f"),
				x, y, iarc, value);
		    }

		    cnt++;

		}
	    }
	}

	/* Close the file */
	if (Rast3d_close(cf2) == 0) {
	    clean();
	    G_fatal_error(_("Error closing output file %s"), gradient);
	} else
            G_message(_("3D raster map <%s> created"), gradient);
    }

  /*** Write out aspect1 results ***/
    if (aspect1 != NULL) {

	cf3 = Rast3d_open_new_opt_tile_size(aspect1, RASTER3D_USE_CACHE_DEFAULT, &current_region, FCELL_TYPE, 32); 
	if (cf3 == NULL) {
	    clean();
	    G_fatal_error(_("Unable to open %s for writing"), aspect1);
	}

	/* seek to the beginning */
	G_fseek(Tmp_fd_dy, 0L, 0);

	/* Read data in from temp file */
	read_val =
	    fread(data, sizeof(float), nsizr * nsizc * nsizl, Tmp_fd_dy);
	if (read_val < 0) {
	    clean();
	    G_fatal_error(_("Unable to read data from temp file"));
	}

	cnt = 0;
	for (iarc = 0; iarc < nsizl; iarc++) {

	    for (y = nsizr - 1; y >= 0; y--) {	/* changed by AV */
		for (x = 0; x < nsizc; x++) {
		    if (maskmap != NULL)
			bmask = BM_get(bitmask, x, nsizr - y - 1);
		    else
			bmask = 1;
		    value = data[cnt] * 180 / M_PI;
		    if (!bmask)
			Rast3d_set_null_value(&value, 1, FCELL_TYPE);
		    if (Rast3d_put_float(cf3, x, y, iarc, value) == 0) {
			clean();
			G_fatal_error(
				_("Error writing cell (%d,%d,%d) with value %f"),
				x, y, iarc, value);
		    }

		    cnt++;

		}
	    }
	}

	/* Close the file */
	if (Rast3d_close(cf3) == 0) {
	    clean();
	    G_fatal_error(_("Error closing output file %s"), aspect1);
	} else
            G_message(_("3D raster map <%s> created"), aspect1);
    }

  /*** Write out aspect2 results ***/
    if (aspect2 != NULL) {

	cf4 = Rast3d_open_new_opt_tile_size(aspect2, RASTER3D_USE_CACHE_DEFAULT, &current_region, FCELL_TYPE, 32); 
	if (cf4 == NULL) {
	    clean();
	    G_fatal_error(_("Unable to open %s for writing"), aspect2);
	}

	/* seek to the beginning */
	G_fseek(Tmp_fd_dz, 0L, 0);

	/* Read data in from temp file */
	read_val =
	    fread(data, sizeof(float), nsizr * nsizc * nsizl, Tmp_fd_dz);
	if (read_val < 0) {
	    clean();
	    G_fatal_error(_("Unable to read data from temp file"));
	}

	cnt = 0;
	for (iarc = 0; iarc < nsizl; iarc++) {

	    for (y = nsizr - 1; y >= 0; y--) {	/* changed by AV */
		for (x = 0; x < nsizc; x++) {
		    if (maskmap != NULL)
			bmask = BM_get(bitmask, x, nsizr - y - 1);
		    else
			bmask = 1;
		    value = data[cnt] * 180 / M_PI;
		    if (!bmask)
			Rast3d_set_null_value(&value, 1, FCELL_TYPE);
		    if (Rast3d_put_float(cf4, x, y, iarc, value) == 0) {
			clean();
			G_fatal_error(
				_("Error writing cell (%d,%d,%d) with value %f"),
				x, y, iarc, value);
		    }

		    cnt++;

		}
	    }
	}

	/* Close the file */
	if (Rast3d_close(cf4) == 0) {
	    clean();
	    G_fatal_error(_("Error closing output file %s"), aspect2);
	} else
            G_message(_("3D raster map <%s> created"), aspect2);
    }

  /*** Write out ncurv results ***/
    if (ncurv != NULL) {

	cf5 = Rast3d_open_new_opt_tile_size(ncurv, RASTER3D_USE_CACHE_DEFAULT, &current_region, FCELL_TYPE, 32); 
	if (cf5 == NULL) {
	    clean();
	    G_fatal_error(_("Unable to open %s for writing"), ncurv);
	}

	/* seek to the beginning */
	G_fseek(Tmp_fd_xx, 0L, 0);

	/* Read data in from temp file */
	read_val =
	    fread(data, sizeof(float), nsizr * nsizc * nsizl, Tmp_fd_xx);
	if (read_val < 0) {
	    clean();
	    G_fatal_error(_("Unable to read data from temp file"));
	}

	cnt = 0;
	for (iarc = 0; iarc < nsizl; iarc++) {

	    for (y = nsizr - 1; y >= 0; y--) {	/* changed by AV */
		for (x = 0; x < nsizc; x++) {
		    if (maskmap != NULL)
			bmask = BM_get(bitmask, x, nsizr - y - 1);
		    else
			bmask = 1;
		    value = data[cnt];
		    if (!bmask)
			Rast3d_set_null_value(&value, 1, FCELL_TYPE);
		    if (Rast3d_put_float(cf5, x, y, iarc, value) == 0) {
			clean();
			G_fatal_error(
				_("Error writing cell (%d,%d,%d) with value %f"),
				x, y, iarc, value);
		    }

		    cnt++;

		}
	    }
	}

	/* Close the file */
	if (Rast3d_close(cf5) == 0) {
	    clean();
	    G_fatal_error(_("Error closing output file %s"), ncurv);
	} else
            G_message(_("3D raster map <%s> created"), ncurv);
    }

  /*** Write out gcurv results ***/
    if (gcurv != NULL) {

	cf6 = Rast3d_open_new_opt_tile_size(gcurv, RASTER3D_USE_CACHE_DEFAULT, &current_region, FCELL_TYPE, 32); 
	if (cf6 == NULL) {
	    clean();
	    G_fatal_error(_("Unable to open %s for writing"), gcurv);
	}

	/* seek to the beginning */
	G_fseek(Tmp_fd_yy, 0L, 0);

	/* Read data in from temp file */
	read_val =
	    fread(data, sizeof(float), nsizr * nsizc * nsizl, Tmp_fd_yy);
	if (read_val < 0) {
	    clean();
	    G_fatal_error(_("Unable to read data from temp file"));
	}

	cnt = 0;
	for (iarc = 0; iarc < nsizl; iarc++) {

	    for (y = nsizr - 1; y >= 0; y--) {	/* changed by AV */
		for (x = 0; x < nsizc; x++) {
		    if (maskmap != NULL)
			bmask = BM_get(bitmask, x, nsizr - y - 1);
		    else
			bmask = 1;
		    value = data[cnt];
		    if (!bmask)
			Rast3d_set_null_value(&value, 1, FCELL_TYPE);
		    if (Rast3d_put_float(cf6, x, y, iarc, value) == 0) {
			clean();
			G_fatal_error(
				_("Error writing cell (%d,%d,%d) with value %f"),
				x, y, iarc, value);
		    }

		    cnt++;

		}
	    }
	}

	/* Close the file */
	if (Rast3d_close(cf6) == 0) {
	    clean();
	    G_fatal_error(_("Error closing output file %s"), gcurv);
	} else
            G_message(_("3D raster map <%s> created"), gcurv);
    }

  /*** Write mcurv results ***/
    if (mcurv != NULL) {

	cf7 = Rast3d_open_new_opt_tile_size(mcurv, RASTER3D_USE_CACHE_DEFAULT, &current_region, FCELL_TYPE, 32); 
	if (cf7 == NULL) {
	    clean();
	    G_fatal_error(_("Unable to open %s for writing"), mcurv);
	}

	/* seek to the beginning */
	G_fseek(Tmp_fd_xy, 0L, 0);

	/* Read data in from temp file */
	read_val =
	    fread(data, sizeof(float), nsizr * nsizc * nsizl, Tmp_fd_xy);
	if (read_val < 0) {
	    clean();
	    G_fatal_error(_("Unable to read data from temp file"));
	}

	cnt = 0;
	for (iarc = 0; iarc < nsizl; iarc++) {

	    for (y = nsizr - 1; y >= 0; y--) {	/* changed by AV */
		for (x = 0; x < nsizc; x++) {
		    if (maskmap != NULL)
			bmask = BM_get(bitmask, x, nsizr - y - 1);
		    else
			bmask = 1;
		    value = data[cnt];
		    if (!bmask)
			Rast3d_set_null_value(&value, 1, FCELL_TYPE);
		    if (Rast3d_put_float(cf7, x, y, iarc, value) == 0) {
			clean();
			G_fatal_error(
				_("Error writing cell (%d,%d,%d) with value %f"),
				x, y, iarc, value);
		    }

		    cnt++;

		}
	    }
	}

	/* Close the file */
	if (Rast3d_close(cf7) == 0) {
	    clean();
	    G_fatal_error(_("Error closing output file %s"), mcurv);
	} else
            G_message(_("3D raster map <%s> created"), mcurv);
    }

    G_free(data);

    return 1;
}
Пример #4
0
Файл: main.c Проект: caomw/grass
int main(int argc, char **argv)
{
    RASTER3D_Map *input;
    RASTER3D_Map *output;
    RASTER3D_Region region;
    struct GModule *module;
    stat_func *method_fn;
    double quantile;
    int x, y, z;

    /* Initialize GRASS */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster3d"));
    G_add_keyword(_("neighbor"));
    G_add_keyword(_("aggregation"));
    G_add_keyword(_("statistics"));
    G_add_keyword(_("filter"));
    module->description =
	_("Makes each voxel value a "
	  "function of the values assigned to the voxels "
	  "around it, and stores new voxel values in an output 3D raster map");

    /* Get parameters from user */
    set_params();

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (NULL == G_find_raster3d(param.input->answer, ""))
	Rast3d_fatal_error(_("3D raster map <%s> not found"),
			   param.input->answer);

    Rast3d_init_defaults();
    Rast3d_get_window(&region);

    nx = region.cols;
    ny = region.rows;
    nz = region.depths;

    /* Size fo the moving window */
    x_size = atoi(param.window->answers[0]);
    y_size = atoi(param.window->answers[1]);
    z_size = atoi(param.window->answers[2]);

    /* Distances in all directions */
    x_dist = x_size / 2;
    y_dist = y_size / 2;
    z_dist = z_size / 2;

    /* Maximum size of the buffer */
    size = x_size * y_size * z_size;

    /* Set the computation method */
    method_fn = menu[find_method(param.method->answer)].method;

    if (param.quantile->answer)
	quantile = atof(param.quantile->answer);
    else
	quantile = 0.0;

    input = Rast3d_open_cell_old(param.input->answer,
				 G_find_raster3d(param.input->answer, ""),
				 &region, RASTER3D_TILE_SAME_AS_FILE,
				 RASTER3D_USE_CACHE_DEFAULT);

    if (input == NULL)
	Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
			   param.input->answer);

    output =
	Rast3d_open_new_opt_tile_size(param.output->answer,
				      RASTER3D_USE_CACHE_X, &region,
				      DCELL_TYPE, 32);

    if (output == NULL)
	Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"),
			   param.output->answer);

    Rast3d_min_unlocked(output, RASTER3D_USE_CACHE_X);
    Rast3d_autolock_on(output);
    Rast3d_unlock_all(output);

    DCELL *buff = NULL, value;

    buff = (DCELL *) calloc(size, sizeof(DCELL));

    if (buff == NULL)
	Rast3d_fatal_error(_("Unable to allocate buffer"));

    for (z = 0; z < nz; z++) {
	for (y = 0; y < ny; y++) {
	    for (x = 0; x < nx; x++) {
		/* Gather values in moving window */
		int num = gather_values(input, buff, x, y, z);

		/* Compute the resulting value */
		if (num > 0)
		    (*method_fn) (&value, buff, num, &quantile);
		else
		    Rast_set_d_null_value(&value, 1);
		/* Write the value */
		Rast3d_put_double(output, x, y, z, value);
	    }
	}
    }

    free(buff);

    if (!Rast3d_flush_all_tiles(output))
	G_fatal_error(_("Error flushing tiles"));

    Rast3d_autolock_off(output);
    Rast3d_unlock_all(output);

    Rast3d_close(input);
    Rast3d_close(output);

    return 0;
}
int test_large_file(int depths, int rows, int cols, int tile_size)
{
    int sum = 0;
    int x, y, z, count;
    DCELL value;

    G_message("Testing DCELL put function for large files");

    RASTER3D_Region region;
    RASTER3D_Map *map = NULL;

    /* We need to set up a specific region for the new raster3d map.
     * First we safe the default region. */
    Rast3d_get_window(&region);

    region.bottom = -365.5;
    region.top = 365.5;
    region.south = -90;
    region.north = 90;
    region.west = -180;
    region.east = 180;
    region.rows = rows;
    region.cols = cols;
    region.depths = depths;

    Rast3d_adjust_region(&region);

    G_message("Creating 3D raster map");

    map = Rast3d_open_new_opt_tile_size("test_put_get_value_dcell_large",
                                        RASTER3D_USE_CACHE_XY, &region, DCELL_TYPE, tile_size);

    /* The window is the same as the map region ... of course */
    Rast3d_set_window_map(map, &region);

    /*Write -1 first to see if the tile handling works correctly */
    for(z = 0; z < region.depths; z++) {
        G_percent(z, region.depths, 1);
        for(y = 0; y < region.rows; y++) {
            for(x = 0; x < region.cols; x++) {
                /* Put the counter as cell value */
                value = -1;
                Rast3d_put_value(map, x, y, z, &value, DCELL_TYPE);
            }
        }
    }

    G_percent(1, 1, 1);
    G_message("Rewriting the values");

    /* Now write the values to be evaluated */
    count = 1;
    for(z = 0; z < region.depths; z++) {
        G_percent(z, region.depths, 1);
        for(y = 0; y < region.rows; y++) {
            for(x = 0; x < region.cols; x++) {
                /* Put the counter as cell value */
                value = count;
                Rast3d_put_value(map, x, y, z, &value, DCELL_TYPE);
                count++;
            }
        }
    }

    G_percent(1, 1, 1);

    G_message("Verifying 3D raster map");

    count = 1;
    for(z = 0; z < region.depths; z++) {
        G_percent(z, region.depths, 1);
        for(y = 0; y < region.rows; y++) {
            for(x = 0; x < region.cols; x++) {
                /* Check the counter as cell value */
                Rast3d_get_value(map, x, y, z, &value, DCELL_TYPE);
                if(fabs(value - (double)(count) > EPSILON)) {
                    G_message("At: z %i y %i x %i -- value %.14lf != %.14lf\n",
                              z, y, x, value, (double)(count));
                    sum++;
                }
                count++;
            }
        }
    }
    G_percent(1, 1, 1);
    Rast3d_close(map);

    G_remove("grid3", "test_put_get_value_dcell_large");

    return sum;
}
int test_large_file_sparse_random(int depths, int rows, int cols, int tile_size)
{
    int sum = 0;
    int x, y, z, i;
    DCELL value, random_value;
    DCELL *random_value_vector = G_calloc(RAND_VALUE_VECTOR_SIZE, sizeof(DCELL));

    G_message("Testing DCELL put function for large files filled with sparse random values");

    RASTER3D_Region region;
    RASTER3D_Map *map = NULL;

    /* We need to set up a specific region for the new raster3d map.
     * First we safe the default region. */
    Rast3d_get_window(&region);

    region.bottom = -365.5;
    region.top = 365.5;
    region.south = -90;
    region.north = 90;
    region.west = -180;
    region.east = 180;
    region.rows = rows;
    region.cols = cols;
    region.depths = depths;

    Rast3d_adjust_region(&region);

    G_message("Creating 3D raster map filled with sparse random values");

    map = Rast3d_open_new_opt_tile_size("test_put_get_value_dcell_large_sparse_random",
                                        RASTER3D_USE_CACHE_XY, &region, DCELL_TYPE, tile_size);

    /* The window is the same as the map region ... of course */
    Rast3d_set_window_map(map, &region);

    srand(1);

    /* We fill the random value vector */
    for(i = 0; i < RAND_VALUE_VECTOR_SIZE; i++) {
        /* Put the counter as cell value */
        value = (DCELL)rand();
        value /= RAND_MAX;
        if(value <= 0.7)
            value = 0.0;
        else if(value <= 0.8)
            value = 1.0;
        else if(value <= 0.9)
            value = 2.0;
        else if(value <= 1.0)
            value = 3.0;
        else
            value = 4.0;
        random_value_vector[i] = value;
    }

    i = 0;

    for(z = 0; z < region.depths; z++) {
        G_percent(z, region.depths, 1);
        for(y = 0; y < region.rows; y++) {
            for(x = 0; x < region.cols; x++) {
                /* Put the counter as cell value */
                value = random_value_vector[i];
                Rast3d_put_value(map, x, y, z, &value, DCELL_TYPE);
                i++;
                if(i == RAND_VALUE_VECTOR_SIZE)
                    i = 0;
            }
        }
    }

    G_percent(1, 1, 1);
    /* Write everything to the disk */
    Rast3d_flush_all_tiles(map);
    Rast3d_close(map);

    G_message("Verifying 3D raster map filled with sparse random values");

    map = Rast3d_open_cell_old("test_put_get_value_dcell_large_sparse_random",
                               G_mapset(), &region, DCELL_TYPE, RASTER3D_USE_CACHE_XY);

    i = 0;

    for(z = 0; z < region.depths; z++) {
        G_percent(z, region.depths, 1);
        for(y = 0; y < region.rows; y++) {
            for(x = 0; x < region.cols; x++) {
                /* Check the counter as cell value */
                Rast3d_get_value(map, x, y, z, &value, DCELL_TYPE);
                if(fabs(value - random_value_vector[i]) > EPSILON) {
                    G_message("At: z %i y %i x %i -- value %.14lf != %.14lf\n",
                              z, y, x, value, random_value);
                    sum++;
                }
                i++;
                if(i == RAND_VALUE_VECTOR_SIZE)
                    i = 0;
            }
        }
    }
    G_percent(1, 1, 1);
    Rast3d_close(map);

    G_free(random_value_vector);

    G_remove("grid3", "test_put_get_value_dcell_large_sparse_random");

    return sum;
}
int test_large_file_zeros(int depths, int rows, int cols, int tile_size)
{
    int sum = 0;
    int x, y, z;
    DCELL value;

    G_message("Testing DCELL put function for large files filled with zeros");

    RASTER3D_Region region;
    RASTER3D_Map *map = NULL;

    /* We need to set up a specific region for the new raster3d map.
     * First we safe the default region. */
    Rast3d_get_window(&region);

    region.bottom = -365.5;
    region.top = 365.5;
    region.south = -90;
    region.north = 90;
    region.west = -180;
    region.east = 180;
    region.rows = rows;
    region.cols = cols;
    region.depths = depths;

    Rast3d_adjust_region(&region);

    G_message("Creating 3D raster map filled with zeros");

    map = Rast3d_open_new_opt_tile_size("test_put_get_value_dcell_large_zeros",
                                        RASTER3D_USE_CACHE_XY, &region, DCELL_TYPE, tile_size);

    /* The window is the same as the map region ... of course */
    Rast3d_set_window_map(map, &region);

    for(z = 0; z < region.depths; z++) {
        G_percent(z, region.depths, 1);
        for(y = 0; y < region.rows; y++) {
            for(x = 0; x < region.cols; x++) {
                /* Put the counter as cell value */
                value = 0.0;
                Rast3d_put_value(map, x, y, z, &value, DCELL_TYPE);
            }
        }
    }

    G_percent(1, 1, 1);
    /* Write everything to the disk */
    Rast3d_flush_all_tiles(map);
    Rast3d_close(map);

    G_message("Verifying 3D raster map filled with zeros");

    map = Rast3d_open_cell_old("test_put_get_value_dcell_large_zeros",
                               G_mapset(), &region, DCELL_TYPE, RASTER3D_USE_CACHE_XY);

    for(z = 0; z < region.depths; z++) {
        G_percent(z, region.depths, 1);
        for(y = 0; y < region.rows; y++) {
            for(x = 0; x < region.cols; x++) {
                /* Check the counter as cell value */
                Rast3d_get_value(map, x, y, z, &value, DCELL_TYPE);
                if(value > EPSILON) {
                    G_message("At: z %i y %i x %i -- value %.14lf != 0.0\n",
                              z, y, x, value);
                    sum++;
                }
            }
        }
    }
    G_percent(1, 1, 1);
    Rast3d_close(map);

    G_remove("grid3", "test_put_get_value_dcell_large_zeros");

    return sum;
}