static void write_cats(const char *element, const char *name, struct Categories *cats) { FILE *fd; int i, fp_map; char *descr; DCELL val1, val2; char str1[100], str2[100]; fd = G_fopen_new(element, name); if (!fd) G_fatal_error(_("Unable to open %s file for map <%s>"), element, name); /* write # cats - note # indicate 3.0 or later */ fprintf(fd, "# %ld categories\n", (long)cats->num); /* title */ fprintf(fd, "%s\n", cats->title != NULL ? cats->title : ""); /* write format and coefficients */ fprintf(fd, "%s\n", cats->fmt != NULL ? cats->fmt : ""); fprintf(fd, "%.2f %.2f %.2f %.2f\n", cats->m1, cats->a1, cats->m2, cats->a2); /* if the map is integer or if this is a vector map, sort labels */ if (strncmp(element, "dig", 3) == 0) fp_map = 0; else fp_map = Rast_map_is_fp(name, G_mapset()); if (!fp_map) Rast_sort_cats(cats); /* write the cat numbers:label */ for (i = 0; i < Rast_quant_nof_rules(&cats->q); i++) { descr = Rast_get_ith_d_cat(cats, i, &val1, &val2); if ((cats->fmt && cats->fmt[0]) || (descr && descr[0])) { if (val1 == val2) { sprintf(str1, "%.10f", val1); G_trim_decimal(str1); fprintf(fd, "%s:%s\n", str1, descr != NULL ? descr : ""); } else { sprintf(str1, "%.10f", val1); G_trim_decimal(str1); sprintf(str2, "%.10f", val2); G_trim_decimal(str2); fprintf(fd, "%s:%s:%s\n", str1, str2, descr != NULL ? descr : ""); } } } fclose(fd); }
int parse_layer(char *s) { char name[GNAME_MAX]; const char *mapset; struct FPRange fp_range; int n; strcpy(name, s); mapset = G_find_raster2(name, ""); if (mapset == NULL) G_fatal_error(_("Raster map <%s> not found"), s); n = nlayers++; layers = (LAYER *) G_realloc(layers, nlayers * sizeof(LAYER)); is_fp = (int *)G_realloc(is_fp, (nlayers + 1) * sizeof(int)); DMAX = (DCELL *) G_realloc(DMAX, (nlayers + 1) * sizeof(DCELL)); DMIN = (DCELL *) G_realloc(DMIN, (nlayers + 1) * sizeof(DCELL)); if (!as_int) is_fp[n] = Rast_map_is_fp(name, mapset); else is_fp[n] = 0; if (is_fp[n]) { if (Rast_read_fp_range(name, mapset, &fp_range) < 0) G_fatal_error(_("Unable to read fp range for raster map <%s>"), name); Rast_get_fp_range_min_max(&fp_range, &DMIN[n], &DMAX[n]); } layers[n].name = G_store(name); layers[n].mapset = mapset; if (Rast_read_cats(name, mapset, &layers[n].labels) < 0) G_fatal_error(_("Unable to read category file of raster map <%s@%s>"), name, mapset); return 0; }
static CELL read_cats(const char *element, const char *name, const char *mapset, struct Categories *pcats, int full) { FILE *fd; char buff[1024]; CELL cat; DCELL val1, val2; int old = 0, fp_map; long num = -1; if (strncmp(element, "dig", 3) == 0) fp_map = 0; else fp_map = Rast_map_is_fp(name, mapset); if (!(fd = G_fopen_old(element, name, mapset))) return -2; /* Read the number of categories */ if (G_getl(buff, sizeof buff, fd) == 0) goto error; if (sscanf(buff, "# %ld", &num) == 1) old = 0; else if (sscanf(buff, "%ld", &num) == 1) old = 1; if (!full) { fclose(fd); if (num < 0) return 0; /* coorect */ return (CELL) num; } /* Read the title for the file */ if (G_getl(buff, sizeof buff, fd) == 0) goto error; G_strip(buff); /* G_ascii_check(buff) ; */ Rast_init_cats(buff, pcats); if (num >= 0) pcats->num = num; if (!old) { char fmt[256]; float m1, a1, m2, a2; if (G_getl(fmt, sizeof fmt, fd) == 0) goto error; /* next line contains equation coefficients */ if (G_getl(buff, sizeof buff, fd) == 0) goto error; if (sscanf(buff, "%f %f %f %f", &m1, &a1, &m2, &a2) != 4) goto error; Rast_set_cats_fmt(fmt, m1, a1, m2, a2, pcats); } /* Read all category names */ for (cat = 0;; cat++) { char label[1024]; if (G_getl(buff, sizeof buff, fd) == 0) break; if (old) Rast_set_c_cat(&cat, &cat, buff, pcats); else { *label = 0; if (sscanf(buff, "%1s", label) != 1) continue; if (*label == '#') continue; *label = 0; /* for fp maps try to read a range of data */ if (fp_map && sscanf(buff, "%lf:%lf:%[^\n]", &val1, &val2, label) == 3) Rast_set_cat(&val1, &val2, label, pcats, DCELL_TYPE); else if (sscanf(buff, "%d:%[^\n]", &cat, label) >= 1) Rast_set_cat(&cat, &cat, label, pcats, CELL_TYPE); else if (sscanf(buff, "%lf:%[^\n]", &val1, label) >= 1) Rast_set_cat(&val1, &val1, label, pcats, DCELL_TYPE); else goto error; } } fclose(fd); return 0; error: fclose(fd); return -1; }
int main(int argc, char *argv[]) { struct GModule *module; struct { struct Option *quant, *perc, *slots, *basemap, *covermap, *output; } opt; struct { struct Flag *r, *p; } flag; const char *basemap, *covermap; char **outputs; int reclass, print; int cover_fd, base_fd; struct Range range; struct FPRange fprange; int i; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("statistics")); module->description = _("Compute category quantiles using two passes."); opt.basemap = G_define_standard_option(G_OPT_R_BASE); opt.covermap = G_define_standard_option(G_OPT_R_COVER); opt.quant = G_define_option(); opt.quant->key = "quantiles"; opt.quant->type = TYPE_INTEGER; opt.quant->required = NO; opt.quant->description = _("Number of quantiles"); opt.perc = G_define_option(); opt.perc->key = "percentiles"; opt.perc->type = TYPE_DOUBLE; opt.perc->multiple = YES; opt.perc->description = _("List of percentiles"); opt.perc->answer = "50"; opt.slots = G_define_option(); opt.slots->key = "bins"; opt.slots->type = TYPE_INTEGER; opt.slots->required = NO; opt.slots->description = _("Number of bins to use"); opt.slots->answer = "1000"; opt.output = G_define_standard_option(G_OPT_R_OUTPUT); opt.output->description = _("Resultant raster map(s)"); opt.output->required = NO; opt.output->multiple = YES; flag.r = G_define_flag(); flag.r->key = 'r'; flag.r->description = _("Create reclass map with statistics as category labels"); flag.p = G_define_flag(); flag.p->key = 'p'; flag.p->description = _("Do not create output maps; just print statistics"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); basemap = opt.basemap->answer; covermap = opt.covermap->answer; outputs = opt.output->answers; reclass = flag.r->answer; print = flag.p->answer; if (!print && !opt.output->answers) G_fatal_error(_("Either -%c or %s= must be given"), flag.p->key, opt.output->key); if (print && opt.output->answers) G_fatal_error(_("-%c and %s= are mutually exclusive"), flag.p->key, opt.output->key); num_slots = atoi(opt.slots->answer); if (opt.quant->answer) { num_quants = atoi(opt.quant->answer) - 1; quants = G_calloc(num_quants, sizeof(DCELL)); for (i = 0; i < num_quants; i++) quants[i] = 1.0 * (i + 1) / (num_quants + 1); } else { for (i = 0; opt.perc->answers[i]; i++) ; num_quants = i; quants = G_calloc(num_quants, sizeof(DCELL)); for (i = 0; i < num_quants; i++) quants[i] = atof(opt.perc->answers[i]) / 100; qsort(quants, num_quants, sizeof(DCELL), compare_dcell); } if (opt.output->answer) { for (i = 0; opt.output->answers[i]; i++) ; if (i != num_quants) G_fatal_error(_("Number of quantiles (%d) does not match number of output maps (%d)"), num_quants, i); } base_fd = Rast_open_old(basemap, ""); cover_fd = Rast_open_old(covermap, ""); if (Rast_map_is_fp(basemap, "") != 0) G_fatal_error(_("The base map must be an integer (CELL) map")); if (Rast_read_range(basemap, "", &range) < 0) G_fatal_error(_("Unable to read range of base map <%s>"), basemap); Rast_get_range_min_max(&range, &min, &max); num_cats = max - min + 1; if (num_cats > MAX_CATS) G_fatal_error(_("Base map <%s> has too many categories (max: %d)"), basemap, MAX_CATS); Rast_read_fp_range(covermap, "", &fprange); Rast_get_fp_range_min_max(&fprange, &f_min, &f_max); slot_size = (f_max - f_min) / num_slots; basecats = G_calloc(num_cats, sizeof(struct basecat)); for (i = 0; i < num_cats; i++) basecats[i].slots = G_calloc(num_slots, sizeof(unsigned int)); rows = Rast_window_rows(); cols = Rast_window_cols(); get_slot_counts(base_fd, cover_fd); initialize_bins(); fill_bins(base_fd, cover_fd); sort_bins(); compute_quantiles(); if (print) print_quantiles(); else if (reclass) do_reclass(basemap, outputs); else do_output(base_fd, outputs, covermap); Rast_close(cover_fd); Rast_close(base_fd); return (EXIT_SUCCESS); }
int main(int argc, char **argv) { static DCELL *count, *sum, *mean, *sumu, *sum2, *sum3, *sum4, *min, *max; DCELL *result; struct GModule *module; struct { struct Option *method, *basemap, *covermap, *output; } opt; struct { struct Flag *c, *r; } flag; char methods[2048]; const char *basemap, *covermap, *output; int usecats; int reclass; int base_fd, cover_fd; struct Categories cats; CELL *base_buf; DCELL *cover_buf; struct Range range; CELL mincat, ncats; int method; int rows, cols; int row, col, i; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("statistics")); module->description = _("Calculates category or object oriented statistics (accumulator-based statistics)."); opt.basemap = G_define_standard_option(G_OPT_R_BASE); opt.covermap = G_define_standard_option(G_OPT_R_COVER); opt.method = G_define_option(); opt.method->key = "method"; opt.method->type = TYPE_STRING; opt.method->required = YES; opt.method->description = _("Method of object-based statistic"); for (i = 0; menu[i].name; i++) { if (i) strcat(methods, ","); else *(methods) = 0; strcat(methods, menu[i].name); } opt.method->options = G_store(methods); for (i = 0; menu[i].name; i++) { if (i) strcat(methods, ";"); else *(methods) = 0; strcat(methods, menu[i].name); strcat(methods, ";"); strcat(methods, menu[i].text); } opt.method->descriptions = G_store(methods); opt.output = G_define_standard_option(G_OPT_R_OUTPUT); opt.output->description = _("Resultant raster map"); opt.output->required = YES; flag.c = G_define_flag(); flag.c->key = 'c'; flag.c->description = _("Cover values extracted from the category labels of the cover map"); flag.r = G_define_flag(); flag.r->key = 'r'; flag.r->description = _("Create reclass map with statistics as category labels"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); basemap = opt.basemap->answer; covermap = opt.covermap->answer; output = opt.output->answer; usecats = flag.c->answer; reclass = flag.r->answer; for (i = 0; menu[i].name; i++) if (strcmp(menu[i].name, opt.method->answer) == 0) break; if (!menu[i].name) { G_warning(_("<%s=%s> unknown %s"), opt.method->key, opt.method->answer, opt.method->key); G_usage(); exit(EXIT_FAILURE); } method = menu[i].val; base_fd = Rast_open_old(basemap, ""); cover_fd = Rast_open_old(covermap, ""); if (usecats && Rast_read_cats(covermap, "", &cats) < 0) G_fatal_error(_("Unable to read category file of cover map <%s>"), covermap); if (Rast_map_is_fp(basemap, "") != 0) G_fatal_error(_("The base map must be an integer (CELL) map")); if (Rast_read_range(basemap, "", &range) < 0) G_fatal_error(_("Unable to read range of base map <%s>"), basemap); mincat = range.min; ncats = range.max - range.min + 1; rows = Rast_window_rows(); cols = Rast_window_cols(); switch (method) { case COUNT: count = G_calloc(ncats, sizeof(DCELL)); break; case SUM: sum = G_calloc(ncats, sizeof(DCELL)); break; case MIN: min = G_malloc(ncats * sizeof(DCELL)); break; case MAX: max = G_malloc(ncats * sizeof(DCELL)); break; case RANGE: min = G_malloc(ncats * sizeof(DCELL)); max = G_malloc(ncats * sizeof(DCELL)); break; case AVERAGE: case ADEV: case VARIANCE2: case STDDEV2: case SKEWNESS2: case KURTOSIS2: count = G_calloc(ncats, sizeof(DCELL)); sum = G_calloc(ncats, sizeof(DCELL)); break; case VARIANCE1: case STDDEV1: count = G_calloc(ncats, sizeof(DCELL)); sum = G_calloc(ncats, sizeof(DCELL)); sum2 = G_calloc(ncats, sizeof(DCELL)); break; case SKEWNESS1: count = G_calloc(ncats, sizeof(DCELL)); sum = G_calloc(ncats, sizeof(DCELL)); sum2 = G_calloc(ncats, sizeof(DCELL)); sum3 = G_calloc(ncats, sizeof(DCELL)); break; case KURTOSIS1: count = G_calloc(ncats, sizeof(DCELL)); sum = G_calloc(ncats, sizeof(DCELL)); sum2 = G_calloc(ncats, sizeof(DCELL)); sum4 = G_calloc(ncats, sizeof(DCELL)); break; } if (min) for (i = 0; i < ncats; i++) min[i] = 1e300; if (max) for (i = 0; i < ncats; i++) max[i] = -1e300; base_buf = Rast_allocate_c_buf(); cover_buf = Rast_allocate_d_buf(); G_message(_("First pass")); for (row = 0; row < rows; row++) { Rast_get_c_row(base_fd, base_buf, row); Rast_get_d_row(cover_fd, cover_buf, row); for (col = 0; col < cols; col++) { int n; DCELL v; if (Rast_is_c_null_value(&base_buf[col])) continue; if (Rast_is_d_null_value(&cover_buf[col])) continue; n = base_buf[col] - mincat; if (n < 0 || n >= ncats) continue; v = cover_buf[col]; if (usecats) sscanf(Rast_get_c_cat((CELL *) &v, &cats), "%lf", &v); if (count) count[n]++; if (sum) sum[n] += v; if (sum2) sum2[n] += v * v; if (sum3) sum3[n] += v * v * v; if (sum4) sum4[n] += v * v * v * v; if (min && min[n] > v) min[n] = v; if (max && max[n] < v) max[n] = v; } G_percent(row, rows, 2); } G_percent(row, rows, 2); result = G_calloc(ncats, sizeof(DCELL)); switch (method) { case ADEV: case VARIANCE2: case STDDEV2: case SKEWNESS2: case KURTOSIS2: mean = G_calloc(ncats, sizeof(DCELL)); for (i = 0; i < ncats; i++) mean[i] = sum[i] / count[i]; G_free(sum); break; } switch (method) { case ADEV: sumu = G_calloc(ncats, sizeof(DCELL)); break; case VARIANCE2: case STDDEV2: sum2 = G_calloc(ncats, sizeof(DCELL)); break; case SKEWNESS2: sum2 = G_calloc(ncats, sizeof(DCELL)); sum3 = G_calloc(ncats, sizeof(DCELL)); break; case KURTOSIS2: sum2 = G_calloc(ncats, sizeof(DCELL)); sum4 = G_calloc(ncats, sizeof(DCELL)); break; } if (mean) { G_message(_("Second pass")); for (row = 0; row < rows; row++) { Rast_get_c_row(base_fd, base_buf, row); Rast_get_d_row(cover_fd, cover_buf, row); for (col = 0; col < cols; col++) { int n; DCELL v, d; if (Rast_is_c_null_value(&base_buf[col])) continue; if (Rast_is_d_null_value(&cover_buf[col])) continue; n = base_buf[col] - mincat; if (n < 0 || n >= ncats) continue; v = cover_buf[col]; if (usecats) sscanf(Rast_get_c_cat((CELL *) &v, &cats), "%lf", &v); d = v - mean[n]; if (sumu) sumu[n] += fabs(d); if (sum2) sum2[n] += d * d; if (sum3) sum3[n] += d * d * d; if (sum4) sum4[n] += d * d * d * d; } G_percent(row, rows, 2); } G_percent(row, rows, 2); G_free(mean); G_free(cover_buf); } switch (method) { case COUNT: for (i = 0; i < ncats; i++) result[i] = count[i]; break; case SUM: for (i = 0; i < ncats; i++) result[i] = sum[i]; break; case AVERAGE: for (i = 0; i < ncats; i++) result[i] = sum[i] / count[i]; break; case MIN: for (i = 0; i < ncats; i++) result[i] = min[i]; break; case MAX: for (i = 0; i < ncats; i++) result[i] = max[i]; break; case RANGE: for (i = 0; i < ncats; i++) result[i] = max[i] - min[i]; break; case VARIANCE1: for (i = 0; i < ncats; i++) { double n = count[i]; double var = (sum2[i] - sum[i] * sum[i] / n) / (n - 1); result[i] = var; } break; case STDDEV1: for (i = 0; i < ncats; i++) { double n = count[i]; double var = (sum2[i] - sum[i] * sum[i] / n) / (n - 1); result[i] = sqrt(var); } break; case SKEWNESS1: for (i = 0; i < ncats; i++) { double n = count[i]; double var = (sum2[i] - sum[i] * sum[i] / n) / (n - 1); double skew = (sum3[i] / n - 3 * sum[i] * sum2[i] / (n * n) + 2 * sum[i] * sum[i] * sum[i] / (n * n * n)) / (pow(var, 1.5)); result[i] = skew; } break; case KURTOSIS1: for (i = 0; i < ncats; i++) { double n = count[i]; double var = (sum2[i] - sum[i] * sum[i] / n) / (n - 1); double kurt = (sum4[i] / n - 4 * sum[i] * sum3[i] / (n * n) + 6 * sum[i] * sum[i] * sum2[i] / (n * n * n) - 3 * sum[i] * sum[i] * sum[i] * sum[i] / (n * n * n * n)) / (var * var) - 3; result[i] = kurt; } break; case ADEV: for (i = 0; i < ncats; i++) result[i] = sumu[i] / count[i]; break; case VARIANCE2: for (i = 0; i < ncats; i++) result[i] = sum2[i] / (count[i] - 1); break; case STDDEV2: for (i = 0; i < ncats; i++) result[i] = sqrt(sum2[i] / (count[i] - 1)); break; case SKEWNESS2: for (i = 0; i < ncats; i++) { double n = count[i]; double var = sum2[i] / (n - 1); double sdev = sqrt(var); result[i] = sum3[i] / (sdev * sdev * sdev) / n; } G_free(count); G_free(sum2); G_free(sum3); break; case KURTOSIS2: for (i = 0; i < ncats; i++) { double n = count[i]; double var = sum2[i] / (n - 1); result[i] = sum4[i] / (var * var) / n - 3; } G_free(count); G_free(sum2); G_free(sum4); break; } if (reclass) { const char *tempfile = G_tempfile(); char *input_arg = G_malloc(strlen(basemap) + 7); char *output_arg = G_malloc(strlen(output) + 8); char *rules_arg = G_malloc(strlen(tempfile) + 7); FILE *fp; G_message(_("Generating reclass map")); sprintf(input_arg, "input=%s", basemap); sprintf(output_arg, "output=%s", output); sprintf(rules_arg, "rules=%s", tempfile); fp = fopen(tempfile, "w"); if (!fp) G_fatal_error(_("Unable to open temporary file")); for (i = 0; i < ncats; i++) fprintf(fp, "%d = %d %f\n", mincat + i, mincat + i, result[i]); fclose(fp); G_spawn("r.reclass", "r.reclass", input_arg, output_arg, rules_arg, NULL); } else { int out_fd; DCELL *out_buf; struct Colors colors; G_message(_("Writing output map")); out_fd = Rast_open_fp_new(output); out_buf = Rast_allocate_d_buf(); for (row = 0; row < rows; row++) { Rast_get_c_row(base_fd, base_buf, row); for (col = 0; col < cols; col++) if (Rast_is_c_null_value(&base_buf[col])) Rast_set_d_null_value(&out_buf[col], 1); else out_buf[col] = result[base_buf[col] - mincat]; Rast_put_d_row(out_fd, out_buf); G_percent(row, rows, 2); } G_percent(row, rows, 2); Rast_close(out_fd); if (Rast_read_colors(covermap, "", &colors) > 0) Rast_write_colors(output, G_mapset(), &colors); } return 0; }
int main(int argc, char **argv) { char *name; int overlay; int invert, fp; struct GModule *module; struct Option *map; struct Option *vallist; struct Option *bg; struct Flag *flag_n; struct Flag *flag_i; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("display")); G_add_keyword(_("raster")); module->description = _("Displays user-specified raster map in the active " "graphics frame."); /* set up command line */ map = G_define_standard_option(G_OPT_R_MAP); map->description = _("Name of raster map to be displayed"); vallist = G_define_option(); vallist->key = "values"; vallist->key_desc = "value[-value]"; vallist->type = TYPE_STRING; vallist->required = NO; vallist->multiple = YES; vallist->description = _("List of categories or values to be displayed"); vallist->guisection = _("Selection"); bg = G_define_standard_option(G_OPT_C_BG); bg->key_desc = "color"; bg->gisprompt = "old_color,color,color"; bg->label = _("Background color (for null)"); bg->description = _("Either a standard color name or R:G:B triplet"); bg->guisection = _("Null cells"); flag_n = G_define_flag(); flag_n->key = 'n'; flag_n->description = _("Make null cells opaque"); flag_n->guisection = _("Null cells"); flag_i = G_define_flag(); flag_i->key = 'i'; flag_i->description = _("Invert value list"); flag_i->guisection = _("Selection"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); name = map->answer; overlay = !flag_n->answer; invert = flag_i->answer; if (D_open_driver() != 0) G_fatal_error(_("No graphics device selected. " "Use d.mon to select graphics device.")); fp = Rast_map_is_fp(name, ""); if (vallist->answer) { if (fp) parse_vallist(vallist->answers, &d_mask); else parse_catlist(vallist->answers, &mask); } /* use DCELL even if the map is FCELL */ display(name, overlay, bg->answer, fp ? DCELL_TYPE : CELL_TYPE, invert); D_save_command(G_recreate_command()); D_close_driver(); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int *fd; char **names; char **ptr; char *name; /* flags */ int raw_data; int with_coordinates; int with_xy; int with_percents; int with_counts; int with_areas; int with_labels; /* printf format */ char fmt[20]; int dp; struct Range range; struct FPRange fp_range; struct Quant q; CELL min, max, null_set = 0; DCELL dmin, dmax; struct GModule *module; struct { struct Flag *A; /* print averaged values instead of intervals */ struct Flag *a; /* area */ struct Flag *c; /* cell counts */ struct Flag *p; /* percents */ struct Flag *l; /* with labels */ struct Flag *q; /* quiet */ struct Flag *n; /* Suppress reporting of any NULLs */ struct Flag *N; /* Suppress reporting of NULLs when all values are NULL */ struct Flag *one; /* one cell per line */ struct Flag *x; /* with row/col */ struct Flag *g; /* with east/north */ struct Flag *i; /* use quant rules for fp map, i.e. read it as int */ struct Flag *r; /* raw output: when nsteps option is used, report indexes of ranges instead of ranges themselves; when -C (cats) option is used reports indexes of fp ranges = ind. of labels */ struct Flag *C; /* report stats for labeled ranges in cats files */ } flag; struct { struct Option *cell; struct Option *fs; struct Option *nv; struct Option *output; struct Option *nsteps; /* divide data range into nsteps and report stats for these ranges: only for fp maps NOTE: when -C flag is used, and there are explicit fp ranges in cats or when the map is int, nsteps is ignored */ } option; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("statistics")); module->description = _("Generates area statistics for raster map layers."); /* Define the different options */ option.cell = G_define_standard_option(G_OPT_R_INPUTS); option.output = G_define_standard_option(G_OPT_F_OUTPUT); option.output->required = NO; option.output->description = _("Name for output file (if omitted or \"-\" output to stdout)"); option.fs = G_define_standard_option(G_OPT_F_SEP); option.fs->key_desc = "character|space|tab"; option.fs->answer = "space"; option.fs->description = _("Output field separator"); option.nv = G_define_option(); option.nv->key = "nv"; option.nv->type = TYPE_STRING; option.nv->required = NO; option.nv->multiple = NO; option.nv->answer = "*"; option.nv->description = _("String representing no data cell value"); option.nsteps = G_define_option(); option.nsteps->key = "nsteps"; option.nsteps->type = TYPE_INTEGER; option.nsteps->required = NO; option.nsteps->multiple = NO; option.nsteps->answer = "255"; option.nsteps->description = _("Number of fp subranges to collect stats from"); /* Define the different flags */ flag.one = G_define_flag(); flag.one->key = '1'; flag.one->description = _("One cell (range) per line"); flag.A = G_define_flag(); flag.A->key = 'A'; flag.A->description = _("Print averaged values instead of intervals"); flag.A->guisection = _("Print"); flag.a = G_define_flag(); flag.a->key = 'a'; flag.a->description = _("Print area totals"); flag.a->guisection = _("Print"); flag.c = G_define_flag(); flag.c->key = 'c'; flag.c->description = _("Print cell counts"); flag.c->guisection = _("Print"); flag.p = G_define_flag(); flag.p->key = 'p'; flag.p->description = _("Print APPROXIMATE percents (total percent may not be 100%)"); flag.p->guisection = _("Print"); flag.l = G_define_flag(); flag.l->key = 'l'; flag.l->description = _("Print category labels"); flag.l->guisection = _("Print"); flag.g = G_define_flag(); flag.g->key = 'g'; flag.g->description = _("Print grid coordinates (east and north)"); flag.g->guisection = _("Print"); flag.x = G_define_flag(); flag.x->key = 'x'; flag.x->description = _("Print x and y (column and row)"); flag.x->guisection = _("Print"); flag.r = G_define_flag(); flag.r->key = 'r'; flag.r->description = _("Print raw indexes of fp ranges (fp maps only)"); flag.r->guisection = _("Print"); flag.n = G_define_flag(); flag.n->key = 'n'; flag.n->description = _("Suppress reporting of any NULLs"); flag.N = G_define_flag(); flag.N->key = 'N'; flag.N->description = _("Suppress reporting of NULLs when all values are NULL"); flag.C = G_define_flag(); flag.C->key = 'C'; flag.C->description = _("Report for cats fp ranges (fp maps only)"); flag.i = G_define_flag(); flag.i->key = 'i'; flag.i->description = _("Read fp map as integer (use map's quant rules)"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); name = option.output->answer; if (name != NULL && strcmp(name, "-") != 0) { if (NULL == freopen(name, "w", stdout)) { G_fatal_error(_("Unable to open file <%s> for writing"), name); } } sscanf(option.nsteps->answer, "%d", &nsteps); if (nsteps <= 0) { G_warning(_("'%s' must be greater than zero; using %s=255"), option.nsteps->key, option.nsteps->key); nsteps = 255; } cat_ranges = flag.C->answer; averaged = flag.A->answer; raw_output = flag.r->answer; as_int = flag.i->answer; nrows = Rast_window_rows(); ncols = Rast_window_cols(); fd = NULL; nfiles = 0; dp = -1; with_percents = flag.p->answer; with_counts = flag.c->answer; with_areas = flag.a->answer; with_labels = flag.l->answer; no_nulls = flag.n->answer; no_nulls_all = flag.N->answer; no_data_str = option.nv->answer; raw_data = flag.one->answer; with_coordinates = flag.g->answer; with_xy = flag.x->answer; if (with_coordinates || with_xy) raw_data = 1; /* get field separator */ strcpy(fs, " "); if (option.fs->answer) { if (strcmp(option.fs->answer, "space") == 0) *fs = ' '; else if (strcmp(option.fs->answer, "tab") == 0) *fs = '\t'; else if (strcmp(option.fs->answer, "\\t") == 0) *fs = '\t'; else *fs = *option.fs->answer; } /* open all raster maps */ if (option.cell->answers[0] == NULL) G_fatal_error(_("Raster map not found")); names = option.cell->answers; ptr = option.cell->answers; for (; *ptr != NULL; ptr++) { name = *ptr; fd = (int *)G_realloc(fd, (nfiles + 1) * sizeof(int)); is_fp = (int *)G_realloc(is_fp, (nfiles + 1) * sizeof(int)); DMAX = (DCELL *) G_realloc(DMAX, (nfiles + 1) * sizeof(DCELL)); DMIN = (DCELL *) G_realloc(DMIN, (nfiles + 1) * sizeof(DCELL)); fd[nfiles] = Rast_open_old(name, ""); if (!as_int) is_fp[nfiles] = Rast_map_is_fp(name, ""); else { is_fp[nfiles] = 0; if (cat_ranges || nsteps != 255) G_warning(_("Raster map <%s> is reading as integer map! " "Flag '-%c' and/or '%s' option will be ignored."), name, flag.C->key, option.nsteps->key); } if (with_labels || (cat_ranges && is_fp[nfiles])) { labels = (struct Categories *) G_realloc(labels, (nfiles + 1) * sizeof(struct Categories)); if (Rast_read_cats(name, "", &labels[nfiles]) < 0) Rast_init_cats("", &labels[nfiles]); } if (is_fp[nfiles]) /* floating point map */ { Rast_quant_init(&q); if (cat_ranges) { if (!Rast_quant_nof_rules(&labels[nfiles].q)) { G_warning(_("Cats for raster map <%s> are either missing or have no explicit labels. " "Using %s=%d."), name, option.nsteps->key, nsteps); cat_ranges = 0; } else if (nsteps != 255) G_warning(_("Flag '-%c' was given, using cats fp ranges of raster map <%s>, " "ignoring '%s' option"), flag.C->key, name, option.nsteps->key); } if (!cat_ranges) { /* DO NOT use else here, cat_ranges can change */ if (Rast_read_fp_range(name, "", &fp_range) < 0) G_fatal_error(_("Unable to read fp range of raster map <%s>"), name); Rast_get_fp_range_min_max(&fp_range, &DMIN[nfiles], &DMAX[nfiles]); G_debug(3, "file %2d: dmin=%f dmax=%f", nfiles, DMIN[nfiles], DMAX[nfiles]); Rast_quant_add_rule(&q, DMIN[nfiles], DMAX[nfiles], 1, nsteps+1); /* set the quant rules for reading the map */ Rast_set_quant_rules(fd[nfiles], &q); Rast_quant_get_limits(&q, &dmin, &dmax, &min, &max); G_debug(2, "overall: dmin=%f dmax=%f, qmin=%d qmax=%d", dmin, dmax, min, max); Rast_quant_free(&q); } else { /* cats ranges */ /* set the quant rules for reading the map */ Rast_set_quant_rules(fd[nfiles], &labels[nfiles].q); Rast_quant_get_limits(&labels[nfiles].q, &dmin, &dmax, &min, &max); } } else { if (Rast_read_range(name, "", &range) < 0) G_fatal_error(_("Unable to read range for map <%s>"), name); Rast_get_range_min_max(&range, &min, &max); } if (!null_set) { null_set = 1; NULL_CELL = max + 1; } else if (NULL_CELL < max + 1) NULL_CELL = max + 1; nfiles++; } if (dp < 0) strcpy(fmt, "%lf"); else sprintf(fmt, "%%.%dlf", dp); if (raw_data) raw_stats(fd, with_coordinates, with_xy, with_labels); else cell_stats(fd, with_percents, with_counts, with_areas, with_labels, fmt); exit(EXIT_SUCCESS); }
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); }
/*! \brief Get map data type \param filename raster map name \param negflag \return -1 if map is integer and Rast_read_range() fails \return data type (ARRY_*) */ int Gs_numtype(const char *filename, int *negflag) { CELL max = 0, min = 0; struct Range range; const char *mapset; int shortbits, charbits, bitplace; static int max_short, max_char; static int first = 1; if (first) { max_short = max_char = 1; shortbits = 8 * sizeof(short); for (bitplace = 1; bitplace < shortbits; ++bitplace) { /*1 bit for sign */ max_short *= 2; } max_short -= 1; /* NO bits for sign, using unsigned char */ charbits = 8 * sizeof(unsigned char); for (bitplace = 0; bitplace < charbits; ++bitplace) { max_char *= 2; } max_char -= 1; first = 0; } mapset = G_find_raster2(filename, ""); if (!mapset) { G_warning(_("Raster map <%s> not found"), filename); return -1; } if (Rast_map_is_fp(filename, mapset)) { G_debug(3, "Gs_numtype(): fp map detected"); return (ATTY_FLOAT); } if (-1 == Rast_read_range(filename, mapset, &range)) { return (-1); } Rast_get_range_min_max(&range, &min, &max); *negflag = (min < 0); if (max < max_char && min > 0) { return (ATTY_CHAR); } if (max < max_short && min > -max_short) { return (ATTY_SHORT); } return (ATTY_INT); }
int main(int argc, char **argv) { char name[128] = ""; struct Option *map; struct GModule *module; char *mapset; char buff[500]; /* must run in a term window */ G_putenv("GRASS_UI_TERM", "1"); /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("display")); G_add_keyword(_("raster")); module->description = "Allows the user to interactively change the color table " "of a raster map layer displayed on the graphics monitor."; map = G_define_option(); map->key = "map"; map->type = TYPE_STRING; if (*name) map->answer = name; if (*name) map->required = NO; else map->required = YES; map->gisprompt = "old,cell,raster"; map->description = "Name of raster map"; if (G_parser(argc, argv)) exit(1); /* Make sure map is available */ if (map->answer == NULL) exit(0); mapset = G_find_raster2(map->answer, ""); if (mapset == NULL) { char msg[256]; sprintf(msg, "Raster file [%s] not available", map->answer); G_fatal_error(msg); } if (Rast_map_is_fp(map->answer, mapset)) { sprintf(buff, "Raster file [%s] is floating point! \nd.colors only works with integer maps", map->answer); G_fatal_error(buff); } /* connect to the driver */ if (R_open_driver() != 0) G_fatal_error("No graphics device selected"); /* Read in the map region associated with graphics window */ D_setup(0); get_map_info(map->answer, mapset); R_close_driver(); exit(0); }
int main(int argc, char **argv) { char *map_name; int color; int lines; int cols; struct FPRange fp_range; struct Colors colors; double ratio; DCELL dmin, dmax, dval; int cats_num; int cur_dot_row, cur_dot_col; int dots_per_line, dots_per_col; int atcat; int white, black; int atcol, atline; int count, offset; double t, b, l, r; int fp, new_colr; double x_box[5], y_box[5]; struct GModule *module; struct Option *opt1, *opt2, *opt3, *opt4; struct Flag *skip_null; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("display")); G_add_keyword(_("raster")); module->description = _("Displays the color table associated with a raster map layer."); opt1 = G_define_standard_option(G_OPT_R_MAP); opt1->description = _("Name of raster map whose color table is to be displayed"); opt2 = G_define_option(); opt2->key = "color"; opt2->type = TYPE_STRING; opt2->answer = DEFAULT_BG_COLOR; opt2->gisprompt = "old_color,color,color"; opt2->description = _("Color of lines separating the colors of the color table"); opt3 = G_define_option(); opt3->key = "lines"; opt3->type = TYPE_INTEGER; opt3->options = "1-1000"; opt3->description = _("Number of lines to appear in the color table"); opt4 = G_define_option(); opt4->key = "cols"; opt4->type = TYPE_INTEGER; opt4->options = "1-1000"; opt4->description = _("Number of columns to appear in the color table"); skip_null = G_define_flag(); skip_null->key = 'n'; skip_null->description = _("Don't draw a collar showing the NULL color in FP maps"); /* Check command line */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); map_name = opt1->answer; fp = Rast_map_is_fp(map_name, ""); if (opt2->answer != NULL) { new_colr = D_translate_color(opt2->answer); color = new_colr; } if (fp) lines = 1; else lines = 0; if (opt3->answer != NULL) { if (fp) G_warning(_("<%s> is floating-point; " "ignoring [lines] and drawing continuous color ramp"), map_name); else sscanf(opt3->answer, "%d", &lines); } if (fp) cols = 1; else cols = 0; if (opt4->answer) { if (fp) G_warning(_("<%s> is floating-point; " "ignoring [cols] and drawing continuous color ramp"), map_name); else sscanf(opt4->answer, "%d", &cols); } /* Make sure map is available */ if (Rast_read_colors(map_name, "", &colors) == -1) G_fatal_error(_("Color file for <%s> not available"), map_name); if (Rast_read_fp_range(map_name, "", &fp_range) == -1) G_fatal_error(_("Range file for <%s> not available"), map_name); if (D_open_driver() != 0) G_fatal_error(_("No graphics device selected. " "Use d.mon to select graphics device.")); D_setup_unity(0); D_get_src(&t, &b, &l, &r); Rast_get_fp_range_min_max(&fp_range, &dmin, &dmax); if (Rast_is_d_null_value(&dmin) || Rast_is_d_null_value(&dmax)) G_fatal_error(_("Data range is empty")); cats_num = (int)dmax - (int)dmin + 1; if (lines <= 0 && cols <= 0) { double dx, dy; dy = (double)(b - t); dx = (double)(r - l); ratio = dy / dx; cols = 1 + sqrt((dmax - dmin + 1.) / ratio); lines = 1 + cats_num / cols; } else if (lines > 0 && cols <= 0) { cols = 1 + cats_num / lines; } else if (cols > 0 && lines <= 0) { lines = 1 + cats_num / cols; } /* otherwise, accept without complaint what the user requests * It is possible that the number of lines and cols is not * sufficient for the number of categories. */ dots_per_line = (b - t) / lines; dots_per_col = (r - l) / cols; x_box[0] = 0; y_box[0] = 0; x_box[1] = 0; y_box[1] = (6 - dots_per_line); x_box[2] = (dots_per_col - 6); y_box[2] = 0; x_box[3] = 0; y_box[3] = (dots_per_line - 6); x_box[4] = (6 - dots_per_col); y_box[4] = 0; white = D_translate_color("white"); black = D_translate_color("black"); Rast_set_c_null_value(&atcat, 1); if (!fp) { for (atcol = 0; atcol < cols; atcol++) { cur_dot_row = t; cur_dot_col = l + atcol * dots_per_col; count = 0; for (atline = 0; atline < lines; atline++) { cur_dot_row += dots_per_line; /* Draw outer border box */ D_use_color(color); D_begin(); D_move_abs(cur_dot_col + 2, (cur_dot_row - 1)); D_cont_rel(0, (2 - dots_per_line)); D_cont_rel((dots_per_col - 2), 0); D_cont_rel(0, (dots_per_line - 2)); D_cont_rel((2 - dots_per_col), 0); D_end(); D_stroke(); /* Draw black box */ D_use_color(black); D_begin(); D_move_abs(cur_dot_col + 3, (cur_dot_row - 2)); D_cont_rel(0, (4 - dots_per_line)); D_cont_rel((dots_per_col - 4), 0); D_cont_rel(0, (dots_per_line - 4)); D_cont_rel((4 - dots_per_col), 0); D_end(); D_stroke(); /* Color box */ D_color((CELL) atcat, &colors); D_pos_abs(cur_dot_col + 4, (cur_dot_row - 3)); D_polygon_rel(x_box, y_box, 5); count++; /* first cat number is null value */ if (count == 1) atcat = (int)dmin; else if (++atcat > (int)dmax) break; } if (atcat > (int)dmax) break; } /* col loop */ } /* int map */ else { /*** draw continuous color ramp for fp map ***/ cur_dot_row = t + dots_per_line; cur_dot_col = l; /* Draw outer border box */ D_use_color(color); D_begin(); D_move_abs(cur_dot_col + 1, (cur_dot_row - 1)); D_cont_rel(0, (2 - dots_per_line)); D_cont_rel((dots_per_col - 2), 0); D_cont_rel(0, (dots_per_line - 2)); D_cont_rel((2 - dots_per_col), 0); D_end(); D_stroke(); /* Draw black box */ D_use_color(black); D_begin(); D_move_abs(cur_dot_col + 2, (cur_dot_row - 2)); D_cont_rel(0, (4 - dots_per_line)); D_cont_rel((dots_per_col - 4), 0); D_cont_rel(0, (dots_per_line - 4)); D_cont_rel((4 - dots_per_col), 0); D_end(); D_stroke(); /* Color ramp box */ /* get separate color for each pixel */ /* fisrt 5 pixels draw null color */ y_box[1] = -1; y_box[3] = 1; x_box[2] = (dots_per_col - 6); x_box[4] = (6 - dots_per_col); G_debug(1, "dots_per_line: %d dmin=%.2f dmax=%.2f", dots_per_line, dmin, dmax); if (skip_null->answer) offset = 1; else offset = 4; for (r = 0; r < dots_per_line - 6; r++) { if ((r <= 4) && !skip_null->answer) Rast_set_d_null_value(&dval, 1); else dval = dmin + r*(dmax - dmin) / (dots_per_line - 6 - offset); D_d_color(dval, &colors); D_pos_abs(cur_dot_col + 3, (cur_dot_row - 3) - r); D_polygon_rel(x_box, y_box, 5); } } D_save_command(G_recreate_command()); D_close_driver(); exit(EXIT_SUCCESS); }