double distance(double east, double west) { double incr; double meters; double e1, e2; /* calculate the distance from east edge to west edge at north==0.0 * for lat-lon this will be along equator. For other databases the * north value will make no difference * * Note, must do lat-lon in 3 pieces, otherwise distance "line" may * go the wrong way around the globe */ G_begin_distance_calculations(); if (east < west) { double temp; temp = east; east = west; west = temp; } incr = (east - west) / 3.0; e1 = west + incr; e2 = e1 + incr; meters = G_distance(west, 0.0, e1, 0.0) + G_distance(e1, 0.0, e2, 0.0) + G_distance(e2, 0.0, east, 0.0); return meters; }
/*! \brief Calculate line length. If projection is LL, the length is measured along the geodesic. \param Points pointer to line_pnts structure geometry \return line length */ double Vect_line_geodesic_length(const struct line_pnts *Points) { int j, dc; double dx, dy, dz, dxy, len = 0; dc = G_begin_distance_calculations(); if (Points->n_points < 2) return 0; for (j = 0; j < Points->n_points - 1; j++) { if (dc == 2) dxy = G_geodesic_distance(Points->x[j], Points->y[j], Points->x[j + 1], Points->y[j + 1]); else { dx = Points->x[j + 1] - Points->x[j]; dy = Points->y[j + 1] - Points->y[j]; dxy = hypot(dx, dy); } dz = Points->z[j + 1] - Points->z[j]; len += hypot(dxy, dz); } return len; }
/*! \brief Calculates distance in METERS between two points in current projection (2D) Uses G_distance(). \param from 'from' point (X, Y) \param to 'to' point (X, Y) \return distance */ double Gs_distance(double *from, double *to) { static int first = 1; if (first) { first = 0; G_begin_distance_calculations(); } return G_distance(from[0], from[1], to[0], to[1]); }
int shape_index(int fd, char **par, area_des ad, double *result) { double area; struct Cell_head hd; CELL complete_value; double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2; int mask_fd = -1, null_count = 0; int i = 0, k = 0; int *mask_buf; Rast_set_c_null_value(&complete_value, 1); Rast_get_cellhd(ad->raster, "", &hd); /* open mask if needed */ if (ad->mask == 1) { if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) return 0; mask_buf = malloc(ad->cl * sizeof(int)); for (i = 0; i < ad->rl; i++) { if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) return 0; for (k = 0; k < ad->cl; k++) { if (mask_buf[k] == 0) { null_count++; } } } } /*calculate distance */ G_begin_distance_calculations(); /* EW Dist at North edge */ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north); /* EW Dist at South Edge */ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south); /* NS Dist at East edge */ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south); /* NS Dist at West edge */ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south); area = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) * (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (ad->rl * ad->cl - null_count); *result = area; return 1; }
static double distance(double from[2], double to[2], double min, double max, int binary) { static int first = 1; double dist; if (first) { first = 0; G_begin_distance_calculations(); } dist = G_distance(from[0], from[1], to[0], to[1]); if ((dist >= min) && (dist <= max)) if (!binary) return dist; else return 1; else return 0; /* should be NULL ? */ }
int calculateF(int fd, struct area_entry *ad, double *result) { FCELL *buf, *buf_sup, *buf_null; FCELL corrCell, precCell, supCell; long npatch, area; long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp; struct pst *pst; long nalloc, incr; int i, j, k; int connected; int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked; struct Cell_head hd; Rast_get_window(&hd); buf_null = Rast_allocate_f_buf(); Rast_set_f_null_value(buf_null, Rast_window_cols()); buf_sup = buf_null; /* initialize patch ids */ pid_corr = G_malloc(Rast_window_cols() * sizeof(long)); pid_sup = G_malloc(Rast_window_cols() * sizeof(long)); for (j = 0; j < Rast_window_cols(); j++) { pid_corr[j] = 0; pid_sup[j] = 0; } /* open mask if needed */ mask_fd = -1; mask_buf = mask_sup = NULL; masked = FALSE; if (ad->mask == 1) { if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) return RLI_ERRORE; mask_buf = G_malloc(ad->cl * sizeof(int)); if (mask_buf == NULL) { G_fatal_error("malloc mask_buf failed"); return RLI_ERRORE; } mask_sup = G_malloc(ad->cl * sizeof(int)); if (mask_sup == NULL) { G_fatal_error("malloc mask_buf failed"); return RLI_ERRORE; } for (j = 0; j < ad->cl; j++) mask_buf[j] = 0; masked = TRUE; } /* calculate number of patches */ npatch = 0; area = 0; pid = 0; /* patch size and type */ incr = 1024; if (incr > ad->rl) incr = ad->rl; if (incr > ad->cl) incr = ad->cl; if (incr < 2) incr = 2; nalloc = incr; pst = G_malloc(nalloc * sizeof(struct pst)); for (k = 0; k < nalloc; k++) { pst[k].count = 0; } for (i = 0; i < ad->rl; i++) { buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad); if (i > 0) { buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad); } if (masked) { mask_tmp = mask_sup; mask_sup = mask_buf; mask_buf = mask_tmp; if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) return 0; } ltmp = pid_sup; pid_sup = pid_corr; pid_corr = ltmp; Rast_set_f_null_value(&precCell, 1); connected = 0; for (j = 0; j < ad->cl; j++) { pid_corr[j + ad->x] = 0; corrCell = buf[j + ad->x]; if (masked && (mask_buf[j] == 0)) { Rast_set_f_null_value(&corrCell, 1); } if (Rast_is_f_null_value(&corrCell)) { connected = 0; precCell = corrCell; continue; } area++; supCell = buf_sup[j + ad->x]; if (masked && (mask_sup[j] == 0)) { Rast_set_f_null_value(&supCell, 1); } if (!Rast_is_f_null_value(&precCell) && corrCell == precCell) { pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x]; connected = 1; pst[pid_corr[j + ad->x]].count++; } else { connected = 0; } if (!Rast_is_f_null_value(&supCell) && corrCell == supCell) { if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) { /* connect or merge */ /* after r.clump */ if (connected) { npatch--; if (npatch == 0) { G_fatal_error("npatch == 0 at row %d, col %d", i, j); } } old_pid = pid_corr[j + ad->x]; new_pid = pid_sup[j + ad->x]; pid_corr[j + ad->x] = new_pid; if (old_pid > 0) { /* merge */ /* update left side of the current row */ for (k = 0; k < j; k++) { if (pid_corr[k + ad->x] == old_pid) pid_corr[k + ad->x] = new_pid; } /* update right side of the previous row */ for (k = j + 1; k < ad->cl; k++) { if (pid_sup[k + ad->x] == old_pid) pid_sup[k + ad->x] = new_pid; } pst[new_pid].count += pst[old_pid].count; pst[old_pid].count = 0; if (old_pid == pid) pid--; } else { pst[new_pid].count++; } } connected = 1; } if (!connected) { /* start new patch */ npatch++; pid++; pid_corr[j + ad->x] = pid; if (pid >= nalloc) { pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst)); for (k = nalloc; k < pid + incr; k++) pst[k].count = 0; nalloc = pid + incr; } pst[pid].count = 1; pst[pid].type.t = CELL_TYPE; pst[pid].type.val.c = corrCell; } precCell = corrCell; } } if (npatch > 0) { double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2; double area_p; double cell_size_m; double min, max; /* calculate distance */ G_begin_distance_calculations(); /* EW Dist at North edge */ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north); /* EW Dist at South Edge */ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south); /* NS Dist at East edge */ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south); /* NS Dist at West edge */ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south); cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) * (((NS_DIST1 + NS_DIST2) / 2) / hd.rows); /* get min and max patch size */ min = 1.0 / 0.0; /* inf */ max = -1.0 / 0.0; /* -inf */ for (old_pid = 1; old_pid <= pid; old_pid++) { if (pst[old_pid].count > 0) { area_p = cell_size_m * pst[old_pid].count / 10000; if (min > area_p) min = area_p; if (max < area_p) max = area_p; } } *result = max - min; } else Rast_set_d_null_value(result, 1); if (masked) { close(mask_fd); G_free(mask_buf); G_free(mask_sup); } G_free(buf_null); G_free(pid_corr); G_free(pid_sup); G_free(pst); return RLI_OK; }
int main(int argc, char *argv[]) { struct GModule *module; struct Option *in_dir_opt, *in_stm_opt, *in_elev_opt, *in_method_opt, *opt_swapsize, *out_dist_opt, *out_diff_opt; struct Flag *flag_outs, *flag_sub, *flag_near, *flag_segmentation; char *method_name[] = { "UPSTREAM", "DOWNSTREAM" }; int method; int number_of_segs; int outlets_num; int number_of_streams; int outs, subs, near, segmentation; /*flags */ int j; G_gisinit(argv[0]); module = G_define_module(); module->label = _("Calculates distance to and elevation above streams and outlet."); module->description = _("The module can work in stream mode where target are streams and " "outlets mode where targets are outlets."); G_add_keyword(_("raster")); G_add_keyword(_("hydrology")); G_add_keyword(_("stream network")); G_add_keyword(_("watercourse distance")); in_stm_opt = G_define_standard_option(G_OPT_R_INPUT); in_stm_opt->key = "stream_rast"; in_stm_opt->description = _("Name of input raster map with stream network " "(in outlet mode is the name for outlet raster map)"); in_dir_opt = G_define_standard_option(G_OPT_R_INPUT); in_dir_opt->key = "direction"; in_dir_opt->description = _("Name of input raster map with flow direction"); in_elev_opt = G_define_standard_option(G_OPT_R_ELEV); in_elev_opt->required = NO; in_elev_opt->guisection = _("Input maps"); in_method_opt = G_define_option(); in_method_opt->key = "method"; in_method_opt->description = _("Calculation method"); in_method_opt->type = TYPE_STRING; in_method_opt->required = YES; in_method_opt->options = "upstream,downstream"; in_method_opt->answer = "downstream"; out_dist_opt = G_define_standard_option(G_OPT_R_OUTPUT); out_dist_opt->key = "distance"; out_dist_opt->required = NO; out_dist_opt->description = _("Name for output distance raster map"); out_dist_opt->guisection = _("Output maps"); out_diff_opt = G_define_standard_option(G_OPT_R_OUTPUT); out_diff_opt->key = "difference"; out_diff_opt->required = NO; out_diff_opt->description = _("Name for output elevation difference raster map"); out_diff_opt->guisection = _("Output maps"); opt_swapsize = G_define_option(); opt_swapsize->key = "memory"; opt_swapsize->type = TYPE_INTEGER; opt_swapsize->answer = "300"; opt_swapsize->description = _("Max memory used in memory swap mode (MB)"); opt_swapsize->guisection = _("Memory settings"); flag_outs = G_define_flag(); flag_outs->key = 'o'; flag_outs->description = _("Calculate parameters for outlets (outlet mode) instead of (default) streams"); flag_sub = G_define_flag(); flag_sub->key = 's'; flag_sub->description = _("Calculate parameters for subbasins (ignored in stream mode)"); flag_near = G_define_flag(); flag_near->key = 'n'; flag_near->description = _("Calculate nearest local maximum (ignored in downstream calculation)"); flag_segmentation = G_define_flag(); flag_segmentation->key = 'm'; flag_segmentation->description = _("Use memory swap (operation is slow)"); flag_segmentation->guisection = _("Memory settings"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (!out_diff_opt->answer && !out_dist_opt->answer) G_fatal_error(_("You must select at least one output raster map")); if (out_diff_opt->answer && !in_elev_opt->answer) G_fatal_error(_("Output elevation difference raster map requires " "input elevation raster map to be specified")); if (!strcmp(in_method_opt->answer, "upstream")) method = UPSTREAM; else if (!strcmp(in_method_opt->answer, "downstream")) method = DOWNSTREAM; outs = (flag_outs->answer != 0); subs = (flag_sub->answer != 0); near = (flag_near->answer != 0); segmentation = (flag_segmentation->answer != 0); nrows = Rast_window_rows(); ncols = Rast_window_cols(); G_begin_distance_calculations(); fifo_max = 4 * (nrows + ncols); fifo_points = (POINT *) G_malloc((fifo_max + 1) * sizeof(POINT)); if (!segmentation) { G_message(_("All in RAM calculation - method <%s>..."), method_name[method]); MAP map_dirs, map_streams, map_distance, map_elevation, map_tmp_elevation; CELL **streams, **dirs; DCELL **distance; DCELL **elevation = NULL; DCELL **tmp_elevation = NULL; ram_create_map(&map_streams, CELL_TYPE); ram_read_map(&map_streams, in_stm_opt->answer, 1, CELL_TYPE); ram_create_map(&map_dirs, CELL_TYPE); ram_read_map(&map_dirs, in_dir_opt->answer, 1, CELL_TYPE); ram_create_map(&map_distance, DCELL_TYPE); streams = (CELL **) map_streams.map; dirs = (CELL **) map_dirs.map; distance = (DCELL **) map_distance.map; number_of_streams = (int)map_streams.max + 1; outlets_num = ram_find_outlets(streams, number_of_streams, dirs, subs, outs); ram_init_distance(streams, distance, outlets_num, outs); ram_release_map(&map_streams); if (in_elev_opt->answer) { ram_create_map(&map_elevation, DCELL_TYPE); ram_read_map(&map_elevation, in_elev_opt->answer, 0, -1); elevation = (DCELL **) map_elevation.map; } /* map elevation will be replaced by elevation difference map */ if (method == DOWNSTREAM) { G_message(_("Calculate downstream parameters...")); for (j = 0; j < outlets_num; ++j) { G_percent(j, outlets_num, 1); ram_calculate_downstream(dirs, distance, elevation, outlets[j], outs); } G_percent(j, outlets_num, 1); } else if (method == UPSTREAM) { if (out_diff_opt->answer) { ram_create_map(&map_tmp_elevation, DCELL_TYPE); tmp_elevation = (DCELL **) map_tmp_elevation.map; } for (j = 0; j < outlets_num; ++j) ram_fill_basins(outlets[j], distance, dirs); ram_calculate_upstream(distance, dirs, elevation, tmp_elevation, near); } else { G_fatal_error(_("Unrecognised method of processing")); } /* end methods */ if (out_diff_opt->answer) { ram_prep_null_elevation(distance, elevation); ram_write_map(&map_elevation, out_diff_opt->answer, DCELL_TYPE, 1, -1); } if (out_dist_opt->answer) ram_write_map(&map_distance, out_dist_opt->answer, DCELL_TYPE, 1, -1); ram_release_map(&map_dirs); ram_release_map(&map_distance); if (in_elev_opt->answer) ram_release_map(&map_elevation); if (in_elev_opt->answer && method == UPSTREAM) ram_release_map(&map_tmp_elevation); } if (segmentation) { G_message(_("Calculating segments in direction <%s> (may take some time)..."), method_name[method]); SEG map_dirs, map_streams, map_distance, map_elevation, map_tmp_elevation; SEGMENT *streams, *dirs, *distance; SEGMENT *elevation = NULL; SEGMENT *tmp_elevation = NULL; number_of_segs = (int)atof(opt_swapsize->answer); if (method == DOWNSTREAM) number_of_segs = number_of_segs < 32 ? (int)(32 / 0.18) : number_of_segs / 0.18; else /* two elevation maps */ number_of_segs = number_of_segs < 32 ? (int)(32 / 0.24) : number_of_segs / 0.24; seg_create_map(&map_streams, SROWS, SCOLS, number_of_segs, CELL_TYPE); seg_read_map(&map_streams, in_stm_opt->answer, 1, CELL_TYPE); seg_create_map(&map_dirs, SROWS, SCOLS, number_of_segs, CELL_TYPE); seg_read_map(&map_dirs, in_dir_opt->answer, 1, CELL_TYPE); seg_create_map(&map_distance, SROWS, SCOLS, number_of_segs, DCELL_TYPE); streams = &map_streams.seg; dirs = &map_dirs.seg; distance = &map_distance.seg; number_of_streams = (int)map_streams.max + 1; outlets_num = seg_find_outlets(streams, number_of_streams, dirs, subs, outs); seg_init_distance(streams, distance, outlets_num, outs); seg_release_map(&map_streams); if (in_elev_opt->answer) { seg_create_map(&map_elevation, SROWS, SCOLS, number_of_segs, DCELL_TYPE); seg_read_map(&map_elevation, in_elev_opt->answer, 0, -1); elevation = &map_elevation.seg; } /* map elevation will be replaced by elevation difference map */ if (method == DOWNSTREAM) { G_message(_("Calculate downstream parameters...")); for (j = 0; j < outlets_num; ++j) { G_percent(j, outlets_num, 1); seg_calculate_downstream(dirs, distance, elevation, outlets[j], outs); } G_percent(j, outlets_num, 1); } else if (method == UPSTREAM) { if (out_diff_opt->answer) { seg_create_map(&map_tmp_elevation, SROWS, SCOLS, number_of_segs, DCELL_TYPE); tmp_elevation = &map_tmp_elevation.seg; } for (j = 0; j < outlets_num; ++j) seg_fill_basins(outlets[j], distance, dirs); seg_calculate_upstream(distance, dirs, elevation, tmp_elevation, near); } else { G_fatal_error(_("Unrecognised method of processing")); } /* end methods */ if (out_dist_opt->answer) seg_write_map(&map_distance, out_dist_opt->answer, DCELL_TYPE, 1, -1); if (out_diff_opt->answer) { seg_prep_null_elevation(distance, elevation); seg_write_map(&map_elevation, out_diff_opt->answer, DCELL_TYPE, 1, -1); } seg_release_map(&map_dirs); seg_release_map(&map_distance); if (in_elev_opt->answer) seg_release_map(&map_elevation); if (in_elev_opt->answer && method == UPSTREAM) seg_release_map(&map_tmp_elevation); } G_free(fifo_points); exit(EXIT_SUCCESS); }
/*! \brief Calculate geodesic distance of point to line in meters. Sets (if not null): - px, py - point on line, - dist - distance to line, - spdist - distance to point on line from segment beginning, - sldist - distance to point on line form line beginning along line \param points pointer to line_pnts structure \param ux,uy,uz point coordinates \param with_z flag if to use z coordinate (3D calculation) \param[out] px,py,pz point on line \param[out] dist distance to line, \param[out] spdist distance of point from segment beginning \param[out] lpdist distance of point from line \return nearest segment (first is 1) */ int Vect_line_geodesic_distance(const struct line_pnts *points, double ux, double uy, double uz, int with_z, double *px, double *py, double *pz, double *dist, double *spdist, double *lpdist) { int i; double distance; double new_dist; double tpx, tpy, tpz, ttpx, ttpy, ttpz; double tdist, tspdist, tlpdist = 0, tlpdistseg; double dz; int n_points; int segment; G_begin_distance_calculations(); n_points = points->n_points; if (n_points == 1) { distance = G_distance(ux, uy, points->x[0], points->y[0]); if (with_z) distance = hypot(distance, uz - points->z[0]); tpx = points->x[0]; tpy = points->y[0]; tpz = points->z[0]; tdist = distance; tspdist = 0; tlpdist = 0; segment = 0; } else { distance = dig_distance2_point_to_line(ux, uy, uz, points->x[0], points->y[0], points->z[0], points->x[1], points->y[1], points->z[1], with_z, &tpx, &tpy, &tpz, NULL, NULL); distance = G_distance(ux, uy, tpx, tpy); if (with_z) distance = hypot(distance, uz - tpz); segment = 1; for (i = 1; i < n_points - 1; i++) { new_dist = dig_distance2_point_to_line(ux, uy, uz, points->x[i], points->y[i], points->z[i], points->x[i + 1], points->y[i + 1], points->z[i + 1], with_z, &ttpx, &ttpy, &ttpz, NULL, NULL); new_dist = G_distance(ux, uy, ttpx, ttpy); if (with_z) new_dist = hypot(new_dist, uz - ttpz); if (new_dist < distance) { distance = new_dist; segment = i + 1; tpx = ttpx; tpy = ttpy; tpz = ttpz; } } /* calculate distance from beginning of segment */ tspdist = G_distance(points->x[segment - 1], points->y[segment - 1], tpx, tpy); if (with_z) { dz = points->z[segment - 1] - tpz; tspdist += hypot(tspdist, dz); } /* calculate distance from beginning of line */ if (lpdist) { tlpdist = 0; for (i = 0; i < segment - 1; i++) { tlpdistseg = G_distance(points->x[i], points->y[i], points->x[i + 1], points->y[i + 1]); if (with_z) { dz = points->z[i + 1] - points->z[i]; tlpdistseg += hypot(tlpdistseg, dz); } tlpdist += tlpdistseg; } tlpdist += tspdist; } tdist = distance; } if (px) *px = tpx; if (py) *py = tpy; if (pz && with_z) *pz = tpz; if (dist) *dist = tdist; if (spdist) *spdist = tspdist; if (lpdist) *lpdist = tlpdist; return (segment); }
int patch_density(int fd, char **par, area_des ad, double *result) { CELL *buf, *sup; int count = 0, i, j, connected = 0, complete_line = 1, other_above = 0; double area; struct Cell_head hd; CELL complete_value; double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2; int mask_fd = -1, *mask_buf, *mask_sup, null_count = 0; Rast_set_c_null_value(&complete_value, 1); Rast_get_cellhd(ad->raster, "", &hd); sup = Rast_allocate_c_buf(); /* open mask if needed */ if (ad->mask == 1) { if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) return 0; mask_buf = malloc(ad->cl * sizeof(int)); mask_sup = malloc(ad->cl * sizeof(int)); } /*calculate distance */ G_begin_distance_calculations(); /* EW Dist at North edge */ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north); /* EW Dist at South Edge */ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south); /* NS Dist at East edge */ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south); /* NS Dist at West edge */ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south); /*calculate number of patch */ for (i = 0; i < ad->rl; i++) { buf = RLI_get_cell_raster_row(fd, i + ad->y, ad); if (i > 0) { sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad); } /* mask values */ if (ad->mask == 1) { int k; if (i > 0) { int *tmp; tmp = mask_sup; mask_buf = mask_sup; } if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) return 0; for (k = 0; k < ad->cl; k++) { if (mask_buf[k] == 0) { Rast_set_c_null_value(mask_buf + k, 1); null_count++; } } } if (complete_line) { if (!Rast_is_null_value(&(buf[ad->x]), CELL_TYPE) && buf[ad->x] != complete_value) count++; for (j = 0; j < ad->cl - 1; j++) { if (buf[j + ad->x] != buf[j + 1 + ad->x]) { complete_line = 0; if (!Rast_is_null_value(&(buf[j + 1 + ad->x]), CELL_TYPE) && buf[j + 1 + ad->x] != complete_value) count++; } } if (complete_line) { complete_value = buf[ad->x]; } } else { complete_line = 1; connected = 0; other_above = 0; for (j = 0; j < ad->cl; j++) { if (sup[j + ad->x] == buf[j + ad->x]) { connected = 1; if (other_above) { other_above = 0; count--; } } else { if (connected && !Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE)) other_above = 1; } if (j < ad->cl - 1 && buf[j + ad->x] != buf[j + 1 + ad->x]) { complete_line = 0; if (!connected && !Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE)) { count++; connected = 0; other_above = 0; } else { connected = 0; other_above = 0; } } } if (!connected && sup[ad->cl - 1 + ad->x] != buf[ad->cl - 1 + ad->x]) { if (!Rast_is_null_value (&(buf[ad->cl - 1 + ad->x]), CELL_TYPE)) { count++; complete_line = 0; } } if (complete_line) complete_value = buf[ad->x]; } } area = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) * (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (ad->rl * ad->cl - null_count); if (area != 0) *result = (count / area) * 1000000; else *result = -1; G_free(sup); return RLI_OK; }
int camera_angle(char *name) { int row, col, nrows, ncols; double XC = group.XC; double YC = group.YC; double ZC = group.ZC; double c_angle, c_angle_min, c_alt, c_az, slope, aspect; double radians_to_degrees = 180.0 / M_PI; /* double degrees_to_radians = M_PI / 180.0; */ DCELL e1, e2, e3, e4, e5, e6, e7, e8, e9; double factor, V, H, dx, dy, dz, key; double north, south, east, west, ns_med; FCELL *fbuf0, *fbuf1, *fbuf2, *tmpbuf, *outbuf; int elevfd, outfd; struct Cell_head cellhd; struct Colors colr; FCELL clr_min, clr_max; struct History hist; char *type; G_message(_("Calculating camera angle to local surface...")); select_target_env(); /* align target window to elevation map, otherwise we get artefacts * like in r.slope.aspect -a */ Rast_get_cellhd(elev_name, elev_mapset, &cellhd); Rast_align_window(&target_window, &cellhd); Rast_set_window(&target_window); elevfd = Rast_open_old(elev_name, elev_mapset); if (elevfd < 0) { G_fatal_error(_("Could not open elevation raster")); return 1; } nrows = target_window.rows; ncols = target_window.cols; outfd = Rast_open_new(name, FCELL_TYPE); fbuf0 = Rast_allocate_buf(FCELL_TYPE); fbuf1 = Rast_allocate_buf(FCELL_TYPE); fbuf2 = Rast_allocate_buf(FCELL_TYPE); outbuf = Rast_allocate_buf(FCELL_TYPE); /* give warning if location units are different from meters and zfactor=1 */ factor = G_database_units_to_meters_factor(); if (factor != 1.0) G_warning(_("Converting units to meters, factor=%.6f"), factor); G_begin_distance_calculations(); north = Rast_row_to_northing(0.5, &target_window); ns_med = Rast_row_to_northing(1.5, &target_window); south = Rast_row_to_northing(2.5, &target_window); east = Rast_col_to_easting(2.5, &target_window); west = Rast_col_to_easting(0.5, &target_window); V = G_distance(east, north, east, south) * 4; H = G_distance(east, ns_med, west, ns_med) * 4; c_angle_min = 90; Rast_get_row(elevfd, fbuf1, 0, FCELL_TYPE); Rast_get_row(elevfd, fbuf2, 1, FCELL_TYPE); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); Rast_set_null_value(outbuf, ncols, FCELL_TYPE); /* first and last row */ if (row == 0 || row == nrows - 1) { Rast_put_row(outfd, outbuf, FCELL_TYPE); continue; } tmpbuf = fbuf0; fbuf0 = fbuf1; fbuf1 = fbuf2; fbuf2 = tmpbuf; Rast_get_row(elevfd, fbuf2, row + 1, FCELL_TYPE); north = Rast_row_to_northing(row + 0.5, &target_window); for (col = 1; col < ncols - 1; col++) { e1 = fbuf0[col - 1]; if (Rast_is_d_null_value(&e1)) continue; e2 = fbuf0[col]; if (Rast_is_d_null_value(&e2)) continue; e3 = fbuf0[col + 1]; if (Rast_is_d_null_value(&e3)) continue; e4 = fbuf1[col - 1]; if (Rast_is_d_null_value(&e4)) continue; e5 = fbuf1[col]; if (Rast_is_d_null_value(&e5)) continue; e6 = fbuf1[col + 1]; if (Rast_is_d_null_value(&e6)) continue; e7 = fbuf2[col - 1]; if (Rast_is_d_null_value(&e7)) continue; e8 = fbuf2[col]; if (Rast_is_d_null_value(&e8)) continue; e9 = fbuf2[col + 1]; if (Rast_is_d_null_value(&e9)) continue; dx = ((e1 + e4 + e4 + e7) - (e3 + e6 + e6 + e9)) / H; dy = ((e7 + e8 + e8 + e9) - (e1 + e2 + e2 + e3)) / V; /* compute topographic parameters */ key = dx * dx + dy * dy; /* slope in radians */ slope = atan(sqrt(key)); /* aspect in radians */ if (key == 0.) aspect = 0.; else if (dx == 0) { if (dy > 0) aspect = M_PI / 2; else aspect = 1.5 * M_PI; } else { aspect = atan2(dy, dx); if (aspect <= 0.) aspect = 2 * M_PI + aspect; } /* camera altitude angle in radians */ east = Rast_col_to_easting(col + 0.5, &target_window); dx = east - XC; dy = north - YC; dz = ZC - e5; c_alt = atan(sqrt(dx * dx + dy * dy) / dz); /* camera azimuth angle in radians */ c_az = atan(dy / dx); if (east < XC && north != YC) c_az += M_PI; else if (north < YC && east > XC) c_az += 2 * M_PI; /* camera angle to real ground */ /* orthogonal to ground: 90 degrees */ /* parallel to ground: 0 degrees */ c_angle = asin(cos(c_alt) * cos(slope) - sin(c_alt) * sin(slope) * cos(c_az - aspect)); outbuf[col] = c_angle * radians_to_degrees; if (c_angle_min > outbuf[col]) c_angle_min = outbuf[col]; } Rast_put_row(outfd, outbuf, FCELL_TYPE); } G_percent(row, nrows, 2); Rast_close(elevfd); Rast_close(outfd); G_free(fbuf0); G_free(fbuf1); G_free(fbuf2); G_free(outbuf); type = "raster"; Rast_short_history(name, type, &hist); Rast_command_history(&hist); Rast_write_history(name, &hist); Rast_init_colors(&colr); if (c_angle_min < 0) { clr_min = (FCELL)((int)(c_angle_min / 10 - 1)) * 10; clr_max = 0; Rast_add_f_color_rule(&clr_min, 0, 0, 0, &clr_max, 0, 0, 0, &colr); } clr_min = 0; clr_max = 10; Rast_add_f_color_rule(&clr_min, 0, 0, 0, &clr_max, 255, 0, 0, &colr); clr_min = 10; clr_max = 40; Rast_add_f_color_rule(&clr_min, 255, 0, 0, &clr_max, 255, 255, 0, &colr); clr_min = 40; clr_max = 90; Rast_add_f_color_rule(&clr_min, 255, 255, 0, &clr_max, 0, 255, 0, &colr); Rast_write_colors(name, G_mapset(), &colr); select_current_env(); return 1; }
double get_dist(double *dist_to_nbr, double *contour) { int ct_dir, r_nbr, c_nbr; double dx, dy, ns_res, ew_res; if (G_projection() == PROJECTION_LL) { double ew_dist1, ew_dist2, ew_dist3; double ns_dist1, ns_dist2, ns_dist3; G_begin_distance_calculations(); /* EW Dist at North edge */ ew_dist1 = G_distance(window.east, window.north, window.west, window.north); /* EW Dist at Center */ ew_dist2 = G_distance(window.east, (window.north + window.south) / 2., window.west, (window.north + window.south) / 2.); /* EW Dist at South Edge */ ew_dist3 = G_distance(window.east, window.south, window.west, window.south); /* NS Dist at East edge */ ns_dist1 = G_distance(window.east, window.north, window.east, window.south); /* NS Dist at Center */ ns_dist2 = G_distance((window.west + window.east) / 2., window.north, (window.west + window.east) / 2., window.south); /* NS Dist at West edge */ ns_dist3 = G_distance(window.west, window.north, window.west, window.south); ew_res = (ew_dist1 + ew_dist2 + ew_dist3) / (3 * window.cols); ns_res = (ns_dist1 + ns_dist2 + ns_dist3) / (3 * window.rows); } else { ns_res = window.ns_res; ew_res = window.ew_res; } for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (r_nbr, c_nbr) for neighbours */ r_nbr = nextdr[ct_dir]; c_nbr = nextdc[ct_dir]; /* account for rare cases when ns_res != ew_res */ dy = ABS(r_nbr) * ns_res; dx = ABS(c_nbr) * ew_res; if (ct_dir < 4) dist_to_nbr[ct_dir] = (dx + dy) * ele_scale; else dist_to_nbr[ct_dir] = sqrt(dx * dx + dy * dy) * ele_scale; } /* Quinn et al. 1991: * ns contour: ew_res / 2 * ew contour: ns_res / 2 * diag contour: sqrt(ns_res * nsres / 4 + ew_res * ew_res / 4) / 2 * = sqrt(ns_res * nsres + ew_res * ew_res) / 4 * if ns_res == ew_res: * sqrt(2 * (res * res) / 4 = res * 0.354 * * contour lengths "have been subjectively chosen", * no justification why the diagonal contour is shorter * BUT: if the diag contour is a bit shorter than the cardinal contour, * this is further enhancing the correction for diagonal flow bias * diagonal slope is already corrected for longer distance * smaller slope and shorter contour length have the same effect: * higher TCI */ if (sides == 8) { /* contours are sides of an octagon, irregular if ns_res != ew_res * ideally: arc lengths of an ellipse */ contour[0] = contour[1] = tan(atan(ew_res / ns_res) / 2.) * ns_res; contour[2] = contour[3] = tan(atan(ns_res / ew_res) / 2.) * ew_res; G_debug(1, "ns contour: %.4f", contour[0]); G_debug(1, "ew contour: %.4f", contour[2]); contour[4] = (ew_res - contour[0]); contour[5] = (ns_res - contour[2]); contour[7] = sqrt(contour[4] * contour[4] + contour[5] * contour[5]) / 2.; G_debug(1, "diag contour: %.4f", contour[7]); contour[4] = contour[5] = contour[6] = contour[7]; } else { /* contours are sides of a rectangle */ contour[0] = contour[1] = ew_res; contour[2] = contour[3] = ns_res; } return ew_res * ns_res; }
int main(int argc, char **argv) { IO rasters[] = { /* rasters stores output buffers */ {"dem",YES,"Input dem","input",UNKNOWN,-1,NULL}, /* WARNING: this one map is input */ {"forms",NO,"Most common geomorphic forms","patterns",CELL_TYPE,-1,NULL}, {"ternary",NO,"code of ternary patterns","patterns",CELL_TYPE,-1,NULL}, {"positive",NO,"code of binary positive patterns","patterns",CELL_TYPE,-1,NULL}, {"negative",NO,"code of binary negative patterns","patterns",CELL_TYPE,-1,NULL}, {"intensity",NO,"rasters containing mean relative elevation of the form","geometry",FCELL_TYPE,-1,NULL}, {"exposition",NO,"rasters containing maximum difference between extend and central cell","geometry",FCELL_TYPE,-1,NULL}, {"range",NO,"rasters containing difference between max and min elevation of the form extend","geometry",FCELL_TYPE,-1,NULL}, {"variance",NO,"rasters containing variance of form boundary","geometry",FCELL_TYPE,-1,NULL}, {"elongation",NO,"rasters containing local elongation","geometry",FCELL_TYPE,-1,NULL}, {"azimuth",NO,"rasters containing local azimuth of the elongation","geometry",FCELL_TYPE,-1,NULL}, {"extend",NO,"rasters containing local extend (area) of the form","geometry",FCELL_TYPE,-1,NULL}, {"width",NO,"rasters containing local width of the form","geometry",FCELL_TYPE,-1,NULL} }; /* adding more maps change IOSIZE macro */ CATCOLORS ccolors[CNT]={ /* colors and cats for forms */ {ZERO, 0, 0, 0, "forms"}, {FL, 220, 220, 220, "flat"}, {PK, 56, 0, 0, "summit"}, {RI, 200, 0, 0, "ridge"}, {SH, 255, 80, 20, "shoulder"}, {CV, 250, 210, 60, "spur"}, {SL, 255, 255, 60, "slope"}, {CN, 180, 230, 20, "hollow"}, {FS, 60, 250, 150, "footslope"}, {VL, 0, 0, 255, "valley"}, {PT, 0, 0, 56, "depression"}, {__, 255, 0, 255, "ERROR"}}; struct GModule *module; struct Option *opt_input, *opt_output[io_size], *par_search_radius, *par_skip_radius, *par_flat_treshold, *par_flat_distance; struct Flag *flag_units, *flag_extended; struct History history; int i,j, n; int meters=0, multires=0, extended=0; /* flags */ int row,cur_row,col,radius; int pattern_size; double max_resolution; char prefix[20]; G_gisinit(argv[0]); { /* interface parameters */ module = G_define_module(); module->description = _("Calculate geomorphons (terrain forms)and associated geometry using machine vision approach"); G_add_keyword("Geomorphons"); G_add_keyword("Terrain patterns"); G_add_keyword("Machine vision geomorphometry"); opt_input = G_define_standard_option(G_OPT_R_INPUT); opt_input->key = rasters[0].name; opt_input->required = rasters[0].required; opt_input->description = _(rasters[0].description); for (i=1;i<io_size;++i) { /* WARNING: loop starts from one, zero is for input */ opt_output[i] = G_define_standard_option(G_OPT_R_OUTPUT); opt_output[i]->key = rasters[i].name; opt_output[i]->required = NO; opt_output[i]->description = _(rasters[i].description); opt_output[i]->guisection = _(rasters[i].gui); } par_search_radius = G_define_option(); par_search_radius->key = "search"; par_search_radius->type = TYPE_INTEGER; par_search_radius->answer = "3"; par_search_radius->required = YES; par_search_radius->description = _("Outer search radius"); par_skip_radius = G_define_option(); par_skip_radius->key = "skip"; par_skip_radius->type = TYPE_INTEGER; par_skip_radius->answer = "0"; par_skip_radius->required = YES; par_skip_radius->description = _("Inner search radius"); par_flat_treshold = G_define_option(); par_flat_treshold->key = "flat"; par_flat_treshold->type = TYPE_DOUBLE; par_flat_treshold->answer = "1"; par_flat_treshold->required = YES; par_flat_treshold->description = _("Flatenss treshold (degrees)"); par_flat_distance = G_define_option(); par_flat_distance->key = "dist"; par_flat_distance->type = TYPE_DOUBLE; par_flat_distance->answer = "0"; par_flat_distance->required = YES; par_flat_distance->description = _("Flatenss distance, zero for none"); flag_units = G_define_flag(); flag_units->key = 'm'; flag_units->description = _("Use meters to define search units (default is cells)"); flag_extended = G_define_flag(); flag_extended->key = 'e'; flag_extended->description = _("Use extended form correction"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); } { /* calculate parameters */ int num_outputs=0; double search_radius, skip_radius, start_radius, step_radius; double ns_resolution; for (i=1;i<io_size;++i) /* check for outputs */ if(opt_output[i]->answer) { if (G_legal_filename(opt_output[i]->answer) < 0) G_fatal_error(_("<%s> is an illegal file name"), opt_output[i]->answer); num_outputs++; } if(!num_outputs && !multires) G_fatal_error(_("At least one output is required")); meters=(flag_units->answer != 0); extended=(flag_extended->answer != 0); nrows = Rast_window_rows(); ncols = Rast_window_cols(); Rast_get_window(&window); G_begin_distance_calculations(); if(G_projection()==PROJECTION_LL) { /* for LL max_res should be NS */ ns_resolution=G_distance(0,Rast_row_to_northing(0, &window),0,Rast_row_to_northing(1, &window)); max_resolution=ns_resolution; } else { max_resolution=MAX(window.ns_res,window.ew_res); /* max_resolution MORE meters per cell */ } G_message("NSRES, %f", ns_resolution); cell_res=max_resolution; /* this parameter is global */ /* search distance */ search_radius=atof(par_search_radius->answer); search_cells=meters?(int)(search_radius/max_resolution):search_radius; if(search_cells<1) G_fatal_error(_("Search radius size must cover at least 1 cell")); row_radius_size=meters?ceil(search_radius/max_resolution):search_radius; row_buffer_size=row_radius_size*2+1; search_distance=(meters)?search_radius:max_resolution*search_cells; /* skip distance */ skip_radius=atof(par_skip_radius->answer); skip_cells=meters?(int)(skip_radius/max_resolution):skip_radius; if(skip_cells>=search_cells) G_fatal_error(_("Skip radius size must be at least 1 cell lower than radius")); skip_distance=(meters)?skip_radius:ns_resolution*skip_cells; /* flatness parameters */ flat_threshold=atof(par_flat_treshold->answer); if(flat_threshold<=0.) G_fatal_error(_("Flatenss treshold must be grater than 0")); flat_threshold=DEGREE2RAD(flat_threshold); flat_distance=atof(par_flat_distance->answer); flat_distance=(meters)?flat_distance:ns_resolution*flat_distance; flat_threshold_height=tan(flat_threshold)*flat_distance; if((flat_distance>0&&flat_distance<=skip_distance)||flat_distance>=search_distance) { G_warning(_("Flatenss distance should be between skip and search radius. Otherwise ignored")); flat_distance=0; } if (search_distance<10*cell_res) extended=0; /* print information about distances */ G_message("Search distance m: %f, cells: %d", search_distance, search_cells); G_message("Skip distance m: %f, cells: %d", skip_distance, skip_cells); G_message("Flat threshold distance m: %f, height: %f",flat_distance, flat_threshold_height); G_message("%s version",(extended)?"extended":"basic"); } /* generate global ternary codes */ for(i=0;i<6561;++i) global_ternary_codes[i]=ternary_rotate(i); /* open DEM */ strcpy(elevation.elevname,opt_input->answer); open_map(&elevation); PATTERN* pattern; PATTERN patterns[4]; void* pointer_buf; int formA, formB, formC; double search_dist=search_distance; double skip_dist=skip_distance; double flat_dist=flat_distance; double area_of_octagon=4*(search_distance*search_distance)*sin(DEGREE2RAD(45.)); cell_step=1; /* prepare outputs */ for (i=1;i<io_size;++i) if(opt_output[i]->answer) { rasters[i].fd=Rast_open_new(opt_output[i]->answer,rasters[i].out_data_type); rasters[i].buffer=Rast_allocate_buf(rasters[i].out_data_type); } /* main loop */ for(row=0;row<nrows;++row) { G_percent(row, nrows, 2); cur_row = (row < row_radius_size)?row: ((row >= nrows-row_radius_size-1) ? row_buffer_size - (nrows-row-1) : row_radius_size); if(row>(row_radius_size) && row<nrows-(row_radius_size+1)) shift_buffers(row); for (col=0;col<ncols;++col) { /* on borders forms ussualy are innatural. */ if(row<(skip_cells+1) || row>nrows-(skip_cells+2) || col<(skip_cells+1) || col>ncols-(skip_cells+2) || Rast_is_f_null_value(&elevation.elev[cur_row][col])) { /* set outputs to NULL and do nothing if source value is null or border*/ for (i=1;i<io_size;++i) if(opt_output[i]->answer) { pointer_buf=rasters[i].buffer; switch (rasters[i].out_data_type) { case CELL_TYPE: Rast_set_c_null_value(&((CELL*)pointer_buf)[col],1); break; case FCELL_TYPE: Rast_set_f_null_value(&((FCELL*)pointer_buf)[col],1); break; case DCELL_TYPE: Rast_set_d_null_value(&((DCELL*)pointer_buf)[col],1); break; default: G_fatal_error(_("Unknown output data type")); } } continue; } /* end null value */ { int cur_form, small_form; search_distance=search_dist; skip_distance=skip_dist; flat_distance=flat_dist; pattern_size=calc_pattern(&patterns[0],row,cur_row,col); pattern=&patterns[0]; cur_form=determine_form(pattern->num_negatives,pattern->num_positives); /* correction of forms */ if(extended) { /* 1) remove extensive innatural forms: ridges, peaks, shoulders and footslopes */ if((cur_form==4||cur_form==8||cur_form==2||cur_form==3)) { search_distance=(search_dist/4.<4*max_resolution)? 4*max_resolution : search_dist/4.; skip_distance=0; flat_distance=0; pattern_size=calc_pattern(&patterns[1],row,cur_row,col); pattern=&patterns[1]; small_form=determine_form(pattern->num_negatives,pattern->num_positives); if(cur_form==4||cur_form==8) cur_form=(small_form==1)? 1 : cur_form; if(cur_form==2||cur_form==3) cur_form=small_form; } } /* end of correction */ pattern=&patterns[0]; if(opt_output[o_forms]->answer) ((CELL*)rasters[o_forms].buffer)[col]=cur_form; } if(opt_output[o_ternary]->answer) ((CELL*)rasters[o_ternary].buffer)[col]=determine_ternary(pattern->pattern); if(opt_output[o_positive]->answer) ((CELL*)rasters[o_positive].buffer)[col]=pattern->num_positives;//rotate(pattern->positives); if(opt_output[o_negative]->answer) ((CELL*)rasters[o_negative].buffer)[col]=pattern->num_negatives;//rotate(pattern->negatives); if(opt_output[o_intensity]->answer) ((FCELL*)rasters[o_intensity].buffer)[col]=intensity(pattern->elevation,pattern_size); if(opt_output[o_exposition]->answer) ((FCELL*)rasters[o_exposition].buffer)[col]=exposition(pattern->elevation); if(opt_output[o_range]->answer) ((FCELL*)rasters[o_range].buffer)[col]=range(pattern->elevation); if(opt_output[o_variance]->answer) ((FCELL*)rasters[o_variance].buffer)[col]=variance(pattern->elevation, pattern_size); // used only for next four shape functions if(opt_output[o_elongation]->answer ||opt_output[o_azimuth]->answer|| opt_output[o_extend]->answer || opt_output[o_width]->answer) { float azimuth,elongation,width; radial2cartesian(pattern); shape(pattern, pattern_size,&azimuth,&elongation,&width); if(opt_output[o_azimuth]->answer) ((FCELL*)rasters[o_azimuth].buffer)[col]=azimuth; if(opt_output[o_elongation]->answer) ((FCELL*)rasters[o_elongation].buffer)[col]=elongation; if(opt_output[o_width]->answer) ((FCELL*)rasters[o_width].buffer)[col]=width; } if(opt_output[o_extend]->answer) ((FCELL*)rasters[o_extend].buffer)[col]=extends(pattern, pattern_size)/area_of_octagon; } /* end for col */ /* write existing outputs */ for (i=1;i<io_size;++i) if(opt_output[i]->answer) Rast_put_row(rasters[i].fd, rasters[i].buffer, rasters[i].out_data_type); } G_percent(row, nrows, 2); /* end main loop */ /* finish and close */ free_map(elevation.elev, row_buffer_size+1); for (i=1;i<io_size;++i) if(opt_output[i]->answer) { G_free(rasters[i].buffer); Rast_close(rasters[i].fd); Rast_short_history(opt_output[i]->answer, "raster", &history); Rast_command_history(&history); Rast_write_history(opt_output[i]->answer, &history); } if(opt_output[o_forms]->answer) write_form_cat_colors(opt_output[o_forms]->answer,ccolors); if(opt_output[o_intensity]->answer) write_contrast_colors(opt_output[o_intensity]->answer); if(opt_output[o_exposition]->answer) write_contrast_colors(opt_output[o_exposition]->answer); if(opt_output[o_range]->answer) write_contrast_colors(opt_output[o_range]->answer); G_message("Done!"); exit(EXIT_SUCCESS); }
int seg_stream_geometry(SEGMENT *streams, SEGMENT *dirs) { int i, s, d; /* s - streams index; d - direction */ int done = 1; int r, c; int next_r, next_c; int prev_r, prev_c; int cur_stream, next_stream, dirs_cell; float cur_northing, cur_easting; float next_northing, next_easting; float init_northing, init_easting; double cur_length = 0.; double cur_accum_length = 0.; STREAM *SA = stream_attributes; /* for better code readability */ struct Cell_head window; G_get_window(&window); G_message(_("Finding longest streams...")); G_begin_distance_calculations(); for (s = 0; s < init_num; ++s) { /* main loop on springs */ G_percent(s, init_num, 2); r = (int)init_cells[s] / ncols; c = (int)init_cells[s] % ncols; Segment_get(streams, &cur_stream, r, c); cur_length = 0; done = 1; SA[cur_stream].init = init_cells[s]; /* stored as index */ init_northing = window.north - (r + .5) * window.ns_res; init_easting = window.west + (c + .5) * window.ew_res; while (done) { cur_northing = window.north - (r + .5) * window.ns_res; cur_easting = window.west + (c + .5) * window.ew_res; Segment_get(dirs, &dirs_cell, r, c); d = abs(dirs_cell); next_r = NR(d); next_c = NC(d); if (NOT_IN_REGION(d)) Rast_set_c_null_value(&next_stream, 1); else Segment_get(streams, &next_stream, next_r, next_c); if (d < 1 || NOT_IN_REGION(d) || !next_stream) { cur_length = (window.ns_res + window.ew_res) / 2; SA[cur_stream].accum_length += cur_length; SA[cur_stream].length += cur_length; SA[cur_stream].stright = G_distance(cur_easting, cur_northing, init_easting, init_northing); SA[cur_stream].outlet = (r * ncols + c); /* add outlet to sorting */ break; } next_northing = window.north - (next_r + .5) * window.ns_res; next_easting = window.west + (next_c + .5) * window.ew_res; cur_length = G_distance(next_easting, next_northing, cur_easting, cur_northing); SA[cur_stream].accum_length += cur_length; SA[cur_stream].length += cur_length; prev_r = r; prev_c = c; r = next_r; c = next_c; if (next_stream != cur_stream) { SA[cur_stream].stright = G_distance(next_easting, next_northing, init_easting, init_northing); init_northing = cur_northing; init_easting = cur_easting; SA[cur_stream].outlet = (prev_r * ncols + prev_c); cur_stream = next_stream; cur_accum_length = 0; SA[cur_stream].init = (r * ncols + c); for (i = 0; i < SA[cur_stream].trib_num; ++i) { if (SA[SA[cur_stream].trib[i]].accum_length == 0) { done = 0; cur_accum_length = 0; break; /* do not pass accum */ } if (SA[SA[cur_stream].trib[i]].accum_length > cur_accum_length) cur_accum_length = SA[SA[cur_stream].trib[i]].accum_length; } /* end for i */ SA[cur_stream].accum_length = cur_accum_length; } /* end if */ } /* end while */ } /* end for s */ G_percent(1, 1, 1); return 0; }
int main(int argc, char *argv[]) { char *name, *outfile; int fd, projection; FILE *fp; double res; char *null_string; char ebuf[256], nbuf[256], label[512], formatbuff[256]; char b1[100], b2[100]; int n; int havefirst = FALSE; int coords = 0, i, k = -1; double e1, e2, n1, n2; RASTER_MAP_TYPE data_type; struct Cell_head window; struct { struct Option *opt1, *profile, *res, *output, *null_str; struct Flag *g, *c; } parm; struct GModule *module; G_gisinit(argv[0]); /* Set description */ module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("profile")); module->description = _("Outputs the raster map layer values lying on user-defined line(s)."); parm.opt1 = G_define_standard_option(G_OPT_R_INPUT); parm.output = G_define_option(); parm.output->key = "output"; parm.output->type = TYPE_STRING; parm.output->required = NO; parm.output->answer = "-"; parm.output->gisprompt = "new_file,file,output"; parm.output->description = _("Name of file for output (use output=- for stdout)"); parm.profile = G_define_option(); parm.profile->key = "profile"; parm.profile->type = TYPE_STRING; parm.profile->required = NO; parm.profile->multiple = YES; parm.profile->key_desc = "east,north"; parm.profile->description = _("Profile coordinate pairs"); parm.res = G_define_option(); parm.res->key = "res"; parm.res->type = TYPE_DOUBLE; parm.res->required = NO; parm.res->description = _("Resolution along profile (default = current region resolution)"); parm.null_str = G_define_option(); parm.null_str->key = "null"; parm.null_str->type = TYPE_STRING; parm.null_str->required = NO; parm.null_str->answer = "*"; parm.null_str->description = _("Character to represent no data cell"); parm.g = G_define_flag(); parm.g->key = 'g'; parm.g->description = _("Output easting and northing in first two columns of four column output"); parm.c = G_define_flag(); parm.c->key = 'c'; parm.c->description = _("Output RRR:GGG:BBB color values for each profile point"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); clr = 0; if (parm.c->answer) clr = 1; /* color output */ null_string = parm.null_str->answer; G_get_window(&window); projection = G_projection(); if (parm.res->answer) { res = atof(parm.res->answer); /* Catch bad resolution ? */ if (res <= 0) G_fatal_error(_("Illegal resolution! [%g]"), res); } else { /* Do average of EW and NS res */ res = (window.ew_res + window.ns_res) / 2; } G_message(_("Using resolution [%g]"), res); G_begin_distance_calculations(); /* Open Input File for reading */ /* Get Input Name */ name = parm.opt1->answer; if (parm.g->answer) coords = 1; /* Open Raster File */ fd = Rast_open_old(name, ""); /* initialize color structure */ if (clr) Rast_read_colors(name, "", &colors); /* Open ASCII file for output or stdout */ outfile = parm.output->answer; if ((strcmp("-", outfile)) == 0) { fp = stdout; } else if (NULL == (fp = fopen(outfile, "w"))) G_fatal_error(_("Unable to open file <%s>"), outfile); /* Get Raster Type */ data_type = Rast_get_map_type(fd); /* Done with file */ /* Show message giving output format */ G_message(_("Output Format:")); if (coords == 1) sprintf(formatbuff, _("[Easting] [Northing] [Along Track Dist.(m)] [Elevation]")); else sprintf(formatbuff, _("[Along Track Dist.(m)] [Elevation]")); if (clr) strcat(formatbuff, _(" [RGB Color]")); G_message(formatbuff); /* Get Profile Start Coords */ if (!parm.profile->answer) { /* Assume input from stdin */ for (n = 1; input(b1, ebuf, b2, nbuf, label); n++) { G_debug(4, "stdin line %d: ebuf=[%s] nbuf=[%s]", n, ebuf, nbuf); if (!G_scan_easting(ebuf, &e2, G_projection()) || !G_scan_northing(nbuf, &n2, G_projection())) G_fatal_error(_("Invalid coordinates %s %s"), ebuf, nbuf); if (havefirst) do_profile(e1, e2, n1, n2, name, coords, res, fd, data_type, fp, null_string); e1 = e2; n1 = n2; havefirst = TRUE; } } else { /* Coords from Command Line */ for (i = 0; parm.profile->answers[i]; i += 2) { /* Test for number coordinate pairs */ k = i; } if (k == 0) { /* Only one coordinate pair supplied */ G_scan_easting(parm.profile->answers[0], &e1, G_projection()); G_scan_northing(parm.profile->answers[1], &n1, G_projection()); e2 = e1; n2 = n1; /* Get profile info */ do_profile(e1, e2, n1, n2, name, coords, res, fd, data_type, fp, null_string); } else { for (i = 0; i <= k - 2; i += 2) { G_scan_easting(parm.profile->answers[i], &e1, G_projection()); G_scan_northing(parm.profile->answers[i + 1], &n1, G_projection()); G_scan_easting(parm.profile->answers[i + 2], &e2, G_projection()); G_scan_northing(parm.profile->answers[i + 3], &n2, G_projection()); /* Get profile info */ do_profile(e1, e2, n1, n2, name, coords, res, fd, data_type, fp, null_string); } } } Rast_close(fd); fclose(fp); if (clr) Rast_free_colors(&colors); exit(EXIT_SUCCESS); } /* Done with main */
int main(int argc, char *argv[]) { const char *name; char outfile[GNAME_MAX]; int fd, projection; char buf[512], buf1[1024], buf2[1024]; int screen_x, screen_y; int i, k; int frame_start = 0; double e1, e2, n1, n2; RASTER_MAP_TYPE data_type; struct Cell_head window; struct { struct Option *opt1, *route, *name, *output, *dist, *ht, *frames, *start; struct Flag *f, *c, *k, *o, *e; } parm; struct GModule *module; G_gisinit(argv[0]); /* Set description */ module = G_define_module(); G_add_keyword(_("miscellaneous")); G_add_keyword(_("graphics")); G_add_keyword(_("raster")); G_add_keyword(_("raster3d")); G_add_keyword(_("vector")); G_add_keyword(_("visualization")); module->description = _("Creates fly-through script to run in NVIZ."); parm.opt1 = G_define_standard_option(G_OPT_R_INPUT); parm.output = G_define_standard_option(G_OPT_F_OUTPUT); parm.output->description = _("Name of output script"); parm.name = G_define_option(); parm.name->key = "name"; parm.name->type = TYPE_STRING; parm.name->required = NO; parm.name->description = _("Prefix of output images (default = NVIZ)"); parm.route = G_define_option(); parm.route->key = "route"; parm.route->type = TYPE_STRING; parm.route->required = NO; parm.route->multiple = YES; parm.route->key_desc = "east,north"; parm.route->description = _("Route coordinates (east,north)"); parm.dist = G_define_option(); parm.dist->key = "dist"; parm.dist->type = TYPE_DOUBLE; parm.dist->required = YES; parm.dist->description = _("Camera layback distance (in map units)"); parm.ht = G_define_option(); parm.ht->key = "ht"; parm.ht->type = TYPE_DOUBLE; parm.ht->required = YES; parm.ht->description = _("Camera height above terrain"); parm.frames = G_define_option(); parm.frames->key = "frames"; parm.frames->type = TYPE_INTEGER; parm.frames->required = YES; parm.frames->description = _("Number of frames"); parm.start = G_define_option(); parm.start->key = "start"; parm.start->type = TYPE_INTEGER; parm.start->required = NO; parm.start->description = _("Start frame number (default=0)"); parm.f = G_define_flag(); parm.f->key = 'f'; parm.f->description = _("Full render -- Save images"); parm.c = G_define_flag(); parm.c->key = 'c'; parm.c->description = _("Fly at constant elevation (ht)"); parm.k = G_define_flag(); parm.k->key = 'k'; parm.k->description = _("Include command in the script to output a KeyFrame file"); parm.o = G_define_flag(); parm.o->key = 'o'; parm.o->description = _("Render images off-screen"); parm.e = G_define_flag(); parm.e->key = 'e'; parm.e->description = _("Enable vector and sites drawing"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* check arguments */ if (!parm.route->answer) G_fatal_error(_("Either -i flag and/or route parameter must be used")); /* get GRASS parameters */ G_get_window(&window); projection = G_projection(); D_do_conversions(&window, 0, 1, 0, 1); /* setup screen coords */ screen_x = ((int)D_get_d_west() + (int)D_get_d_east()) / 2; screen_y = ((int)D_get_d_north() + (int)D_get_d_south()) / 2; /* get camera parameters */ DIST = atof(parm.dist->answer); HT = atof(parm.ht->answer); no_frames = atoi(parm.frames->answer); if (parm.start->answer) frame_start = atoi(parm.start->answer); if (parm.c->answer) height_flag = 1; if (parm.k->answer) key_frames = 1; if (parm.o->answer && !parm.f->answer) G_fatal_error(_("Off-screen only available with full render mode")); if (parm.o->answer) off_screen = 1; /* Initialize coords */ e1 = e2 = n1 = n2 = -9999.; G_begin_distance_calculations(); /* Open Input File for reading */ name = parm.opt1->answer; /* Open Raster File */ fd = Rast_open_old(name, ""); /* Set Image name */ if (parm.name->answer) sprintf(img_name, "%s", parm.name->answer); else sprintf(img_name, "NVIZ"); /* Open ASCII file for output */ /* append ".nvscr" to filename if it doesn't already have it */ strncpy(outfile, parm.output->answer, GNAME_MAX - 7); outfile[GNAME_MAX - 7] = '\0'; /* strncpy() doesn't null terminate the string */ if (strcmp(&outfile[strlen(outfile) - 6], ".nvscr") != 0) strcat(outfile, ".nvscr"); if (NULL == (fp = fopen(outfile, "w"))) G_fatal_error(_("Unable to open file <%s>"), outfile); /* Get Raster Type */ data_type = Rast_get_map_type(fd); /* Done with file */ /* Output initial startup stuff */ sprintf(buf1, "## REGION: n=%f s=%f e=%f w=%f\n## Input=%s Dist=%f Ht=%f\n", window.north, window.south, window.east, window.west, outfile, DIST, HT); sprintf(buf2, "\nset FRAMES %d\n", no_frames); strcat(buf1, buf2); fprintf(fp, "%s", buf1); sprintf(buf1, "SendScriptLine \"Nclear_keys\""); sprintf(buf2, "\nSendScriptLine \"Nupdate_frames\""); strcat(buf1, buf2); fprintf(fp, "%s", buf1); sprintf(buf1, "\nSendScriptLine \"Nset_numsteps $FRAMES\""); sprintf(buf2, "\nSendScriptLine \"Nupdate_frames\"\n"); strcat(buf1, buf2); fprintf(fp, "%s", buf1); /* Use Linear mode for smooth frame transition */ sprintf(buf1, "\nSendScriptLine \"Nset_interp_mode linear\""); sprintf(buf2, "\nSendScriptLine \"Nupdate_frames\"\n\n"); strcat(buf1, buf2); fprintf(fp, "%s", buf1); /* eanble vector and sites drawing */ if (parm.e->answer) { sprintf(buf1, "\nSendScriptLine \"Nshow_vect on\""); sprintf(buf2, "\nSendScriptLine \"Nshow_sites on\"\n\n"); strcat(buf1, buf2); fprintf(fp, "%s", buf1); } /* Coords from Command Line */ for (i = 0; parm.route->answers[i]; i += 2) { /* Test for number coordinate pairs */ k = i; } if (k < 6) { /* Only one coordinate pair supplied */ G_fatal_error(_("You must provide at least four points %d"), k); } else { for (i = 0; i <= k - 2; i += 2) { sscanf(parm.route->answers[i], "%lf", &e1); sscanf(parm.route->answers[i + 1], "%lf", &n1); sscanf(parm.route->answers[i + 2], "%lf", &e2); sscanf(parm.route->answers[i + 3], "%lf", &n2); /* Get profile info */ do_profile(e1, e2, n1, n2, name, fd, data_type); /* Get last coord */ if (i == k - 2) do_profile(e2, e2, n2, n2, name, fd, data_type); } } /* done with coordinates */ /* Output final part of script */ /* generate key-frame script */ if (key_frames) { strcpy(buf, outfile); buf[strlen(outfile) - 6] = '\0'; /* skip extension */ strcat(buf, ".kanim"); fprintf(fp, "\n## The following saves the animation to a format\n"); fprintf(fp, "## suitable for editing with the kanimator panel\n"); fprintf(fp, "SendScriptLine \"Nprint_keys %s\"\n", buf); fprintf(fp, "puts \"Saving Key Frame file %s\"\n", buf); } /* output off-screen option */ if (off_screen) { fprintf(fp, "\n## Off screen rendering enabled \n"); fprintf(fp, "## Ensure main window is minimized before running\n"); fprintf(fp, "SendScriptLine \"Noff_screen 1\"\n"); } fprintf(fp, "\n\nset num %d", frame_start); fprintf(fp, "\n\nfor {set frame 1} {$frame <= $FRAMES} {incr frame} {"); if (parm.f->answer) { /* Full render and save */ fprintf(fp, "\nset name %s", img_name); fprintf(fp, "\nset num2 [format \"\%%04d\" $num]"); fprintf(fp, "\nappend name $num2 \".ppm\""); fprintf(fp, "\nSendScriptLine \"Ndo_framestep $frame 1\""); fprintf(fp, "\nSendScriptLine \"Nwrite_ppm $name \""); fprintf(fp, "\nincr num"); }
int main(int argc, char *argv[]) { int i, type, stat; int day, yr, Out_proj; int out_zone = 0; int overwrite; /* overwrite output map */ const char *mapset; const char *omap_name, *map_name, *iset_name, *iloc_name; struct pj_info info_in; struct pj_info info_out; const char *gbase; char date[40], mon[4]; struct GModule *module; struct Option *omapopt, *mapopt, *isetopt, *ilocopt, *ibaseopt, *smax; struct Key_Value *in_proj_keys, *in_unit_keys; struct Key_Value *out_proj_keys, *out_unit_keys; struct line_pnts *Points, *Points2; struct line_cats *Cats; struct Map_info Map; struct Map_info Out_Map; struct bound_box src_box, tgt_box; int nowrap = 0, recommend_nowrap = 0; double lmax; struct { struct Flag *list; /* list files in source location */ struct Flag *transformz; /* treat z as ellipsoidal height */ struct Flag *wrap; /* latlon output: wrap to 0,360 */ struct Flag *no_topol; /* do not build topology */ } flag; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("projection")); G_add_keyword(_("transformation")); G_add_keyword(_("import")); module->description = _("Re-projects a vector map from one location to the current location."); /* set up the options and flags for the command line parser */ ilocopt = G_define_standard_option(G_OPT_M_LOCATION); ilocopt->required = YES; ilocopt->label = _("Location containing input vector map"); ilocopt->guisection = _("Source"); isetopt = G_define_standard_option(G_OPT_M_MAPSET); isetopt->label = _("Mapset containing input vector map"); isetopt->description = _("Default: name of current mapset"); isetopt->guisection = _("Source"); mapopt = G_define_standard_option(G_OPT_V_INPUT); mapopt->required = NO; mapopt->label = _("Name of input vector map to re-project"); mapopt->description = NULL; mapopt->guisection = _("Source"); ibaseopt = G_define_standard_option(G_OPT_M_DBASE); ibaseopt->label = _("Path to GRASS database of input location"); smax = G_define_option(); smax->key = "smax"; smax->type = TYPE_DOUBLE; smax->required = NO; smax->answer = "10000"; smax->label = _("Maximum segment length in meters in output vector map"); smax->description = _("Increases accuracy of reprojected shapes, disable with smax=0"); smax->guisection = _("Target"); omapopt = G_define_standard_option(G_OPT_V_OUTPUT); omapopt->required = NO; omapopt->description = _("Name for output vector map (default: input)"); omapopt->guisection = _("Target"); flag.list = G_define_flag(); flag.list->key = 'l'; flag.list->description = _("List vector maps in input mapset and exit"); flag.transformz = G_define_flag(); flag.transformz->key = 'z'; flag.transformz->description = _("3D vector maps only"); flag.transformz->label = _("Assume z coordinate is ellipsoidal height and " "transform if possible"); flag.transformz->guisection = _("Target"); flag.wrap = G_define_flag(); flag.wrap->key = 'w'; flag.wrap->description = _("Latlon output only, default is -180,180"); flag.wrap->label = _("Disable wrapping to -180,180 for latlon output"); flag.transformz->guisection = _("Target"); flag.no_topol = G_define_flag(); flag.no_topol->key = 'b'; flag.no_topol->label = _("Do not build vector topology"); flag.no_topol->description = _("Recommended for massive point projection"); /* The parser checks if the map already exists in current mapset, we switch out the check and do it in the module after the parser */ overwrite = G_check_overwrite(argc, argv); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* start checking options and flags */ /* set input vector map name and mapset */ map_name = mapopt->answer; if (omapopt->answer) omap_name = omapopt->answer; else omap_name = map_name; if (omap_name && !flag.list->answer && !overwrite && G_find_vector2(omap_name, G_mapset())) G_fatal_error(_("option <%s>: <%s> exists. To overwrite, use the --overwrite flag"), omapopt->key, omap_name); if (isetopt->answer) iset_name = isetopt->answer; else iset_name = G_store(G_mapset()); iloc_name = ilocopt->answer; if (ibaseopt->answer) gbase = ibaseopt->answer; else gbase = G_store(G_gisdbase()); if (!ibaseopt->answer && strcmp(iloc_name, G_location()) == 0) G_fatal_error(_("Input and output locations can not be the same")); lmax = atof(smax->answer); if (lmax < 0) lmax = 0; Out_proj = G_projection(); if (Out_proj == PROJECTION_LL && flag.wrap->answer) nowrap = 1; G_begin_distance_calculations(); /* Change the location here and then come back */ select_target_env(); G_setenv_nogisrc("GISDBASE", gbase); G_setenv_nogisrc("LOCATION_NAME", iloc_name); stat = G_mapset_permissions(iset_name); if (stat >= 0) { /* yes, we can access the mapset */ /* if requested, list the vector maps in source location - MN 5/2001 */ if (flag.list->answer) { int i; char **list; G_verbose_message(_("Checking location <%s> mapset <%s>"), iloc_name, iset_name); list = G_list(G_ELEMENT_VECTOR, G_getenv_nofatal("GISDBASE"), G_getenv_nofatal("LOCATION_NAME"), iset_name); if (list[0]) { for (i = 0; list[i]; i++) { fprintf(stdout, "%s\n", list[i]); } fflush(stdout); } else { G_important_message(_("No vector maps found")); } exit(EXIT_SUCCESS); /* leave v.proj after listing */ } if (mapopt->answer == NULL) { G_fatal_error(_("Required parameter <%s> not set"), mapopt->key); } G_setenv_nogisrc("MAPSET", iset_name); /* Make sure map is available */ mapset = G_find_vector2(map_name, iset_name); if (mapset == NULL) G_fatal_error(_("Vector map <%s> in location <%s> mapset <%s> not found"), map_name, iloc_name, iset_name); /*** Get projection info for input mapset ***/ in_proj_keys = G_get_projinfo(); if (in_proj_keys == NULL) exit(EXIT_FAILURE); /* apparently the +over switch must be set in the input projection, * not the output latlon projection */ if (Out_proj == PROJECTION_LL && nowrap == 1) G_set_key_value("+over", "defined", in_proj_keys); in_unit_keys = G_get_projunits(); if (in_unit_keys == NULL) exit(EXIT_FAILURE); if (pj_get_kv(&info_in, in_proj_keys, in_unit_keys) < 0) exit(EXIT_FAILURE); Vect_set_open_level(1); G_debug(1, "Open old: location: %s mapset : %s", G_location_path(), G_mapset()); if (Vect_open_old(&Map, map_name, mapset) < 0) G_fatal_error(_("Unable to open vector map <%s>"), map_name); } else if (stat < 0) { /* allow 0 (i.e. denied permission) */ /* need to be able to read from others */ if (stat == 0) G_fatal_error(_("Mapset <%s> in input location <%s> - permission denied"), iset_name, iloc_name); else G_fatal_error(_("Mapset <%s> in input location <%s> not found"), iset_name, iloc_name); } select_current_env(); /****** get the output projection parameters ******/ out_proj_keys = G_get_projinfo(); if (out_proj_keys == NULL) exit(EXIT_FAILURE); out_unit_keys = G_get_projunits(); if (out_unit_keys == NULL) exit(EXIT_FAILURE); if (pj_get_kv(&info_out, out_proj_keys, out_unit_keys) < 0) exit(EXIT_FAILURE); G_free_key_value(in_proj_keys); G_free_key_value(in_unit_keys); G_free_key_value(out_proj_keys); G_free_key_value(out_unit_keys); if (G_verbose() == G_verbose_max()) { pj_print_proj_params(&info_in, &info_out); } /* Initialize the Point / Cat structure */ Points = Vect_new_line_struct(); Points2 = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); /* test if latlon wrapping to -180,180 should be disabled */ if (Out_proj == PROJECTION_LL && nowrap == 0) { int first = 1, counter = 0; double x, y; /* Cycle through all lines */ Vect_rewind(&Map); while (1) { type = Vect_read_next_line(&Map, Points, Cats); /* read line */ if (type == 0) continue; /* Dead */ if (type == -1) G_fatal_error(_("Reading input vector map")); if (type == -2) break; if (first && Points->n_points > 0) { first = 0; src_box.E = src_box.W = Points->x[0]; src_box.N = src_box.S = Points->y[0]; src_box.T = src_box.B = Points->z[0]; } for (i = 0; i < Points->n_points; i++) { if (src_box.E < Points->x[i]) src_box.E = Points->x[i]; if (src_box.W > Points->x[i]) src_box.W = Points->x[i]; if (src_box.N < Points->y[i]) src_box.N = Points->y[i]; if (src_box.S > Points->y[i]) src_box.S = Points->y[i]; } counter++; } if (counter == 0) { G_warning(_("Input vector map <%s> is empty"), omap_name); exit(EXIT_SUCCESS); } /* NW corner */ x = src_box.W; y = src_box.N; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } tgt_box.E = x; tgt_box.W = x; tgt_box.N = y; tgt_box.S = y; /* SW corner */ x = src_box.W; y = src_box.S; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } if (tgt_box.W > x) tgt_box.W = x; if (tgt_box.E < x) tgt_box.E = x; if (tgt_box.N < y) tgt_box.N = y; if (tgt_box.S > y) tgt_box.S = y; /* NE corner */ x = src_box.E; y = src_box.N; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } if (tgt_box.W > x) { tgt_box.E = x + 360; recommend_nowrap = 1; } if (tgt_box.N < y) tgt_box.N = y; if (tgt_box.S > y) tgt_box.S = y; /* SE corner */ x = src_box.E; y = src_box.S; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } if (tgt_box.W > x) { if (tgt_box.E < x + 360) tgt_box.E = x + 360; recommend_nowrap = 1; } if (tgt_box.N < y) tgt_box.N = y; if (tgt_box.S > y) tgt_box.S = y; } G_debug(1, "Open new: location: %s mapset : %s", G_location_path(), G_mapset()); if (Vect_open_new(&Out_Map, omap_name, Vect_is_3d(&Map)) < 0) G_fatal_error(_("Unable to create vector map <%s>"), omap_name); Vect_set_error_handler_io(NULL, &Out_Map); /* register standard i/o error handler */ Vect_copy_head_data(&Map, &Out_Map); Vect_hist_copy(&Map, &Out_Map); Vect_hist_command(&Out_Map); out_zone = info_out.zone; Vect_set_zone(&Out_Map, out_zone); /* Read and write header info */ sprintf(date, "%s", G_date()); sscanf(date, "%*s%s%d%*s%d", mon, &day, &yr); if (yr < 2000) yr = yr - 1900; else yr = yr - 2000; sprintf(date, "%s %d %d", mon, day, yr); Vect_set_date(&Out_Map, date); /* line densification works only with vector topology */ if (Map.format != GV_FORMAT_NATIVE) lmax = 0; /* Cycle through all lines */ Vect_rewind(&Map); i = 0; G_message(_("Reprojecting primitives ...")); while (TRUE) { ++i; G_progress(i, 1e3); type = Vect_read_next_line(&Map, Points, Cats); /* read line */ if (type == 0) continue; /* Dead */ if (type == -1) G_fatal_error(_("Reading input vector map")); if (type == -2) break; Vect_line_prune(Points); if (lmax > 0 && (type & GV_LINES) && Points->n_points > 1) { double x1, y1, z1, x2, y2, z2; double dx, dy, dz; double l; int i, n; Vect_reset_line(Points2); for (i = 0; i < Points->n_points - 1; i++) { x1 = Points->x[i]; y1 = Points->y[i]; z1 = Points->z[i]; n = i + 1; x2 = Points->x[n]; y2 = Points->y[n]; z2 = Points->z[n]; dx = x2 - x1; dy = y2 - y1; dz = z2 - z1; if (pj_do_transform(1, &x1, &y1, flag.transformz->answer ? &z1 : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } if (pj_do_transform(1, &x2, &y2, flag.transformz->answer ? &z2 : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } Vect_append_point(Points2, x1, y1, z1); l = G_distance(x1, y1, x2, y2); if (l > lmax) { int j; double x, y, z; x1 = Points->x[i]; y1 = Points->y[i]; z1 = Points->z[i]; n = ceil(l / lmax); for (j = 1; j < n; j++) { x = x1 + dx * j / n; y = y1 + dy * j / n; z = z1 + dz * j / n; if (pj_do_transform(1, &x, &y, flag.transformz->answer ? &z : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } Vect_append_point(Points2, x, y, z); } } } Vect_append_point(Points2, x2, y2, z2); Vect_write_line(&Out_Map, type, Points2, Cats); /* write line */ } else { if (pj_do_transform(Points->n_points, Points->x, Points->y, flag.transformz->answer ? Points->z : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } Vect_write_line(&Out_Map, type, Points, Cats); /* write line */ } } /* end lines section */ G_progress(1, 1); /* Copy tables */ if (Vect_copy_tables(&Map, &Out_Map, 0)) G_warning(_("Failed to copy attribute table to output map")); Vect_close(&Map); if (!flag.no_topol->answer) Vect_build(&Out_Map); Vect_close(&Out_Map); if (recommend_nowrap) G_important_message(_("Try to disable wrapping to -180,180 " "if topological errors occurred")); exit(EXIT_SUCCESS); }
int calculateF(int fd, area_des ad, struct Cell_head hd, double *result) { FCELL *buf; FCELL *buf_sup; FCELL corrCell; FCELL precCell; FCELL supCell; int i, j; int mask_fd = -1, *mask_buf; int ris = 0; int masked = FALSE; long npatch = 0; long tot = 0; long zero = 0; long uno = 1; long idCorr = 0; long lastId = 0; long doppi = 0; long *mask_patch_sup; long *mask_patch_corr; double indice = 0; double area = 0; /*if all cells are null area=0 */ double areaCorrect = 0; double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2; avlID_tree albero = NULL; avlID_table *array; /* open mask if needed */ if (ad->mask == 1) { if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) return RLI_ERRORE; mask_buf = G_malloc(ad->cl * sizeof(int)); if (mask_buf == NULL) { G_fatal_error("malloc mask_buf failed"); return RLI_ERRORE; } masked = TRUE; } mask_patch_sup = G_malloc(ad->cl * sizeof(long)); if (mask_patch_sup == NULL) { G_fatal_error("malloc mask_patch_sup failed"); return RLI_ERRORE; } mask_patch_corr = G_malloc(ad->cl * sizeof(long)); if (mask_patch_corr == NULL) { G_fatal_error("malloc mask_patch_corr failed"); return RLI_ERRORE; } buf_sup = Rast_allocate_f_buf(); if (buf_sup == NULL) { G_fatal_error("malloc buf_sup failed"); return RLI_ERRORE; } buf = Rast_allocate_f_buf(); if (buf == NULL) { G_fatal_error("malloc buf failed"); return RLI_ERRORE; } Rast_set_f_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */ for (i = 0; i < ad->cl; i++) { mask_patch_sup[i] = 0; mask_patch_corr[i] = 0; } /*for each raster row */ for (j = 0; j < ad->rl; j++) { if (j > 0) { buf_sup = RLI_get_fcell_raster_row(fd, j - 1 + ad->y, ad); } buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad); if (masked) { if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) { G_fatal_error("mask read failed"); return RLI_ERRORE; } } Rast_set_f_null_value(&precCell, 1); for (i = 0; i < ad->cl; i++) { /*for each cell in the row */ corrCell = buf[i + ad->x]; if (((masked) && (mask_buf[i + ad->x] == 0))) { Rast_set_f_null_value(&corrCell, 1); } if (!(Rast_is_null_value(&corrCell, FCELL_TYPE))) { area++; if (i > 0) precCell = buf[i - 1 + ad->x]; if (j == 0) Rast_set_f_null_value(&supCell, 1); else supCell = buf_sup[i + ad->x]; if (corrCell != precCell) { if (corrCell != supCell) { /*new patch */ if (idCorr == 0) { /*first patch */ lastId = 1; idCorr = 1; mask_patch_corr[i] = idCorr; } else { /*not first patch */ /* put in the tree previous value */ if (albero == NULL) { albero = avlID_make(idCorr, uno); if (albero == NULL) { G_fatal_error("avlID_make error"); return RLI_ERRORE; } npatch++; } else { /*tree not empty */ ris = avlID_add(&albero, idCorr, uno); switch (ris) { case AVL_ERR: { G_fatal_error("avlID_add error"); return RLI_ERRORE; } case AVL_ADD: { npatch++; break; } case AVL_PRES: { break; } default: { G_fatal_error ("avlID_add unknown error"); return RLI_ERRORE; } } } lastId++; idCorr = lastId; mask_patch_corr[i] = idCorr; } } else { /*current cell and upper cell are equal */ if ((corrCell == precCell) && (mask_patch_sup[i] != mask_patch_corr[i - 1])) { long r = 0; long del = mask_patch_sup[i]; r = avlID_sub(&albero, del); if (r == 0) { G_fatal_error("avlID_sub error"); return RLI_ERRORE; } /*Remove one patch because it makes part of a patch already found */ ris = avlID_add(&albero, idCorr, uno); switch (ris) { case AVL_ERR: { G_fatal_error("avlID_add error"); return RLI_ERRORE; } case AVL_ADD: { npatch++; break; } case AVL_PRES: { break; } default: { G_fatal_error("avlID_add unknown error"); return RLI_ERRORE; } } r = i; while (i < ad->cl) { if (mask_patch_sup[r] == del) { mask_patch_sup[r] = idCorr; } else { r = ad->cl + 1; } } } if (albero == NULL) { albero = avlID_make(idCorr, uno); if (albero == NULL) { G_fatal_error("avlID_make error"); return RLI_ERRORE; } npatch++; } else { /*the tree (albero) isn't null */ ris = avlID_add(&albero, idCorr, uno); switch (ris) { case AVL_ERR: { G_fatal_error("avlID_add error"); return RLI_ERRORE; } case AVL_ADD: { npatch++; break; } case AVL_PRES: { break; } default: { G_fatal_error("avlID_add unknown error"); return RLI_ERRORE; } } } idCorr = mask_patch_sup[i]; mask_patch_corr[i] = idCorr; } } else { /*current cell and previous cell are equal */ if ((corrCell == supCell) && (mask_patch_sup[i] != mask_patch_corr[i - 1])) { int l; mask_patch_corr[i] = mask_patch_sup[i]; l = i - 1; while (l >= 0) { if (mask_patch_corr[l] == idCorr) { mask_patch_corr[l] = mask_patch_sup[i]; l--; } else { l = (-1); } } lastId--; idCorr = mask_patch_sup[i]; } else { mask_patch_corr[i] = idCorr; } } } else { /*null cell or cell not to consider */ mask_patch_corr[i] = 0; } } mask_patch_sup = mask_patch_corr; } if (area != 0) { if (albero == NULL) { albero = avlID_make(idCorr, uno); if (albero == NULL) { G_fatal_error("avlID_make error"); return RLI_ERRORE; } npatch++; } else { ris = avlID_add(&albero, idCorr, uno); switch (ris) { case AVL_ERR: { G_fatal_error("avlID_add error"); return RLI_ERRORE; } case AVL_ADD: { npatch++; break; } case AVL_PRES: { break; } default: { G_fatal_error("avlID_add unknown error"); return RLI_ERRORE; } } } array = G_malloc(npatch * sizeof(avlID_tableRow)); if (array == NULL) { G_fatal_error("malloc array failed"); return RLI_ERRORE; } tot = avlID_to_array(albero, zero, array); if (tot != npatch) { G_warning ("avlID_to_array unaspected value. the result could be wrong"); return RLI_ERRORE; } for (i = 0; i < npatch; i++) { if (array[i]->tot == 0) doppi++; } npatch = npatch - doppi; /*calculate distance */ G_begin_distance_calculations(); /* EW Dist at North edge */ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north); /* EW Dist at South Edge */ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south); /* NS Dist at East edge */ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south); /* NS Dist at West edge */ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south); areaCorrect = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) * (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (area); indice = areaCorrect / npatch; G_free(array); } else indice = (double)(0); *result = indice; if (masked) G_free(mask_buf); G_free(mask_patch_corr); return RLI_OK; }
int main(int argc, char *argv[]) { char *name, *outfile; const char *unit; int unit_id; double factor; int fd, projection; FILE *fp, *coor_fp; double res; char *null_string; char ebuf[256], nbuf[256], label[512], formatbuff[256]; char b1[100], b2[100]; int n; int havefirst = FALSE; int coords = 0, i, k = -1; double e1, e2, n1, n2; RASTER_MAP_TYPE data_type; struct Cell_head window; struct { struct Option *opt1, *profile, *res, *output, *null_str, *coord_file, *units; struct Flag *g, *c, *m; } parm; struct GModule *module; G_gisinit(argv[0]); /* Set description */ module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("profile")); module->description = _("Outputs the raster map layer values lying on user-defined line(s)."); parm.opt1 = G_define_standard_option(G_OPT_R_INPUT); parm.output = G_define_standard_option(G_OPT_F_OUTPUT); parm.output->required = NO; parm.output->answer = "-"; parm.output->description = _("Name of file for output (use output=- for stdout)"); parm.profile = G_define_standard_option(G_OPT_M_COORDS); parm.profile->required = NO; parm.profile->multiple = YES; parm.profile->description = _("Profile coordinate pairs"); parm.coord_file = G_define_standard_option(G_OPT_F_INPUT); parm.coord_file->key = "file"; parm.coord_file->required = NO; parm.coord_file->label = _("Name of input file containing coordinate pairs"); parm.coord_file->description = _("Use instead of the 'coordinates' option. " "\"-\" reads from stdin."); parm.res = G_define_option(); parm.res->key = "resolution"; parm.res->type = TYPE_DOUBLE; parm.res->required = NO; parm.res->description = _("Resolution along profile (default = current region resolution)"); parm.null_str = G_define_option(); parm.null_str->key = "null"; parm.null_str->type = TYPE_STRING; parm.null_str->required = NO; parm.null_str->answer = "*"; parm.null_str->description = _("Character to represent no data cell"); parm.g = G_define_flag(); parm.g->key = 'g'; parm.g->description = _("Output easting and northing in first two columns of four column output"); parm.c = G_define_flag(); parm.c->key = 'c'; parm.c->description = _("Output RRR:GGG:BBB color values for each profile point"); parm.units = G_define_standard_option(G_OPT_M_UNITS); parm.units->options = "meters,kilometers,feet,miles"; parm.units->label = parm.units->description; parm.units->description = _("If units are not specified, current location units are used. " "Meters are used by default in geographic (latlon) locations."); if (G_parser(argc, argv)) exit(EXIT_FAILURE); clr = 0; if (parm.c->answer) clr = 1; /* color output */ null_string = parm.null_str->answer; if ((parm.profile->answer && parm.coord_file->answer) || (!parm.profile->answer && !parm.coord_file->answer)) G_fatal_error(_("Either use profile option or coordinate_file " " option, but not both")); G_get_window(&window); projection = G_projection(); /* get conversion factor and units name */ if (parm.units->answer) { unit_id = G_units(parm.units->answer); factor = 1. / G_meters_to_units_factor(unit_id); unit = G_get_units_name(unit_id, 1, 0); } /* keep meters in case of latlon */ else if (projection == PROJECTION_LL) { factor = 1; unit = "meters"; } else { /* get conversion factor to current units */ unit = G_database_unit_name(1); factor = G_database_units_to_meters_factor(); } if (parm.res->answer) { res = atof(parm.res->answer); /* Catch bad resolution ? */ if (res <= 0) G_fatal_error(_("Illegal resolution %g [%s]"), res / factor, unit); } else { /* Do average of EW and NS res */ res = (window.ew_res + window.ns_res) / 2; } G_message(_("Using resolution: %g [%s]"), res / factor, unit); G_begin_distance_calculations(); /* Open Input File for reading */ /* Get Input Name */ name = parm.opt1->answer; if (parm.g->answer) coords = 1; /* Open Raster File */ fd = Rast_open_old(name, ""); /* initialize color structure */ if (clr) Rast_read_colors(name, "", &colors); /* Open ASCII file for output or stdout */ outfile = parm.output->answer; if ((strcmp("-", outfile)) == 0) { fp = stdout; } else if (NULL == (fp = fopen(outfile, "w"))) G_fatal_error(_("Unable to open file <%s>"), outfile); /* Get Raster Type */ data_type = Rast_get_map_type(fd); /* Done with file */ /* Show message giving output format */ G_message(_("Output columns:")); if (coords == 1) sprintf(formatbuff, _("Easting, Northing, Along track dist. [%s], Elevation"), unit); else sprintf(formatbuff, _("Along track dist. [%s], Elevation"), unit); if (clr) strcat(formatbuff, _(" RGB color")); G_message(formatbuff); /* Get Profile Start Coords */ if (parm.coord_file->answer) { if (strcmp("-", parm.coord_file->answer) == 0) coor_fp = stdin; else coor_fp = fopen(parm.coord_file->answer, "r"); if (coor_fp == NULL) G_fatal_error(_("Could not open <%s>"), parm.coord_file->answer); for (n = 1; input(b1, ebuf, b2, nbuf, label, coor_fp); n++) { G_debug(4, "stdin line %d: ebuf=[%s] nbuf=[%s]", n, ebuf, nbuf); if (!G_scan_easting(ebuf, &e2, G_projection()) || !G_scan_northing(nbuf, &n2, G_projection())) G_fatal_error(_("Invalid coordinates %s %s"), ebuf, nbuf); if (havefirst) do_profile(e1, e2, n1, n2, coords, res, fd, data_type, fp, null_string, unit, factor); e1 = e2; n1 = n2; havefirst = TRUE; } if (coor_fp != stdin) fclose(coor_fp); } else { /* Coords given on the Command Line using the profile= option */ for (i = 0; parm.profile->answers[i]; i += 2) { /* Test for number coordinate pairs */ k = i; } if (k == 0) { /* Only one coordinate pair supplied */ G_scan_easting(parm.profile->answers[0], &e1, G_projection()); G_scan_northing(parm.profile->answers[1], &n1, G_projection()); e2 = e1; n2 = n1; /* Get profile info */ do_profile(e1, e2, n1, n2, coords, res, fd, data_type, fp, null_string, unit, factor); } else { for (i = 0; i <= k - 2; i += 2) { G_scan_easting(parm.profile->answers[i], &e1, G_projection()); G_scan_northing(parm.profile->answers[i + 1], &n1, G_projection()); G_scan_easting(parm.profile->answers[i + 2], &e2, G_projection()); G_scan_northing(parm.profile->answers[i + 3], &n2, G_projection()); /* Get profile info */ do_profile(e1, e2, n1, n2, coords, res, fd, data_type, fp, null_string, unit, factor); } } } Rast_close(fd); fclose(fp); if (clr) Rast_free_colors(&colors); exit(EXIT_SUCCESS); } /* Done with main */
int main(int argc, char *argv[]) { /* IO output[] = { {"local_diff",NO,"Local elevation difference"}, {"out_dist",NO,"Upstream distance form init"}, */ struct GModule *module; struct Option *in_dir_opt, /* options */ *in_stm_opt, *in_elev_opt, *out_identifier_opt, *out_distance_opt, *out_difference_opt, *out_gradient_opt, *out_curvature_opt, *opt_swapsize; struct Flag *flag_segmentation, *flag_local, *flag_cells, *flag_downstream; char *method_name[] = { "UPSTREAM", "DOWNSTREAM" }; int number_of_segs; int number_of_streams; int segmentation, downstream, local, cells; /*flags */ /* initialize GIS environment */ G_gisinit(argv[0]); /* initialize module */ module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("hydrology")); G_add_keyword(_("stream network")); module->description = _("Calculates local parameters for individual streams."); in_stm_opt = G_define_standard_option(G_OPT_R_INPUT); in_stm_opt->key = "stream_rast"; in_stm_opt->description = _("Name of input raster map with stream network"); in_dir_opt = G_define_standard_option(G_OPT_R_INPUT); in_dir_opt->key = "direction"; in_dir_opt->description = _("Name of input raster map with flow direction"); in_elev_opt = G_define_standard_option(G_OPT_R_ELEV); out_identifier_opt = G_define_standard_option(G_OPT_R_OUTPUT); out_identifier_opt->key = "identifier"; out_identifier_opt->required = NO; out_identifier_opt->description = _("Name for output unique stream identifier raster map"); out_identifier_opt->guisection = _("Output maps"); out_distance_opt = G_define_standard_option(G_OPT_R_OUTPUT); out_distance_opt->key = "distance"; out_distance_opt->required = NO; out_distance_opt->description = _("Name for output init/join/outlet distance raster map"); out_distance_opt->guisection = _("Output maps"); out_difference_opt = G_define_standard_option(G_OPT_R_OUTPUT); out_difference_opt->key = "difference"; out_difference_opt->required = NO; out_difference_opt->description = _("Name for output elevation init/join/outlet difference raster map"); out_difference_opt->guisection = _("Output maps"); out_gradient_opt = G_define_standard_option(G_OPT_R_OUTPUT); out_gradient_opt->key = "gradient"; out_gradient_opt->required = NO; out_gradient_opt->description = _("Name for output mean init/join/outlet gradient of stream raster map"); out_gradient_opt->guisection = _("Output maps"); out_curvature_opt = G_define_standard_option(G_OPT_R_OUTPUT); out_curvature_opt->key = "curvature"; out_curvature_opt->required = NO; out_curvature_opt->description = _("Name for output local stream curvature raster map"); out_curvature_opt->guisection = _("Output maps"); opt_swapsize = G_define_option(); opt_swapsize->key = "memory"; opt_swapsize->type = TYPE_INTEGER; opt_swapsize->answer = "300"; opt_swapsize->description = _("Maximum memory used in memory swap mode (MB)"); opt_swapsize->guisection = _("Memory settings"); flag_downstream = G_define_flag(); flag_downstream->key = 'd'; flag_downstream->description = _("Calculate parameters from outlet (downstream values)"); flag_local = G_define_flag(); flag_local->key = 'l'; flag_local->description = _("Calculate local values (for current cell)"); flag_cells = G_define_flag(); flag_cells->key = 'c'; flag_cells->description = _("Calculate distance in cell count (ignored local)"); flag_segmentation = G_define_flag(); flag_segmentation->key = 'm'; flag_segmentation->description = _("Use memory swap (operation is slow)"); flag_segmentation->guisection = _("Memory settings"); if (G_parser(argc, argv)) /* parser */ exit(EXIT_FAILURE); segmentation = (flag_segmentation->answer != 0); downstream = (flag_downstream->answer != 0); if (!out_identifier_opt->answer && !out_distance_opt->answer && !out_difference_opt->answer && !out_gradient_opt->answer && !out_curvature_opt->answer) G_fatal_error(_("You must select at least one output raster maps")); local = (flag_local->answer != 0); cells = (flag_cells->answer != 0); nrows = Rast_window_rows(); ncols = Rast_window_cols(); G_get_window(&window); G_begin_distance_calculations(); if (!segmentation) { MAP map_dirs, map_streams, map_elevation, map_output, map_identifier; CELL **streams, **dirs, **identifier = NULL; FCELL **elevation; DCELL **output; G_message(_("All in RAM calculation - direction <%s>..."), method_name[downstream]); ram_create_map(&map_streams, CELL_TYPE); ram_read_map(&map_streams, in_stm_opt->answer, 1, CELL_TYPE); ram_create_map(&map_dirs, CELL_TYPE); ram_read_map(&map_dirs, in_dir_opt->answer, 1, CELL_TYPE); ram_create_map(&map_elevation, FCELL_TYPE); ram_read_map(&map_elevation, in_elev_opt->answer, 0, -1); streams = (CELL **) map_streams.map; dirs = (CELL **) map_dirs.map; elevation = (FCELL **) map_elevation.map; number_of_streams = ram_number_of_streams(streams, dirs) + 1; ram_build_streamlines(streams, dirs, elevation, number_of_streams); ram_release_map(&map_streams); ram_release_map(&map_dirs); ram_create_map(&map_output, DCELL_TYPE); output = (DCELL **) map_output.map; /* one output for all maps */ if (out_identifier_opt->answer) { ram_create_map(&map_identifier, CELL_TYPE); identifier = (CELL **) map_identifier.map; ram_calculate_identifiers(identifier, number_of_streams, downstream); ram_write_map(&map_identifier, out_identifier_opt->answer, CELL_TYPE, 1, 0); ram_release_map(&map_identifier); } if (out_difference_opt->answer) { ram_set_null_output(output); if (local) ram_calculate_difference(output, number_of_streams, downstream); else ram_calculate_drop(output, number_of_streams, downstream); ram_write_map(&map_output, out_difference_opt->answer, DCELL_TYPE, 0, 0); } if (out_distance_opt->answer) { ram_set_null_output(output); if (local && !cells) ram_calculate_local_distance(output, number_of_streams, downstream); if (!local && !cells) ram_calculate_distance(output, number_of_streams, downstream); if (cells) ram_calculate_cell(output, number_of_streams, downstream); ram_write_map(&map_output, out_distance_opt->answer, DCELL_TYPE, 0, 0); } if (out_gradient_opt->answer) { ram_set_null_output(output); if (local) ram_calculate_local_gradient(output, number_of_streams, downstream); else ram_calculate_gradient(output, number_of_streams, downstream); ram_write_map(&map_output, out_gradient_opt->answer, DCELL_TYPE, 0, 0); } if (out_curvature_opt->answer) { ram_set_null_output(output); ram_calculate_curvature(output, number_of_streams, downstream); ram_write_map(&map_output, out_curvature_opt->answer, DCELL_TYPE, 0, 0); } ram_release_map(&map_output); } if (segmentation) { SEG map_dirs, map_streams, map_elevation, map_output, map_identifier; SEGMENT *streams, *dirs, *elevation, *output, *identifier; G_message(_("Calculating segments in direction <%s> (may take some time)..."), method_name[downstream]); number_of_segs = (int)atof(opt_swapsize->answer); number_of_segs = number_of_segs < 32 ? (int)(32 / 0.18) : number_of_segs / 0.18; seg_create_map(&map_streams, SROWS, SCOLS, number_of_segs, CELL_TYPE); seg_read_map(&map_streams, in_stm_opt->answer, 1, CELL_TYPE); seg_create_map(&map_dirs, SROWS, SCOLS, number_of_segs, CELL_TYPE); seg_read_map(&map_dirs, in_dir_opt->answer, 1, CELL_TYPE); seg_create_map(&map_elevation, SROWS, SCOLS, number_of_segs, FCELL_TYPE); seg_read_map(&map_elevation, in_elev_opt->answer, 0, -1); streams = &map_streams.seg; dirs = &map_dirs.seg; elevation = &map_elevation.seg; number_of_streams = seg_number_of_streams(streams, dirs) + 1; seg_build_streamlines(streams, dirs, elevation, number_of_streams); seg_release_map(&map_streams); seg_release_map(&map_dirs); seg_create_map(&map_output, SROWS, SCOLS, number_of_segs, DCELL_TYPE); output = &map_output.seg; /* one output for all maps */ if (out_identifier_opt->answer) { seg_create_map(&map_identifier, SROWS, SCOLS, number_of_segs, CELL_TYPE); identifier = &map_identifier.seg; seg_calculate_identifiers(identifier, number_of_streams, downstream); seg_write_map(&map_identifier, out_identifier_opt->answer, CELL_TYPE, 1, 0); seg_release_map(&map_identifier); } if (out_difference_opt->answer) { seg_set_null_output(output); if (local) seg_calculate_difference(output, number_of_streams, downstream); else seg_calculate_drop(output, number_of_streams, downstream); seg_write_map(&map_output, out_difference_opt->answer, DCELL_TYPE, 0, 0); } if (out_distance_opt->answer) { seg_set_null_output(output); if (local && !cells) seg_calculate_local_distance(output, number_of_streams, downstream); if (!local && !cells) seg_calculate_distance(output, number_of_streams, downstream); if (cells) seg_calculate_cell(output, number_of_streams, downstream); seg_write_map(&map_output, out_distance_opt->answer, DCELL_TYPE, 0, 0); } if (out_gradient_opt->answer) { seg_set_null_output(output); if (local) seg_calculate_local_gradient(output, number_of_streams, downstream); else seg_calculate_gradient(output, number_of_streams, downstream); seg_write_map(&map_output, out_gradient_opt->answer, DCELL_TYPE, 0, 0); } if (out_curvature_opt->answer) { seg_set_null_output(output); seg_calculate_curvature(output, number_of_streams, downstream); seg_write_map(&map_output, out_curvature_opt->answer, DCELL_TYPE, 0, 0); } seg_release_map(&map_output); } free_attributes(number_of_streams); exit(EXIT_SUCCESS); }