void color_rules_to_cats(dbCatValArray *cvarr, int is_fp, struct Colors *vcolors, struct Colors *colors) { int i, cat; dbCatVal *cv; int red, grn, blu; /* color table for categories */ G_message(_("Converting color rules into categories...")); for (i = 0; i < cvarr->n_values; i++) { cv = &(cvarr->value[i]); cat = cv->cat; if (is_fp) { if (Rast_get_d_color((const DCELL *) &(cv->val.d), &red, &grn, &blu, vcolors) == 0) { /* G_warning(_("No color rule defined for value %f"), cv->val.d); */ G_debug(3, "scan_attr(): cat=%d, val=%f -> no color rule", cat, cv->val.d); continue; } } else { if (Rast_get_c_color((const CELL *) &(cv->val.i), &red, &grn, &blu, vcolors) == 0) { /* G_warning(_("No color rule defined for value %d"), cv->val.i); */ G_debug(3, "scan_attr(): cat=%d, val=%d -> no color rule", cat, cv->val.i); continue; } } G_debug(3, "scan_attr(): cat=%d, val=%f, r=%d, g=%d, b=%d", cat, is_fp ? cv->val.d : cv->val.i, red, grn, blu); Rast_add_c_color_rule((const CELL*) &cat, red, grn, blu, (const CELL*) &cat, red, grn, blu, colors); } }
int display_area(struct Map_info *Map, struct cat_list *Clist, const struct Cell_head *window, const struct color_rgb *bcolor, const struct color_rgb *fcolor, int chcat, int id_flag, int cats_color_flag, int default_width, double width_scale, struct Colors *zcolors, dbCatValArray *cvarr_rgb, struct Colors *colors, dbCatValArray *cvarr_width, int nrec_width) { int num, area, isle, n_isles, n_points; double xl, yl; struct line_pnts *Points, * APoints, **IPoints; struct line_cats *Cats; int n_ipoints_alloc; int cat, centroid; int red, grn, blu; int i, custom_rgb, found; int width; struct bound_box box; if (Vect_level(Map) < 2) { G_warning(_("Unable to display areas, topology not available. " "Please try to rebuild topology using " "v.build or v.build.all.")); return 1; } G_debug(1, "display areas:"); centroid = 0; Points = Vect_new_line_struct(); APoints = Vect_new_line_struct(); n_ipoints_alloc = 10; IPoints = (struct line_pnts **)G_malloc(n_ipoints_alloc * sizeof(struct line_pnts *)); for (i = 0; i < n_ipoints_alloc; i++) { IPoints[i] = Vect_new_line_struct(); } Cats = Vect_new_cats_struct(); num = Vect_get_num_areas(Map); G_debug(2, "\tn_areas = %d", num); for (area = 1; area <= num; area++) { G_debug(3, "\tarea = %d", area); if (!Vect_area_alive(Map, area)) continue; centroid = Vect_get_area_centroid(Map, area); if (!centroid) { continue; } /* Check box */ Vect_get_area_box(Map, area, &box); if (box.N < window->south || box.S > window->north || box.E < window->west || box.W > window->east) { if (window->proj != PROJECTION_LL) continue; else { /* out of bounds for -180 to 180, try 0 to 360 as well */ if (box.N < window->south || box.S > window->north) continue; if (box.E + 360 < window->west || box.W + 360 > window->east) continue; } } custom_rgb = FALSE; found = FALSE; if (chcat) { if (id_flag) { if (!(Vect_cat_in_cat_list(area, Clist))) continue; } else { G_debug(3, "centroid = %d", centroid); if (centroid < 1) continue; Vect_read_line(Map, Points, Cats, centroid); for (i = 0; i < Cats->n_cats; i++) { G_debug(3, " centroid = %d, field = %d, cat = %d", centroid, Cats->field[i], Cats->cat[i]); if (Cats->field[i] == Clist->field && Vect_cat_in_cat_list(Cats->cat[i], Clist)) { found = TRUE; break; } } if (!found) continue; } } else if (Clist->field > 0) { found = FALSE; G_debug(3, "\tcentroid = %d", centroid); if (centroid < 1) continue; Vect_read_line(Map, NULL, Cats, centroid); for (i = 0; i < Cats->n_cats; i++) { G_debug(3, "\tcentroid = %d, field = %d, cat = %d", centroid, Cats->field[i], Cats->cat[i]); if (Cats->field[i] == Clist->field) { found = TRUE; break; } } /* lines with no category will be displayed */ if (Cats->n_cats > 0 && !found) continue; } /* fill */ Vect_get_area_points(Map, area, APoints); G_debug(3, "\tn_points = %d", APoints->n_points); if (APoints->n_points < 3) { G_warning(_("Invalid area %d skipped (not enough points)"), area); continue; } Vect_reset_line(Points); Vect_append_points(Points, APoints, GV_FORWARD); n_points = Points->n_points; xl = Points->x[n_points - 1]; yl = Points->y[n_points - 1]; n_isles = Vect_get_area_num_isles(Map, area); if (n_isles >= n_ipoints_alloc) { IPoints = (struct line_pnts **)G_realloc(IPoints, (n_isles + 10) * sizeof(struct line_pnts *)); for (i = n_ipoints_alloc; i < n_isles + 10; i++) { IPoints[i] = Vect_new_line_struct(); } n_ipoints_alloc = n_isles + 10; } for (i = 0; i < n_isles; i++) { isle = Vect_get_area_isle(Map, area, i); Vect_get_isle_points(Map, isle, IPoints[i]); Vect_append_points(Points, IPoints[i], GV_FORWARD); Vect_append_point(Points, xl, yl, 0.0); /* ??? */ } cat = Vect_get_area_cat(Map, area, (Clist->field > 0 ? Clist->field : (Cats->n_cats > 0 ? Cats->field[0] : 1))); if (!centroid && cat == -1) { continue; } /* z height colors */ if (zcolors) { if (Rast_get_d_color(&Points->z[0], &red, &grn, &blu, zcolors) == 1) custom_rgb = TRUE; else custom_rgb = FALSE; } /* custom colors */ if (colors || cvarr_rgb) { custom_rgb = get_table_color(cat, area, colors, cvarr_rgb, &red, &grn, &blu); } /* random colors */ if (cats_color_flag) { custom_rgb = get_cat_color(area, Cats, Clist, &red, &grn, &blu); } /* line width */ if (nrec_width) { width = (int) get_property(cat, area, cvarr_width, (double) width_scale, (double) default_width); D_line_width(width); } if (fcolor || zcolors) { if (!cvarr_rgb && !cats_color_flag && !zcolors && !colors) { D_RGB_color(fcolor->r, fcolor->g, fcolor->b); D_polygon_abs(Points->x, Points->y, Points->n_points); } else { if (custom_rgb) { D_RGB_color((unsigned char)red, (unsigned char)grn, (unsigned char)blu); } else { D_RGB_color(fcolor->r, fcolor->g, fcolor->b); } if (cat >= 0) { D_polygon_abs(Points->x, Points->y, Points->n_points); } } } /* boundary */ if (bcolor) { if (custom_rgb) { D_RGB_color((unsigned char)red, (unsigned char)grn, (unsigned char)blu); } else { D_RGB_color(bcolor->r, bcolor->g, bcolor->b); } /* use different user defined render methods */ D_polyline_abs(APoints->x, APoints->y, APoints->n_points); for (i = 0; i < n_isles; i++) { /* use different user defined render methods */ D_polyline_abs(IPoints[i]->x, IPoints[i]->y, IPoints[i]->n_points); } } } if ((colors || cvarr_rgb) && get_num_color_rules_skipped() > 0) G_warning(_n("%d invalid color rule for areas skipped", "%d invalid color rules for areas skipped", get_num_color_rules_skipped()), get_num_color_rules_skipped()); Vect_destroy_line_struct(Points); Vect_destroy_line_struct(APoints); for (i = 0; i < n_ipoints_alloc; i++) { Vect_destroy_line_struct(IPoints[i]); } G_free(IPoints); Vect_destroy_cats_struct(Cats); return 0; }
/* *************************************************************** */ int main(int argc, char *argv[]) { int i, j; int nfiles; int fd[NFILES]; struct Categories cats[NFILES]; struct Cell_head window; struct Colors ncolor[NFILES]; struct Colors colors; RASTER_MAP_TYPE out_type[NFILES]; CELL *cell[NFILES]; DCELL *dcell[NFILES]; /* int row, col; */ double drow, dcol; int row_in_window, in_window; double east, north; int line; char buffer[1024]; char **ptr; struct Option *opt1, *opt2, *opt3, *opt4, *opt_fs; struct Flag *label_flag, *cache_flag, *int_flag, *color_flag, *header_flag; char fs; int Cache_size; int done = FALSE; int point, point_cnt; struct order *cache; int cur_row; int projection; int cache_hit = 0, cache_miss = 0; int cache_hit_tot = 0, cache_miss_tot = 0; int pass = 0; int cache_report = FALSE; char tmp_buf[500], *null_str; int red, green, blue; struct GModule *module; G_gisinit(argv[0]); /* Set description */ module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("position")); G_add_keyword(_("querying")); module->description = _("Queries raster map layers on their category values and category labels."); opt1 = G_define_option(); opt1->key = "input"; opt1->type = TYPE_STRING; opt1->required = YES; opt1->multiple = YES; opt1->gisprompt = "old,cell,raster"; opt1->description = _("Name of existing raster map(s) to query"); opt2 = G_define_option(); opt2->key = "cache"; opt2->type = TYPE_INTEGER; opt2->required = NO; opt2->multiple = NO; opt2->description = _("Size of point cache"); opt2->answer = "500"; opt2->guisection = _("Advanced"); opt3 = G_define_option(); opt3->key = "null"; opt3->type = TYPE_STRING; opt3->required = NO; opt3->answer = "*"; opt3->description = _("Char string to represent no data cell"); opt_fs = G_define_standard_option(G_OPT_F_SEP); opt4 = G_define_option(); opt4->key = "east_north"; opt4->type = TYPE_DOUBLE; opt4->key_desc = "east,north"; opt4->required = NO; opt4->multiple = YES; opt4->description = _("Coordinates for query"); header_flag = G_define_flag(); header_flag->key = 'n'; header_flag->description = _("Output header row"); label_flag = G_define_flag(); label_flag->key = 'f'; label_flag->description = _("Show the category labels of the grid cell(s)"); color_flag = G_define_flag(); color_flag->key = 'r'; color_flag->description = _("Output color values as RRR:GGG:BBB"); int_flag = G_define_flag(); int_flag->key = 'i'; int_flag->description = _("Output integer category values, not cell values"); cache_flag = G_define_flag(); cache_flag->key = 'c'; cache_flag->description = _("Turn on cache reporting"); cache_flag->guisection = _("Advanced"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); tty = isatty(0); projection = G_projection(); /* see v.in.ascii for a better solution */ if (opt_fs->answer != NULL) { if (strcmp(opt_fs->answer, "space") == 0) fs = ' '; else if (strcmp(opt_fs->answer, "tab") == 0) fs = '\t'; else if (strcmp(opt_fs->answer, "\\t") == 0) fs = '\t'; else fs = opt_fs->answer[0]; } null_str = opt3->answer; if (tty) Cache_size = 1; else Cache_size = atoi(opt2->answer); if (Cache_size < 1) Cache_size = 1; cache = (struct order *)G_malloc(sizeof(struct order) * Cache_size); /*enable cache report */ if (cache_flag->answer) cache_report = TRUE; ptr = opt1->answers; nfiles = 0; for (; *ptr != NULL; ptr++) { char name[GNAME_MAX]; if (nfiles >= NFILES) G_fatal_error(_("can only do up to %d raster maps"), NFILES); strcpy(name, *ptr); fd[nfiles] = Rast_open_old(name, ""); out_type[nfiles] = Rast_get_map_type(fd[nfiles]); if (int_flag->answer) out_type[nfiles] = CELL_TYPE; if (color_flag->answer) { Rast_read_colors(name, "", &colors); ncolor[nfiles] = colors; } if (label_flag->answer && Rast_read_cats(name, "", &cats[nfiles]) < 0) G_fatal_error(_("Unable to read category file for <%s>"), name); nfiles++; } for (i = 0; i < nfiles; i++) { if (int_flag->answer) out_type[i] = CELL_TYPE; cell[i] = Rast_allocate_c_buf(); if (out_type[i] != CELL_TYPE) dcell[i] = Rast_allocate_d_buf(); } G_get_window(&window); if(header_flag->answer) { fprintf(stdout, "easting%cnorthing%csite_name", fs, fs); ptr = opt1->answers; for (; *ptr != NULL; ptr++) { char name[GNAME_MAX]; strcpy(name, *ptr); fprintf(stdout, "%c%s", fs, name); if (label_flag->answer) fprintf(stdout, "%c%s_label", fs, name); if (color_flag->answer) fprintf(stdout, "%c%s_color", fs, name); } fprintf(stdout, "\n"); } line = 0; if (!opt4->answers && tty) fprintf(stderr, "enter points, \"end\" to quit\n"); j = 0; done = FALSE; while (!done) { pass++; if (cache_report & !tty) fprintf(stderr, "Pass %3d Line %6d - ", pass, line); cache_hit = cache_miss = 0; if (!opt4->answers && tty) { fprintf(stderr, "\neast north [label] > "); Cache_size = 1; } { point_cnt = 0; for (i = 0; i < Cache_size; i++) { if (!opt4->answers && fgets(buffer, 1000, stdin) == NULL) done = TRUE; else { line++; if ((!opt4->answers && (strncmp(buffer, "end\n", 4) == 0 || strncmp(buffer, "exit\n", 5) == 0)) || (opt4->answers && !opt4->answers[j])) done = TRUE; else { *(cache[point_cnt].lab_buf) = *(cache[point_cnt].east_buf) = *(cache[point_cnt].north_buf) = 0; if (!opt4->answers) sscanf(buffer, "%s %s %[^\n]", cache[point_cnt].east_buf, cache[point_cnt].north_buf, cache[point_cnt].lab_buf); else { strcpy(cache[point_cnt].east_buf, opt4->answers[j++]); strcpy(cache[point_cnt].north_buf, opt4->answers[j++]); } if (*(cache[point_cnt].east_buf) == 0) continue; /* skip blank lines */ if (*(cache[point_cnt].north_buf) == 0) { oops(line, buffer, "two coordinates (east north) required"); continue; } if (!G_scan_northing (cache[point_cnt].north_buf, &north, window.proj) || !G_scan_easting(cache[point_cnt].east_buf, &east, window.proj)) { oops(line, buffer, "invalid coordinate(s)"); continue; } /* convert north, east to row and col */ drow = Rast_northing_to_row(north, &window); dcol = Rast_easting_to_col(east, &window); /* a special case. * if north falls at southern edge, or east falls on eastern edge, * the point will appear outside the window. * So, for these edges, bring the point inside the window */ if (drow == window.rows) drow--; if (dcol == window.cols) dcol--; cache[point_cnt].row = (int)drow; cache[point_cnt].col = (int)dcol; cache[point_cnt].point = point_cnt; point_cnt++; } } } } if (Cache_size > 1) qsort(cache, point_cnt, sizeof(struct order), by_row); /* extract data from files and store in cache */ cur_row = -99; for (point = 0; point < point_cnt; point++) { row_in_window = 1; in_window = 1; if (cache[point].row < 0 || cache[point].row >= window.rows) row_in_window = in_window = 0; if (cache[point].col < 0 || cache[point].col >= window.cols) in_window = 0; if (!in_window) { if (tty) fprintf(stderr, "** note ** %s %s is outside your current window\n", cache[point].east_buf, cache[point].north_buf); } if (cur_row != cache[point].row) { cache_miss++; if (row_in_window) for (i = 0; i < nfiles; i++) { Rast_get_c_row(fd[i], cell[i], cache[point].row); if (out_type[i] != CELL_TYPE) Rast_get_d_row(fd[i], dcell[i], cache[point].row); } cur_row = cache[point].row; } else cache_hit++; for (i = 0; i < nfiles; i++) { if (in_window) cache[point].value[i] = cell[i][cache[point].col]; else Rast_set_c_null_value(&(cache[point].value[i]), 1); if (out_type[i] != CELL_TYPE) { if (in_window) cache[point].dvalue[i] = dcell[i][cache[point].col]; else Rast_set_d_null_value(&(cache[point].dvalue[i]), 1); } if (color_flag->answer) { if (out_type[i] == CELL_TYPE) Rast_get_c_color(&cell[i][cache[point].col], &red, &green, &blue, &ncolor[i]); else Rast_get_d_color(&dcell[i][cache[point].col], &red, &green, &blue, &ncolor[i]); sprintf(cache[point].clr_buf[i], "%03d:%03d:%03d", red, green, blue); } } } /* point loop */ if (Cache_size > 1) qsort(cache, point_cnt, sizeof(struct order), by_point); /* report data from re-ordered cache */ for (point = 0; point < point_cnt; point++) { G_debug(1, "%s|%s at col %d, row %d\n", cache[point].east_buf, cache[point].north_buf, cache[point].col, cache[point].row); fprintf(stdout, "%s%c%s%c%s", cache[point].east_buf, fs, cache[point].north_buf, fs, cache[point].lab_buf); for (i = 0; i < nfiles; i++) { if (out_type[i] == CELL_TYPE) { if (Rast_is_c_null_value(&cache[point].value[i])) { fprintf(stdout, "%c%s", fs, null_str); if (label_flag->answer) fprintf(stdout, "%c", fs); if (color_flag->answer) fprintf(stdout, "%c", fs); continue; } fprintf(stdout, "%c%ld", fs, (long)cache[point].value[i]); } else { /* FCELL or DCELL */ if (Rast_is_d_null_value(&cache[point].dvalue[i])) { fprintf(stdout, "%c%s", fs, null_str); if (label_flag->answer) fprintf(stdout, "%c", fs); if (color_flag->answer) fprintf(stdout, "%c", fs); continue; } if (out_type[i] == FCELL_TYPE) sprintf(tmp_buf, "%.7g", cache[point].dvalue[i]); else /* DCELL */ sprintf(tmp_buf, "%.15g", cache[point].dvalue[i]); G_trim_decimal(tmp_buf); /* not needed with %g? */ fprintf(stdout, "%c%s", fs, tmp_buf); } if (label_flag->answer) fprintf(stdout, "%c%s", fs, Rast_get_c_cat(&(cache[point].value[i]), &cats[i])); if (color_flag->answer) fprintf(stdout, "%c%s", fs, cache[point].clr_buf[i]); } fprintf(stdout, "\n"); } if (cache_report & !tty) fprintf(stderr, "Cache Hit: %6d Miss: %6d\n", cache_hit, cache_miss); cache_hit_tot += cache_hit; cache_miss_tot += cache_miss; cache_hit = cache_miss = 0; } if (!opt4->answers && tty) fprintf(stderr, "\n"); if (cache_report & !tty) fprintf(stderr, "Total: Cache Hit: %6d Miss: %6d\n", cache_hit_tot, cache_miss_tot); exit(EXIT_SUCCESS); }