/*! * \brief Extract a cell value from raster map (bilinear interpolation). * * Extract a cell value from raster map at given northing and easting * with a sampled 3x3 window using a bilinear interpolation. * * \param fd file descriptor * \param window region settings * \param cats categories * \param north northing position * \param east easting position * \param usedesc flag to scan category label * * \return cell value at given position */ DCELL Rast_get_sample_bilinear(int fd, const struct Cell_head * window, struct Categories * cats, double north, double east, int usedesc) { int row, col; double grid[2][2]; DCELL *arow = Rast_allocate_d_buf(); DCELL *brow = Rast_allocate_d_buf(); double frow, fcol, trow, tcol; DCELL result; frow = Rast_northing_to_row(north, window); fcol = Rast_easting_to_col(east, window); /* convert northing and easting to row and col, resp */ row = (int)floor(frow - 0.5); col = (int)floor(fcol - 0.5); trow = frow - row - 0.5; tcol = fcol - col - 0.5; if (row < 0 || row + 1 >= Rast_window_rows() || col < 0 || col + 1 >= Rast_window_cols()) { Rast_set_d_null_value(&result, 1); goto done; } Rast_get_d_row(fd, arow, row); Rast_get_d_row(fd, brow, row + 1); if (Rast_is_d_null_value(&arow[col]) || Rast_is_d_null_value(&arow[col + 1]) || Rast_is_d_null_value(&brow[col]) || Rast_is_d_null_value(&brow[col + 1])) { Rast_set_d_null_value(&result, 1); goto done; } /*- * now were ready to do bilinear interpolation over * arow[col], arow[col+1], * brow[col], brow[col+1] */ if (usedesc) { char *buf; G_squeeze(buf = Rast_get_c_cat((int *)&(arow[col]), cats)); grid[0][0] = scancatlabel(buf); G_squeeze(buf = Rast_get_c_cat((CELL *) & (arow[col + 1]), cats)); grid[0][1] = scancatlabel(buf); G_squeeze(buf = Rast_get_c_cat((CELL *) & (brow[col]), cats)); grid[1][0] = scancatlabel(buf); G_squeeze(buf = Rast_get_c_cat((CELL *) & (brow[col + 1]), cats)); grid[1][1] = scancatlabel(buf); } else { grid[0][0] = arow[col]; grid[0][1] = arow[col + 1]; grid[1][0] = brow[col]; grid[1][1] = brow[col + 1]; } result = Rast_interp_bilinear(tcol, trow, grid[0][0], grid[0][1], grid[1][0], grid[1][1]); done: G_free(arow); G_free(brow); return result; }
char *get_label(struct Map *map, CELL cat) { return Rast_get_c_cat(&cat, &map->labels); }
int o_sdev(const char *basemap, const char *covermap, const char *outputmap, int usecats, struct Categories *cats) { struct Popen stats_child, reclass_child; FILE *stats, *reclass; int first, mem, i, count; long basecat, covercat, catb, catc; double value, sdev, x; double *tab; mem = MEM * sizeof(double); tab = (double *)G_malloc(mem); stats = run_stats(&stats_child, basemap, covermap, "-cn"); reclass = run_reclass(&reclass_child, basemap, outputmap); first = 1; while (read_stats(stats, &basecat, &covercat, &value)) { if (first) { first = 0; catb = basecat; catc = covercat; i = 0; count = 0; } if (basecat != catb) { s_dev(tab, count, &sdev); fprintf(reclass, "%ld = %ld %f\n", catb, catb, sdev); catb = basecat; catc = covercat; count = 0; } if (usecats) sscanf(Rast_get_c_cat((CELL *) &covercat, cats), "%lf", &x); else x = covercat; for (i = 0; i < value; i++) { if (count * sizeof(double) >= mem) { mem += MEM * sizeof(double); tab = (double *)G_realloc(tab, mem); /* fprintf(stderr,"MALLOC: %d KB needed\n",(int)(mem/1024)); */ } tab[count++] = x; } } if (first) { catb = catc = 0; } s_dev(tab, count, &sdev); fprintf(reclass, "%ld = %ld %f\n", catb, catb, sdev); G_debug(5, "%ld = %ld %f\n", catb, catb, sdev); G_popen_close(&stats_child); G_popen_close(&reclass_child); return 0; }
/*! \brief Get categories/labels Formats label as in d.what.rast -> (catval) catlabel \param filename raster map name \param drow \param dcol \param catstr category string \return 1 on success \return 0 on failure */ int Gs_get_cat_label(const char *filename, int drow, int dcol, char *catstr) { struct Categories cats; const char *mapset; CELL *buf; DCELL *dbuf; RASTER_MAP_TYPE map_type; int fd = -1; if ((mapset = G_find_raster2(filename, "")) == NULL) { G_warning(_("Raster map <%s> not found"), filename); return 0; } if (-1 != Rast_read_cats(filename, mapset, &cats)) { fd = Rast_open_old(filename, mapset); map_type = Rast_get_map_type(fd); if (map_type == CELL_TYPE) { buf = Rast_allocate_c_buf(); Rast_get_c_row(fd, buf, drow); if (Rast_is_c_null_value(&buf[dcol])) { sprintf(catstr, "(NULL) %s", Rast_get_c_cat(&buf[dcol], &cats)); } else { sprintf(catstr, "(%d) %s", buf[dcol], Rast_get_c_cat(&buf[dcol], &cats)); } G_free(buf); } else { /* fp map */ dbuf = Rast_allocate_d_buf(); Rast_get_d_row(fd, dbuf, drow); if (Rast_is_d_null_value(&dbuf[dcol])) { sprintf(catstr, "(NULL) %s", Rast_get_d_cat(&dbuf[dcol], &cats)); } else { sprintf(catstr, "(%g) %s", dbuf[dcol], Rast_get_d_cat(&dbuf[dcol], &cats)); } G_free(dbuf); } } else { strcpy(catstr, "no category label"); return 0; } /* TODO: may want to keep these around for multiple queries */ Rast_free_cats(&cats); if (fd >= 0) Rast_close(fd); return (1); }
int get_training_classes(struct parms *parms, struct files *files, struct SigSet *S) { int fd; CELL *cell; CELL cat; struct Cell_stats cell_stats; CELL *list; int row, nrows, ncols; int i, n; long count; struct ClassSig *Sig; fd = files->train_fd; cell = files->train_cell; nrows = Rast_window_rows(); ncols = Rast_window_cols(); /* determine the non-zero categories in the map */ I_InitSigSet(S); I_SigSetNBands(S, files->nbands); I_SetSigTitle(S, Rast_get_cats_title(&files->training_labels)); Rast_init_cell_stats(&cell_stats); G_message(_("Finding training classes...")); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); Rast_get_c_row(fd, cell, row); Rast_update_cell_stats(cell, ncols, &cell_stats); } G_percent(nrows, nrows, 2); /* convert this to an array */ Rast_rewind_cell_stats(&cell_stats); n = 0; while (Rast_next_cell_stat(&cat, &count, &cell_stats)) { if (count > 1) { Sig = I_NewClassSig(S); I_SetClassTitle(Sig, Rast_get_c_cat(&cat, &files->training_labels)); Sig->classnum = cat; /* initialize this class with maxsubclasses (by allocating them) */ for (i = 0; i < parms->maxsubclasses; i++) I_NewSubSig(S, Sig); I_AllocClassData(S, Sig, count); n++; } else G_warning(_("Training class %d only has one cell - this class will be ignored"), cat); } if (n == 0) { G_fatal_error(_("Training map has no classes")); } list = (CELL *) G_calloc(n, sizeof(CELL)); n = 0; Rast_rewind_cell_stats(&cell_stats); while (Rast_next_cell_stat(&cat, &count, &cell_stats)) if (count > 1) list[n++] = cat; Rast_free_cell_stats(&cell_stats); files->ncats = n; files->training_cats = list; if (files->ncats == 1) G_message(_("1 class found")); else G_message(_("%d classes found"), files->ncats); 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); }