示例#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;
}
示例#2
0
文件: line.c 项目: caomw/grass
/*!
  \brief Calculate line length.
  
  If projection is LL, the length is measured along the geodesic.
  
  \param Points pointer to line_pnts structure geometry
  
  \return line length
*/
double Vect_line_geodesic_length(const struct line_pnts *Points)
{
    int j, dc;
    double dx, dy, dz, dxy, len = 0;

    dc = G_begin_distance_calculations();

    if (Points->n_points < 2)
	return 0;

    for (j = 0; j < Points->n_points - 1; j++) {
	if (dc == 2)
	    dxy =
		G_geodesic_distance(Points->x[j], Points->y[j],
				    Points->x[j + 1], Points->y[j + 1]);
	else {
	    dx = Points->x[j + 1] - Points->x[j];
	    dy = Points->y[j + 1] - Points->y[j];
	    dxy = hypot(dx, dy);
	}

	dz = Points->z[j + 1] - Points->z[j];
	len += hypot(dxy, dz);
    }

    return len;
}
示例#3
0
文件: Gs3.c 项目: caomw/grass
/*!
   \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]);
}
示例#4
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;
}
示例#5
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 ? */
}
示例#6
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;
}
示例#7
0
文件: main.c 项目: caomw/grass
int main(int argc, char *argv[])
{

    struct GModule *module;
    struct Option *in_dir_opt,
	*in_stm_opt,
	*in_elev_opt,
	*in_method_opt, *opt_swapsize, *out_dist_opt, *out_diff_opt;
    struct Flag *flag_outs, *flag_sub, *flag_near, *flag_segmentation;
    char *method_name[] = { "UPSTREAM", "DOWNSTREAM" };
    int method;
    int number_of_segs;
    int outlets_num;
    int number_of_streams;
    int outs, subs, near, segmentation;	/*flags */
    int j;

    G_gisinit(argv[0]);

    module = G_define_module();
    module->label = _("Calculates distance to and elevation above streams and outlet.");
    module->description =
      _("The module can work in stream mode where target are streams and "
        "outlets mode where targets are outlets.");
    G_add_keyword(_("raster"));
    G_add_keyword(_("hydrology"));
    G_add_keyword(_("stream network"));
    G_add_keyword(_("watercourse distance"));

    in_stm_opt = G_define_standard_option(G_OPT_R_INPUT);
    in_stm_opt->key = "stream_rast";
    in_stm_opt->description = _("Name of input raster map with stream network "
                                "(in outlet mode is the name for outlet raster map)");

    in_dir_opt = G_define_standard_option(G_OPT_R_INPUT);
    in_dir_opt->key = "direction";
    in_dir_opt->description = _("Name of input raster map with flow direction");

    in_elev_opt = G_define_standard_option(G_OPT_R_ELEV);
    in_elev_opt->required = NO;
    in_elev_opt->guisection = _("Input maps");

    in_method_opt = G_define_option();
    in_method_opt->key = "method";
    in_method_opt->description = _("Calculation method");
    in_method_opt->type = TYPE_STRING;
    in_method_opt->required = YES;
    in_method_opt->options = "upstream,downstream";
    in_method_opt->answer = "downstream";

    out_dist_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_dist_opt->key = "distance";
    out_dist_opt->required = NO;
    out_dist_opt->description = _("Name for output distance raster map");
    out_dist_opt->guisection = _("Output maps");

    out_diff_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_diff_opt->key = "difference";
    out_diff_opt->required = NO;
    out_diff_opt->description = _("Name for output elevation difference raster map");
    out_diff_opt->guisection = _("Output maps");

    opt_swapsize = G_define_option();
    opt_swapsize->key = "memory";
    opt_swapsize->type = TYPE_INTEGER;
    opt_swapsize->answer = "300";
    opt_swapsize->description = _("Max memory used in memory swap mode (MB)");
    opt_swapsize->guisection = _("Memory settings");

    flag_outs = G_define_flag();
    flag_outs->key = 'o';
    flag_outs->description =
	_("Calculate parameters for outlets (outlet mode) instead of (default) streams");

    flag_sub = G_define_flag();
    flag_sub->key = 's';
    flag_sub->description =
	_("Calculate parameters for subbasins (ignored in stream mode)");

    flag_near = G_define_flag();
    flag_near->key = 'n';
    flag_near->description =
	_("Calculate nearest local maximum (ignored in downstream calculation)");

    flag_segmentation = G_define_flag();
    flag_segmentation->key = 'm';
    flag_segmentation->description = _("Use memory swap (operation is slow)");
    flag_segmentation->guisection = _("Memory settings");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (!out_diff_opt->answer && !out_dist_opt->answer)
	G_fatal_error(_("You must select at least one output raster map"));
    if (out_diff_opt->answer && !in_elev_opt->answer)
	G_fatal_error(_("Output elevation difference raster map requires "
                        "input elevation raster map to be specified"));
    
    if (!strcmp(in_method_opt->answer, "upstream"))
	method = UPSTREAM;
    else if (!strcmp(in_method_opt->answer, "downstream"))
	method = DOWNSTREAM;

    outs = (flag_outs->answer != 0);
    subs = (flag_sub->answer != 0);
    near = (flag_near->answer != 0);
    segmentation = (flag_segmentation->answer != 0);

    nrows = Rast_window_rows();
    ncols = Rast_window_cols();
    G_begin_distance_calculations();

    fifo_max = 4 * (nrows + ncols);
    fifo_points = (POINT *) G_malloc((fifo_max + 1) * sizeof(POINT));

    if (!segmentation) {
	G_message(_("All in RAM calculation - method <%s>..."),
		  method_name[method]);
	MAP map_dirs, map_streams, map_distance, map_elevation,
	    map_tmp_elevation;
	CELL **streams, **dirs;
	DCELL **distance;
	DCELL **elevation = NULL;
	DCELL **tmp_elevation = NULL;

	ram_create_map(&map_streams, CELL_TYPE);
	ram_read_map(&map_streams, in_stm_opt->answer, 1, CELL_TYPE);
	ram_create_map(&map_dirs, CELL_TYPE);
	ram_read_map(&map_dirs, in_dir_opt->answer, 1, CELL_TYPE);
	ram_create_map(&map_distance, DCELL_TYPE);

	streams = (CELL **) map_streams.map;
	dirs = (CELL **) map_dirs.map;
	distance = (DCELL **) map_distance.map;
	number_of_streams = (int)map_streams.max + 1;

	outlets_num =
	    ram_find_outlets(streams, number_of_streams, dirs, subs, outs);
	ram_init_distance(streams, distance, outlets_num, outs);
	ram_release_map(&map_streams);

	if (in_elev_opt->answer) {
	    ram_create_map(&map_elevation, DCELL_TYPE);
	    ram_read_map(&map_elevation, in_elev_opt->answer, 0, -1);
	    elevation = (DCELL **) map_elevation.map;
	}			/* map elevation will be replaced by elevation difference map */


	if (method == DOWNSTREAM) {
	    G_message(_("Calculate downstream parameters..."));
	    for (j = 0; j < outlets_num; ++j) {
		G_percent(j, outlets_num, 1);
		ram_calculate_downstream(dirs, distance, elevation,
					 outlets[j], outs);
	    }
	    G_percent(j, outlets_num, 1);

	}
	else if (method == UPSTREAM) {

	    if (out_diff_opt->answer) {
		ram_create_map(&map_tmp_elevation, DCELL_TYPE);
		tmp_elevation = (DCELL **) map_tmp_elevation.map;
	    }

	    for (j = 0; j < outlets_num; ++j)
		ram_fill_basins(outlets[j], distance, dirs);
	    ram_calculate_upstream(distance, dirs, elevation, tmp_elevation,
				   near);

	}
	else {
	    G_fatal_error(_("Unrecognised method of processing"));
	}			/* end methods */

	if (out_diff_opt->answer) {
	    ram_prep_null_elevation(distance, elevation);
	    ram_write_map(&map_elevation, out_diff_opt->answer, DCELL_TYPE, 1,
			  -1);
	}

	if (out_dist_opt->answer)
	    ram_write_map(&map_distance, out_dist_opt->answer, DCELL_TYPE, 1,
			  -1);

	ram_release_map(&map_dirs);
	ram_release_map(&map_distance);

	if (in_elev_opt->answer)
	    ram_release_map(&map_elevation);
	if (in_elev_opt->answer && method == UPSTREAM)
	    ram_release_map(&map_tmp_elevation);
    }

    if (segmentation) {
	G_message(_("Calculating segments in direction <%s> (may take some time)..."),
		  method_name[method]);
	SEG map_dirs, map_streams, map_distance, map_elevation,
	    map_tmp_elevation;
	SEGMENT *streams, *dirs, *distance;
	SEGMENT *elevation = NULL;
	SEGMENT *tmp_elevation = NULL;

	number_of_segs = (int)atof(opt_swapsize->answer);
	if (method == DOWNSTREAM)
	    number_of_segs = number_of_segs < 32 ? (int)(32 / 0.18) : number_of_segs / 0.18;
	else			/* two elevation maps */
	    number_of_segs = number_of_segs < 32 ? (int)(32 / 0.24) : number_of_segs / 0.24;

	seg_create_map(&map_streams, SROWS, SCOLS, number_of_segs, CELL_TYPE);
	seg_read_map(&map_streams, in_stm_opt->answer, 1, CELL_TYPE);
	seg_create_map(&map_dirs, SROWS, SCOLS, number_of_segs, CELL_TYPE);
	seg_read_map(&map_dirs, in_dir_opt->answer, 1, CELL_TYPE);
	seg_create_map(&map_distance, SROWS, SCOLS, number_of_segs,
		       DCELL_TYPE);

	streams = &map_streams.seg;
	dirs = &map_dirs.seg;
	distance = &map_distance.seg;
	number_of_streams = (int)map_streams.max + 1;

	outlets_num =
	    seg_find_outlets(streams, number_of_streams, dirs, subs, outs);
	seg_init_distance(streams, distance, outlets_num, outs);
	seg_release_map(&map_streams);

	if (in_elev_opt->answer) {
	    seg_create_map(&map_elevation, SROWS, SCOLS, number_of_segs,
			   DCELL_TYPE);
	    seg_read_map(&map_elevation, in_elev_opt->answer, 0, -1);
	    elevation = &map_elevation.seg;
	}			/* map elevation will be replaced by elevation difference map */

	if (method == DOWNSTREAM) {
	    G_message(_("Calculate downstream parameters..."));
	    for (j = 0; j < outlets_num; ++j) {
		G_percent(j, outlets_num, 1);
		seg_calculate_downstream(dirs, distance, elevation,
					 outlets[j], outs);
	    }
	    G_percent(j, outlets_num, 1);

	}
	else if (method == UPSTREAM) {

	    if (out_diff_opt->answer) {
		seg_create_map(&map_tmp_elevation, SROWS, SCOLS,
			       number_of_segs, DCELL_TYPE);
		tmp_elevation = &map_tmp_elevation.seg;
	    }

	    for (j = 0; j < outlets_num; ++j)
		seg_fill_basins(outlets[j], distance, dirs);
	    seg_calculate_upstream(distance, dirs, elevation, tmp_elevation,
				   near);

	}
	else {
	    G_fatal_error(_("Unrecognised method of processing"));
	}			/* end methods */

	if (out_dist_opt->answer)
	    seg_write_map(&map_distance, out_dist_opt->answer, DCELL_TYPE, 1,
			  -1);

	if (out_diff_opt->answer) {
	    seg_prep_null_elevation(distance, elevation);
	    seg_write_map(&map_elevation, out_diff_opt->answer, DCELL_TYPE, 1,
			  -1);
	}

	seg_release_map(&map_dirs);
	seg_release_map(&map_distance);

	if (in_elev_opt->answer)
	    seg_release_map(&map_elevation);
	if (in_elev_opt->answer && method == UPSTREAM)
	    seg_release_map(&map_tmp_elevation);
    }

    G_free(fifo_points);
    exit(EXIT_SUCCESS);
}
示例#8
0
文件: line.c 项目: caomw/grass
/*!
  \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);
}
示例#9
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;
}
示例#10
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;
}
示例#11
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;
}
示例#12
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);
}
示例#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;
}
示例#14
0
int main(int argc, char *argv[])
{
    char *name, *outfile;
    int fd, projection;
    FILE *fp;
    double res;
    char *null_string;
    char ebuf[256], nbuf[256], label[512], formatbuff[256];
    char b1[100], b2[100];
    int n;
    int havefirst = FALSE;
    int coords = 0, i, k = -1;
    double e1, e2, n1, n2;
    RASTER_MAP_TYPE data_type;
    struct Cell_head window;
    struct
    {
	struct Option *opt1, *profile, *res, *output, *null_str;
	struct Flag *g, *c;
    }
    parm;
    struct GModule *module;

    G_gisinit(argv[0]);

    /* Set description */
    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("profile"));
    module->description =
	_("Outputs the raster map layer values lying on user-defined line(s).");

    parm.opt1 = G_define_standard_option(G_OPT_R_INPUT);

    parm.output = G_define_option();
    parm.output->key = "output";
    parm.output->type = TYPE_STRING;
    parm.output->required = NO;
    parm.output->answer = "-";
    parm.output->gisprompt = "new_file,file,output";
    parm.output->description =
	_("Name of file for output (use output=- for stdout)");

    parm.profile = G_define_option();
    parm.profile->key = "profile";
    parm.profile->type = TYPE_STRING;
    parm.profile->required = NO;
    parm.profile->multiple = YES;
    parm.profile->key_desc = "east,north";
    parm.profile->description = _("Profile coordinate pairs");

    parm.res = G_define_option();
    parm.res->key = "res";
    parm.res->type = TYPE_DOUBLE;
    parm.res->required = NO;
    parm.res->description =
	_("Resolution along profile (default = current region resolution)");

    parm.null_str = G_define_option();
    parm.null_str->key = "null";
    parm.null_str->type = TYPE_STRING;
    parm.null_str->required = NO;
    parm.null_str->answer = "*";
    parm.null_str->description = _("Character to represent no data cell");

    parm.g = G_define_flag();
    parm.g->key = 'g';
    parm.g->description =
	_("Output easting and northing in first two columns of four column output");

    parm.c = G_define_flag();
    parm.c->key = 'c';
    parm.c->description =
	_("Output RRR:GGG:BBB color values for each profile point");


    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    clr = 0;
    if (parm.c->answer)
	clr = 1;		/* color output */

    null_string = parm.null_str->answer;

    G_get_window(&window);
    projection = G_projection();
    if (parm.res->answer) {
	res = atof(parm.res->answer);
	/* Catch bad resolution ? */
	if (res <= 0)
	    G_fatal_error(_("Illegal resolution! [%g]"), res);
    }
    else {
	/* Do average of EW and NS res */
	res = (window.ew_res + window.ns_res) / 2;
    }

    G_message(_("Using resolution [%g]"), res);

    G_begin_distance_calculations();

    /* Open Input File for reading */
    /* Get Input Name */
    name = parm.opt1->answer;
    if (parm.g->answer)
	coords = 1;

    /* Open Raster File */
    fd = Rast_open_old(name, "");

    /* initialize color structure */
    if (clr)
	Rast_read_colors(name, "", &colors);

    /* Open ASCII file for output or stdout */
    outfile = parm.output->answer;

    if ((strcmp("-", outfile)) == 0) {
	fp = stdout;
    }
    else if (NULL == (fp = fopen(outfile, "w")))
	G_fatal_error(_("Unable to open file <%s>"), outfile);

    /* Get Raster Type */
    data_type = Rast_get_map_type(fd);
    /* Done with file */

    /* Show message giving output format */
    G_message(_("Output Format:"));
    if (coords == 1)
	sprintf(formatbuff,
		_("[Easting] [Northing] [Along Track Dist.(m)] [Elevation]"));
    else
	sprintf(formatbuff, _("[Along Track Dist.(m)] [Elevation]"));
    if (clr)
	strcat(formatbuff, _(" [RGB Color]"));
    G_message(formatbuff);

    /* Get Profile Start Coords */
    if (!parm.profile->answer) {
	/* Assume input from stdin */
	for (n = 1; input(b1, ebuf, b2, nbuf, label); n++) {
	    G_debug(4, "stdin line %d: ebuf=[%s]  nbuf=[%s]", n, ebuf, nbuf);
	    if (!G_scan_easting(ebuf, &e2, G_projection()) ||
		!G_scan_northing(nbuf, &n2, G_projection()))
		G_fatal_error(_("Invalid coordinates %s %s"), ebuf, nbuf);

	    if (havefirst)
		do_profile(e1, e2, n1, n2, name, coords, res, fd, data_type,
			   fp, null_string);
	    e1 = e2;
	    n1 = n2;
	    havefirst = TRUE;
	}
    }
    else {
	/* Coords from Command Line */
	for (i = 0; parm.profile->answers[i]; i += 2) {
	    /* Test for number coordinate pairs */
	    k = i;
	}

	if (k == 0) {
	    /* Only one coordinate pair supplied */
	    G_scan_easting(parm.profile->answers[0], &e1, G_projection());
	    G_scan_northing(parm.profile->answers[1], &n1, G_projection());
	    e2 = e1;
	    n2 = n1;

	    /* Get profile info */
	    do_profile(e1, e2, n1, n2, name, coords, res, fd, data_type, fp,
		       null_string);
	}
	else {
	    for (i = 0; i <= k - 2; i += 2) {
		G_scan_easting(parm.profile->answers[i], &e1, G_projection());
		G_scan_northing(parm.profile->answers[i + 1], &n1,
				G_projection());
		G_scan_easting(parm.profile->answers[i + 2], &e2,
			       G_projection());
		G_scan_northing(parm.profile->answers[i + 3], &n2,
				G_projection());

		/* Get profile info */
		do_profile(e1, e2, n1, n2, name, coords, res, fd, data_type,
			   fp, null_string);

	    }
	}
    }

    Rast_close(fd);
    fclose(fp);

    if (clr)
	Rast_free_colors(&colors);

    exit(EXIT_SUCCESS);
}				/* Done with main */
示例#15
0
int main(int argc, char *argv[])
{
    const char *name;
    char outfile[GNAME_MAX];
    int fd, projection;
    char buf[512], buf1[1024], buf2[1024];
    int screen_x, screen_y;
    int i, k;
    int frame_start = 0;
    double e1, e2, n1, n2;
    RASTER_MAP_TYPE data_type;
    struct Cell_head window;
    struct
    {
	struct Option *opt1, *route, *name, *output, *dist, *ht, *frames,
	    *start;
	struct Flag *f, *c, *k, *o, *e;
    }
    parm;
    struct GModule *module;

    G_gisinit(argv[0]);

    /* Set description */
    module = G_define_module();
    G_add_keyword(_("miscellaneous"));
    G_add_keyword(_("graphics"));
    G_add_keyword(_("raster"));
    G_add_keyword(_("raster3d"));
    G_add_keyword(_("vector"));
    G_add_keyword(_("visualization"));
    module->description = _("Creates fly-through script to run in NVIZ.");

    parm.opt1 = G_define_standard_option(G_OPT_R_INPUT);

    parm.output = G_define_standard_option(G_OPT_F_OUTPUT);
    parm.output->description = _("Name of output script");

    parm.name = G_define_option();
    parm.name->key = "name";
    parm.name->type = TYPE_STRING;
    parm.name->required = NO;
    parm.name->description = _("Prefix of output images (default = NVIZ)");

    parm.route = G_define_option();
    parm.route->key = "route";
    parm.route->type = TYPE_STRING;
    parm.route->required = NO;
    parm.route->multiple = YES;
    parm.route->key_desc = "east,north";
    parm.route->description = _("Route coordinates (east,north)");

    parm.dist = G_define_option();
    parm.dist->key = "dist";
    parm.dist->type = TYPE_DOUBLE;
    parm.dist->required = YES;
    parm.dist->description = _("Camera layback distance (in map units)");

    parm.ht = G_define_option();
    parm.ht->key = "ht";
    parm.ht->type = TYPE_DOUBLE;
    parm.ht->required = YES;
    parm.ht->description = _("Camera height above terrain");

    parm.frames = G_define_option();
    parm.frames->key = "frames";
    parm.frames->type = TYPE_INTEGER;
    parm.frames->required = YES;
    parm.frames->description = _("Number of frames");

    parm.start = G_define_option();
    parm.start->key = "start";
    parm.start->type = TYPE_INTEGER;
    parm.start->required = NO;
    parm.start->description = _("Start frame number (default=0)");


    parm.f = G_define_flag();
    parm.f->key = 'f';
    parm.f->description = _("Full render -- Save images");

    parm.c = G_define_flag();
    parm.c->key = 'c';
    parm.c->description = _("Fly at constant elevation (ht)");

    parm.k = G_define_flag();
    parm.k->key = 'k';
    parm.k->description =
	_("Include command in the script to output a KeyFrame file");

    parm.o = G_define_flag();
    parm.o->key = 'o';
    parm.o->description = _("Render images off-screen");

    parm.e = G_define_flag();
    parm.e->key = 'e';
    parm.e->description = _("Enable vector and sites drawing");


    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* check arguments */
    if (!parm.route->answer)
	G_fatal_error(_("Either -i flag and/or route parameter must be used"));

    /* get GRASS parameters */
    G_get_window(&window);
    projection = G_projection();
    D_do_conversions(&window, 0, 1, 0, 1);

    /* setup screen coords */
    screen_x = ((int)D_get_d_west() + (int)D_get_d_east()) / 2;
    screen_y = ((int)D_get_d_north() + (int)D_get_d_south()) / 2;

    /* get camera parameters */
    DIST = atof(parm.dist->answer);
    HT = atof(parm.ht->answer);
    no_frames = atoi(parm.frames->answer);

    if (parm.start->answer)
	frame_start = atoi(parm.start->answer);

    if (parm.c->answer)
	height_flag = 1;
    if (parm.k->answer)
	key_frames = 1;
    if (parm.o->answer && !parm.f->answer)
	G_fatal_error(_("Off-screen only available with full render mode"));
    if (parm.o->answer)
	off_screen = 1;

    /* Initialize coords */
    e1 = e2 = n1 = n2 = -9999.;

    G_begin_distance_calculations();

    /* Open Input File for reading */
    name = parm.opt1->answer;

    /* Open Raster File */
    fd = Rast_open_old(name, "");

    /* Set Image name */
    if (parm.name->answer)
	sprintf(img_name, "%s", parm.name->answer);
    else
	sprintf(img_name, "NVIZ");


    /* Open ASCII file for output */
    /* append ".nvscr" to filename if it doesn't already have it */
    strncpy(outfile, parm.output->answer, GNAME_MAX - 7);
    outfile[GNAME_MAX - 7] = '\0';	/* strncpy() doesn't null terminate the string */
    if (strcmp(&outfile[strlen(outfile) - 6], ".nvscr") != 0)
	strcat(outfile, ".nvscr");

    if (NULL == (fp = fopen(outfile, "w")))
	G_fatal_error(_("Unable to open file <%s>"), outfile);

    /* Get Raster Type */
    data_type = Rast_get_map_type(fd);
    /* Done with file */

    /* Output initial startup stuff */
    sprintf(buf1,
	    "## REGION: n=%f s=%f e=%f w=%f\n## Input=%s Dist=%f Ht=%f\n",
	    window.north, window.south, window.east, window.west, outfile,
	    DIST, HT);

    sprintf(buf2, "\nset FRAMES %d\n", no_frames);
    strcat(buf1, buf2);
    fprintf(fp, "%s", buf1);

    sprintf(buf1, "SendScriptLine \"Nclear_keys\"");
    sprintf(buf2, "\nSendScriptLine \"Nupdate_frames\"");
    strcat(buf1, buf2);
    fprintf(fp, "%s", buf1);

    sprintf(buf1, "\nSendScriptLine \"Nset_numsteps $FRAMES\"");
    sprintf(buf2, "\nSendScriptLine \"Nupdate_frames\"\n");
    strcat(buf1, buf2);
    fprintf(fp, "%s", buf1);

    /* Use Linear mode for smooth frame transition */
    sprintf(buf1, "\nSendScriptLine \"Nset_interp_mode linear\"");
    sprintf(buf2, "\nSendScriptLine \"Nupdate_frames\"\n\n");
    strcat(buf1, buf2);
    fprintf(fp, "%s", buf1);

    /* eanble vector and sites drawing */
    if (parm.e->answer) {
	sprintf(buf1, "\nSendScriptLine \"Nshow_vect on\"");
	sprintf(buf2, "\nSendScriptLine \"Nshow_sites on\"\n\n");
	strcat(buf1, buf2);
	fprintf(fp, "%s", buf1);
    }

    /* Coords from Command Line */
    for (i = 0; parm.route->answers[i]; i += 2) {
	/* Test for number coordinate pairs */
	k = i;
    }

    if (k < 6) {
	/* Only one coordinate pair supplied */
	G_fatal_error(_("You must provide at least four points %d"), k);

    }
    else {
	for (i = 0; i <= k - 2; i += 2) {
	    sscanf(parm.route->answers[i], "%lf", &e1);
	    sscanf(parm.route->answers[i + 1], "%lf", &n1);
	    sscanf(parm.route->answers[i + 2], "%lf", &e2);
	    sscanf(parm.route->answers[i + 3], "%lf", &n2);
	    /* Get profile info */
	    do_profile(e1, e2, n1, n2, name, fd, data_type);

	    /* Get last coord */
	    if (i == k - 2)
		do_profile(e2, e2, n2, n2, name, fd, data_type);
	}
    }
	/* done with coordinates */


    /* Output final part of script */
    /* generate key-frame script */
    if (key_frames) {
	strcpy(buf, outfile);
	buf[strlen(outfile) - 6] = '\0';	/* skip extension */
	strcat(buf, ".kanim");
	fprintf(fp, "\n## The following saves the animation to a format\n");
	fprintf(fp, "## suitable for editing with the kanimator panel\n");
	fprintf(fp, "SendScriptLine \"Nprint_keys %s\"\n", buf);
	fprintf(fp, "puts \"Saving Key Frame file %s\"\n", buf);
    }

    /* output off-screen option */
    if (off_screen) {
	fprintf(fp, "\n## Off screen rendering enabled \n");
	fprintf(fp, "## Ensure main window is minimized before running\n");
	fprintf(fp, "SendScriptLine \"Noff_screen 1\"\n");
    }

    fprintf(fp, "\n\nset num %d", frame_start);
    fprintf(fp, "\n\nfor {set frame 1} {$frame <= $FRAMES} {incr frame} {");

    if (parm.f->answer) {
	/* Full render and save */
	fprintf(fp, "\nset name %s", img_name);
	fprintf(fp, "\nset num2 [format \"\%%04d\" $num]");
	fprintf(fp, "\nappend name $num2 \".ppm\"");
	fprintf(fp, "\nSendScriptLine \"Ndo_framestep $frame 1\"");
	fprintf(fp, "\nSendScriptLine \"Nwrite_ppm $name \"");
	fprintf(fp, "\nincr num");
    }
示例#16
0
文件: main.c 项目: GRASS-GIS/grass-ci
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);
}
示例#17
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;
}
示例#18
0
文件: main.c 项目: caomw/grass
int main(int argc, char *argv[])
{
    char *name, *outfile;
    const char *unit;
    int unit_id;
    double factor;
    int fd, projection;
    FILE *fp, *coor_fp;
    double res;
    char *null_string;
    char ebuf[256], nbuf[256], label[512], formatbuff[256];
    char b1[100], b2[100];
    int n;
    int havefirst = FALSE;
    int coords = 0, i, k = -1;
    double e1, e2, n1, n2;
    RASTER_MAP_TYPE data_type;
    struct Cell_head window;
    struct
    {
	struct Option *opt1, *profile, *res, *output, *null_str, *coord_file, *units;
	struct Flag *g, *c, *m;
    }
    parm;
    struct GModule *module;

    G_gisinit(argv[0]);

    /* Set description */
    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("profile"));
    module->description =
	_("Outputs the raster map layer values lying on user-defined line(s).");

    parm.opt1 = G_define_standard_option(G_OPT_R_INPUT);

    parm.output = G_define_standard_option(G_OPT_F_OUTPUT);
    parm.output->required = NO;
    parm.output->answer = "-";
    parm.output->description =
	_("Name of file for output (use output=- for stdout)");

    parm.profile = G_define_standard_option(G_OPT_M_COORDS);
    parm.profile->required = NO;
    parm.profile->multiple = YES;
    parm.profile->description = _("Profile coordinate pairs");

    parm.coord_file = G_define_standard_option(G_OPT_F_INPUT);
    parm.coord_file->key = "file";
    parm.coord_file->required = NO;
    parm.coord_file->label =
	_("Name of input file containing coordinate pairs");
    parm.coord_file->description =
	_("Use instead of the 'coordinates' option. "
	  "\"-\" reads from stdin.");

    parm.res = G_define_option();
    parm.res->key = "resolution";
    parm.res->type = TYPE_DOUBLE;
    parm.res->required = NO;
    parm.res->description =
	_("Resolution along profile (default = current region resolution)");

    parm.null_str = G_define_option();
    parm.null_str->key = "null";
    parm.null_str->type = TYPE_STRING;
    parm.null_str->required = NO;
    parm.null_str->answer = "*";
    parm.null_str->description = _("Character to represent no data cell");

    parm.g = G_define_flag();
    parm.g->key = 'g';
    parm.g->description =
	_("Output easting and northing in first two columns of four column output");

    parm.c = G_define_flag();
    parm.c->key = 'c';
    parm.c->description =
	_("Output RRR:GGG:BBB color values for each profile point");

    parm.units = G_define_standard_option(G_OPT_M_UNITS);
    parm.units->options = "meters,kilometers,feet,miles";
    parm.units->label = parm.units->description;
    parm.units->description = _("If units are not specified, current location units are used. "
                                "Meters are used by default in geographic (latlon) locations.");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    clr = 0;
    if (parm.c->answer)
	clr = 1;		/* color output */

    null_string = parm.null_str->answer;

    if ((parm.profile->answer && parm.coord_file->answer) ||
	(!parm.profile->answer && !parm.coord_file->answer))
	G_fatal_error(_("Either use profile option or coordinate_file "
			" option, but not both"));

    G_get_window(&window);
    projection = G_projection();

    /* get conversion factor and units name */
    if (parm.units->answer) {
        unit_id = G_units(parm.units->answer);
        factor = 1. / G_meters_to_units_factor(unit_id);
        unit = G_get_units_name(unit_id, 1, 0);
    }
    /* keep meters in case of latlon */
    else if (projection == PROJECTION_LL) {
        factor = 1;
        unit = "meters";
    } 
    else {
        /* get conversion factor to current units */
        unit = G_database_unit_name(1);
        factor = G_database_units_to_meters_factor();
    }

    if (parm.res->answer) {
	res = atof(parm.res->answer);
	/* Catch bad resolution ? */
	if (res <= 0)
	    G_fatal_error(_("Illegal resolution %g [%s]"), res / factor, unit);
    }
    else {
	/* Do average of EW and NS res */
	res = (window.ew_res + window.ns_res) / 2;
    }

    G_message(_("Using resolution: %g [%s]"), res / factor, unit);

    G_begin_distance_calculations();

    /* Open Input File for reading */
    /* Get Input Name */
    name = parm.opt1->answer;
    if (parm.g->answer)
	coords = 1;

    /* Open Raster File */
    fd = Rast_open_old(name, "");

    /* initialize color structure */
    if (clr)
	Rast_read_colors(name, "", &colors);

    /* Open ASCII file for output or stdout */
    outfile = parm.output->answer;

    if ((strcmp("-", outfile)) == 0) {
	fp = stdout;
    }
    else if (NULL == (fp = fopen(outfile, "w")))
	G_fatal_error(_("Unable to open file <%s>"), outfile);

    /* Get Raster Type */
    data_type = Rast_get_map_type(fd);
    /* Done with file */

    /* Show message giving output format */
    G_message(_("Output columns:"));
    if (coords == 1)
	sprintf(formatbuff,
		_("Easting, Northing, Along track dist. [%s], Elevation"), unit);
    else
	sprintf(formatbuff, _("Along track dist. [%s], Elevation"), unit);
    if (clr)
	strcat(formatbuff, _(" RGB color"));
    G_message(formatbuff);

    /* Get Profile Start Coords */
    if (parm.coord_file->answer) {
	if (strcmp("-", parm.coord_file->answer) == 0)
	    coor_fp = stdin;
	else
	    coor_fp = fopen(parm.coord_file->answer, "r");

	if (coor_fp == NULL)
	    G_fatal_error(_("Could not open <%s>"), parm.coord_file->answer);


	for (n = 1; input(b1, ebuf, b2, nbuf, label, coor_fp); n++) {
	    G_debug(4, "stdin line %d: ebuf=[%s]  nbuf=[%s]", n, ebuf, nbuf);
	    if (!G_scan_easting(ebuf, &e2, G_projection()) ||
		!G_scan_northing(nbuf, &n2, G_projection()))
		G_fatal_error(_("Invalid coordinates %s %s"), ebuf, nbuf);

	    if (havefirst)
		do_profile(e1, e2, n1, n2, coords, res, fd, data_type,
			   fp, null_string, unit, factor);
	    e1 = e2;
	    n1 = n2;
	    havefirst = TRUE;
	}

	if (coor_fp != stdin)
	    fclose(coor_fp);
    }
    else {
	/* Coords given on the Command Line using the profile= option */
	for (i = 0; parm.profile->answers[i]; i += 2) {
	    /* Test for number coordinate pairs */
	    k = i;
	}

	if (k == 0) {
	    /* Only one coordinate pair supplied */
	    G_scan_easting(parm.profile->answers[0], &e1, G_projection());
	    G_scan_northing(parm.profile->answers[1], &n1, G_projection());
	    e2 = e1;
	    n2 = n1;

	    /* Get profile info */
	    do_profile(e1, e2, n1, n2, coords, res, fd, data_type, fp,
		       null_string, unit, factor);
	}
	else {
	    for (i = 0; i <= k - 2; i += 2) {
		G_scan_easting(parm.profile->answers[i], &e1, G_projection());
		G_scan_northing(parm.profile->answers[i + 1], &n1,
				G_projection());
		G_scan_easting(parm.profile->answers[i + 2], &e2,
			       G_projection());
		G_scan_northing(parm.profile->answers[i + 3], &n2,
				G_projection());

		/* Get profile info */
		do_profile(e1, e2, n1, n2, coords, res, fd, data_type,
			   fp, null_string, unit, factor);

	    }
	}
    }

    Rast_close(fd);
    fclose(fp);

    if (clr)
	Rast_free_colors(&colors);

    exit(EXIT_SUCCESS);
}				/* Done with main */
示例#19
0
文件: main.c 项目: caomw/grass
int main(int argc, char *argv[])
{
    /*
       IO output[] = {
       {"local_diff",NO,"Local elevation difference"},
       {"out_dist",NO,"Upstream distance form init"},
     */

    struct GModule *module;
    struct Option *in_dir_opt,	/* options */
     *in_stm_opt,
	*in_elev_opt,
	*out_identifier_opt,
	*out_distance_opt,
	*out_difference_opt,
	*out_gradient_opt, *out_curvature_opt, *opt_swapsize;

    struct Flag *flag_segmentation,
	*flag_local, *flag_cells, *flag_downstream;

    char *method_name[] = { "UPSTREAM", "DOWNSTREAM" };
    int number_of_segs;
    int number_of_streams;
    int segmentation, downstream, local, cells;	/*flags */

    /* initialize GIS environment */
    G_gisinit(argv[0]);

    /* initialize module */
    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("hydrology"));
    G_add_keyword(_("stream network"));
    module->description =
	_("Calculates local parameters for individual streams.");

    in_stm_opt = G_define_standard_option(G_OPT_R_INPUT);
    in_stm_opt->key = "stream_rast";
    in_stm_opt->description = _("Name of input raster map with stream network");

    in_dir_opt = G_define_standard_option(G_OPT_R_INPUT);
    in_dir_opt->key = "direction";
    in_dir_opt->description = _("Name of input raster map with flow direction");

    in_elev_opt = G_define_standard_option(G_OPT_R_ELEV);

    out_identifier_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_identifier_opt->key = "identifier";
    out_identifier_opt->required = NO;
    out_identifier_opt->description = _("Name for output unique stream identifier raster map");
    out_identifier_opt->guisection = _("Output maps");

    out_distance_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_distance_opt->key = "distance";
    out_distance_opt->required = NO;
    out_distance_opt->description = _("Name for output init/join/outlet distance raster map");
    out_distance_opt->guisection = _("Output maps");

    out_difference_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_difference_opt->key = "difference";
    out_difference_opt->required = NO;
    out_difference_opt->description =
        _("Name for output elevation init/join/outlet difference raster map");
    out_difference_opt->guisection = _("Output maps");

    out_gradient_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_gradient_opt->key = "gradient";
    out_gradient_opt->required = NO;
    out_gradient_opt->description =
	_("Name for output mean init/join/outlet gradient of stream raster map");
    out_gradient_opt->guisection = _("Output maps");

    out_curvature_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_curvature_opt->key = "curvature";
    out_curvature_opt->required = NO;
    out_curvature_opt->description = _("Name for output local stream curvature raster map");
    out_curvature_opt->guisection = _("Output maps");

    opt_swapsize = G_define_option();
    opt_swapsize->key = "memory";
    opt_swapsize->type = TYPE_INTEGER;
    opt_swapsize->answer = "300";
    opt_swapsize->description = _("Maximum memory used in memory swap mode (MB)");
    opt_swapsize->guisection = _("Memory settings");

    flag_downstream = G_define_flag();
    flag_downstream->key = 'd';
    flag_downstream->description =
	_("Calculate parameters from outlet (downstream values)");

    flag_local = G_define_flag();
    flag_local->key = 'l';
    flag_local->description = _("Calculate local values (for current cell)");

    flag_cells = G_define_flag();
    flag_cells->key = 'c';
    flag_cells->description = _("Calculate distance in cell count (ignored local)");

    flag_segmentation = G_define_flag();
    flag_segmentation->key = 'm';
    flag_segmentation->description = _("Use memory swap (operation is slow)");
    flag_segmentation->guisection = _("Memory settings");

    if (G_parser(argc, argv))	/* parser */
	exit(EXIT_FAILURE);

    segmentation = (flag_segmentation->answer != 0);
    downstream = (flag_downstream->answer != 0);

    if (!out_identifier_opt->answer &&
	!out_distance_opt->answer &&
	!out_difference_opt->answer &&
	!out_gradient_opt->answer && !out_curvature_opt->answer)
	G_fatal_error(_("You must select at least one output raster maps"));

    local = (flag_local->answer != 0);
    cells = (flag_cells->answer != 0);
    nrows = Rast_window_rows();
    ncols = Rast_window_cols();
    G_get_window(&window);
    G_begin_distance_calculations();

    if (!segmentation) {
	MAP map_dirs, map_streams, map_elevation, map_output, map_identifier;
	CELL **streams, **dirs, **identifier = NULL;
	FCELL **elevation;
	DCELL **output;

	G_message(_("All in RAM calculation - direction <%s>..."),
		  method_name[downstream]);
	ram_create_map(&map_streams, CELL_TYPE);
	ram_read_map(&map_streams, in_stm_opt->answer, 1, CELL_TYPE);
	ram_create_map(&map_dirs, CELL_TYPE);
	ram_read_map(&map_dirs, in_dir_opt->answer, 1, CELL_TYPE);
	ram_create_map(&map_elevation, FCELL_TYPE);
	ram_read_map(&map_elevation, in_elev_opt->answer, 0, -1);

	streams = (CELL **) map_streams.map;
	dirs = (CELL **) map_dirs.map;
	elevation = (FCELL **) map_elevation.map;

	number_of_streams = ram_number_of_streams(streams, dirs) + 1;
	ram_build_streamlines(streams, dirs, elevation, number_of_streams);
	ram_release_map(&map_streams);
	ram_release_map(&map_dirs);
	ram_create_map(&map_output, DCELL_TYPE);
	output = (DCELL **) map_output.map;	/* one output for all maps */

	if (out_identifier_opt->answer) {
	    ram_create_map(&map_identifier, CELL_TYPE);
	    identifier = (CELL **) map_identifier.map;
	    ram_calculate_identifiers(identifier, number_of_streams,
				      downstream);
	    ram_write_map(&map_identifier, out_identifier_opt->answer,
			  CELL_TYPE, 1, 0);
	    ram_release_map(&map_identifier);
	}

	if (out_difference_opt->answer) {
	    ram_set_null_output(output);
	    if (local)
		ram_calculate_difference(output, number_of_streams,
					 downstream);
	    else
		ram_calculate_drop(output, number_of_streams, downstream);
	    ram_write_map(&map_output, out_difference_opt->answer, DCELL_TYPE,
			  0, 0);
	}

	if (out_distance_opt->answer) {
	    ram_set_null_output(output);
	    if (local && !cells)
		ram_calculate_local_distance(output, number_of_streams,
					     downstream);
	    if (!local && !cells)
		ram_calculate_distance(output, number_of_streams, downstream);
	    if (cells)
		ram_calculate_cell(output, number_of_streams, downstream);
	    ram_write_map(&map_output, out_distance_opt->answer, DCELL_TYPE,
			  0, 0);
	}

	if (out_gradient_opt->answer) {
	    ram_set_null_output(output);
	    if (local)
		ram_calculate_local_gradient(output, number_of_streams,
					     downstream);
	    else
		ram_calculate_gradient(output, number_of_streams, downstream);
	    ram_write_map(&map_output, out_gradient_opt->answer, DCELL_TYPE,
			  0, 0);
	}

	if (out_curvature_opt->answer) {
	    ram_set_null_output(output);
	    ram_calculate_curvature(output, number_of_streams, downstream);
	    ram_write_map(&map_output, out_curvature_opt->answer, DCELL_TYPE,
			  0, 0);
	}

	ram_release_map(&map_output);
    }


    if (segmentation) {
	SEG map_dirs, map_streams, map_elevation, map_output, map_identifier;
	SEGMENT *streams, *dirs, *elevation, *output, *identifier;

	G_message(_("Calculating segments in direction <%s> (may take some time)..."),
		  method_name[downstream]);

	number_of_segs = (int)atof(opt_swapsize->answer);
	number_of_segs = number_of_segs < 32 ? (int)(32 / 0.18) : number_of_segs / 0.18;

	seg_create_map(&map_streams, SROWS, SCOLS, number_of_segs, CELL_TYPE);
	seg_read_map(&map_streams, in_stm_opt->answer, 1, CELL_TYPE);
	seg_create_map(&map_dirs, SROWS, SCOLS, number_of_segs, CELL_TYPE);
	seg_read_map(&map_dirs, in_dir_opt->answer, 1, CELL_TYPE);
	seg_create_map(&map_elevation, SROWS, SCOLS, number_of_segs,
		       FCELL_TYPE);
	seg_read_map(&map_elevation, in_elev_opt->answer, 0, -1);

	streams = &map_streams.seg;
	dirs = &map_dirs.seg;
	elevation = &map_elevation.seg;

	number_of_streams = seg_number_of_streams(streams, dirs) + 1;
	seg_build_streamlines(streams, dirs, elevation, number_of_streams);
	seg_release_map(&map_streams);
	seg_release_map(&map_dirs);
	seg_create_map(&map_output, SROWS, SCOLS, number_of_segs, DCELL_TYPE);
	output = &map_output.seg;	/* one output for all maps */

	if (out_identifier_opt->answer) {
	    seg_create_map(&map_identifier, SROWS, SCOLS, number_of_segs,
			   CELL_TYPE);
	    identifier = &map_identifier.seg;
	    seg_calculate_identifiers(identifier, number_of_streams,
				      downstream);
	    seg_write_map(&map_identifier, out_identifier_opt->answer,
			  CELL_TYPE, 1, 0);
	    seg_release_map(&map_identifier);
	}

	if (out_difference_opt->answer) {
	    seg_set_null_output(output);
	    if (local)
		seg_calculate_difference(output, number_of_streams,
					 downstream);
	    else
		seg_calculate_drop(output, number_of_streams, downstream);
	    seg_write_map(&map_output, out_difference_opt->answer, DCELL_TYPE,
			  0, 0);
	}

	if (out_distance_opt->answer) {
	    seg_set_null_output(output);
	    if (local && !cells)
		seg_calculate_local_distance(output, number_of_streams,
					     downstream);
	    if (!local && !cells)
		seg_calculate_distance(output, number_of_streams, downstream);
	    if (cells)
		seg_calculate_cell(output, number_of_streams, downstream);
	    seg_write_map(&map_output, out_distance_opt->answer, DCELL_TYPE,
			  0, 0);
	}

	if (out_gradient_opt->answer) {
	    seg_set_null_output(output);
	    if (local)
		seg_calculate_local_gradient(output, number_of_streams,
					     downstream);
	    else
		seg_calculate_gradient(output, number_of_streams, downstream);
	    seg_write_map(&map_output, out_gradient_opt->answer, DCELL_TYPE,
			  0, 0);
	}

	if (out_curvature_opt->answer) {
	    seg_set_null_output(output);
	    seg_calculate_curvature(output, number_of_streams, downstream);
	    seg_write_map(&map_output, out_curvature_opt->answer, DCELL_TYPE,
			  0, 0);
	}

	seg_release_map(&map_output);
    }
    free_attributes(number_of_streams);
    exit(EXIT_SUCCESS);
}