void Rast_align_window(struct Cell_head *window, const struct Cell_head *ref) { int preserve; window->ns_res = ref->ns_res; window->ew_res = ref->ew_res; window->zone = ref->zone; window->proj = ref->proj; preserve = window->proj == PROJECTION_LL && window->east == (window->west + 360); window->south = Rast_row_to_northing(ceil(Rast_northing_to_row(window->south, ref)), ref); window->north = Rast_row_to_northing(floor(Rast_northing_to_row(window->north, ref)), ref); window->east = Rast_col_to_easting(ceil(Rast_easting_to_col(window->east, ref)), ref); window->west = Rast_col_to_easting(floor(Rast_easting_to_col(window->west, ref)), ref); if (window->proj == PROJECTION_LL) { while (window->north > 90.0) window->north -= window->ns_res; while (window->south < -90.0) window->south += window->ns_res; if (preserve) window->east = window->west + 360; else while (window->east - window->west > 360.0) window->east -= window->ew_res; } G_adjust_Cell_head(window, 0, 0); }
static void snap_to_grid(struct Cell_head *cur_hd, const struct Cell_head *ref_hd) { int lidx = (int) floor(Rast_easting_to_col( cur_hd->west, ref_hd)); int ridx = (int) floor(Rast_easting_to_col( cur_hd->east, ref_hd)); int bidx = (int) floor(Rast_northing_to_row(cur_hd->south, ref_hd)); int tidx = (int) floor(Rast_northing_to_row(cur_hd->north, ref_hd)); cur_hd->west = Rast_col_to_easting( lidx + 0.0, ref_hd); cur_hd->east = Rast_col_to_easting( ridx + 1.0, ref_hd); cur_hd->south = Rast_row_to_northing(bidx + 1.0, ref_hd); cur_hd->north = Rast_row_to_northing(tidx + 0.0, ref_hd); }
/*! * \brief Extract a cell value from raster map (neighbor interpolation) * * Extract a cell value from raster map at given northing and easting * with a sampled 3x3 window using a neighbor 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_nearest(int fd, const struct Cell_head * window, struct Categories * cats, double north, double east, int usedesc) { int row, col; DCELL result; DCELL *maprow = Rast_allocate_d_buf(); /* convert northing and easting to row and col, resp */ row = (int)floor(Rast_northing_to_row(north, window)); col = (int)floor(Rast_easting_to_col(east, window)); if (row < 0 || row >= Rast_window_rows() || col < 0 || col >= Rast_window_cols()) { Rast_set_d_null_value(&result, 1); goto done; } Rast_get_d_row(fd, maprow, row); if (Rast_is_d_null_value(&maprow[col])) { Rast_set_d_null_value(&result, 1); goto done; } if (usedesc) { char *buf = Rast_get_c_cat((CELL *) & (maprow[col]), cats); G_squeeze(buf); result = scancatlabel(buf); } else result = maprow[col]; done: G_free(maprow); return result; }
/* 0 on out of region or NULL, 1 on success */ int rast_segment_get_value_xy(SEGMENT * base_segment, struct Cell_head *input_region, RASTER_MAP_TYPE rtype, double x, double y, double *value) { /* Rast gives double, Segment needs off_t */ off_t base_row = Rast_northing_to_row(y, input_region); off_t base_col = Rast_easting_to_col(x, input_region); /* skip points which are outside the base raster * (null propagation) */ if (base_row < 0 || base_col < 0 || base_row >= input_region->rows || base_col >= input_region->cols) return 0; if (rtype == DCELL_TYPE) { DCELL tmp; Segment_get(base_segment, &tmp, base_row, base_col); if (Rast_is_d_null_value(&tmp)) return 0; *value = (double)tmp; } else if (rtype == FCELL_TYPE) { FCELL tmp; Segment_get(base_segment, &tmp, base_row, base_col); if (Rast_is_f_null_value(&tmp)) return 0; *value = (double)tmp; } else { CELL tmp; Segment_get(base_segment, &tmp, base_row, base_col); if (Rast_is_c_null_value(&tmp)) return 0; *value = (double)tmp; } return 1; }
int main(int argc, char *argv[]) { int i, j, nlines, type, field, cat; int fd; /* struct Categories RCats; *//* TODO */ struct Cell_head window; RASTER_MAP_TYPE out_type; CELL *cell; DCELL *dcell; double drow, dcol; char buf[2000]; struct Option *vect_opt, *rast_opt, *field_opt, *col_opt, *where_opt; int Cache_size; struct order *cache; int cur_row; struct GModule *module; struct Map_info Map; struct line_pnts *Points; struct line_cats *Cats; int point; int point_cnt; /* number of points in cache */ int outside_cnt; /* points outside region */ int nocat_cnt; /* points inside region but without category */ int dupl_cnt; /* duplicate categories */ struct bound_box box; int *catexst, *cex; struct field_info *Fi; dbString stmt; dbDriver *driver; int select, norec_cnt, update_cnt, upderr_cnt, col_type; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("raster")); G_add_keyword(_("position")); G_add_keyword(_("querying")); G_add_keyword(_("attribute table")); module->description = _("Uploads raster values at positions of vector points to the table."); vect_opt = G_define_standard_option(G_OPT_V_INPUT); vect_opt->key = "vector"; vect_opt->description = _("Name of input vector points map for which to edit attribute table"); rast_opt = G_define_standard_option(G_OPT_R_INPUT); rast_opt->key = "raster"; rast_opt->description = _("Name of existing raster map to be queried"); field_opt = G_define_standard_option(G_OPT_V_FIELD); col_opt = G_define_option(); col_opt->key = "column"; col_opt->type = TYPE_STRING; col_opt->required = YES; col_opt->description = _("Column name (will be updated by raster values)"); where_opt = G_define_standard_option(G_OPT_DB_WHERE); if (G_parser(argc, argv)) exit(EXIT_FAILURE); field = atoi(field_opt->answer); db_init_string(&stmt); Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); G_get_window(&window); Vect_region_box(&window, &box); /* T and B set to +/- PORT_DOUBLE_MAX */ /* Open vector */ Vect_set_open_level(2); Vect_open_old(&Map, vect_opt->answer, ""); Fi = Vect_get_field(&Map, field); if (Fi == NULL) G_fatal_error(_("Database connection not defined for layer %d"), field); /* Open driver */ driver = db_start_driver_open_database(Fi->driver, Fi->database); if (driver == NULL) { G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Fi->database, Fi->driver); } /* Open raster */ fd = Rast_open_old(rast_opt->answer, ""); out_type = Rast_get_map_type(fd); /* TODO: Later possibly category labels */ /* if ( Rast_read_cats (name, "", &RCats) < 0 ) G_fatal_error ( "Cannot read category file"); */ /* Check column type */ col_type = db_column_Ctype(driver, Fi->table, col_opt->answer); if (col_type == -1) G_fatal_error(_("Column <%s> not found"), col_opt->answer); if (col_type != DB_C_TYPE_INT && col_type != DB_C_TYPE_DOUBLE) G_fatal_error(_("Column type not supported")); if (out_type == CELL_TYPE && col_type == DB_C_TYPE_DOUBLE) G_warning(_("Raster type is integer and column type is float")); if (out_type != CELL_TYPE && col_type == DB_C_TYPE_INT) G_warning(_("Raster type is float and column type is integer, some data lost!!")); /* Read vector points to cache */ Cache_size = Vect_get_num_primitives(&Map, GV_POINT); /* Note: Some space may be wasted (outside region or no category) */ cache = (struct order *)G_calloc(Cache_size, sizeof(struct order)); point_cnt = outside_cnt = nocat_cnt = 0; nlines = Vect_get_num_lines(&Map); G_debug(1, "Reading %d vector features fom map", nlines); for (i = 1; i <= nlines; i++) { type = Vect_read_line(&Map, Points, Cats, i); G_debug(4, "line = %d type = %d", i, type); /* check type */ if (!(type & GV_POINT)) continue; /* Points only */ /* check region */ if (!Vect_point_in_box(Points->x[0], Points->y[0], 0.0, &box)) { outside_cnt++; continue; } Vect_cat_get(Cats, field, &cat); if (cat < 0) { /* no category of given field */ nocat_cnt++; continue; } G_debug(4, " cat = %d", cat); /* Add point to cache */ drow = Rast_northing_to_row(Points->y[0], &window); dcol = Rast_easting_to_col(Points->x[0], &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].cat = cat; cache[point_cnt].count = 1; point_cnt++; } Vect_set_db_updated(&Map); Vect_hist_command(&Map); Vect_close(&Map); G_debug(1, "Read %d vector points", point_cnt); /* Cache may contain duplicate categories, sort by cat, find and remove duplicates * and recalc count and decrease point_cnt */ qsort(cache, point_cnt, sizeof(struct order), by_cat); G_debug(1, "Points are sorted, starting duplicate removal loop"); for (i = 0, j = 1; j < point_cnt; j++) if (cache[i].cat != cache[j].cat) cache[++i] = cache[j]; else cache[i].count++; point_cnt = i + 1; G_debug(1, "%d vector points left after removal of duplicates", point_cnt); /* Report number of points not used */ if (outside_cnt) G_warning(_("%d points outside current region were skipped"), outside_cnt); if (nocat_cnt) G_warning(_("%d points without category were skipped"), nocat_cnt); /* Sort cache by current region row */ qsort(cache, point_cnt, sizeof(struct order), by_row); /* Allocate space for raster row */ if (out_type == CELL_TYPE) cell = Rast_allocate_c_buf(); else dcell = Rast_allocate_d_buf(); /* Extract raster values from file and store in cache */ G_debug(1, "Extracting raster values"); cur_row = -1; for (point = 0; point < point_cnt; point++) { if (cache[point].count > 1) continue; /* duplicate cats */ if (cur_row != cache[point].row) { if (out_type == CELL_TYPE) Rast_get_c_row(fd, cell, cache[point].row); else Rast_get_d_row(fd, dcell, cache[point].row); } cur_row = cache[point].row; if (out_type == CELL_TYPE) { cache[point].value = cell[cache[point].col]; } else { cache[point].dvalue = dcell[cache[point].col]; } } /* point loop */ /* Update table from cache */ G_debug(1, "Updating db table"); /* select existing categories to array (array is sorted) */ select = db_select_int(driver, Fi->table, Fi->key, NULL, &catexst); db_begin_transaction(driver); norec_cnt = update_cnt = upderr_cnt = dupl_cnt = 0; for (point = 0; point < point_cnt; point++) { if (cache[point].count > 1) { G_warning(_("More points (%d) of category %d, value set to 'NULL'"), cache[point].count, cache[point].cat); dupl_cnt++; } /* category exist in DB ? */ cex = (int *)bsearch((void *)&(cache[point].cat), catexst, select, sizeof(int), srch_cat); if (cex == NULL) { /* cat does not exist in DB */ norec_cnt++; G_warning(_("No record for category %d in table <%s>"), cache[point].cat, Fi->table); continue; } sprintf(buf, "update %s set %s = ", Fi->table, col_opt->answer); db_set_string(&stmt, buf); if (out_type == CELL_TYPE) { if (cache[point].count > 1 || Rast_is_c_null_value(&cache[point].value)) { sprintf(buf, "NULL"); } else { sprintf(buf, "%d ", cache[point].value); } } else { /* FCELL or DCELL */ if (cache[point].count > 1 || Rast_is_d_null_value(&cache[point].dvalue)) { sprintf(buf, "NULL"); } else { sprintf(buf, "%.10f", cache[point].dvalue); } } db_append_string(&stmt, buf); sprintf(buf, " where %s = %d", Fi->key, cache[point].cat); db_append_string(&stmt, buf); /* user provides where condition: */ if (where_opt->answer) { sprintf(buf, " AND %s", where_opt->answer); db_append_string(&stmt, buf); } G_debug(3, db_get_string(&stmt)); /* Update table */ if (db_execute_immediate(driver, &stmt) == DB_OK) { update_cnt++; } else { upderr_cnt++; } } G_debug(1, "Committing DB transaction"); db_commit_transaction(driver); G_free(catexst); db_close_database_shutdown_driver(driver); db_free_string(&stmt); /* Report */ G_message(_("%d categories loaded from table"), select); G_message(_("%d categories loaded from vector"), point_cnt); G_message(_("%d categories from vector missing in table"), norec_cnt); G_message(_("%d duplicate categories in vector"), dupl_cnt); if (!where_opt->answer) G_message(_("%d records updated"), update_cnt); G_message(_("%d update errors"), upderr_cnt); exit(EXIT_SUCCESS); }
static void resamp_unweighted(void) { stat_func *method_fn; DCELL *values; int *col_map, *row_map; int row, col; method_fn = menu[method].method; values = G_malloc(row_scale * col_scale * sizeof(DCELL)); col_map = G_malloc((dst_w.cols + 1) * sizeof(int)); row_map = G_malloc((dst_w.rows + 1) * sizeof(int)); for (col = 0; col <= dst_w.cols; col++) { double x = Rast_col_to_easting(col, &dst_w); col_map[col] = (int)floor(Rast_easting_to_col(x, &src_w) + 0.5); } for (row = 0; row <= dst_w.rows; row++) { double y = Rast_row_to_northing(row, &dst_w); row_map[row] = (int)floor(Rast_northing_to_row(y, &src_w) + 0.5); } for (row = 0; row < dst_w.rows; row++) { int maprow0 = row_map[row + 0]; int maprow1 = row_map[row + 1]; int count = maprow1 - maprow0; int i; G_percent(row, dst_w.rows, 2); for (i = 0; i < count; i++) Rast_get_d_row(infile, bufs[i], maprow0 + i); for (col = 0; col < dst_w.cols; col++) { int mapcol0 = col_map[col + 0]; int mapcol1 = col_map[col + 1]; int null = 0; int n = 0; int i, j; for (i = maprow0; i < maprow1; i++) for (j = mapcol0; j < mapcol1; j++) { DCELL *src = &bufs[i - maprow0][j]; DCELL *dst = &values[n++]; if (Rast_is_d_null_value(src)) { Rast_set_d_null_value(dst, 1); null = 1; } else *dst = *src; } if (null && nulls) Rast_set_d_null_value(&outbuf[col], 1); else (*method_fn) (&outbuf[col], values, n, closure); } Rast_put_d_row(outfile, outbuf); } }
int main(int argc, char *argv[]) { struct GModule *module; struct { struct Option *rastin, *rastout, *method, *quantile; } parm; struct { struct Flag *nulls, *weight; } flag; struct History history; char title[64]; char buf_nsres[100], buf_ewres[100]; struct Colors colors; int row; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("resample")); module->description = _("Resamples raster map layers to a coarser grid using aggregation."); parm.rastin = G_define_standard_option(G_OPT_R_INPUT); parm.rastout = G_define_standard_option(G_OPT_R_OUTPUT); parm.method = G_define_option(); parm.method->key = "method"; parm.method->type = TYPE_STRING; parm.method->required = NO; parm.method->description = _("Aggregation method"); parm.method->options = build_method_list(); parm.method->answer = "average"; parm.quantile = G_define_option(); parm.quantile->key = "quantile"; parm.quantile->type = TYPE_DOUBLE; parm.quantile->required = NO; parm.quantile->description = _("Quantile to calculate for method=quantile"); parm.quantile->options = "0.0-1.0"; parm.quantile->answer = "0.5"; flag.nulls = G_define_flag(); flag.nulls->key = 'n'; flag.nulls->description = _("Propagate NULLs"); flag.weight = G_define_flag(); flag.weight->key = 'w'; flag.weight->description = _("Weight according to area (slower)"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); nulls = flag.nulls->answer; method = find_method(parm.method->answer); if (method < 0) G_fatal_error(_("Unknown method <%s>"), parm.method->answer); if (menu[method].method == c_quant) { quantile = atoi(parm.quantile->answer); closure = &quantile; } G_get_set_window(&dst_w); /* set window to old map */ Rast_get_cellhd(parm.rastin->answer, "", &src_w); /* enlarge source window */ { int r0 = (int)floor(Rast_northing_to_row(dst_w.north, &src_w)); int r1 = (int)ceil(Rast_northing_to_row(dst_w.south, &src_w)); int c0 = (int)floor(Rast_easting_to_col(dst_w.west, &src_w)); int c1 = (int)ceil(Rast_easting_to_col(dst_w.east, &src_w)); src_w.south -= src_w.ns_res * (r1 - src_w.rows); src_w.north += src_w.ns_res * (-r0); src_w.west -= src_w.ew_res * (-c0); src_w.east += src_w.ew_res * (c1 - src_w.cols); src_w.rows = r1 - r0; src_w.cols = c1 - c0; } Rast_set_input_window(&src_w); Rast_set_output_window(&dst_w); row_scale = 2 + ceil(dst_w.ns_res / src_w.ns_res); col_scale = 2 + ceil(dst_w.ew_res / src_w.ew_res); /* allocate buffers for input rows */ bufs = G_malloc(row_scale * sizeof(DCELL *)); for (row = 0; row < row_scale; row++) bufs[row] = Rast_allocate_d_input_buf(); /* open old map */ infile = Rast_open_old(parm.rastin->answer, ""); /* allocate output buffer */ outbuf = Rast_allocate_d_output_buf(); /* open new map */ outfile = Rast_open_new(parm.rastout->answer, DCELL_TYPE); if (flag.weight->answer && menu[method].method_w) resamp_weighted(); else resamp_unweighted(); G_percent(dst_w.rows, dst_w.rows, 2); Rast_close(infile); Rast_close(outfile); /* record map metadata/history info */ sprintf(title, "Aggregate resample by %s", parm.method->answer); Rast_put_cell_title(parm.rastout->answer, title); Rast_short_history(parm.rastout->answer, "raster", &history); Rast_set_history(&history, HIST_DATSRC_1, parm.rastin->answer); G_format_resolution(src_w.ns_res, buf_nsres, src_w.proj); G_format_resolution(src_w.ew_res, buf_ewres, src_w.proj); Rast_format_history(&history, HIST_DATSRC_2, "Source map NS res: %s EW res: %s", buf_nsres, buf_ewres); Rast_command_history(&history); Rast_write_history(parm.rastout->answer, &history); /* copy color table from source map */ if (strcmp(parm.method->answer, "sum") != 0) { if (Rast_read_colors(parm.rastin->answer, "", &colors) < 0) G_fatal_error(_("Unable to read color table for %s"), parm.rastin->answer); Rast_mark_colors_as_fp(&colors); Rast_write_colors(parm.rastout->answer, G_mapset(), &colors); } return (EXIT_SUCCESS); }
static void resamp_weighted(void) { stat_func_w *method_fn; DCELL(*values)[2]; double *col_map, *row_map; int row, col; method_fn = menu[method].method_w; values = G_malloc(row_scale * col_scale * 2 * sizeof(DCELL)); col_map = G_malloc((dst_w.cols + 1) * sizeof(double)); row_map = G_malloc((dst_w.rows + 1) * sizeof(double)); for (col = 0; col <= dst_w.cols; col++) { double x = Rast_col_to_easting(col, &dst_w); col_map[col] = Rast_easting_to_col(x, &src_w); } for (row = 0; row <= dst_w.rows; row++) { double y = Rast_row_to_northing(row, &dst_w); row_map[row] = Rast_northing_to_row(y, &src_w); } for (row = 0; row < dst_w.rows; row++) { double y0 = row_map[row + 0]; double y1 = row_map[row + 1]; int maprow0 = (int)floor(y0); int maprow1 = (int)ceil(y1); int count = maprow1 - maprow0; int i; G_percent(row, dst_w.rows, 2); for (i = 0; i < count; i++) Rast_get_d_row(infile, bufs[i], maprow0 + i); for (col = 0; col < dst_w.cols; col++) { double x0 = col_map[col + 0]; double x1 = col_map[col + 1]; int mapcol0 = (int)floor(x0); int mapcol1 = (int)ceil(x1); int null = 0; int n = 0; int i, j; for (i = maprow0; i < maprow1; i++) { double ky = (i == maprow0) ? 1 - (y0 - maprow0) : (i == maprow1 - 1) ? 1 - (maprow1 - y1) : 1; for (j = mapcol0; j < mapcol1; j++) { double kx = (j == mapcol0) ? 1 - (x0 - mapcol0) : (j == mapcol1 - 1) ? 1 - (mapcol1 - x1) : 1; DCELL *src = &bufs[i - maprow0][j]; DCELL *dst = &values[n++][0]; if (Rast_is_d_null_value(src)) { Rast_set_d_null_value(&dst[0], 1); null = 1; } else { dst[0] = *src; dst[1] = kx * ky; } } } if (null && nulls) Rast_set_d_null_value(&outbuf[col], 1); else (*method_fn) (&outbuf[col], values, n, closure); } Rast_put_d_row(outfile, outbuf); } }
/*! * \brief Extract a cell value from raster map (cubic interpolation). * * Extract a cell value from raster map at given northing and easting * with a sampled 3x3 window using a cubic 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_cubic(int fd, const struct Cell_head * window, struct Categories * cats, double north, double east, int usedesc) { int i, j, row, col; double grid[4][4]; DCELL *rows[4]; double frow, fcol, trow, tcol; DCELL result; for (i = 0; i < 4; i++) rows[i] = Rast_allocate_d_buf(); 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 - 1.5); col = (int)floor(fcol - 1.5); trow = frow - row - 1.5; tcol = fcol - col - 1.5; if (row < 0 || row + 3 >= Rast_window_rows() || col < 0 || col + 3 >= Rast_window_cols()) { Rast_set_d_null_value(&result, 1); goto done; } for (i = 0; i < 4; i++) Rast_get_d_row(fd, rows[i], row + i); for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) if (Rast_is_d_null_value(&rows[i][col + j])) { Rast_set_d_null_value(&result, 1); goto done; } /* * now were ready to do cubic interpolation over * arow[col], arow[col+1], arow[col+2], arow[col+3], * brow[col], brow[col+1], brow[col+2], brow[col+3], * crow[col], crow[col+1], crow[col+2], crow[col+3], * drow[col], drow[col+1], drow[col+2], drow[col+3], */ if (usedesc) { char *buf; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { G_squeeze(buf = Rast_get_c_cat((CELL *) & (rows[i][col + j]), cats)); grid[i][j] = scancatlabel(buf); } } } else { for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) grid[i][j] = rows[i][col + j]; } result = Rast_interp_bicubic(tcol, trow, grid[0][0], grid[0][1], grid[0][2], grid[0][3], grid[1][0], grid[1][1], grid[1][2], grid[1][3], grid[2][0], grid[2][1], grid[2][2], grid[2][3], grid[3][0], grid[3][1], grid[3][2], grid[3][3]); done: for (i = 0; i < 4; i++) G_free(rows[i]); return result; }
/*! * \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; }
int main(int argc, char *argv[]) { char *terrainmap, *seedmap, *lakemap; int rows, cols, in_terran_fd, out_fd, lake_fd, row, col, pases, pass; int lastcount, curcount, start_col = 0, start_row = 0; double east, north, area = 0, volume = 0; FCELL **in_terran, **out_water, water_level, max_depth = 0, min_depth = 0; FCELL water_window[3][3]; struct Option *tmap_opt, *smap_opt, *wlvl_opt, *lake_opt, *sdxy_opt; struct Flag *negative_flag, *overwrite_flag; struct GModule *module; struct Colors colr; struct Cell_head window; struct History history; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("hydrology")); G_add_keyword(_("hazard")); G_add_keyword(_("flood")); module->description = _("Fills lake at given point to given level."); tmap_opt = G_define_standard_option(G_OPT_R_ELEV); wlvl_opt = G_define_option(); wlvl_opt->key = "water_level"; wlvl_opt->description = _("Water level"); wlvl_opt->type = TYPE_DOUBLE; wlvl_opt->required = YES; lake_opt = G_define_standard_option(G_OPT_R_OUTPUT); lake_opt->key = "lake"; lake_opt->required = NO; lake_opt->guisection = _("Output"); sdxy_opt = G_define_standard_option(G_OPT_M_COORDS); sdxy_opt->label = _("Seed point coordinates"); sdxy_opt->description = _("Either this coordinates pair or a seed" " map have to be specified"); sdxy_opt->required = NO; sdxy_opt->multiple = NO; sdxy_opt->guisection = _("Seed"); smap_opt = G_define_standard_option(G_OPT_R_MAP); smap_opt->key = "seed"; smap_opt->label = _("Input raster map with given starting point(s) (at least 1 cell > 0)"); smap_opt->description = _("Either this parameter or a coordinates pair have to be specified"); smap_opt->required = NO; smap_opt->guisection = _("Seed"); negative_flag = G_define_flag(); negative_flag->key = 'n'; negative_flag->description = _("Use negative depth values for lake raster map"); overwrite_flag = G_define_flag(); overwrite_flag->key = 'o'; overwrite_flag->description = _("Overwrite seed map with result (lake) map"); overwrite_flag->guisection = _("Output"); if (G_parser(argc, argv)) /* Returns 0 if successful, non-zero otherwise */ exit(EXIT_FAILURE); if (smap_opt->answer && sdxy_opt->answer) G_fatal_error(_("Both seed map and coordinates cannot be specified")); if (!smap_opt->answer && !sdxy_opt->answer) G_fatal_error(_("Seed map or seed coordinates must be set!")); if (sdxy_opt->answer && !lake_opt->answer) G_fatal_error(_("Seed coordinates and output map lake= must be set!")); if (lake_opt->answer && overwrite_flag->answer) G_fatal_error(_("Both lake and overwrite cannot be specified")); if (!lake_opt->answer && !overwrite_flag->answer) G_fatal_error(_("Output lake map or overwrite flag must be set!")); terrainmap = tmap_opt->answer; seedmap = smap_opt->answer; sscanf(wlvl_opt->answer, "%f", &water_level); lakemap = lake_opt->answer; /* If lakemap is set, write to it, else is set overwrite flag and we should write to seedmap. */ if (lakemap) lake_fd = Rast_open_new(lakemap, 1); rows = Rast_window_rows(); cols = Rast_window_cols(); /* If we use x,y as seed... */ if (sdxy_opt->answer) { G_get_window(&window); east = window.east; north = window.north; G_scan_easting(sdxy_opt->answers[0], &east, G_projection()); G_scan_northing(sdxy_opt->answers[1], &north, G_projection()); start_col = (int)Rast_easting_to_col(east, &window); start_row = (int)Rast_northing_to_row(north, &window); if (start_row < 0 || start_row > rows || start_col < 0 || start_col > cols) G_fatal_error(_("Seed point outside the current region")); } /* Open terrain map */ in_terran_fd = Rast_open_old(terrainmap, ""); /* Open seed map */ if (smap_opt->answer) out_fd = Rast_open_old(seedmap, ""); /* Pointers to rows. Row = ptr to 'col' size array. */ in_terran = (FCELL **) G_malloc(rows * sizeof(FCELL *)); out_water = (FCELL **) G_malloc(rows * sizeof(FCELL *)); if (in_terran == NULL || out_water == NULL) G_fatal_error(_("G_malloc: out of memory")); G_debug(1, "Loading maps..."); /* foo_rows[row] == array with data (2d array). */ for (row = 0; row < rows; row++) { in_terran[row] = (FCELL *) G_malloc(cols * sizeof(FCELL)); out_water[row] = (FCELL *) G_calloc(cols, sizeof(FCELL)); /* In newly created space load data from file. */ Rast_get_f_row(in_terran_fd, in_terran[row], row); if (smap_opt->answer) Rast_get_f_row(out_fd, out_water[row], row); G_percent(row + 1, rows, 5); } /* Set seed point */ if (sdxy_opt->answer) /* Check is water level higher than seed point */ if (in_terran[start_row][start_col] >= water_level) G_fatal_error(_("Given water level at seed point is below earth surface. " "Increase water level or move seed point.")); out_water[start_row][start_col] = 1; /* Close seed map for reading. */ if (smap_opt->answer) Rast_close(out_fd); /* Open output map for writing. */ if (lakemap) out_fd = lake_fd; else out_fd = Rast_open_new(seedmap, 1); /* More pases are renudant. Real pases count is controlled by altered cell count. */ pases = (int)(rows * cols) / 2; G_debug(1, "Starting lake filling at level of %8.4f in %d passes. Percent done:", water_level, pases); lastcount = 0; for (pass = 0; pass < pases; pass++) { G_debug(3, "Pass: %d", pass); curcount = 0; /* Move from left upper corner to right lower corner. */ for (row = 0; row < rows; row++) { for (col = 0; col < cols; col++) { /* Loading water data into window. */ load_window_values(out_water, water_window, rows, cols, row, col); /* Cheking presence of water. */ if (is_near_water(water_window) == 1) { if (in_terran[row][col] < water_level) { out_water[row][col] = water_level - in_terran[row][col]; curcount++; } else { out_water[row][col] = 0; /* Cell is higher than water level -> NULL. */ } } } } if (curcount == lastcount) break; /* We done. */ lastcount = curcount; curcount = 0; /* Move backwards - from lower right corner to upper left corner. */ for (row = rows - 1; row >= 0; row--) { for (col = cols - 1; col >= 0; col--) { load_window_values(out_water, water_window, rows, cols, row, col); if (is_near_water(water_window) == 1) { if (in_terran[row][col] < water_level) { out_water[row][col] = water_level - in_terran[row][col]; curcount++; } else { out_water[row][col] = 0; } } } } G_percent(pass + 1, pases, 10); if (curcount == lastcount) break; /* We done. */ lastcount = curcount; } /*pases */ G_percent(pases, pases, 10); /* Show 100%. */ save_map(out_water, out_fd, rows, cols, negative_flag->answer, &min_depth, &max_depth, &area, &volume); G_message(_("Lake depth from %f to %f (specified water level is taken as zero)"), min_depth, max_depth); G_message(_("Lake area %f square meters"), area); G_message(_("Lake volume %f cubic meters"), volume); G_important_message(_("Volume is correct only if lake depth (terrain raster map) is in meters")); /* Close all files. Lake map gets written only now. */ Rast_close(in_terran_fd); Rast_close(out_fd); /* Add blue color gradient from light bank to dark depth */ Rast_init_colors(&colr); if (negative_flag->answer == 1) { Rast_add_f_color_rule(&max_depth, 0, 240, 255, &min_depth, 0, 50, 170, &colr); } else { Rast_add_f_color_rule(&min_depth, 0, 240, 255, &max_depth, 0, 50, 170, &colr); } Rast_write_colors(lakemap, G_mapset(), &colr); Rast_short_history(lakemap, "raster", &history); Rast_command_history(&history); Rast_write_history(lakemap, &history); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { struct GModule *module; struct Option *rastin, *rastout, *method; struct History history; char title[64]; char buf_nsres[100], buf_ewres[100]; struct Colors colors; int infile, outfile; DCELL *outbuf; int row, col; struct Cell_head dst_w, src_w; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("resample")); module->description = _("Resamples raster map layers to a finer grid using interpolation."); rastin = G_define_standard_option(G_OPT_R_INPUT); rastout = G_define_standard_option(G_OPT_R_OUTPUT); method = G_define_option(); method->key = "method"; method->type = TYPE_STRING; method->required = NO; method->description = _("Interpolation method"); method->options = "nearest,bilinear,bicubic,lanczos"; method->answer = "bilinear"; if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (G_strcasecmp(method->answer, "nearest") == 0) neighbors = 1; else if (G_strcasecmp(method->answer, "bilinear") == 0) neighbors = 2; else if (G_strcasecmp(method->answer, "bicubic") == 0) neighbors = 4; else if (G_strcasecmp(method->answer, "lanczos") == 0) neighbors = 5; else G_fatal_error(_("Invalid method: %s"), method->answer); G_get_set_window(&dst_w); /* set window to old map */ Rast_get_cellhd(rastin->answer, "", &src_w); /* enlarge source window */ { double north = Rast_row_to_northing(0.5, &dst_w); double south = Rast_row_to_northing(dst_w.rows - 0.5, &dst_w); int r0 = (int)floor(Rast_northing_to_row(north, &src_w) - 0.5) - 2; int r1 = (int)floor(Rast_northing_to_row(south, &src_w) - 0.5) + 3; double west = Rast_col_to_easting(0.5, &dst_w); double east = Rast_col_to_easting(dst_w.cols - 0.5, &dst_w); int c0 = (int)floor(Rast_easting_to_col(west, &src_w) - 0.5) - 2; int c1 = (int)floor(Rast_easting_to_col(east, &src_w) - 0.5) + 3; src_w.south -= src_w.ns_res * (r1 - src_w.rows); src_w.north += src_w.ns_res * (-r0); src_w.west -= src_w.ew_res * (-c0); src_w.east += src_w.ew_res * (c1 - src_w.cols); src_w.rows = r1 - r0; src_w.cols = c1 - c0; } Rast_set_input_window(&src_w); /* allocate buffers for input rows */ for (row = 0; row < neighbors; row++) bufs[row] = Rast_allocate_d_input_buf(); cur_row = -100; /* open old map */ infile = Rast_open_old(rastin->answer, ""); /* reset window to current region */ Rast_set_output_window(&dst_w); outbuf = Rast_allocate_d_output_buf(); /* open new map */ outfile = Rast_open_new(rastout->answer, DCELL_TYPE); switch (neighbors) { case 1: /* nearest */ for (row = 0; row < dst_w.rows; row++) { double north = Rast_row_to_northing(row + 0.5, &dst_w); double maprow_f = Rast_northing_to_row(north, &src_w) - 0.5; int maprow0 = (int)floor(maprow_f + 0.5); G_percent(row, dst_w.rows, 2); read_rows(infile, maprow0); for (col = 0; col < dst_w.cols; col++) { double east = Rast_col_to_easting(col + 0.5, &dst_w); double mapcol_f = Rast_easting_to_col(east, &src_w) - 0.5; int mapcol0 = (int)floor(mapcol_f + 0.5); double c = bufs[0][mapcol0]; if (Rast_is_d_null_value(&c)) { Rast_set_d_null_value(&outbuf[col], 1); } else { outbuf[col] = c; } } Rast_put_d_row(outfile, outbuf); } break; case 2: /* bilinear */ for (row = 0; row < dst_w.rows; row++) { double north = Rast_row_to_northing(row + 0.5, &dst_w); double maprow_f = Rast_northing_to_row(north, &src_w) - 0.5; int maprow0 = (int)floor(maprow_f); double v = maprow_f - maprow0; G_percent(row, dst_w.rows, 2); read_rows(infile, maprow0); for (col = 0; col < dst_w.cols; col++) { double east = Rast_col_to_easting(col + 0.5, &dst_w); double mapcol_f = Rast_easting_to_col(east, &src_w) - 0.5; int mapcol0 = (int)floor(mapcol_f); int mapcol1 = mapcol0 + 1; double u = mapcol_f - mapcol0; double c00 = bufs[0][mapcol0]; double c01 = bufs[0][mapcol1]; double c10 = bufs[1][mapcol0]; double c11 = bufs[1][mapcol1]; if (Rast_is_d_null_value(&c00) || Rast_is_d_null_value(&c01) || Rast_is_d_null_value(&c10) || Rast_is_d_null_value(&c11)) { Rast_set_d_null_value(&outbuf[col], 1); } else { outbuf[col] = Rast_interp_bilinear(u, v, c00, c01, c10, c11); } } Rast_put_d_row(outfile, outbuf); } break; case 4: /* bicubic */ for (row = 0; row < dst_w.rows; row++) { double north = Rast_row_to_northing(row + 0.5, &dst_w); double maprow_f = Rast_northing_to_row(north, &src_w) - 0.5; int maprow1 = (int)floor(maprow_f); int maprow0 = maprow1 - 1; double v = maprow_f - maprow1; G_percent(row, dst_w.rows, 2); read_rows(infile, maprow0); for (col = 0; col < dst_w.cols; col++) { double east = Rast_col_to_easting(col + 0.5, &dst_w); double mapcol_f = Rast_easting_to_col(east, &src_w) - 0.5; int mapcol1 = (int)floor(mapcol_f); int mapcol0 = mapcol1 - 1; int mapcol2 = mapcol1 + 1; int mapcol3 = mapcol1 + 2; double u = mapcol_f - mapcol1; double c00 = bufs[0][mapcol0]; double c01 = bufs[0][mapcol1]; double c02 = bufs[0][mapcol2]; double c03 = bufs[0][mapcol3]; double c10 = bufs[1][mapcol0]; double c11 = bufs[1][mapcol1]; double c12 = bufs[1][mapcol2]; double c13 = bufs[1][mapcol3]; double c20 = bufs[2][mapcol0]; double c21 = bufs[2][mapcol1]; double c22 = bufs[2][mapcol2]; double c23 = bufs[2][mapcol3]; double c30 = bufs[3][mapcol0]; double c31 = bufs[3][mapcol1]; double c32 = bufs[3][mapcol2]; double c33 = bufs[3][mapcol3]; if (Rast_is_d_null_value(&c00) || Rast_is_d_null_value(&c01) || Rast_is_d_null_value(&c02) || Rast_is_d_null_value(&c03) || Rast_is_d_null_value(&c10) || Rast_is_d_null_value(&c11) || Rast_is_d_null_value(&c12) || Rast_is_d_null_value(&c13) || Rast_is_d_null_value(&c20) || Rast_is_d_null_value(&c21) || Rast_is_d_null_value(&c22) || Rast_is_d_null_value(&c23) || Rast_is_d_null_value(&c30) || Rast_is_d_null_value(&c31) || Rast_is_d_null_value(&c32) || Rast_is_d_null_value(&c33)) { Rast_set_d_null_value(&outbuf[col], 1); } else { outbuf[col] = Rast_interp_bicubic(u, v, c00, c01, c02, c03, c10, c11, c12, c13, c20, c21, c22, c23, c30, c31, c32, c33); } } Rast_put_d_row(outfile, outbuf); } break; case 5: /* lanczos */ for (row = 0; row < dst_w.rows; row++) { double north = Rast_row_to_northing(row + 0.5, &dst_w); double maprow_f = Rast_northing_to_row(north, &src_w) - 0.5; int maprow1 = (int)floor(maprow_f + 0.5); int maprow0 = maprow1 - 2; double v = maprow_f - maprow1; G_percent(row, dst_w.rows, 2); read_rows(infile, maprow0); for (col = 0; col < dst_w.cols; col++) { double east = Rast_col_to_easting(col + 0.5, &dst_w); double mapcol_f = Rast_easting_to_col(east, &src_w) - 0.5; int mapcol2 = (int)floor(mapcol_f + 0.5); int mapcol0 = mapcol2 - 2; int mapcol4 = mapcol2 + 2; double u = mapcol_f - mapcol2; double c[25]; int ci = 0, i, j, do_lanczos = 1; for (i = 0; i < 5; i++) { for (j = mapcol0; j <= mapcol4; j++) { c[ci] = bufs[i][j]; if (Rast_is_d_null_value(&(c[ci]))) { Rast_set_d_null_value(&outbuf[col], 1); do_lanczos = 0; break; } ci++; } if (!do_lanczos) break; } if (do_lanczos) { outbuf[col] = Rast_interp_lanczos(u, v, c); } } Rast_put_d_row(outfile, outbuf); } break; } G_percent(dst_w.rows, dst_w.rows, 2); Rast_close(infile); Rast_close(outfile); /* record map metadata/history info */ sprintf(title, "Resample by %s interpolation", method->answer); Rast_put_cell_title(rastout->answer, title); Rast_short_history(rastout->answer, "raster", &history); Rast_set_history(&history, HIST_DATSRC_1, rastin->answer); G_format_resolution(src_w.ns_res, buf_nsres, src_w.proj); G_format_resolution(src_w.ew_res, buf_ewres, src_w.proj); Rast_format_history(&history, HIST_DATSRC_2, "Source map NS res: %s EW res: %s", buf_nsres, buf_ewres); Rast_command_history(&history); Rast_write_history(rastout->answer, &history); /* copy color table from source map */ if (Rast_read_colors(rastin->answer, "", &colors) < 0) G_fatal_error(_("Unable to read color table for %s"), rastin->answer); Rast_mark_colors_as_fp(&colors); Rast_write_colors(rastout->answer, G_mapset(), &colors); return (EXIT_SUCCESS); }
int main(int argc, char *argv[]) { extern struct Cell_head window; union RASTER_PTR elevbuf, tmpbuf, outbuf; CELL min, max; DCELL dvalue, dvalue2, dmin, dmax; struct History hist; RASTER_MAP_TYPE data_type; struct Range range; struct FPRange fprange; double drow, dcol; int elev_fd, output_fd, zeros; struct { struct Option *opt1, *opt2, *opt3, *opt4, *north, *east, *year, *month, *day, *hour, *minutes, *seconds, *timezone; } parm; struct Flag *flag1, *flag3, *flag4; struct GModule *module; char *name, *outname; double dazi, dalti; double azi, alti; double nstep, estep; double maxh; double east, east1, north, north1; int row1, col1; char OK; double timezone; int year, month, day, hour, minutes, seconds; long retval; int solparms, locparms, use_solpos; double sunrise, sunset, current_time; int sretr = 0, ssetr = 0, sretr_sec = 0, ssetr_sec = 0; double dsretr, dssetr; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("sun position")); module->label = _("Calculates cast shadow areas from sun position and elevation raster map."); module->description = _("Either exact sun position (A) is specified, or date/time to calculate " "the sun position (B) by r.sunmask itself."); parm.opt1 = G_define_standard_option(G_OPT_R_ELEV); parm.opt2 = G_define_standard_option(G_OPT_R_OUTPUT); parm.opt2->required = NO; parm.opt3 = G_define_option(); parm.opt3->key = "altitude"; parm.opt3->type = TYPE_DOUBLE; parm.opt3->required = NO; parm.opt3->options = "0-89.999"; parm.opt3->description = _("Altitude of the sun above horizon, degrees (A)"); parm.opt3->guisection = _("Position"); parm.opt4 = G_define_option(); parm.opt4->key = "azimuth"; parm.opt4->type = TYPE_DOUBLE; parm.opt4->required = NO; parm.opt4->options = "0-360"; parm.opt4->description = _("Azimuth of the sun from the north, degrees (A)"); parm.opt4->guisection = _("Position"); parm.year = G_define_option(); parm.year->key = "year"; parm.year->type = TYPE_INTEGER; parm.year->required = NO; parm.year->description = _("Year (B)"); parm.year->options = "1950-2050"; parm.year->guisection = _("Time"); parm.month = G_define_option(); parm.month->key = "month"; parm.month->type = TYPE_INTEGER; parm.month->required = NO; parm.month->description = _("Month (B)"); parm.month->options = "0-12"; parm.month->guisection = _("Time"); parm.day = G_define_option(); parm.day->key = "day"; parm.day->type = TYPE_INTEGER; parm.day->required = NO; parm.day->description = _("Day (B)"); parm.day->options = "0-31"; parm.day->guisection = _("Time"); parm.hour = G_define_option(); parm.hour->key = "hour"; parm.hour->type = TYPE_INTEGER; parm.hour->required = NO; parm.hour->description = _("Hour (B)"); parm.hour->options = "0-24"; parm.hour->guisection = _("Time"); parm.minutes = G_define_option(); parm.minutes->key = "minute"; parm.minutes->type = TYPE_INTEGER; parm.minutes->required = NO; parm.minutes->description = _("Minutes (B)"); parm.minutes->options = "0-60"; parm.minutes->guisection = _("Time"); parm.seconds = G_define_option(); parm.seconds->key = "second"; parm.seconds->type = TYPE_INTEGER; parm.seconds->required = NO; parm.seconds->description = _("Seconds (B)"); parm.seconds->options = "0-60"; parm.seconds->guisection = _("Time"); parm.timezone = G_define_option(); parm.timezone->key = "timezone"; parm.timezone->type = TYPE_INTEGER; parm.timezone->required = NO; parm.timezone->label = _("Timezone"); parm.timezone->description = _("East positive, offset from GMT, also use to adjust daylight savings"); parm.timezone->guisection = _("Time"); parm.east = G_define_option(); parm.east->key = "east"; parm.east->key_desc = "value"; parm.east->type = TYPE_STRING; parm.east->required = NO; parm.east->label = _("Easting coordinate (point of interest)"); parm.east->description = _("Default: map center"); parm.east->guisection = _("Position"); parm.north = G_define_option(); parm.north->key = "north"; parm.north->key_desc = "value"; parm.north->type = TYPE_STRING; parm.north->required = NO; parm.north->label = _("Northing coordinate (point of interest)"); parm.north->description = _("Default: map center"); parm.north->guisection = _("Position"); flag1 = G_define_flag(); flag1->key = 'z'; flag1->description = _("Don't ignore zero elevation"); flag3 = G_define_flag(); flag3->key = 's'; flag3->description = _("Calculate sun position only and exit"); flag3->guisection = _("Print"); flag4 = G_define_flag(); flag4->key = 'g'; flag4->description = _("Print the sun position output in shell script style"); flag4->guisection = _("Print"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); zeros = flag1->answer; G_get_window(&window); /* if not given, get east and north: XX */ if (!parm.north->answer || !parm.east->answer) { north = (window.north - window.south) / 2. + window.south; east = (window.west - window.east) / 2. + window.east; G_verbose_message(_("Using map center coordinates: %f %f"), east, north); } else { /* user defined east, north: */ sscanf(parm.north->answer, "%lf", &north); sscanf(parm.east->answer, "%lf", &east); if (strlen(parm.east->answer) == 0) G_fatal_error(_("Empty east coordinate specified")); if (strlen(parm.north->answer) == 0) G_fatal_error(_("Empty north coordinate specified")); } /* check which method to use for sun position: either user defines directly sun position or it is calculated */ if (parm.opt3->answer && parm.opt4->answer) solparms = 1; /* opt3 & opt4 complete */ else solparms = 0; /* calculate sun position */ if (parm.year->answer && parm.month->answer && parm.day->answer && parm.hour->answer && parm.minutes->answer && parm.seconds->answer && parm.timezone->answer) locparms = 1; /* complete */ else locparms = 0; if (solparms && locparms) /* both defined */ G_fatal_error(_("Either define sun position or location/date/time parameters")); if (!solparms && !locparms) /* nothing defined */ G_fatal_error(_("Neither sun position nor east/north, date/time/timezone definition are complete")); /* if here, one definition was complete */ if (locparms) { G_message(_("Calculating sun position... (using solpos (V. %s) from NREL)"), SOLPOSVERSION); use_solpos = 1; } else { G_message(_("Using user defined sun azimuth, altitude settings (ignoring eventual other values)")); use_solpos = 0; } name = parm.opt1->answer; outname = parm.opt2->answer; if (!use_solpos) { sscanf(parm.opt3->answer, "%lf", &dalti); sscanf(parm.opt4->answer, "%lf", &dazi); } else { sscanf(parm.year->answer, "%i", &year); sscanf(parm.month->answer, "%i", &month); sscanf(parm.day->answer, "%i", &day); sscanf(parm.hour->answer, "%i", &hour); sscanf(parm.minutes->answer, "%i", &minutes); sscanf(parm.seconds->answer, "%i", &seconds); sscanf(parm.timezone->answer, "%lf", &timezone); } /* NOTES: G_calc_solar_position () - the algorithm will compensate for leap year. - longitude, latitude: decimal degree - timezone: DO NOT ADJUST FOR DAYLIGHT SAVINGS TIME. - timezone: negative for zones west of Greenwich - lat/long: east and north positive - the atmospheric refraction is calculated for 1013hPa, 15�C - time: local time from your watch Order of parameters: long, lat, timezone, year, month, day, hour, minutes, seconds */ if (use_solpos) { G_debug(3, "\nlat:%f long:%f", north, east); retval = calc_solar_position(east, north, timezone, year, month, day, hour, minutes, seconds); /* Remove +0.5 above if you want round-down instead of round-to-nearest */ sretr = (int)floor(pdat->sretr); /* sunrise */ dsretr = pdat->sretr; sretr_sec = (int) floor(((dsretr - floor(dsretr)) * 60 - floor((dsretr - floor(dsretr)) * 60)) * 60); ssetr = (int)floor(pdat->ssetr); /* sunset */ dssetr = pdat->ssetr; ssetr_sec = (int) floor(((dssetr - floor(dssetr)) * 60 - floor((dssetr - floor(dssetr)) * 60)) * 60); /* print the results */ if (retval == 0) { /* error check */ if (flag3->answer) { if (flag4->answer) { fprintf(stdout, "date=%d/%02d/%02d\n", pdat->year, pdat->month, pdat->day); fprintf(stdout, "daynum=%d\n", pdat->daynum); fprintf(stdout, "time=%02i:%02i:%02i\n", pdat->hour, pdat->minute, pdat->second); fprintf(stdout, "decimaltime=%f\n", pdat->hour + (pdat->minute * 100.0 / 60.0 + pdat->second * 100.0 / 3600.0) / 100.); fprintf(stdout, "longitudine=%f\n", pdat->longitude); fprintf(stdout, "latitude=%f\n", pdat->latitude); fprintf(stdout, "timezone=%f\n", pdat->timezone); fprintf(stdout, "sunazimuth=%f\n", pdat->azim); fprintf(stdout, "sunangleabovehorizon=%f\n", pdat->elevref); if (sretr / 60 <= 24.0) { fprintf(stdout, "sunrise=%02d:%02d:%02d\n", sretr / 60, sretr % 60, sretr_sec); fprintf(stdout, "sunset=%02d:%02d:%02d\n", ssetr / 60, ssetr % 60, ssetr_sec); } } else { fprintf(stdout, "%d/%02d/%02d, daynum: %d, time: %02i:%02i:%02i (decimal time: %f)\n", pdat->year, pdat->month, pdat->day, pdat->daynum, pdat->hour, pdat->minute, pdat->second, pdat->hour + (pdat->minute * 100.0 / 60.0 + pdat->second * 100.0 / 3600.0) / 100.); fprintf(stdout, "long: %f, lat: %f, timezone: %f\n", pdat->longitude, pdat->latitude, pdat->timezone); fprintf(stdout, "Solar position: sun azimuth: %f, sun angle above horz. (refraction corrected): %f\n", pdat->azim, pdat->elevref); if (sretr / 60 <= 24.0) { fprintf(stdout, "Sunrise time (without refraction): %02d:%02d:%02d\n", sretr / 60, sretr % 60, sretr_sec); fprintf(stdout, "Sunset time (without refraction): %02d:%02d:%02d\n", ssetr / 60, ssetr % 60, ssetr_sec); } } } sunrise = pdat->sretr / 60.; /* decimal minutes */ sunset = pdat->ssetr / 60.; current_time = pdat->hour + (pdat->minute / 60.) + (pdat->second / 3600.); } else /* fatal error in G_calc_solar_position() */ G_fatal_error(_("Please correct settings")); } if (use_solpos) { dalti = pdat->elevref; dazi = pdat->azim; } /* otherwise already defined */ /* check sunrise */ if (use_solpos) { G_debug(3, "current_time:%f sunrise:%f", current_time, sunrise); if ((current_time < sunrise)) { if (sretr / 60 <= 24.0) G_message(_("Time (%02i:%02i:%02i) is before sunrise (%02d:%02d:%02d)"), pdat->hour, pdat->minute, pdat->second, sretr / 60, sretr % 60, sretr_sec); else G_message(_("Time (%02i:%02i:%02i) is before sunrise"), pdat->hour, pdat->minute, pdat->second); G_warning(_("Nothing to calculate. Please verify settings.")); } if ((current_time > sunset)) { if (sretr / 60 <= 24.0) G_message(_("Time (%02i:%02i:%02i) is after sunset (%02d:%02d:%02d)"), pdat->hour, pdat->minute, pdat->second, ssetr / 60, ssetr % 60, ssetr_sec); else G_message(_("Time (%02i:%02i:%02i) is after sunset"), pdat->hour, pdat->minute, pdat->second); G_warning(_("Nothing to calculate. Please verify settings.")); } } if (flag3->answer && (use_solpos == 1)) { /* we only want the sun position */ exit(EXIT_SUCCESS); } else if (flag3->answer && (use_solpos == 0)) { /* are you joking ? */ G_message(_("You already know the sun position")); exit(EXIT_SUCCESS); } if (!outname) G_fatal_error(_("Option <%s> required"), parm.opt2->key); elev_fd = Rast_open_old(name, ""); output_fd = Rast_open_c_new(outname); data_type = Rast_get_map_type(elev_fd); elevbuf.v = Rast_allocate_buf(data_type); tmpbuf.v = Rast_allocate_buf(data_type); outbuf.v = Rast_allocate_buf(CELL_TYPE); /* binary map */ if (data_type == CELL_TYPE) { if ((Rast_read_range(name, "", &range)) < 0) G_fatal_error(_("Unable to open range file for raster map <%s>"), name); Rast_get_range_min_max(&range, &min, &max); dmin = (double)min; dmax = (double)max; } else { Rast_read_fp_range(name, "", &fprange); Rast_get_fp_range_min_max(&fprange, &dmin, &dmax); } azi = 2 * M_PI * dazi / 360; alti = 2 * M_PI * dalti / 360; nstep = cos(azi) * window.ns_res; estep = sin(azi) * window.ew_res; row1 = 0; G_message(_("Calculating shadows from DEM...")); while (row1 < window.rows) { G_percent(row1, window.rows, 2); col1 = 0; drow = -1; Rast_get_row(elev_fd, elevbuf.v, row1, data_type); while (col1 < window.cols) { dvalue = raster_value(elevbuf, data_type, col1); /* outbuf.c[col1]=1; */ Rast_set_null_value(&outbuf.c[col1], 1, CELL_TYPE); OK = 1; east = Rast_col_to_easting(col1 + 0.5, &window); north = Rast_row_to_northing(row1 + 0.5, &window); east1 = east; north1 = north; if (dvalue == 0.0 && !zeros) OK = 0; while (OK == 1) { east += estep; north += nstep; if (north > window.north || north < window.south || east > window.east || east < window.west) OK = 0; else { maxh = tan(alti) * sqrt((north1 - north) * (north1 - north) + (east1 - east) * (east1 - east)); if ((maxh) > (dmax - dvalue)) OK = 0; else { dcol = Rast_easting_to_col(east, &window); if (drow != Rast_northing_to_row(north, &window)) { drow = Rast_northing_to_row(north, &window); Rast_get_row(elev_fd, tmpbuf.v, (int)drow, data_type); } dvalue2 = raster_value(tmpbuf, data_type, (int)dcol); if ((dvalue2 - dvalue) > (maxh)) { OK = 0; outbuf.c[col1] = 1; } } } } G_debug(3, "Analysing col %i", col1); col1 += 1; } G_debug(3, "Writing result row %i of %i", row1, window.rows); Rast_put_row(output_fd, outbuf.c, CELL_TYPE); row1 += 1; } G_percent(1, 1, 1); Rast_close(output_fd); Rast_close(elev_fd); /* writing history file */ Rast_short_history(outname, "raster", &hist); Rast_format_history(&hist, HIST_DATSRC_1, "raster elevation map %s", name); Rast_command_history(&hist); Rast_write_history(outname, &hist); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { struct GModule *module; struct Option *map, *profile; struct Flag *stored; struct Cell_head window; struct point *points = NULL; int num_points, max_points = 0; double length; double t, b, l, r; int fd; int i; double sx; int last; /* Initialize the GIS calls */ G_gisinit(argv[0]); /* Set description */ module = G_define_module(); G_add_keyword(_("display")); G_add_keyword(_("profile")); G_add_keyword(_("raster")); module->description = _("Plots profile of a transect."); /* set up command line */ map = G_define_standard_option(G_OPT_R_INPUT); map->description = _("Raster map to be profiled"); profile = G_define_option(); profile->key = "profile"; profile->type = TYPE_DOUBLE; profile->required = YES; profile->multiple = YES; profile->key_desc = "east,north"; profile->description = _("Profile coordinate pairs"); stored = G_define_flag(); stored->key = 'r'; stored->description = _("Use map's range recorded range"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); mapname = map->answer; fd = Rast_open_old(mapname, ""); if (stored->answer) get_map_range(); else get_region_range(fd); G_get_window(&window); num_points = 0; length = 0; for (i = 0; profile->answers[i]; i += 2) { struct point *p; double x, y; if (num_points >= max_points) { max_points = num_points + 100; points = G_realloc(points, max_points * sizeof(struct point)); } p = &points[num_points]; G_scan_easting( profile->answers[i+0], &x, G_projection()); G_scan_northing(profile->answers[i+1], &y, G_projection()); p->x = Rast_easting_to_col (x, &window); p->y = Rast_northing_to_row(y, &window); if (num_points > 0) { const struct point *prev = &points[num_points-1]; double dx = fabs(p->x - prev->x); double dy = fabs(p->y - prev->y); double d = sqrt(dx * dx + dy * dy); length += d; p->d = length; } num_points++; } points[0].d = 0; if (num_points < 2) G_fatal_error(_("At least two points are required")); /* establish connection with graphics driver */ if (D_open_driver() != 0) G_fatal_error(_("No graphics device selected. " "Use d.mon to select graphics device.")); D_setup2(1, 0, 1.05, -0.05, -0.15, 1.05); plot_axes(); D_use_color(D_translate_color(DEFAULT_FG_COLOR)); D_get_src(&t, &b, &l, &r); t -= 0.1 * (t - b); b += 0.1 * (t - b); l += 0.1 * (r - l); r -= 0.1 * (r - l); D_begin(); i = 0; last = 0; for (sx = 0; sx < 1; sx += D_get_d_to_u_xconv()) { double d = length * (sx - l); const struct point *p, *next; double k, sy, x, y; DCELL v; for (;;) { p = &points[i]; next = &points[i + 1]; k = (d - p->d) / (next->d - p->d); if (k < 1) break; i++; } x = p->x * (1 - k) + next->x * k; y = p->y * (1 - k) + next->y * k; if (!get_cell(&v, fd, x, y)) { last = 0; continue; } sy = (v - min) / (max - min); if (last) D_cont_abs(sx, sy); else D_move_abs(sx, sy); last = 1; } D_end(); D_stroke(); D_close_driver(); exit(EXIT_SUCCESS); }
/* *************************************************************** */ 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); }
/*--------------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { /* Variables' declarations */ int row, nrows, col, ncols, MaxPoints; int nsubregion_col, nsubregion_row; int subregion = 0, nsubregions = 0; int last_row, last_column; int nlines, nlines_first, line_num; int more; int clas, region = TRUE; double Z_interp; double Thres_j, Thres_d, ew_resol, ns_resol; double minNS, minEW, maxNS, maxEW; const char *mapset; char buf[1024], table_name[GNAME_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; int colorBordo, ripieno, conta, lungPunti, lungHull, xi, c1, c2; double altPiano; extern double **P, **cvxHull, **punti_bordo; /* Struct declarations */ struct Cell_head elaboration_reg, original_reg; struct element_grow **raster_matrix; struct Map_info In, Out, First; struct Option *in_opt, *out_opt, *first_opt, *Thres_j_opt, *Thres_d_opt; struct GModule *module; struct line_pnts *points, *points_first; struct line_cats *Cats, *Cats_first; struct field_info *field; dbDriver *driver; dbString sql; dbTable *table; dbCursor cursor; /*------------------------------------------------------------------------------------------*/ /* Options' declaration */ ; module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("LIDAR")); module->description = _("Building contour determination and Region Growing " "algorithm for determining the building inside"); in_opt = G_define_standard_option(G_OPT_V_INPUT); in_opt->description = _("Input vector (v.lidar.edgedetection output"); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); first_opt = G_define_option(); first_opt->key = "first"; first_opt->type = TYPE_STRING; first_opt->key_desc = "name"; first_opt->required = YES; first_opt->gisprompt = "old,vector,vector"; first_opt->description = _("Name of the first pulse vector map"); Thres_j_opt = G_define_option(); Thres_j_opt->key = "tj"; Thres_j_opt->type = TYPE_DOUBLE; Thres_j_opt->required = NO; Thres_j_opt->description = _("Threshold for cell object frequency in region growing"); Thres_j_opt->answer = "0.2"; Thres_d_opt = G_define_option(); Thres_d_opt->key = "td"; Thres_d_opt->type = TYPE_DOUBLE; Thres_d_opt->required = NO; Thres_d_opt->description = _("Threshold for double pulse in region growing"); Thres_d_opt->answer = "0.6"; /* Parsing */ G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); Thres_j = atof(Thres_j_opt->answer); Thres_d = atof(Thres_d_opt->answer); Thres_j += 1; /* Open input vector */ Vect_check_input_output_name(in_opt->answer, out_opt->answer, GV_FATAL_EXIT); if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) { G_fatal_error(_("Vector map <%s> not found"), in_opt->answer); } /* Setting auxiliar table's name */ if (G_name_is_fully_qualified(in_opt->answer, xname, xmapset)) { sprintf(table_name, "%s_edge_Interpolation", xname); } else sprintf(table_name, "%s_edge_Interpolation", in_opt->answer); Vect_set_open_level(1); /* WITHOUT TOPOLOGY */ if (Vect_open_old(&In, in_opt->answer, mapset) < 1) G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer); Vect_set_open_level(1); /* WITHOUT TOPOLOGY */ if (Vect_open_old(&First, first_opt->answer, mapset) < 1) G_fatal_error(_("Unable to open vector map <%s>"), first_opt->answer); /* Open output vector */ if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) { Vect_close(&In); Vect_close(&First); exit(EXIT_FAILURE); } /* Copy vector Head File */ Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); /* Starting driver and open db for edgedetection interpolation table */ field = Vect_get_field(&In, F_INTERPOLATION); /*if (field == NULL) G_fatal_error (_("Cannot read field info")); */ driver = db_start_driver_open_database(field->driver, field->database); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), field->driver); /* is this the right place to open the cursor ??? */ db_init_string(&sql); db_zero_string(&sql); sprintf(buf, "SELECT Interp,ID FROM %s", table_name); G_debug(1, "buf: %s", buf); db_append_string(&sql, buf); if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) G_fatal_error(_("Unable to open table <%s>"), table_name); count_obj = 1; /* no topology, get number of lines in input vector */ nlines = 0; points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); Vect_rewind(&In); while (Vect_read_next_line(&In, points, Cats) > 0) { nlines++; } Vect_rewind(&In); /* no topology, get number of lines in first pulse input vector */ nlines_first = 0; points_first = Vect_new_line_struct(); Cats_first = Vect_new_cats_struct(); Vect_rewind(&First); while (Vect_read_next_line(&First, points_first, Cats_first) > 0) { nlines_first++; } Vect_rewind(&First); /* Setting regions and boxes */ G_debug(1, _("Setting regions and boxes")); G_get_set_window(&original_reg); G_get_set_window(&elaboration_reg); /* Fixing parameters of the elaboration region */ /*! The original_region will be divided into subregions */ ew_resol = original_reg.ew_res; ns_resol = original_reg.ns_res; /* calculate number of subregions */ nsubregion_col = ceil((original_reg.east - original_reg.west) / (LATO * ew_resol)) + 0.5; nsubregion_row = ceil((original_reg.north - original_reg.south) / (LATO * ns_resol)) + 0.5; if (nsubregion_col < 0) nsubregion_col = 0; if (nsubregion_row < 0) nsubregion_row = 0; nsubregions = nsubregion_row * nsubregion_col; /* Subdividing and working with tiles */ elaboration_reg.south = original_reg.north; last_row = FALSE; while (last_row == FALSE) { /* For each strip of LATO rows */ elaboration_reg.north = elaboration_reg.south; if (elaboration_reg.north > original_reg.north) /* First row */ elaboration_reg.north = original_reg.north; elaboration_reg.south = elaboration_reg.north - LATO * ns_resol; if (elaboration_reg.south <= original_reg.south) { /* Last row */ elaboration_reg.south = original_reg.south; last_row = TRUE; } elaboration_reg.east = original_reg.west; last_column = FALSE; while (last_column == FALSE) { /* For each strip of LATO columns */ struct bound_box elaboration_box; subregion++; if (nsubregions > 1) G_message(_("subregion %d of %d"), subregion, nsubregions); elaboration_reg.west = elaboration_reg.east; if (elaboration_reg.west < original_reg.west) /* First column */ elaboration_reg.west = original_reg.west; elaboration_reg.east = elaboration_reg.west + LATO * ew_resol; if (elaboration_reg.east >= original_reg.east) { /* Last column */ elaboration_reg.east = original_reg.east; last_column = TRUE; } /* Setting the active region */ elaboration_reg.ns_res = ns_resol; elaboration_reg.ew_res = ew_resol; nrows = (elaboration_reg.north - elaboration_reg.south) / ns_resol + 0.1; ncols = (elaboration_reg.east - elaboration_reg.west) / ew_resol + 0.1; elaboration_reg.rows = nrows; elaboration_reg.cols = ncols; G_debug(1, _("Rows = %d"), nrows); G_debug(1, _("Columns = %d"), ncols); raster_matrix = structMatrix(0, nrows, 0, ncols); MaxPoints = nrows * ncols; /* Initializing matrix */ for (row = 0; row <= nrows; row++) { for (col = 0; col <= ncols; col++) { raster_matrix[row][col].interp = 0; raster_matrix[row][col].fi = 0; raster_matrix[row][col].bordo = 0; raster_matrix[row][col].dueImp = SINGLE_PULSE; raster_matrix[row][col].orig = 0; raster_matrix[row][col].fo = 0; raster_matrix[row][col].clas = PRE_TERRAIN; raster_matrix[row][col].fc = 0; raster_matrix[row][col].obj = 0; } } G_verbose_message(_("read points in input vector")); Vect_region_box(&elaboration_reg, &elaboration_box); line_num = 0; Vect_rewind(&In); while (Vect_read_next_line(&In, points, Cats) > 0) { line_num++; if ((Vect_point_in_box (points->x[0], points->y[0], points->z[0], &elaboration_box)) && ((points->x[0] != elaboration_reg.west) || (points->x[0] == original_reg.west)) && ((points->y[0] != elaboration_reg.north) || (points->y[0] == original_reg.north))) { row = (int)(Rast_northing_to_row (points->y[0], &elaboration_reg)); col = (int)(Rast_easting_to_col (points->x[0], &elaboration_reg)); Z_interp = 0; /* TODO: make sure the current db_fetch() usage works */ /* why not: */ /* db_init_string(&sql); sprintf(buf, "SELECT Interp,ID FROM %s WHERE ID=%d", table_name, line_num); db_append_string(&sql, buf); if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) G_fatal_error(_("Unable to open table <%s>"), table_name); while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) { dbColumn *Z_Interp_col; dbValue *Z_Interp_value; table = db_get_cursor_table(&cursor); Z_Interp_col = db_get_table_column(table, 1); if (db_sqltype_to_Ctype(db_get_column_sqltype(Z_Interp_col)) == DB_C_TYPE_DOUBLE) Z_Interp_value = db_get_column_value(Z_Interp_col); else continue; Z_interp = db_get_value_double(Z_Interp_value); break; } db_close_cursor(&cursor); db_free_string(&sql); */ /* instead of */ while (1) { if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK || !more) break; dbColumn *Z_Interp_col, *ID_col; dbValue *Z_Interp_value, *ID_value; table = db_get_cursor_table(&cursor); ID_col = db_get_table_column(table, 1); if (db_sqltype_to_Ctype(db_get_column_sqltype(ID_col)) == DB_C_TYPE_INT) ID_value = db_get_column_value(ID_col); else continue; if (db_get_value_int(ID_value) == line_num) { Z_Interp_col = db_get_table_column(table, 0); if (db_sqltype_to_Ctype (db_get_column_sqltype(Z_Interp_col)) == DB_C_TYPE_DOUBLE) Z_Interp_value = db_get_column_value(Z_Interp_col); else continue; Z_interp = db_get_value_double(Z_Interp_value); break; } } raster_matrix[row][col].interp += Z_interp; raster_matrix[row][col].fi++; /*if (( clas = Vect_get_line_cat (&In, line_num, F_EDGE_DETECTION_CLASS) ) != UNKNOWN_EDGE) { */ if (Vect_cat_get(Cats, F_EDGE_DETECTION_CLASS, &clas)) { raster_matrix[row][col].clas += clas; raster_matrix[row][col].fc++; } raster_matrix[row][col].orig += points->z[0]; raster_matrix[row][col].fo++; } Vect_reset_cats(Cats); Vect_reset_line(points); } for (row = 0; row <= nrows; row++) { for (col = 0; col <= ncols; col++) { if (raster_matrix[row][col].fc != 0) { raster_matrix[row][col].clas--; raster_matrix[row][col]. clas /= raster_matrix[row][col].fc; } if (raster_matrix[row][col].fi != 0) raster_matrix[row][col]. interp /= raster_matrix[row][col].fi; if (raster_matrix[row][col].fo != 0) raster_matrix[row][col]. orig /= raster_matrix[row][col].fo; } } /* DOUBLE IMPULSE */ Vect_rewind(&First); while (Vect_read_next_line(&First, points_first, Cats_first) > 0) { if ((Vect_point_in_box (points_first->x[0], points_first->y[0], points_first->z[0], &elaboration_box)) && ((points->x[0] != elaboration_reg.west) || (points->x[0] == original_reg.west)) && ((points->y[0] != elaboration_reg.north) || (points->y[0] == original_reg.north))) { row = (int)(Rast_northing_to_row (points_first->y[0], &elaboration_reg)); col = (int)(Rast_easting_to_col (points_first->x[0], &elaboration_reg)); if (fabs (points_first->z[0] - raster_matrix[row][col].orig) >= Thres_d) raster_matrix[row][col].dueImp = DOUBLE_PULSE; } Vect_reset_cats(Cats_first); Vect_reset_line(points_first); } /* REGION GROWING */ if (region == TRUE) { G_verbose_message(_("Region Growing")); punti_bordo = G_alloc_matrix(MaxPoints, 3); P = Pvector(0, MaxPoints); colorBordo = 5; ripieno = 6; for (row = 0; row <= nrows; row++) { G_percent(row, nrows, 2); for (col = 0; col <= ncols; col++) { if ((raster_matrix[row][col].clas >= Thres_j) && (raster_matrix[row][col].clas < colorBordo) && (raster_matrix[row][col].fi != 0) && (raster_matrix[row][col].dueImp == SINGLE_PULSE)) { /* Selecting a connected Object zone */ ripieno++; if (ripieno > 10) ripieno = 6; /* Selecting points on a connected edge */ for (conta = 0; conta < MaxPoints; conta++) { punti_bordo[conta][0] = 0; punti_bordo[conta][1] = 0; punti_bordo[conta][2] = 0; P[conta] = punti_bordo[conta]; /* It only makes indexes to be equal, not coord values!! */ } lungPunti = 0; lungHull = 0; regGrow8(elaboration_reg, raster_matrix, punti_bordo, &lungPunti, row, col, colorBordo, Thres_j, MaxPoints); /* CONVEX-HULL COMPUTATION */ lungHull = ch2d(P, lungPunti); cvxHull = G_alloc_matrix(lungHull, 3); for (xi = 0; xi < lungHull; xi++) { cvxHull[xi][0] = P[xi][0]; cvxHull[xi][1] = P[xi][1]; cvxHull[xi][2] = P[xi][2]; } /* Computes the interpoling plane based only on Object points */ altPiano = pianOriz(punti_bordo, lungPunti, &minNS, &minEW, &maxNS, &maxEW, raster_matrix, colorBordo); for (c1 = minNS; c1 <= maxNS; c1++) { for (c2 = minEW; c2 <= maxEW; c2++) { if (checkHull(c1, c2, cvxHull, lungHull) == 1) { raster_matrix[c1][c2].obj = count_obj; if ((raster_matrix[c1][c2].clas == PRE_TERRAIN) && (raster_matrix[c1][c2].orig >= altPiano) && (lungHull > 3)) raster_matrix[c1][c2].clas = ripieno; } } } G_free_matrix(cvxHull); count_obj++; } } } G_free_matrix(punti_bordo); free_Pvector(P, 0, MaxPoints); } /* WRITING THE OUTPUT VECTOR CATEGORIES */ Vect_rewind(&In); while (Vect_read_next_line(&In, points, Cats) > 0) { /* Read every line for buffering points */ if ((Vect_point_in_box (points->x[0], points->y[0], points->z[0], &elaboration_box)) && ((points->x[0] != elaboration_reg.west) || (points->x[0] == original_reg.west)) && ((points->y[0] != elaboration_reg.north) || (points->y[0] == original_reg.north))) { row = (int)(Rast_northing_to_row (points->y[0], &elaboration_reg)); col = (int)(Rast_easting_to_col (points->x[0], &elaboration_reg)); if (raster_matrix[row][col].clas == PRE_TERRAIN) { if (raster_matrix[row][col].dueImp == SINGLE_PULSE) Vect_cat_set(Cats, F_CLASSIFICATION, TERRAIN_SINGLE); else Vect_cat_set(Cats, F_CLASSIFICATION, TERRAIN_DOUBLE); } else { if (raster_matrix[row][col].dueImp == SINGLE_PULSE) Vect_cat_set(Cats, F_CLASSIFICATION, OBJECT_SINGLE); else Vect_cat_set(Cats, F_CLASSIFICATION, OBJECT_DOUBLE); } Vect_cat_set(Cats, F_COUNTER_OBJ, raster_matrix[row][col].obj); Vect_write_line(&Out, GV_POINT, points, Cats); } Vect_reset_cats(Cats); Vect_reset_line(points); } free_structmatrix(raster_matrix, 0, nrows - 1, 0, ncols - 1); } /*! END WHILE; last_column = TRUE */ } /*! END WHILE; last_row = TRUE */ Vect_close(&In); Vect_close(&First); Vect_close(&Out); db_close_database_shutdown_driver(driver); G_done_msg(" "); exit(EXIT_SUCCESS); }