Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
/*!
   \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]);
}
Exemple #4
0
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);
}
Exemple #5
0
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;
    }
}
Exemple #6
0
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 ? */
}
Exemple #7
0
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);
}
Exemple #8
0
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);
}
Exemple #9
0
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;
}
Exemple #10
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 */
Exemple #11
0
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;
}
Exemple #12
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;
}
Exemple #13
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;
}
Exemple #14
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;
}
Exemple #15
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);
}
Exemple #16
0
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);
}
Exemple #17
0
/*!
  \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);
}
Exemple #18
0
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;
}
Exemple #19
0
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;
}
Exemple #20
0
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;
}
Exemple #21
0
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;
}
Exemple #22
0
/* 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 */
Exemple #23
0
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;
}