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; }
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; }
/*! \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]); }
double get_distance(int r, int c, int d) { double northing, easting, next_northing, next_easting; int next_r, next_c; next_r = NR(d); next_c = NC(d); northing = window.north - (r + .5) * window.ns_res; easting = window.west + (c + .5) * window.ew_res; next_northing = window.north - (next_r + .5) * window.ns_res; next_easting = window.west + (next_c + .5) * window.ew_res; return G_distance(easting, northing, next_easting, next_northing); }
void find_minimum_distance(const struct CatEdgeList *list1, const struct CatEdgeList *list2, double *east1, double *north1, double *east2, double *north2, double *distance, const struct Cell_head *region, int overlap, const char *name1, const char *name2) { int i1, i2; double dist; double e1, n1, e2, n2; extern double G_distance(); extern double Rast_row_to_northing(); extern double Rast_col_to_easting(); int zerro_row, zerro_col; int nulldistance = 0; if (overlap) nulldistance = null_distance(name1, name2, &zerro_row, &zerro_col); for (i1 = 0; i1 < list1->ncells; i1++) { e1 = Rast_col_to_easting(list1->col[i1] + 0.5, region); n1 = Rast_row_to_northing(list1->row[i1] + 0.5, region); for (i2 = 0; i2 < list2->ncells; i2++) { if (!nulldistance) { e2 = Rast_col_to_easting(list2->col[i2] + 0.5, region); n2 = Rast_row_to_northing(list2->row[i2] + 0.5, region); dist = G_distance(e1, n1, e2, n2); } else { e2 = e1 = Rast_col_to_easting(zerro_col + 0.5, region); n2 = n1 = Rast_row_to_northing(zerro_row + 0.5, region); dist = 0.; } if ((i1 == 0 && i2 == 0) || (dist < *distance)) { *distance = dist; *east1 = e1; *north1 = n1; *east2 = e2; *north2 = n2; } if (nulldistance) break; } if (nulldistance) break; } }
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 main(int argc, char **argv) { struct Flag *printattributes, *topo_flag, *shell_flag; struct Option *map_opt, *field_opt, *coords_opt, *maxdistance; struct Cell_head window; struct GModule *module; char buf[2000]; int i, level, ret; int *field; double xval, yval, xres, yres, maxd, x; double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2; char nsres[30], ewres[30]; char ch; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("position")); G_add_keyword(_("querying")); module->description = _("Queries a vector map at given locations."); map_opt = G_define_standard_option(G_OPT_V_MAPS); field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL); coords_opt = G_define_standard_option(G_OPT_M_EN); coords_opt->label = _("Coordinates for query"); coords_opt->description = _("If not given read from standard input"); maxdistance = G_define_option(); maxdistance->type = TYPE_DOUBLE; maxdistance->key = "distance"; maxdistance->answer = "0"; maxdistance->multiple = NO; maxdistance->description = _("Query threshold distance"); topo_flag = G_define_flag(); topo_flag->key = 'd'; topo_flag->description = _("Print topological information (debugging)"); topo_flag->guisection = _("Print"); printattributes = G_define_flag(); printattributes->key = 'a'; printattributes->description = _("Print attribute information"); printattributes->guisection = _("Print"); shell_flag = G_define_flag(); shell_flag->key = 'g'; shell_flag->description = _("Print the stats in shell script style"); shell_flag->guisection = _("Print"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (map_opt->answers && map_opt->answers[0]) vect = map_opt->answers; maxd = atof(maxdistance->answer); /* * fprintf(stdout, maxdistance->answer); * fprintf(stdout, "Maxd is %f", maxd); * fprintf(stdout, xcoord->answer); * fprintf(stdout, "xval is %f", xval); * fprintf(stdout, ycoord->answer); * fprintf(stdout, "yval is %f", yval); */ if (maxd == 0.0) { G_get_window(&window); x = window.proj; G_format_resolution(window.ew_res, ewres, x); G_format_resolution(window.ns_res, nsres, x); EW_DIST1 = G_distance(window.east, window.north, window.west, window.north); /* EW Dist at South Edge */ EW_DIST2 = 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 West edge */ NS_DIST2 = G_distance(window.west, window.north, window.west, window.south); xres = ((EW_DIST1 + EW_DIST2) / 2) / window.cols; yres = ((NS_DIST1 + NS_DIST2) / 2) / window.rows; if (xres > yres) maxd = xres; else maxd = yres; } /* Look at maps given on command line */ if (vect) { for (i = 0; vect[i]; i++) ; nvects = i; for (i = 0; field_opt->answers[i]; i++) ; if (nvects != i) G_fatal_error(_("Number of given vector maps (%d) differs from number of layers (%d)"), nvects, i); Map = (struct Map_info *) G_malloc(nvects * sizeof(struct Map_info)); field = (int *) G_malloc(nvects * sizeof(int)); for (i = 0; i < nvects; i++) { level = Vect_open_old2(&Map[i], vect[i], "", field_opt->answers[i]); if (level < 2) G_fatal_error(_("You must build topology on vector map <%s>"), vect[i]); field[i] = Vect_get_field_number(&Map[i], field_opt->answers[i]); } } if (!coords_opt->answer) { /* read them from stdin */ setvbuf(stdin, NULL, _IOLBF, 0); setvbuf(stdout, NULL, _IOLBF, 0); while (fgets(buf, sizeof(buf), stdin) != NULL) { ret = sscanf(buf, "%lf%c%lf", &xval, &ch, &yval); if (ret == 3 && (ch == ',' || ch == ' ' || ch == '\t')) { what(xval, yval, maxd, topo_flag->answer, printattributes->answer, shell_flag->answer, field); } else { G_warning(_("Unknown input format, skipping: '%s'"), buf); continue; } } } else { /* use coords given on command line */ for (i = 0; coords_opt->answers[i] != NULL; i += 2) { xval = atof(coords_opt->answers[i]); yval = atof(coords_opt->answers[i + 1]); what(xval, yval, maxd, topo_flag->answer, printattributes->answer, shell_flag->answer, field); } } for (i = 0; i < nvects; i++) Vect_close(&Map[i]); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { struct Flag *printattributes, *topo_flag, *shell_flag; struct Option *opt1, *coords_opt, *maxdistance; struct Cell_head window; struct GModule *module; char *mapset; char *str; char buf[2000]; int i, j, level, width = 0, mwidth = 0, ret; double xval, yval, xres, yres, maxd, x; double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2; char nsres[30], ewres[30]; char ch; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("vector, querying"); module->description = _("Queries a vector map layer at given locations."); opt1 = G_define_standard_option(G_OPT_V_MAP); opt1->multiple = YES; opt1->required = YES; coords_opt = G_define_option(); coords_opt->key = "east_north"; coords_opt->type = TYPE_DOUBLE; coords_opt->key_desc = "east,north"; coords_opt->required = NO; coords_opt->multiple = YES; coords_opt->label = _("Coordinates for query"); coords_opt->description = _("If not given reads from standard input"); maxdistance = G_define_option(); maxdistance->type = TYPE_DOUBLE; maxdistance->key = "distance"; maxdistance->answer = "0"; maxdistance->multiple = NO; maxdistance->description = _("Query threshold distance"); topo_flag = G_define_flag(); topo_flag->key = 'd'; topo_flag->description = _("Print topological information (debugging)"); printattributes = G_define_flag(); printattributes->key = 'a'; printattributes->description = _("Print attribute information"); shell_flag = G_define_flag(); shell_flag->key = 'g'; shell_flag->description = _("Print the stats in shell script style"); if ((argc > 1 || !vect) && G_parser(argc, argv)) exit(EXIT_FAILURE); if (opt1->answers && opt1->answers[0]) vect = opt1->answers; maxd = atof(maxdistance->answer); /* * fprintf(stdout, maxdistance->answer); * fprintf(stdout, "Maxd is %f", maxd); * fprintf(stdout, xcoord->answer); * fprintf(stdout, "xval is %f", xval); * fprintf(stdout, ycoord->answer); * fprintf(stdout, "yval is %f", yval); */ if (maxd == 0.0) { G_get_window(&window); x = window.proj; G_format_resolution(window.ew_res, ewres, x); G_format_resolution(window.ns_res, nsres, x); EW_DIST1 = G_distance(window.east, window.north, window.west, window.north); /* EW Dist at South Edge */ EW_DIST2 = 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 West edge */ NS_DIST2 = G_distance(window.west, window.north, window.west, window.south); xres = ((EW_DIST1 + EW_DIST2) / 2) / window.cols; yres = ((NS_DIST1 + NS_DIST2) / 2) / window.rows; if (xres > yres) maxd = xres; else maxd = yres; } /* Look at maps given on command line */ if (vect) { for (i = 0; vect[i]; i++) ; nvects = i; Map = (struct Map_info *)G_malloc(nvects * sizeof(struct Map_info)); width = mwidth = 0; for (i = 0; i < nvects; i++) { str = strchr(vect[i], '@'); if (str) j = str - vect[i]; else j = strlen(vect[i]); if (j > width) width = j; mapset = G_find_vector2(vect[i], ""); if (!mapset) G_fatal_error(_("Vector map <%s> not found"), vect[i]); j = strlen(mapset); if (j > mwidth) mwidth = j; level = Vect_open_old(&Map[i], vect[i], mapset); if (level < 2) G_fatal_error(_("You must build topology on vector map <%s>"), vect[i]); G_verbose_message(_("Building spatial index...")); Vect_build_spatial_index(&Map[i]); } } if (!coords_opt->answer) { /* if coords are not given on command line, read them from stdin */ setvbuf(stdin, NULL, _IOLBF, 0); setvbuf(stdout, NULL, _IOLBF, 0); while (fgets(buf, sizeof(buf), stdin) != NULL) { ret = sscanf(buf, "%lf%c%lf", &xval, &ch, &yval); if (ret == 3 && (ch == ',' || ch == ' ' || ch == '\t')) { what(xval, yval, maxd, width, mwidth, topo_flag->answer, printattributes->answer, shell_flag->answer); } else { G_warning(_("Unknown input format, skipping: '%s'"), buf); continue; } } } else { /* use coords given on command line */ for (i = 0; coords_opt->answers[i] != NULL; i += 2) { xval = atof(coords_opt->answers[i]); yval = atof(coords_opt->answers[i + 1]); what(xval, yval, maxd, width, mwidth, topo_flag->answer, printattributes->answer, shell_flag->answer); } } for (i = 0; i < nvects; i++) Vect_close(&Map[i]); exit(EXIT_SUCCESS); }
int seg_calculate_upstream(SEGMENT * distance, SEGMENT * dirs, SEGMENT * elevation, SEGMENT * tmp_elevation, int near) { int r, c; int next_r, next_c; double easting, northing; double cell_easting, cell_northing; int i, j, k, d, d_next; DCELL minus_one_cell = -1; DCELL zero_cell = 0; int done; int counter; int n_inits = 0; double cur_dist; POINT *d_inits; double tmp_dist = 0; double target_elev = 0; CELL dirs_cell; DCELL distance_cell, elevation_cell, tmp_elevation_cell; /* size_t elevation_data_size; */ struct Cell_head window; Rast_get_window(&window); if (elevation) { /* elevation_data_size = Rast_cell_size(DCELL_TYPE); */ for (r = 0; r < nrows; ++r) for (c = 0; c < ncols; ++c) { Segment_get(elevation, &elevation_cell, r, c); Segment_put(tmp_elevation, &elevation_cell, r, c); } } for (r = 0; r < nrows; ++r) for (c = 0; c < ncols; ++c) { Segment_get(distance, &distance_cell, r, c); for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; /* out of border */ j = DIAG(i); next_r = NR(i); next_c = NC(i); Segment_get(dirs, &dirs_cell, next_r, next_c); if (dirs_cell == j && distance_cell != 0) { /* is contributing cell */ Segment_put(distance, &minus_one_cell, r, c); break; } } /* end for i */ Segment_get(distance, &distance_cell, r, c); Segment_get(dirs, &dirs_cell, r, c); if (distance_cell == 1) { if (distance_cell == 1 && dirs_cell > 0) n_inits++; else if (dirs_cell > 0) Segment_put(distance, &minus_one_cell, r, c); } } d_inits = (POINT *) G_malloc(n_inits * sizeof(POINT)); k = 0; for (r = 0; r < nrows; ++r) for (c = 0; c < ncols; ++c) { Segment_get(distance, &distance_cell, r, c); if (distance_cell == 1) { Segment_put(distance, &zero_cell, r, c); if (elevation) Segment_put(elevation, &zero_cell, r, c); Segment_get(dirs, &d, r, c); Segment_get(dirs, &d_next, NR(d), NR(d)); if (d_next < 0) continue; d_inits[k].r = r; d_inits[k].c = c; d_inits[k].cur_dist = 0; if (elevation) Segment_get(tmp_elevation, &(d_inits[k].target_elev), r, c); k++; } } counter = n_inits = k; G_message(_("Calculate upstream parameters...")); while (n_inits > 0) { k = 0; G_percent((counter - n_inits), counter, 10); for (i = 0; i < n_inits; ++i) { r = d_inits[i].r; c = d_inits[i].c; Segment_get(dirs, &d, r, c); next_r = NR(d); next_c = NC(d); tmp_dist = d_inits[i].cur_dist; if (elevation) target_elev = d_inits[i].target_elev; easting = window.west + (c + 0.5) * window.ew_res; northing = window.north - (r + 0.5) * window.ns_res; cell_easting = window.west + (next_c + 0.5) * window.ew_res; cell_northing = window.north - (next_r + 0.5) * window.ns_res; cur_dist = tmp_dist + G_distance(easting, northing, cell_easting, cell_northing); Segment_get(distance, &distance_cell, next_r, next_c); if (near) done = (distance_cell > cur_dist || distance_cell <= 0) ? 1 : 0; else done = (distance_cell < cur_dist || distance_cell <= 0) ? 1 : 0; if (done) { Segment_put(distance, &cur_dist, next_r, next_c); if (elevation) { Segment_get(tmp_elevation, &tmp_elevation_cell, next_r, next_c); tmp_elevation_cell = target_elev - tmp_elevation_cell; Segment_put(elevation, &tmp_elevation_cell, next_r, next_c); } Segment_get(dirs, &dirs_cell, NR(d), NC(d)); if (dirs_cell < 1) continue; d_inits[k].r = next_r; d_inits[k].c = next_c; d_inits[k].cur_dist = cur_dist; if (elevation) d_inits[k].target_elev = target_elev; k++; } /* end of if done */ } n_inits = k; } G_percent(1, 1, 1); return 0; }
/* Establish parameters */ int do_profile(double e1, double e2, double n1, double n2, char *name, int coords, double res, int fd, int data_type, FILE * fp, char *null_string) { float rows, cols, LEN; double Y, X, AZI; cols = e1 - e2; rows = n1 - n2; LEN = G_distance(e1, n1, e2, n2); G_message(_("Approx. transect length [%f] m"), LEN); if (!G_point_in_region(e2, n2)) G_warning(_("Endpoint coordinates are outside of current region settings")); /* Calculate Azimuth of Line */ if (rows == 0 && cols == 0) { /* Special case for no movement */ e = e1; n = n1; read_rast(e, n, dist, fd, coords, data_type, fp, null_string); } if (rows >= 0 && cols < 0) { /* SE Quad or due east */ AZI = atan((rows / cols)); Y = res * sin(AZI); X = res * cos(AZI); if (Y < 0) Y = Y * -1.; if (X < 0) X = X * -1.; if (e != 0.0 && (e != e1 || n != n1)) { dist -= G_distance(e, n, e1, n1); } for (e = e1, n = n1; e < e2 || n > n2; e += X, n -= Y) { read_rast(e, n, dist, fd, coords, data_type, fp, null_string); /* d+=res; */ dist += G_distance(e - X, n + Y, e, n); } } if (rows < 0 && cols <= 0) { /* NE Quad or due north */ AZI = atan((cols / rows)); X = res * sin(AZI); Y = res * cos(AZI); if (Y < 0) Y = Y * -1.; if (X < 0) X = X * -1.; if (e != 0.0 && (e != e1 || n != n1)) { dist -= G_distance(e, n, e1, n1); /* * read_rast (e1, n1, dist, fd, coords, data_type, fp, null_string); */ } for (e = e1, n = n1; e < e2 || n < n2; e += X, n += Y) { read_rast(e, n, dist, fd, coords, data_type, fp, null_string); /* d+=res; */ dist += G_distance(e - X, n - Y, e, n); } } if (rows > 0 && cols >= 0) { /* SW Quad or due south */ AZI = atan((rows / cols)); X = res * cos(AZI); Y = res * sin(AZI); if (Y < 0) Y = Y * -1.; if (X < 0) X = X * -1.; if (e != 0.0 && (e != e1 || n != n1)) { dist -= G_distance(e, n, e1, n1); } for (e = e1, n = n1; e > e2 || n > n2; e -= X, n -= Y) { read_rast(e, n, dist, fd, coords, data_type, fp, null_string); /* d+=res; */ dist += G_distance(e + X, n + Y, e, n); } } if (rows <= 0 && cols > 0) { /* NW Quad or due west */ AZI = atan((rows / cols)); X = res * cos(AZI); Y = res * sin(AZI); if (Y < 0) Y = Y * -1.; if (X < 0) X = X * -1.; if (e != 0.0 && (e != e1 || n != n1)) { dist -= G_distance(e, n, e1, n1); } for (e = e1, n = n1; e > e2 || n < n2; e -= X, n += Y) { read_rast(e, n, dist, fd, coords, data_type, fp, null_string); /* d+=res; */ dist += G_distance(e + X, n - Y, e, n); } } /* * return dist; */ return 0; } /* done with do_profile */
int ram_calculate_downstream(CELL ** dirs, DCELL ** distance, DCELL ** elevation, OUTLET outlet, int outs) { int r, c, i, j; int next_r, next_c; POINT n_cell; double cur_dist = 0; double tmp_dist = 0; double target_elev; /* eleavation at stream or outlet */ double easting, northing; double cell_easting, cell_northing; struct Cell_head window; Rast_get_window(&window); tail = 0; head = -1; r = outlet.r; c = outlet.c; if (elevation) { target_elev = elevation[r][c]; elevation[r][c] = 0.; } while (tail != head) { easting = window.west + (c + .5) * window.ew_res; northing = window.north - (r + .5) * window.ns_res; for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; /* border */ j = DIAG(i); next_r = NR(i); next_c = NC(i); if (dirs[NR(i)][NC(i)] == j) { /* countributing cell, reset distance and elevation */ if (outs) { /* outlet mode */ if (distance[NR(i)][NC(i)] == 0) continue; /* continue loop, point is not added to the queue! */ else { cell_northing = window.north - (next_r + .5) * window.ns_res; cell_easting = window.west + (next_c + .5) * window.ew_res; cur_dist = tmp_dist + G_distance(easting, northing, cell_easting, cell_northing); distance[NR(i)][NC(i)] = cur_dist; } } else { /* stream mode */ if (distance[next_r][next_c] == 0) { cur_dist = 0; if (elevation) target_elev = elevation[next_r][next_c]; } else { cell_northing = window.north - (next_r + .5) * window.ns_res; cell_easting = window.west + (next_c + .5) * window.ew_res; cur_dist = tmp_dist + G_distance(easting, northing, cell_easting, cell_northing); distance[NR(i)][NC(i)] = cur_dist; } } /* end stream mode */ if (elevation) { elevation[next_r][next_c] = elevation[next_r][next_c] - target_elev; n_cell.target_elev = target_elev; } n_cell.r = next_r; n_cell.c = next_c; n_cell.cur_dist = cur_dist; fifo_insert(n_cell); } } /* end for i... */ n_cell = fifo_return_del(); r = n_cell.r; c = n_cell.c; tmp_dist = n_cell.cur_dist; target_elev = n_cell.target_elev; } /* end while */ return 0; }
int ram_calculate_upstream(DCELL ** distance, CELL ** dirs, DCELL ** elevation, DCELL ** tmp_elevation, int near) { int r, c; int next_r, next_c; double easting, northing; double cell_easting, cell_northing; int i, j, k, d; int done; int counter; int n_inits = 0; double cur_dist; POINT *d_inits; double tmp_dist = 0; double target_elev = 0; size_t elevation_data_size; struct Cell_head window; Rast_get_window(&window); if (elevation) { elevation_data_size = Rast_cell_size(DCELL_TYPE); for (r = 0; r < nrows; ++r) memcpy(tmp_elevation[r], elevation[r], ncols * elevation_data_size); } for (r = 0; r < nrows; ++r) for (c = 0; c < ncols; ++c) { for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; /* out of border */ j = DIAG(i); next_r = NR(i); next_c = NC(i); if (dirs[next_r][next_c] == j && distance[r][c] != 0) { /* is contributing cell */ distance[r][c] = -1; break; } } if (distance[r][c] == 1 && dirs[r][c] > 0) n_inits++; else if (dirs[r][c] > 0) distance[r][c] = -1; } d_inits = (POINT *) G_malloc(n_inits * sizeof(POINT)); k = 0; for (r = 0; r < nrows; ++r) for (c = 0; c < ncols; ++c) { if (distance[r][c] == 1) { distance[r][c] = 0; if (elevation) elevation[r][c] = 0; d = dirs[r][c]; if (dirs[NR(d)][NC(d)] < 0) continue; d_inits[k].r = r; d_inits[k].c = c; d_inits[k].cur_dist = 0; if (elevation) d_inits[k].target_elev = tmp_elevation[r][c]; k++; } } counter = n_inits = k; /* return 0; */ G_message(_("Calculate upstream parameters...")); while (n_inits > 0) { k = 0; G_percent((counter - n_inits), counter, 10); for (i = 0; i < n_inits; ++i) { r = d_inits[i].r; c = d_inits[i].c; d = dirs[r][c]; next_r = NR(d); next_c = NC(d); tmp_dist = d_inits[i].cur_dist; if (elevation) target_elev = d_inits[i].target_elev; easting = window.west + (c + 0.5) * window.ew_res; northing = window.north - (r + 0.5) * window.ns_res; cell_easting = window.west + (next_c + 0.5) * window.ew_res; cell_northing = window.north - (next_r + 0.5) * window.ns_res; cur_dist = tmp_dist + G_distance(easting, northing, cell_easting, cell_northing); if (near) done = (distance[next_r][next_c] > cur_dist || distance[next_r][next_c] <= 0) ? 1 : 0; else done = (distance[next_r][next_c] < cur_dist || distance[next_r][next_c] <= 0) ? 1 : 0; if (done) { distance[next_r][next_c] = cur_dist; if (elevation) { elevation[next_r][next_c] = target_elev - tmp_elevation[next_r][next_c]; } if (dirs[NR(d)][NC(d)] < 1) continue; d_inits[k].r = next_r; d_inits[k].c = next_c; d_inits[k].cur_dist = cur_dist; if (elevation) d_inits[k].target_elev = target_elev; k++; } /* end of if done */ } n_inits = k; } G_percent((counter - n_inits), counter, 10); return 0; }
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 seg_calculate_downstream(SEGMENT *dirs, SEGMENT * distance, SEGMENT *elevation, OUTLET outlet, int outs) { int r, c, i, j; int next_r, next_c; POINT n_cell; double cur_dist = 0; double tmp_dist = 0; double target_elev; /* eleavation at stream or outlet */ double easting, northing; double cell_easting, cell_northing; CELL dirs_cell; DCELL distance_cell, elevation_cell; DCELL zero_cell = 0; struct Cell_head window; Rast_get_window(&window); tail = 0; head = -1; r = outlet.r; c = outlet.c; if (elevation) { Segment_get(elevation, &target_elev, r, c); Segment_put(elevation, &zero_cell, r, c); } while (tail != head) { easting = window.west + (c + .5) * window.ew_res; northing = window.north - (r + .5) * window.ns_res; for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; /* border */ j = DIAG(i); next_r = NR(i); next_c = NC(i); Segment_get(dirs, &dirs_cell, next_r, next_c); if (dirs_cell == j) { /* countributing cell, reset distance and elevation */ if (outs) { /* outlet mode */ Segment_get(distance, &distance_cell, next_r, next_c); if (distance_cell == 0) continue; /* continue loop, point is not added to the queue! */ else { cell_northing = window.north - (next_r + .5) * window.ns_res; cell_easting = window.west + (next_c + .5) * window.ew_res; cur_dist = tmp_dist + G_distance(easting, northing, cell_easting, cell_northing); Segment_put(distance, &cur_dist, next_r, next_c); } } else { /* stream mode */ Segment_get(distance, &distance_cell, next_r, next_c); if (distance_cell == 0) { cur_dist = 0; if (elevation) Segment_get(elevation, &target_elev, next_r, next_c); } else { cell_northing = window.north - (next_r + .5) * window.ns_res; cell_easting = window.west + (next_c + .5) * window.ew_res; cur_dist = tmp_dist + G_distance(easting, northing, cell_easting, cell_northing); Segment_put(distance, &cur_dist, next_r, next_c); } } /* end stream mode */ if (elevation) { Segment_get(elevation, &elevation_cell, next_r, next_c); elevation_cell -= target_elev; Segment_put(elevation, &elevation_cell, next_r, next_c); n_cell.target_elev = target_elev; } n_cell.r = next_r; n_cell.c = next_c; n_cell.cur_dist = cur_dist; fifo_insert(n_cell); } } /* end for i... */ n_cell = fifo_return_del(); r = n_cell.r; c = n_cell.c; tmp_dist = n_cell.cur_dist; target_elev = n_cell.target_elev; } /* end while */ return 0; }
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 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); }
/*! \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 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; }
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 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; }
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; }
/* Establish parameters */ int do_profile(double e1, double e2, double n1, double n2, int coords, double res, int fd, int data_type, FILE * fp, char *null_string, const char *unit, double factor) { double rows, cols, LEN; double Y, X, k; cols = e1 - e2; rows = n1 - n2; LEN = G_distance(e1, n1, e2, n2); G_message(_("Approx. transect length: %f [%s]"), LEN / factor, unit); if (!G_point_in_region(e2, n2)) G_warning(_("Endpoint coordinates are outside of current region settings")); /* Calculate Azimuth of Line */ if (rows == 0 && cols == 0) { /* Special case for no movement */ e = e1; n = n1; read_rast(e, n, dist / factor, fd, coords, data_type, fp, null_string); } k = res / hypot(rows, cols); Y = k * rows; X = k * cols; if (Y < 0) Y = Y * -1.; if (X < 0) X = X * -1.; if (e != 0.0 && (e != e1 || n != n1)) { dist -= G_distance(e, n, e1, n1); } if (rows >= 0 && cols < 0) { /* SE Quad or due east */ for (e = e1, n = n1; e < e2 || n > n2; e += X, n -= Y) { read_rast(e, n, dist / factor, fd, coords, data_type, fp, null_string); /* d+=res; */ dist += G_distance(e - X, n + Y, e, n); } } if (rows < 0 && cols <= 0) { /* NE Quad or due north */ for (e = e1, n = n1; e < e2 || n < n2; e += X, n += Y) { read_rast(e, n, dist / factor, fd, coords, data_type, fp, null_string); /* d+=res; */ dist += G_distance(e - X, n - Y, e, n); } } if (rows > 0 && cols >= 0) { /* SW Quad or due south */ for (e = e1, n = n1; e > e2 || n > n2; e -= X, n -= Y) { read_rast(e, n, dist / factor, fd, coords, data_type, fp, null_string); /* d+=res; */ dist += G_distance(e + X, n + Y, e, n); } } if (rows <= 0 && cols > 0) { /* NW Quad or due west */ for (e = e1, n = n1; e > e2 || n < n2; e -= X, n += Y) { read_rast(e, n, dist / factor, fd, coords, data_type, fp, null_string); /* d+=res; */ dist += G_distance(e + X, n - Y, e, n); } } /* * return dist; */ return 0; } /* done with do_profile */
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; }