/* * check_stats() - Check and update statistics * * RETURN: EXIT_SUCCESS / EXIT_FAILURE */ int check_stats(const char *name) { struct Categories cats; struct FPRange fprange; int cats_ok; G_message(_("Updating statistics for <%s>"), name); /* Get category status and max */ cats_ok = (Rast3d_read_cats(name, "", &cats) >= 0); Rast3d_read_range(name, "", &fprange); /* Further category checks */ if (!cats_ok) Rast_init_cats("", &cats); else if (cats.num != fprange.max) { cats.num = fprange.max; cats_ok = 0; } /* Update categories if needed */ if (!cats_ok) { G_message(_("Updating the number of categories for <%s>"), name); Rast3d_write_cats(name, &cats); } Rast_free_cats(&cats); return 0; }
int main(int argc, char **argv) { char *map_name; int maptype; int color; int i; int thin, lines, steps; int fp; int label_indent; int hide_catnum, hide_catstr, show_ticks, show_bg, hide_nodata, do_smooth; struct Categories cats; struct Colors colors; struct GModule *module; struct Option *opt_rast2d, *opt_rast3d, *opt_color, *opt_lines, *opt_thin, *opt_labelnum, *opt_at, *opt_use, *opt_range, *opt_font, *opt_path, *opt_charset, *opt_fontsize, *opt_title, *opt_ticks, *opt_tstep, *opt_brdcolor, *opt_bgcolor, *opt_tit_fontsize, *opt_digits, *opt_units; struct Flag *hidestr, *hidenum, *hidenodata, *smooth, *flipit, *histo, *showtick, *showbg, *log_sc; double X0, X1, Y0, Y1; int flip, UserRange; double UserRangeMin, UserRangeMax, UserRangeTemp; double *catlist; int catlistCount, use_catlist, ticksCount; double fontsize; char *title; char *units; double *tick_values; double t_step; int colorb, colorbg; double tit_fontsize; int log_scale, digits; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("display")); G_add_keyword(_("cartography")); G_add_keyword(_("legend")); module->description = _("Displays a legend for a 2D or 3D raster map in the active frame " "of the graphics monitor."); opt_rast2d = G_define_standard_option(G_OPT_R_MAP); opt_rast2d->key = "raster"; opt_rast2d->required = NO; opt_rast2d->guisection = _("Input"); opt_rast3d = G_define_standard_option(G_OPT_R3_MAP); opt_rast3d->key = "raster_3d"; opt_rast3d->required = NO; opt_rast3d->guisection = _("Input"); opt_title = G_define_option(); opt_title->key = "title"; opt_title->type = TYPE_STRING; opt_title->required = NO; opt_title->description = _("Legend title"); opt_title->guisection = _("Title"); opt_tit_fontsize = G_define_option(); opt_tit_fontsize->key = "title_fontsize"; opt_tit_fontsize->type = TYPE_DOUBLE; opt_tit_fontsize->required = NO; opt_tit_fontsize->options = "1-360"; opt_tit_fontsize->label = _("Title font size"); opt_tit_fontsize->description = _("Default: Same as fontsize"); opt_tit_fontsize->guisection = _("Title"); opt_lines = G_define_option(); opt_lines->key = "lines"; opt_lines->type = TYPE_INTEGER; opt_lines->answer = "0"; opt_lines->options = "0-1000"; opt_lines->description = _("Number of text lines (useful for truncating long legends)"); opt_lines->guisection = _("Advanced"); opt_thin = G_define_option(); opt_thin->key = "thin"; opt_thin->type = TYPE_INTEGER; opt_thin->required = NO; opt_thin->answer = "1"; opt_thin->options = "1-1000"; opt_thin->description = _("Thinning factor (thin=10 gives cats 0,10,20...)"); opt_thin->guisection = _("Advanced"); opt_units = G_define_option(); opt_units->key = "units"; opt_units->type = TYPE_STRING; opt_units->required = NO; opt_units->description = _("Units to display after labels (e.g. meters)"); opt_units->guisection = _("Advanced"); opt_labelnum = G_define_option(); opt_labelnum->key = "labelnum"; opt_labelnum->type = TYPE_INTEGER; opt_labelnum->answer = "5"; opt_labelnum->options = "2-100"; opt_labelnum->description = _("Number of text labels for smooth gradient legend"); opt_labelnum->guisection = _("Gradient"); opt_ticks = G_define_option(); opt_ticks->key = "label_values"; opt_ticks->type = TYPE_DOUBLE; opt_ticks->required = NO; opt_ticks->description = _("Specific values to draw ticks"); opt_ticks->required = NO; opt_ticks->multiple = YES; opt_ticks->guisection = _("Gradient"); opt_tstep = G_define_option(); opt_tstep->key = "label_step"; opt_tstep->type = TYPE_DOUBLE; opt_tstep->required = NO; opt_tstep->description = _("Display label every step"); opt_tstep->guisection = _("Gradient"); opt_digits = G_define_option(); opt_digits->key = "digits"; opt_digits->type = TYPE_INTEGER; opt_digits->required = NO; opt_digits->description = _("Number of digits after decimal point"); opt_digits->guisection = _("Advanced"); opt_digits->answer = NULL; opt_digits->options = "0-6"; opt_at = G_define_option(); opt_at->key = "at"; opt_at->key_desc = "bottom,top,left,right"; opt_at->type = TYPE_DOUBLE; /* needs to be TYPE_DOUBLE to get past options check */ opt_at->required = NO; opt_at->options = "0-100"; opt_at->label = _("Size and placement as percentage of screen coordinates " "(0,0 is lower left)"); opt_at->description = opt_at->key_desc; opt_at->answer = NULL; opt_use = G_define_option(); opt_use->key = "use"; opt_use->type = TYPE_DOUBLE; /* string as it is fed through the parser? */ opt_use->required = NO; opt_use->description = _("List of discrete category numbers/values for legend"); opt_use->multiple = YES; opt_use->guisection = _("Subset"); opt_range = G_define_option(); opt_range->key = "range"; opt_range->key_desc = "min,max"; opt_range->type = TYPE_DOUBLE; /* should it be type_double or _string ?? */ opt_range->required = NO; opt_range->description = _("Use a subset of the map range for the legend (min,max)"); opt_range->guisection = _("Subset"); opt_color = G_define_standard_option(G_OPT_C); opt_color->label = _("Text color"); opt_color->guisection = _("Font settings"); opt_font = G_define_option(); opt_font->key = "font"; opt_font->type = TYPE_STRING; opt_font->required = NO; opt_font->description = _("Font name"); opt_font->guisection = _("Font settings"); opt_fontsize = G_define_option(); opt_fontsize->key = "fontsize"; opt_fontsize->type = TYPE_DOUBLE; opt_fontsize->required = NO; opt_fontsize->options = "1-360"; opt_fontsize->label = _("Font size"); opt_fontsize->description = _("Default: Auto-scaled"); opt_fontsize->guisection = _("Font settings"); opt_path = G_define_standard_option(G_OPT_F_INPUT); opt_path->key = "path"; opt_path->required = NO; opt_path->description = _("Path to font file"); opt_path->gisprompt = "old_file,font,file"; opt_path->guisection = _("Font settings"); opt_charset = G_define_option(); opt_charset->key = "charset"; opt_charset->type = TYPE_STRING; opt_charset->required = NO; opt_charset->description = _("Text encoding (only applicable to TrueType fonts)"); opt_charset->guisection = _("Font settings"); opt_brdcolor = G_define_standard_option(G_OPT_CN); opt_brdcolor->key = "border_color"; opt_brdcolor->answer = "black"; opt_brdcolor->label = _("Border color"); opt_brdcolor->guisection = _("Background"); opt_bgcolor = G_define_standard_option(G_OPT_CN); opt_bgcolor->key = "bgcolor"; opt_bgcolor->answer = "white"; opt_bgcolor->label = _("Background color"); opt_bgcolor->guisection = _("Background"); hidestr = G_define_flag(); hidestr->key = 'v'; hidestr->description = _("Do not show category labels"); hidestr->guisection = _("Advanced"); hidenum = G_define_flag(); hidenum->key = 'c'; hidenum->description = _("Do not show category numbers"); hidenum->guisection = _("Advanced"); showtick = G_define_flag(); showtick->key = 't'; showtick->description = _("Draw legend ticks for labels"); showtick->guisection = _("Gradient"); hidenodata = G_define_flag(); hidenodata->key = 'n'; hidenodata->description = _("Skip categories with no label"); hidenodata->guisection = _("Advanced"); smooth = G_define_flag(); smooth->key = 's'; smooth->description = _("Draw smooth gradient"); smooth->guisection = _("Gradient"); flipit = G_define_flag(); flipit->key = 'f'; flipit->description = _("Flip legend"); flipit->guisection = _("Advanced"); histo = G_define_flag(); histo->key = 'd'; histo->description = _("Add histogram to smoothed legend"); histo->guisection = _("Gradient"); showbg = G_define_flag(); showbg->key = 'b'; showbg->description = _("Show background"); showbg->guisection = _("Background"); log_sc = G_define_flag(); log_sc->key = 'l'; log_sc->description = _("Use logarithmic scale"); log_sc->guisection = _("Advanced"); G_option_required(opt_rast2d, opt_rast3d, NULL); G_option_exclusive(opt_rast2d, opt_rast3d, NULL); G_option_exclusive(hidenum, opt_ticks, NULL); G_option_exclusive(hidenum, opt_tstep, NULL); /* Check command line */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (opt_rast2d->answer) { map_name = opt_rast2d->answer; maptype = MAP_TYPE_RASTER2D; } else { map_name = opt_rast3d->answer; maptype = MAP_TYPE_RASTER3D; } if (opt_title->answer) title = opt_title->answer; else title = ""; if (opt_units->answer) { units = opt_units->answer; } else units = ""; hide_catstr = hidestr->answer; /* note hide_catstr gets changed and re-read below */ hide_catnum = hidenum->answer; show_ticks = showtick->answer; hide_nodata = hidenodata->answer; do_smooth = smooth->answer; flip = flipit->answer; show_bg = showbg->answer; log_scale = log_sc->answer; if (showtick->answer) { label_indent = 12; } else label_indent = 6; if (opt_digits->answer != NULL) sscanf(opt_digits->answer, "%d", &digits); else digits = -1; color = D_parse_color(opt_color->answer, TRUE); if (opt_lines->answer != NULL) sscanf(opt_lines->answer, "%d", &lines); thin = 1; if (opt_thin->answer != NULL) sscanf(opt_thin->answer, "%d", &thin); if (!thin) thin = 1; if (opt_labelnum->answer != NULL) sscanf(opt_labelnum->answer, "%d", &steps); if ((opt_tstep->answer) || (opt_ticks->answer)) steps = 0; if (opt_tstep->answer != NULL) t_step = atof(opt_tstep->answer); ticksCount = 0; if (opt_ticks->answer != NULL) { tick_values = (double *)G_calloc(100 + 1, sizeof(double)); for (i = 0; i < 100; i++) /* fill with dummy values */ tick_values[i] = 1.0 * (i + 1); tick_values[i] = 0; for (i = 0; (opt_ticks->answers[i] != NULL) && i < 100; i++) tick_values[i] = atof(opt_ticks->answers[i]); ticksCount = i; } catlistCount = 0; if (opt_use->answer != NULL) { /* should this be answerS ? */ use_catlist = TRUE; catlist = (double *)G_calloc(100 + 1, sizeof(double)); for (i = 0; i < 100; i++) /* fill with dummy values */ catlist[i] = 1.0 * (i + 1); catlist[i] = 0; for (i = 0; (opt_use->answers[i] != NULL) && i < 100; i++) catlist[i] = atof(opt_use->answers[i]); catlistCount = i; } else use_catlist = FALSE; UserRange = FALSE; if (opt_range->answer != NULL) { /* should this be answerS ? */ sscanf(opt_range->answers[0], "%lf", &UserRangeMin); sscanf(opt_range->answers[1], "%lf", &UserRangeMax); UserRange = TRUE; if (UserRangeMin > UserRangeMax) { UserRangeTemp = UserRangeMax; UserRangeMax = UserRangeMin; UserRangeMin = UserRangeTemp; flip = !flip; } } if (maptype == MAP_TYPE_RASTER2D) { if (Rast_read_colors(map_name, "", &colors) == -1) G_fatal_error(_("Color file for <%s> not available"), map_name); fp = Rast_map_is_fp(map_name, ""); Rast_read_cats(map_name, "", &cats); } else { if (Rast3d_read_colors(map_name, "", &colors) == -1) G_fatal_error(_("Color file for <%s> not available"), map_name); fp = TRUE; /* currently raster 3D is always floating point */ Rast3d_read_cats(map_name, "", &cats); } if (fp && !use_catlist) { do_smooth = TRUE; /* fprintf(stderr, "FP map found - switching gradient legend on\n"); */ flip = !flip; } D_open_driver(); /* Parse and select background color */ colorb = D_parse_color(opt_brdcolor->answer, TRUE); colorbg = D_parse_color(opt_bgcolor->answer, TRUE); if (opt_font->answer) D_font(opt_font->answer); else if (opt_path->answer) D_font(opt_path->answer); if (opt_fontsize->answer != NULL) fontsize = atof(opt_fontsize->answer); else fontsize = 12; /* dummy placeholder, should never be called */ if (opt_charset->answer) D_encoding(opt_charset->answer); if (opt_tit_fontsize->answer != NULL) tit_fontsize = atof(opt_tit_fontsize->answer); else tit_fontsize = 0; if (opt_at->answer != NULL) { sscanf(opt_at->answers[0], "%lf", &Y1); sscanf(opt_at->answers[1], "%lf", &Y0); sscanf(opt_at->answers[2], "%lf", &X0); sscanf(opt_at->answers[3], "%lf", &X1); } else { /* default */ Y1 = 12; Y0 = 88; X0 = 3; X1 = 7; if (histo->answer) { X0 += 5; X1 += 5; } } if (show_bg) draw(map_name, maptype, color, thin, lines, steps, fp, label_indent, hide_catnum, hide_catstr, show_ticks, hide_nodata, do_smooth, cats, colors, X0, X1, Y0, Y1, flip, UserRange, UserRangeMin, UserRangeMax, catlist, catlistCount, use_catlist, ticksCount, fontsize, tit_fontsize, title, tick_values, t_step, colorb, colorbg, opt_use, opt_at, opt_fontsize, opt_tstep, opt_range, histo, hidestr, log_scale, 0, digits, units); draw(map_name, maptype, color, thin, lines, steps, fp, label_indent, hide_catnum, hide_catstr, show_ticks, hide_nodata, do_smooth, cats, colors, X0, X1, Y0, Y1, flip, UserRange, UserRangeMin, UserRangeMax, catlist, catlistCount, use_catlist, ticksCount, fontsize, tit_fontsize, title, tick_values, t_step, colorb, colorbg, opt_use, opt_at, opt_fontsize, opt_tstep, opt_range, histo, hidestr, log_scale, 1, digits, units); D_close_driver(); exit(EXIT_SUCCESS); }
/* *************************************************************** */ int main(int argc, char *argv[]) { FCELL val_f; /* for misc use */ DCELL val_d; /* for misc use */ int map_type, zmap_type; univar_stat *stats; char *infile, *zonemap; void *map, *zmap = NULL; RASTER3D_Region region; unsigned int i; unsigned int rows, cols, depths; unsigned int x, y, z; double dmin, dmax; int zone, n_zones, use_zone = 0; char *mapset, *name; struct GModule *module; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster3d")); G_add_keyword(_("statistics")); module->description = _("Calculates univariate statistics from the non-null 3d cells of a raster3d map."); /* Define the different options */ set_params(); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* Set the defaults */ Rast3d_init_defaults(); /* get the current region */ Rast3d_get_window(®ion); cols = region.cols; rows = region.rows; depths = region.depths; name = param.output_file->answer; if (name != NULL && strcmp(name, "-") != 0) { if (NULL == freopen(name, "w", stdout)) { G_fatal_error(_("Unable to open file <%s> for writing"), name); } } /* table field separator */ zone_info.sep = param.separator->answer; if (strcmp(zone_info.sep, "\\t") == 0) zone_info.sep = "\t"; if (strcmp(zone_info.sep, "tab") == 0) zone_info.sep = "\t"; if (strcmp(zone_info.sep, "space") == 0) zone_info.sep = " "; if (strcmp(zone_info.sep, "comma") == 0) zone_info.sep = ","; dmin = 0.0 / 0.0; /* set to nan as default */ dmax = 0.0 / 0.0; /* set to nan as default */ zone_info.min = 0.0 / 0.0; /* set to nan as default */ zone_info.max = 0.0 / 0.0; /* set to nan as default */ zone_info.n_zones = 0; /* open 3D zoning raster with default region */ if ((zonemap = param.zonefile->answer) != NULL) { if (NULL == (mapset = G_find_raster3d(zonemap, ""))) Rast3d_fatal_error(_("3D raster map <%s> not found"), zonemap); zmap = Rast3d_open_cell_old(zonemap, G_find_raster3d(zonemap, ""), ®ion, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); if (zmap == NULL) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), zonemap); zmap_type = Rast3d_tile_type_map(zmap); if (Rast3d_read_cats(zonemap, mapset, &(zone_info.cats))) G_warning("No category support for zoning raster"); Rast3d_range_init(zmap); Rast3d_range_load(zmap); Rast3d_range_min_max(zmap, &dmin, &dmax); /* properly round dmin and dmax */ if (dmin < 0) zone_info.min = dmin - 0.5; else zone_info.min = dmin + 0.5; if (dmax < 0) zone_info.max = dmax - 0.5; else zone_info.max = dmax + 0.5; G_debug(1, "min: %d, max: %d", zone_info.min, zone_info.max); zone_info.n_zones = zone_info.max - zone_info.min + 1; use_zone = 1; } /* Open 3D input raster with default region */ infile = param.inputfile->answer; if (NULL == G_find_raster3d(infile, "")) Rast3d_fatal_error(_("3D raster map <%s> not found"), infile); map = Rast3d_open_cell_old(infile, G_find_raster3d(infile, ""), ®ion, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); if (map == NULL) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), infile); map_type = Rast3d_tile_type_map(map); i = 0; while (param.percentile->answers[i]) i++; n_zones = zone_info.n_zones; if (n_zones == 0) n_zones = 1; stats = create_univar_stat_struct(map_type, i); for (i = 0; i < n_zones; i++) { unsigned int j; for (j = 0; j < stats[i].n_perc; j++) { sscanf(param.percentile->answers[j], "%lf", &(stats[i].perc[j])); } } for (z = 0; z < depths; z++) { /* From the bottom to the top */ if (!(param.shell_style->answer)) G_percent(z, depths - 1, 10); for (y = 0; y < rows; y++) { for (x = 0; x < cols; x++) { zone = 0; if (zone_info.n_zones) { if (zmap_type == FCELL_TYPE) { Rast3d_get_value(zmap, x, y, z, &val_f, FCELL_TYPE); if (Rast3d_is_null_value_num(&val_f, FCELL_TYPE)) continue; if (val_f < 0) zone = val_f - 0.5; else zone = val_f + 0.5; } else if (zmap_type == DCELL_TYPE) { Rast3d_get_value(zmap, x, y, z, &val_d, DCELL_TYPE); if (Rast3d_is_null_value_num(&val_d, DCELL_TYPE)) continue; if (val_d < 0) zone = val_d - 0.5; else zone = val_d + 0.5; } zone -= zone_info.min; } if (map_type == FCELL_TYPE) { Rast3d_get_value(map, x, y, z, &val_f, map_type); if (!Rast3d_is_null_value_num(&val_f, map_type)) { if (param.extended->answer) { if (stats[zone].n >= stats[zone].n_alloc) { size_t msize; stats[zone].n_alloc += 1000; msize = stats[zone].n_alloc * sizeof(FCELL); stats[zone].fcell_array = (FCELL *)G_realloc((void *)stats[zone].fcell_array, msize); } stats[zone].fcell_array[stats[zone].n] = val_f; } stats[zone].sum += val_f; stats[zone].sumsq += (val_f * val_f); stats[zone].sum_abs += fabs(val_f); if (stats[zone].first) { stats[zone].max = val_f; stats[zone].min = val_f; stats[zone].first = FALSE; } else { if (val_f > stats[zone].max) stats[zone].max = val_f; if (val_f < stats[zone].min) stats[zone].min = val_f; } stats[zone].n++; } stats[zone].size++; } else if (map_type == DCELL_TYPE) { Rast3d_get_value(map, x, y, z, &val_d, map_type); if (!Rast3d_is_null_value_num(&val_d, map_type)) { if (param.extended->answer) { if (stats[zone].n >= stats[zone].n_alloc) { size_t msize; stats[zone].n_alloc += 1000; msize = stats[zone].n_alloc * sizeof(DCELL); stats[zone].dcell_array = (DCELL *)G_realloc((void *)stats[zone].dcell_array, msize); } stats[zone].dcell_array[stats[zone].n] = val_d; } stats[zone].sum += val_d; stats[zone].sumsq += val_d * val_d; stats[zone].sum_abs += fabs(val_d); if (stats[zone].first) { stats[zone].max = val_d; stats[zone].min = val_d; stats[zone].first = FALSE; } else { if (val_d > stats[zone].max) stats[zone].max = val_d; if (val_d < stats[zone].min) stats[zone].min = val_d; } stats[zone].n++; } stats[zone].size++; } } } } /* close maps */ Rast3d_close(map); if (zone_info.n_zones) Rast3d_close(zmap); /* create the output */ if (param.table->answer) print_stats_table(stats); else print_stats(stats); /* release memory */ free_univar_stat_struct(stats); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { const char *mapset; struct GModule *module; struct Option *raster, *title_opt, *history_opt; struct Option *datasrc1_opt, *datasrc2_opt, *datadesc_opt; struct Option *map_opt, *units_opt, *vunits_opt; struct Option *load_opt, *save_opt; struct Flag *stats_flag; const char *infile; char title[MAX_TITLE_LEN + 1]; struct History hist; /* Initialize GIS engine */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster3d")); G_add_keyword(_("metadata")); G_add_keyword(_("voxel")); module->description = _("Allows creation and/or modification of " "3D raster map layer support files."); raster = G_define_standard_option(G_OPT_R3_MAP); title_opt = G_define_option(); title_opt->key = "title"; title_opt->key_desc = "phrase"; title_opt->type = TYPE_STRING; title_opt->required = NO; title_opt->description = _("Text to use for map title"); history_opt = G_define_option(); history_opt->key = "history"; history_opt->key_desc = "phrase"; history_opt->type = TYPE_STRING; history_opt->required = NO; history_opt->description = _("Text to append to the next line of the map's metadata file"); units_opt = G_define_option(); units_opt->key = "unit"; units_opt->type = TYPE_STRING; units_opt->required = NO; units_opt->description = _("The map data unit"); vunits_opt = G_define_option(); vunits_opt->key = "vunit"; vunits_opt->type = TYPE_STRING; vunits_opt->required = NO; vunits_opt->description = _("The vertical unit of the map"); datasrc1_opt = G_define_option(); datasrc1_opt->key = "source1"; datasrc1_opt->key_desc = "phrase"; datasrc1_opt->type = TYPE_STRING; datasrc1_opt->required = NO; datasrc1_opt->description = _("Text to use for data source, line 1"); datasrc2_opt = G_define_option(); datasrc2_opt->key = "source2"; datasrc2_opt->key_desc = "phrase"; datasrc2_opt->type = TYPE_STRING; datasrc2_opt->required = NO; datasrc2_opt->description = _("Text to use for data source, line 2"); datadesc_opt = G_define_option(); datadesc_opt->key = "description"; datadesc_opt->key_desc = "phrase"; datadesc_opt->type = TYPE_STRING; datadesc_opt->required = NO; datadesc_opt->description = _("Text to use for data description or keyword(s)"); map_opt = G_define_option(); map_opt->key = "raster"; map_opt->type = TYPE_STRING; map_opt->required = NO; map_opt->gisprompt = "old,cell,raster"; map_opt->description = _("Raster map from which to copy category table"); load_opt = G_define_standard_option(G_OPT_F_INPUT); load_opt->key = "loadhistory"; load_opt->required = NO; load_opt->description = _("Text file from which to load history"); save_opt = G_define_standard_option(G_OPT_F_OUTPUT); save_opt->key = "savehistory"; save_opt->required = NO; save_opt->description = _("Text file in which to save history"); stats_flag = G_define_flag(); stats_flag->key = 's'; stats_flag->description = _("Update range"); /* Parse command-line options */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* Make sure raster exists and set mapset */ infile = raster->answer; mapset = G_find_raster3d(infile, G_mapset()); /* current mapset only for editing */ if (!mapset || strcmp(mapset, G_mapset()) != 0) G_fatal_error(_("3D raster map <%s> not found"), infile); if (title_opt->answer) { strncpy(title, title_opt->answer, MAX_TITLE_LEN); title[MAX_TITLE_LEN - 1] = '\0'; /* strncpy doesn't null terminate over-sized input */ G_strip(title); G_debug(3, "map title= [%s] (%d chars)", title, (int)strlen(title)); Rast3d_read_history(raster->answer, "", &hist); Rast_set_history(&hist, HIST_TITLE, title); Rast3d_write_history(raster->answer, &hist); } if (save_opt->answer) { FILE *fp = fopen(save_opt->answer, "w"); int i; if (!fp) G_fatal_error(_("Unable to open output file <%s>"), save_opt->answer); Rast3d_read_history(raster->answer, "", &hist); for (i = 0; i < Rast_history_length(&hist); i++) fprintf(fp, "%s\n", Rast_history_line(&hist, i)); fclose(fp); } if (load_opt->answer) { FILE *fp = fopen(load_opt->answer, "r"); if (!fp) G_fatal_error(_("Unable to open input file <%s>"), load_opt->answer); Rast3d_read_history(raster->answer, "", &hist); Rast_clear_history(&hist); for (;;) { char buf[80]; if (!G_getl2(buf, sizeof(buf), fp)) break; Rast_append_history(&hist, buf); } fclose(fp); Rast3d_write_history(raster->answer, &hist); } if (history_opt->answer) { Rast3d_read_history(raster->answer, "", &hist); /* two less than defined as if only one less a newline gets appended in the hist file. bug? */ /* Should be RECORD_LEN, but r.info truncates at > 71 chars */ if (strlen(history_opt->answer) > 71) { int i; for (i = 0; i < strlen(history_opt->answer); i += 71) { char buf[72]; strncpy(buf, &history_opt->answer[i], sizeof(buf)-1); buf[sizeof(buf)-1] = '\0'; Rast_append_history(&hist, buf); } } else Rast_append_history(&hist, history_opt->answer); Rast3d_write_history(raster->answer, &hist); } if(units_opt->answer || vunits_opt->answer) { RASTER3D_Map *map; map = Rast3d_open_cell_old(raster->answer, G_mapset(), \ RASTER3D_DEFAULT_WINDOW, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); /* Modify the units */ if (units_opt->answer) Rast3d_set_unit(map, units_opt->answer); if (vunits_opt->answer) Rast3d_set_vertical_unit(map, vunits_opt->answer); Rast3d_rewrite_header(map); Rast3d_close(map); } if (datasrc1_opt->answer || datasrc2_opt->answer || datadesc_opt->answer) { Rast3d_read_history(raster->answer, "", &hist); if (datasrc1_opt->answer) Rast_set_history(&hist, HIST_DATSRC_1, datasrc1_opt->answer); if (datasrc2_opt->answer) Rast_set_history(&hist, HIST_DATSRC_2, datasrc2_opt->answer); if (datadesc_opt->answer) Rast_set_history(&hist, HIST_KEYWRD, datadesc_opt->answer); Rast3d_write_history(raster->answer, &hist); } if (map_opt->answer) { /* use cats from another map */ int fd; struct Categories cats; fd = Rast_open_old(infile, ""); Rast_init_cats("", &cats); if (Rast3d_read_cats(map_opt->answer, "", &cats) < 0) G_fatal_error(_("Unable to read category file of raster map <%s>"), map_opt->answer); Rast3d_write_cats(infile, &cats); G_message(_("cats table for [%s] set to %s"), infile, map_opt->answer); Rast_close(fd); Rast_free_cats(&cats); } /* Check the histogram and range */ if (stats_flag->answer) check_stats(raster->answer); return EXIT_SUCCESS; }