示例#1
0
FILE *openAscii(char *asciiFile, RASTER3D_Region * region)
{
    FILE *fp;
    double tmp;
    char buff[1024];
    char line_buff[1024];

    G_debug(3, "openAscii: opens the ascii file and reads the header");

    fp = fopen(asciiFile, "r");
    if (fp == NULL) {
        perror(asciiFile);
        G_usage();
        exit(EXIT_FAILURE);
    }

    /* Initialize the default order */
    rowOrder = ROW_ORDER_NORTH_TO_SOUTH;
    depthOrder = DEPTH_ORDER_BOTTOM_TO_TOP;

    /* Read the first line and check for grass version */
    G_getl2(line_buff, 1024, fp);

    /* First check for new ascii format*/
    if (sscanf(line_buff, "version: %s", buff) == 1) {
        G_message("Found version information: %s\n", buff);
        if (G_strcasecmp(buff, "grass7") == 0) {

            /* Parse the row and depth order */
            G_getl2(line_buff, 1024, fp);
            if (sscanf(line_buff, "order: %s", buff) != 1)
                fatalError("Unable to parse the row and depth order");

            if (G_strcasecmp(buff, "nsbt") == 0) {
                rowOrder = ROW_ORDER_NORTH_TO_SOUTH;
                depthOrder = DEPTH_ORDER_BOTTOM_TO_TOP;
                G_message("Found north -> south, bottom -> top order (nsbt)");
            }
            if (G_strcasecmp(buff, "snbt") == 0) {
                rowOrder = ROW_ORDER_SOUTH_TO_NORTH;
                depthOrder = DEPTH_ORDER_BOTTOM_TO_TOP;
                G_message("Found south -> north, bottom -> top order (snbt)");
            }
            if (G_strcasecmp(buff, "nstb") == 0) {
                rowOrder = ROW_ORDER_NORTH_TO_SOUTH;
                depthOrder = DEPTH_ORDER_TOP_TO_BOTTOM;
                G_message("Found north -> south, top -> bottom order (nstb)");
            }
            if (G_strcasecmp(buff, "sntb") == 0) {
                rowOrder = ROW_ORDER_SOUTH_TO_NORTH;
                depthOrder = DEPTH_ORDER_TOP_TO_BOTTOM;
                G_message("Found south -> north, top -> bottom order (sntb)");
            }
        } else {
            G_fatal_error(_("Unsupported GRASS version %s"), buff);
        }
    } else {
        /* Rewind the stream if no grass version info found */
        rewind(fp);
    }

    Rast3d_get_window(region);

    readHeaderString(fp, "north:", &(region->north));
    readHeaderString(fp, "south:", &(region->south));
    readHeaderString(fp, "east:", &(region->east));
    readHeaderString(fp, "west:", &(region->west));
    readHeaderString(fp, "top:", &(region->top));
    readHeaderString(fp, "bottom:", &(region->bottom));
    readHeaderString(fp, "rows:", &tmp);
    region->rows = (int) tmp;
    readHeaderString(fp, "cols:", &tmp);
    region->cols = (int) tmp;
    readHeaderString(fp, "levels:", &tmp);
    region->depths = (int) tmp;

    return fp;
}
示例#2
0
/* point_in_buf - test if point px,py is in d buffer of Points
 ** dalpha is in degrees
 ** returns:  1 in buffer
 **           0 not in buffer
 */
static int point_in_buf(struct line_pnts *Points, double px, double py, double da,
			double db, double dalpha)
{
    int i, np;
    double cx, cy;
    double delta, delta_k, k;
    double vx, vy, wx, wy, mx, my, nx, ny;
    double len, tx, ty, d, da2;

    G_debug(3, "point_in_buf()");

    dalpha *= PI / 180;		/* convert dalpha from degrees to radians */

    np = Points->n_points;
    da2 = da * da;
    for (i = 0; i < np - 1; i++) {
	vx = Points->x[i];
	vy = Points->y[i];
	wx = Points->x[i + 1];
	wy = Points->y[i + 1];

	if (da != db) {
	    mx = wx - vx;
	    my = wy - vy;
	    len = LENGTH(mx, my);
	    elliptic_tangent(mx / len, my / len, da, db, dalpha, &cx, &cy);

	    delta = mx * cy - my * cx;
	    delta_k = (px - vx) * cy - (py - vy) * cx;
	    k = delta_k / delta;
	    /*            G_debug(4, "k = %g, k1 = %g", k, (mx * (px - vx) + my * (py - vy)) / (mx * mx + my * my)); */
	    if (k <= 0) {
		nx = vx;
		ny = vy;
	    }
	    else if (k >= 1) {
		nx = wx;
		ny = wy;
	    }
	    else {
		nx = vx + k * mx;
		ny = vy + k * my;
	    }

	    /* inverse transform */
	    elliptic_transform(px - nx, py - ny, 1 / da, 1 / db, dalpha, &tx,
			       &ty);

	    d = dig_distance2_point_to_line(nx + tx, ny + ty, 0, vx, vy, 0,
					    wx, wy, 0, 0, NULL, NULL, NULL,
					    NULL, NULL);

	    /*            G_debug(4, "sqrt(d)*da = %g, len' = %g, olen = %g", sqrt(d)*da, da*LENGTH(tx,ty), LENGTH((px-nx),(py-ny))); */
	    if (d <= 1) {
		/* G_debug(1, "d=%g", d); */
		return 1;
	    }
	}
	else {
	    d = dig_distance2_point_to_line(px, py, 0, vx, vy, 0, wx, wy, 0,
					    0, NULL, NULL, NULL, NULL, NULL);
	    /*            G_debug(4, "sqrt(d)     = %g", sqrt(d)); */
	    if (d <= da2) {
		return 1;
	    }
	}
    }

    return 0;
}
示例#3
0
文件: dbe.c 项目: caomw/grass
int db__driver_open_database(dbHandle * handle)
{
    char *name;
    dbConnection default_connection;
    MYSQL *res;

    db_get_connection(&default_connection);
    name = G_store(db_get_handle_dbname(handle));

    /* if name is empty use default_connection.databaseName */
    if (strlen(name) == 0)
	name = default_connection.databaseName;

    G_debug(3, "db_driver_open_database() mysql: database definition = '%s'",
	    name);

    /* Embedded version */
    {
	char *datadir, *database;
	char *server_args[4];
	char *buf;

	if (!replace_variables(name, &datadir, &database)) {
	    db_d_append_error(_("Unable parse MySQL embedded database name"));
	    db_d_append_error(mysql_error(connection));
	    db_d_report_error();
	    return DB_FAILED;
	}

	server_args[0] = "mesql";	/* this string is not used */
	G_asprintf(&buf, "--datadir=%s", datadir);
	server_args[1] = buf;
	/* With InnoDB it is very slow to close the database */
	server_args[2] = "--skip-innodb";	/* OK? */
	/* Without --bootstrap it complains about missing 
	 * mysql.time_zone_leap_second table */
	server_args[3] = "--bootstrap";	/* OK? */

	if (mysql_server_init(4, server_args, NULL)) {
	    db_d_append_error(_("Cannot initialize MySQL embedded server"));
	    db_d_append_error(mysql_error(connection));
	    db_d_report_error();
	    free(datadir);
	    free(database);
	    return DB_FAILED;
	}

	connection = mysql_init(NULL);
	mysql_options(connection, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);

	res =
	    mysql_real_connect(connection, NULL, NULL, NULL, database, 0,
			       NULL, 0);

	free(datadir);
	free(database);

	if (res == NULL) {
	    db_d_append_error(_("Unable to connect to MySQL embedded server: "));
	    db_d_append_error(mysql_error(connection));
	    db_d_report_error();
	    return DB_FAILED;
	}
    }

    return DB_OK;
}
示例#4
0
文件: plus_struct.c 项目: caomw/grass
int dig_Wr_Plus_head(struct gvfile * fp, struct Plus_head *ptr)
{
    unsigned char buf[10];
    long length = 142;

    dig_rewind(fp);
    dig_set_cur_port(&(ptr->port));

    /* bytes 1 - 5 */
    buf[0] = GV_TOPO_VER_MAJOR;
    buf[1] = GV_TOPO_VER_MINOR;
    buf[2] = GV_TOPO_EARLIEST_MAJOR;
    buf[3] = GV_TOPO_EARLIEST_MINOR;
    buf[4] = ptr->port.byte_order;
    if (0 >= dig__fwrite_port_C((char *)buf, 5, fp))
	return (-1);

    /* determine required offset size from coor file size */
    if (ptr->coor_size > (off_t)PORT_LONG_MAX) {
	/* can only happen when sizeof(off_t) == 8 */
	ptr->off_t_size = 8;
    }
    else
	ptr->off_t_size = 4;

    /* add a new field with off_t_size after byte_order? */

    /* adjust header size for large files */
    if (ptr->off_t_size == 8) {
	/* 7 offset values and coor file size: add 8 * 4 */
	length += 32;
    }

    /* bytes 6 - 9 : header size */
    if (0 >= dig__fwrite_port_L(&length, 1, fp))
	return (0);

    /* byte 10 : dimension 2D or 3D */
    buf[0] = ptr->with_z;
    if (0 >= dig__fwrite_port_C((char *)buf, 1, fp))
	return (0);

    /* bytes 11 - 58 : bound box */
    if (0 >= dig__fwrite_port_D(&(ptr->box.N), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->box.S), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->box.E), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->box.W), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->box.T), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_D(&(ptr->box.B), 1, fp))
	return (-1);

    /* bytes 59 - 86 : number of structures */
    if (0 >= dig__fwrite_port_P(&(ptr->n_nodes), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_edges), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_lines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_areas), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_isles), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_volumes), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_holes), 1, fp))
	return (-1);

    /* bytes 87 - 110 : number of line types */
    if (0 >= dig__fwrite_port_P(&(ptr->n_plines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_llines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_blines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_clines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_flines), 1, fp))
	return (-1);
    if (0 >= dig__fwrite_port_P(&(ptr->n_klines), 1, fp))
	return (-1);

    /* bytes 111 - 138 : Offset */
    if (0 >= dig__fwrite_port_O(&(ptr->Node_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Edge_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Line_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Area_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Isle_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Volume_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fwrite_port_O(&(ptr->Hole_offset), 1, fp, ptr->off_t_size))
	return (-1);

    /* bytes 139 - 142 : Coor size and time */
    if (0 >= dig__fwrite_port_O(&(ptr->coor_size), 1, fp, ptr->off_t_size))
	return (-1);

    G_debug(2, "topo body offset %"PRI_OFF_T, dig_ftell(fp));

    return (0);
}
示例#5
0
/* input line must be looped */
static void convolution_line(struct line_pnts *Points, double da, double db,
			     double dalpha, int side, int round, int caps,
			     double tol, struct line_pnts *nPoints)
{
    int i, j, res, np;
    double *x, *y;
    double tx, ty, vx, vy, wx, wy, nx, ny, mx, my, rx, ry;
    double vx1, vy1, wx1, wy1;
    double a0, b0, c0, a1, b1, c1;
    double phi1, phi2, delta_phi;
    double nsegments, angular_tol, angular_step;
    double angle0, angle1;
    int inner_corner, turns360;

    G_debug(3, "convolution_line() side = %d", side);

    np = Points->n_points;
    x = Points->x;
    y = Points->y;
    if ((np == 0) || (np == 1))
	return;
    if ((x[0] != x[np - 1]) || (y[0] != y[np - 1])) {
	G_fatal_error(_("Line is not looped"));
	return;
    }

    Vect_reset_line(nPoints);

    if ((da == 0) || (db == 0)) {
	Vect_copy_xyz_to_pnts(nPoints, x, y, NULL, np);
	return;
    }

    side = (side >= 0) ? (1) : (-1);	/* normalize variable */
    dalpha *= PI / 180;		/* convert dalpha from degrees to radians */
    angular_tol = angular_tolerance(tol, da, db);

    i = np - 2;
    norm_vector(x[i], y[i], x[i + 1], y[i + 1], &tx, &ty);
    elliptic_tangent(side * tx, side * ty, da, db, dalpha, &vx, &vy);
    angle1 = atan2(ty, tx);
    nx = x[i] + vx;
    ny = y[i] + vy;
    mx = x[i + 1] + vx;
    my = y[i + 1] + vy;
    if (!round)
	line_coefficients(nx, ny, mx, my, &a1, &b1, &c1);

    for (i = 0; i <= np - 2; i++) {
	G_debug(4, "point %d, segment %d-%d", i, i, i + 1);
	/* save the old values */
	if (!round) {
	    a0 = a1;
	    b0 = b1;
	    c0 = c1;
	}
	wx = vx;
	wy = vy;
	angle0 = angle1;

	norm_vector(x[i], y[i], x[i + 1], y[i + 1], &tx, &ty);
	if ((tx == 0) && (ty == 0))
	    continue;
	elliptic_tangent(side * tx, side * ty, da, db, dalpha, &vx, &vy);
	angle1 = atan2(ty, tx);
	nx = x[i] + vx;
	ny = y[i] + vy;
	mx = x[i + 1] + vx;
	my = y[i + 1] + vy;
	if (!round)
	    line_coefficients(nx, ny, mx, my, &a1, &b1, &c1);


	delta_phi = angle1 - angle0;
	if (delta_phi > PI)
	    delta_phi -= 2 * PI;
	else if (delta_phi <= -PI)
	    delta_phi += 2 * PI;
	/* now delta_phi is in [-pi;pi] */
	turns360 = (fabs(fabs(delta_phi) - PI) < 1e-15);
	inner_corner = (side * delta_phi <= 0) && (!turns360);


	/* if <line turns 360> and (<caps> and <not round>) */
	if (turns360 && caps && (!round)) {
	    norm_vector(0, 0, vx, vy, &tx, &ty);
	    elliptic_tangent(side * tx, side * ty, da, db, dalpha, &tx, &ty);
	    Vect_append_point(nPoints, x[i] + wx + tx, y[i] + wy + ty, 0);
	    G_debug(4, " append point (c) x=%.16f y=%.16f", x[i] + wx + tx,
		    y[i] + wy + ty);
	    Vect_append_point(nPoints, nx + tx, ny + ty, 0);	/* nx == x[i] + vx, ny == y[i] + vy */
	    G_debug(4, " append point (c) x=%.16f y=%.16f", nx + tx, ny + ty);
	}

	if ((!turns360) && (!round) && (!inner_corner)) {
	    res = line_intersection(a0, b0, c0, a1, b1, c1, &rx, &ry);
	    if (res == 1) {
		Vect_append_point(nPoints, rx, ry, 0);
		G_debug(4, " append point (o) x=%.16f y=%.16f", rx, ry);
	    }
	    else if (res == 2) {
		/* no need to append point in this case */
	    }
	    else
		G_fatal_error(_("Unexpected result of line_intersection() res = %d"),
			      res);
	}

	if (round && (!inner_corner) && (!turns360 || caps)) {
	    /* we should draw elliptical arc for outside corner */

	    /* inverse transforms */
	    elliptic_transform(wx, wy, 1 / da, 1 / db, dalpha, &wx1, &wy1);
	    elliptic_transform(vx, vy, 1 / da, 1 / db, dalpha, &vx1, &vy1);

	    phi1 = atan2(wy1, wx1);
	    phi2 = atan2(vy1, vx1);
	    delta_phi = side * (phi2 - phi1);

	    /* make delta_phi in [0, 2pi] */
	    if (delta_phi < 0)
		delta_phi += 2 * PI;

	    nsegments = (int)(delta_phi / angular_tol) + 1;
	    angular_step = side * (delta_phi / nsegments);

	    phi1 += angular_step;
	    for (j = 1; j <= nsegments - 1; j++) {
		elliptic_transform(cos(phi1), sin(phi1), da, db, dalpha, &tx,
				   &ty);
		Vect_append_point(nPoints, x[i] + tx, y[i] + ty, 0);
		G_debug(4, " append point (r) x=%.16f y=%.16f", x[i] + tx,
			y[i] + ty);
		phi1 += angular_step;
	    }
	}

	Vect_append_point(nPoints, nx, ny, 0);
	G_debug(4, " append point (s) x=%.16f y=%.16f", nx, ny);
	Vect_append_point(nPoints, mx, my, 0);
	G_debug(4, " append point (s) x=%.16f y=%.16f", mx, my);
    }

    /* close the output line */
    Vect_append_point(nPoints, nPoints->x[0], nPoints->y[0], nPoints->z[0]);
    Vect_line_prune ( nPoints );
}
示例#6
0
void draw_histogram(const char *map_name, int x0, int y0, int width,
		    int height, int color, int flip, int horiz,
		    int map_type, int is_fp, struct FPRange render_range)
{
    int i, nsteps, ystep;
    long cell_count = 0;
    double max_width, width_mult, dx;
    double dy, y0_adjust;	/* only needed for CELL maps */
    struct stat_list dist_stats;
    struct stat_node *ptr;
    struct Range range;
    struct FPRange fprange;
    CELL c_map_min, c_map_max;
    DCELL d_map_min, d_map_max;
    double map_min, map_max, map_range, user_range;
    double crop_min_perc = 0.0, crop_max_perc = 1.0, pad_min_perc = 0.0;

    if (horiz) {
	max_width = height * 1.75;
	nsteps = width - 3;
    }
    else {
	max_width = width * 1.75;
	nsteps = height - 3;
    }


    if (render_range.first_time) {
	/* user specified range, can be either larger
	    or smaller than actual map's range */

	if (is_fp) {
	    Rast_read_fp_range(map_name, "", &fprange);
	    Rast_get_fp_range_min_max(&fprange, &d_map_min, &d_map_max);
	    map_min = (double)d_map_min;
	    map_max = (double)d_map_max;
	}
	else {
	    Rast_read_range(map_name, "", &range);
	    Rast_get_range_min_max(&range, &c_map_min, &c_map_max);
	    map_min = (double)c_map_min;
	    map_max = (double)c_map_max;
	}

	map_range = map_max - map_min;
	user_range = render_range.max - render_range.min;

	if (horiz)
	    nsteps = (int)(0.5 + (map_range * (width - 3) / user_range));
	else
	    nsteps = (int)(0.5 + (map_range * (height - 3) / user_range));

	G_debug(1, "number of steps for r.stats = %d, height-3=%d  width-3=%d",
		nsteps, height - 3, width - 3);

	/* need to know the % of the MAP range where user range starts and stops.
	 *   note that MAP range can be fully inside user range, in which case
	 *   keep 0-100% aka 0,nsteps, i.e. the step number in the nsteps range */

	if (render_range.min > map_min) {
	   crop_min_perc = (render_range.min - map_min) / map_range;
	   G_debug(3, "min: %.02f vs. %.02f (%.02f) ... %.02f%%",
	   	   render_range.min, map_min, map_range, 100 * crop_min_perc);
	}

	if (render_range.max > map_max) {
	    crop_max_perc = 1.0 - ((render_range.max - map_max) / user_range);
	    G_debug(3, "max: %.02f vs. %.02f (%.02f) ... %.02f%%",
		    map_max, render_range.max, map_range, 100 * crop_max_perc);
	}

	if (render_range.min < map_min) {
	   pad_min_perc = (map_min - render_range.min) / user_range;
	   G_debug(3, "Min: %.02f vs. %.02f (%.02f) ... %.02f%%",
	   	   map_min, render_range.min, user_range, 100 * pad_min_perc);
	}

#ifdef amplify_gain
	/* proportion of nsteps to width, use as mult factor to boost the 1.75x
	    when spread out over more nsteps than we are displaying */
	G_debug(0, "max_width was: %.2f  (nsteps=%d)", max_width, nsteps);

	if (nsteps > ((horiz ? width : height) - 3.0))
	    max_width *= nsteps / ((horiz ? width : height) - 3.0);

	G_debug(0, "max_width now: %.2f", max_width);
#endif
    }


    /* TODO */
    if (!is_fp && render_range.first_time) {
	G_warning(_("Histogram constrained by range not yet implemented for "
		  "categorical rasters"));
	return;
    }


    /* get the distribution statistics */
    get_stats(map_name, &dist_stats, nsteps, map_type);

    width_mult = max_width / dist_stats.maxstat;

    D_use_color(color);
    D_begin();

    ptr = dist_stats.ptr;

    if (!is_fp) {
	dy = (nsteps + 3.0) / (1 + dist_stats.maxcat - dist_stats.mincat);

	if (flip)
	    dy *= -1;

	if (dist_stats.mincat == 0)
	    y0_adjust = dy;
	else
	    y0_adjust = 0;

	if (!flip)  /* mmph */
	    y0_adjust += 0.5;
    }


    G_debug(3, "mincat=%ld  maxcat=%ld", dist_stats.mincat, dist_stats.maxcat);

    for (i = dist_stats.mincat, ystep = 0; i <= dist_stats.maxcat; i++) {
	if (!ptr)
	    break;

	/* jump out if user range cuts things shorter than the map's native range */
	if ((horiz && ystep > width - 4) || (!horiz && ystep > height - 4))
	    break;

	/* jump out if user range goes beyond max of map data */
	if (((double)ystep / ((horiz ? width : height) - 3.0)) > crop_max_perc)
	    break;
/* TODO	if (!is_fp && i > render_range.max)
	    break;
*/
	/* haven't made it to the min of the user range yet */
	if (((double)i / nsteps) < crop_min_perc) {
	    continue;
	}

	/* now it's ok advance the plotter position */
	ystep++;

	/* if user range is below the minimum real map value, we need to pad out the space */
	if (render_range.first_time && render_range.min < map_min) {
	    if ( ((double)ystep / ((horiz ? width : height) - 3.0)) < pad_min_perc) {
		i--;
		continue;
	    }
	}

	if (ptr->cat == i) {	/* AH-HA!! found the stat */
	    cell_count = ptr->stat;

	    if (ptr->next != NULL)
		ptr = ptr->next;
	}
	else {			/* we have to look for the stat */

	    /* loop until we find it, or pass where it should be */
	    while (ptr->cat < i && ptr->next != NULL)
		ptr = ptr->next;
	    if (ptr->cat == i) {	/* AH-HA!! found the stat */
		cell_count = ptr->stat;

		if (ptr->next != NULL)
		    ptr = ptr->next;
	    }
	    else		/* stat cannot be found */
		G_debug(5, "No matching stat found, i=%d", i);
	}

	G_debug(5, "i=%d  ptr->cat=%ld  cell_count=%ld", i, ptr->cat, 
		cell_count);

	if (!cell_count)
	    continue;

	dx = cell_count * width_mult;

	if (is_fp) {
	    if (horiz) {
		if (flip)
		    D_move_abs(x0 + width - ystep - 1, y0 - 1);
		else
		    D_move_abs(x0 + ystep + 1, y0 - 1);

		D_cont_rel(0, -dx);
	    }
	    else {  /* vertical */
		if (flip)
		    D_move_abs(x0 - 1, y0 - 1 + height - ystep);
		else
		    D_move_abs(x0 - 1, y0 + 1 + ystep);

		D_cont_rel(-dx, 0);
	    }
	}
	else {	/* categorical */

	    if (horiz) {
		if (flip)
		    D_box_abs(x0 + width + y0_adjust + ((i - 1) * dy),
			      y0 - 1,
			      x0 + width + y0_adjust + 1 + (i * dy),
			      y0 - 1 - dx);
		else
		    D_box_abs(x0 + y0_adjust + ((i - 1) * dy),
			      y0 - 1,
			      x0 - 1 + y0_adjust + (i * dy),
			      y0 - 1 - dx);
	    }
	    else {  /* vertical */

		if (flip)
		    /* GRASS_EPSILON fudge around D_box_abs() weirdness + PNG driver */
		    D_box_abs(x0 - 1 - GRASS_EPSILON * 10,
			      y0 + height + y0_adjust + ((i - 1) * dy),
			      x0 - 1 - dx,
			      y0 + height + y0_adjust + 1 + (i * dy));
		else
		    D_box_abs(x0 - 1 - GRASS_EPSILON * 10,
			      y0 + y0_adjust + ((i - 1) * dy),
			      x0 - 1 - dx,
			      y0 + y0_adjust - 1 + (i * dy));
	    }
	}
    }

    D_close();
    D_end();
    D_stroke();
}
示例#7
0
文件: plus_struct.c 项目: caomw/grass
int dig_Wr_P_line(struct Plus_head *Plus, int n, struct gvfile * fp)
{
    int n_edges = 0;
    char ch;
    struct P_line *ptr;

    G_debug(4, "dig_Wr_P_line() line = %d", n);

    ptr = Plus->Line[n];

    /* if NULL i.e. dead write just 0 instead of type */
    if (ptr == NULL) {
	G_debug(4, "    line is dead -> write 0 only");
	ch = 0;
	if (0 >= dig__fwrite_port_C(&ch, 1, fp))
	    return (-1);
	return 0;
    }

    /* type */
    ch = (char)dig_type_to_store(ptr->type);
    G_debug(5, "    line type  %d -> %d", ptr->type, ch);
    if (0 >= dig__fwrite_port_C(&ch, 1, fp))
	return (-1);

    /* offset */
    if (0 >= dig__fwrite_port_O(&(ptr->offset), 1, fp, Plus->off_t_size))
	return (-1);
	
    if (!ptr->topo)
	return (0);
	
    /* nothing else for points */

    /* centroids */
    if (ptr->type & GV_CENTROID) {
	struct P_topo_c *topo = (struct P_topo_c *)ptr->topo;
	
	if (0 >= dig__fwrite_port_P(&(topo->area), 1, fp))
	    return (-1);
    }
    /* lines */
    else if (ptr->type & GV_LINE) {
	struct P_topo_l *topo = (struct P_topo_l *)ptr->topo;

	if (0 >= dig__fwrite_port_P(&(topo->N1), 1, fp))
	    return (-1);
	if (0 >= dig__fwrite_port_P(&(topo->N2), 1, fp))
	    return (-1);
    }
    /* boundaries */
    else if (ptr->type & GV_BOUNDARY) {
	struct P_topo_b *topo = (struct P_topo_b *)ptr->topo;

	if (0 >= dig__fwrite_port_P(&(topo->N1), 1, fp))
	    return (-1);
	if (0 >= dig__fwrite_port_P(&(topo->N2), 1, fp))
	    return (-1);
	if (0 >= dig__fwrite_port_P(&(topo->left), 1, fp))
	    return (-1);
	if (0 >= dig__fwrite_port_P(&(topo->right), 1, fp))
	    return (-1);
    }
    /* faces */
    else if ((ptr->type & GV_FACE) && Plus->with_z) {	/* reserved for face */
	struct P_topo_f *topo = (struct P_topo_f *)ptr->topo;

	if (0 >= dig__fwrite_port_I(&n_edges, 1, fp))
	    return (-1);

	/* here will be list of edges */

	/* left / right volume / hole */
	if (0 >= dig__fwrite_port_P(&(topo->left), 1, fp))
	    return (-1);
	if (0 >= dig__fwrite_port_P(&(topo->right), 1, fp))
	    return (-1);
    }
    /* kernels */
    else if ((ptr->type & GV_KERNEL) && Plus->with_z) {	/* reserved for kernel (volume number) */
	struct P_topo_k *topo = (struct P_topo_k *)ptr->topo;

	/* volume */
	if (0 >= dig__fwrite_port_P(&(topo->volume), 1, fp))
	    return (-1);
    }

    return (0);
}
示例#8
0
文件: close_maps2.c 项目: caomw/grass
int close_array_seg(void)
{
    struct Colors colors;
    int incr, max, red, green, blue, rd, gr, bl, flag;
    int c, r, map_fd;
    CELL *cellrow, value;
    CELL *theseg;
    RAMSEG thesegseg;

    cellrow = Rast_allocate_c_buf();
    if (seg_flag || bas_flag || haf_flag) {
	if (seg_flag) {
	    theseg = bas;
	    thesegseg = bas_seg;
	}
	else if (bas_flag) {
	    theseg = bas;
	    thesegseg = bas_seg;
	}
	else {
	    theseg = haf;
	    thesegseg = haf_seg;
	}
	max = n_basins;
	G_debug(1, "%d basins created", max);
	Rast_init_colors(&colors);
	if (max > 0)
	    Rast_make_random_colors(&colors, 1, max);
	else {
	    G_warning(_("No basins were created. Verify threshold and region settings."));
	    Rast_make_random_colors(&colors, 1, 2);
	}

	if (max < 1000 && max > 0) {
	    Rast_set_c_color((CELL) 0, 0, 0, 0, &colors);
	    r = 1;
	    incr = 0;
	    while (incr >= 0) {
		G_percent(r, max, 2);
		for (gr = 130 + incr; gr <= 255; gr += 20) {
		    for (rd = 90 + incr; rd <= 255; rd += 30) {
			for (bl = 90 + incr; bl <= 255; bl += 40) {
			    flag = 1;
			    while (flag) {
				Rast_get_c_color(&r, &red, &green, &blue, &colors);
				/* if existing rule is too dark then append a new
				   rule to override it */
				if ((blue * .11 + red * .30 + green * .59) <
				    100) {
				    Rast_set_c_color(r, rd, gr, bl, &colors);
				    flag = 0;
				}
				if (++r > max) {
				    gr = rd = bl = 300;
				    flag = 0;
				    incr = -1;
				}
			    }
			}
		    }
		}
		if (incr >= 0) {
		    incr += 15;
		    if (incr > 120)
			incr = 7;
		}
	    }
	    G_percent(r - 1, max, 3);	/* finish it */
	}
	else
	    G_debug(1,
		    "Too many subbasins to reasonably check for color brightness");
	/* using the existing stack of while/for/for/for/while loops ... */
    }

    /* stream segments map */
    if (seg_flag) {
	map_fd = Rast_open_c_new(seg_name);
	for (r = 0; r < nrows; r++) {
	    Rast_set_c_null_value(cellrow, ncols);	/* reset row to all NULL */
	    for (c = 0; c < ncols; c++) {
		value = FLAG_GET(swale, r, c);
		if (value)
		    cellrow[c] = bas[SEG_INDEX(bas_seg, r, c)];
	    }
	    Rast_put_row(map_fd, cellrow, CELL_TYPE);
	}
	Rast_close(map_fd);
	Rast_write_colors(seg_name, this_mapset, &colors);
    }

    /* basins map */
    if (bas_flag) {
	map_fd = Rast_open_c_new(bas_name);
	for (r = 0; r < nrows; r++) {
	    for (c = 0; c < ncols; c++) {
		cellrow[c] = bas[SEG_INDEX(bas_seg, r, c)];
		if (cellrow[c] == 0)
		    Rast_set_c_null_value(cellrow + c, 1);
	    }
	    Rast_put_row(map_fd, cellrow, CELL_TYPE);
	}
	Rast_close(map_fd);
	Rast_write_colors(bas_name, this_mapset, &colors);
    }

    /* half_basins map */
    if (haf_flag) {
	map_fd = Rast_open_c_new(haf_name);
	for (r = 0; r < nrows; r++) {
	    for (c = 0; c < ncols; c++) {
		cellrow[c] = haf[SEG_INDEX(haf_seg, r, c)];
		if (cellrow[c] == 0)
		    Rast_set_c_null_value(cellrow + c, 1);
	    }
	    Rast_put_row(map_fd, cellrow, CELL_TYPE);
	}
	Rast_close(map_fd);
	Rast_write_colors(haf_name, this_mapset, &colors);
    }

    if (seg_flag || bas_flag || haf_flag)
	Rast_free_colors(&colors);

    G_free(haf);
    G_free(bas);
    G_free(cellrow);
    if (arm_flag)
	fclose(fp);
    close_maps();

    return 0;
}
示例#9
0
/* clean_parallel - clean parallel line created by parallel_line:
 ** - looking for loops and if loop doesn't contain any other loop
 **   and centroid of loop is in buffer removes this loop (repeated)
 ** - optionally removes all end points in buffer
 *    parameters:
 *      Points - parallel line
 *      origPoints - original line
 *      d - offset
 *      rm_end - remove end points in buffer
 ** note1: on some lines (multiply selfcrossing; lines with end points
 **        in buffer of line other; some shapes of ends ) may create nosense
 ** note2: this function is stupid and slow, somebody more clever
 **        than I am should write paralle_line + clean_parallel
 **        better;    RB March 2000
 */
static void clean_parallel(struct line_pnts *Points,
			   struct line_pnts *origPoints, double d, int rm_end)
{
    int i, j, np, npn, sa, sb;
    int sa_max = 0;
    int first = 0, current, last, lcount;
    double *x, *y, px, py, ix, iy;
    static struct line_pnts *sPoints = NULL;

    G_debug(4, "clean_parallel(): npoints = %d, d = %f, rm_end = %d",
	    Points->n_points, d, rm_end);

    x = Points->x;
    y = Points->y;
    np = Points->n_points;

    if (sPoints == NULL)
	sPoints = Vect_new_line_struct();

    Vect_reset_line(sPoints);

    npn = 1;

    /* remove loops */
    while (first < np - 2) {
	/* find first loop which doesn't contain any other loop */
	current = first;
	last = Points->n_points - 2;
	lcount = 0;
	while (find_cross
	       (Points, current, last - 1, current + 1, last, &sa,
		&sb) != 0) {
	    if (lcount == 0) {
		first = sa;
	    }			/* move first forward */

	    current = sa + 1;
	    last = sb;
	    lcount++;
	    G_debug(5, "  current = %d, last = %d, lcount = %d", current,
		    last, lcount);
	}
	if (lcount == 0) {
	    break;
	}			/* loop not found */

	/* ensure sa is monotonically increasing, so npn doesn't reset low */
	if (sa > sa_max)
	    sa_max = sa;
	if (sa < sa_max)
	    break;

	/* remove loop if in buffer */
	if ((sb - sa) == 1) {	/* neighbouring lines overlap */
	    j = sb + 1;
	    npn = sa + 1;
	}
	else {
	    Vect_reset_line(sPoints);
	    dig_find_intersection(x[sa], y[sa], x[sa + 1], y[sa + 1], x[sb],
				  y[sb], x[sb + 1], y[sb + 1], &ix, &iy);
	    Vect_append_point(sPoints, ix, iy, 0);
	    for (i = sa + 1; i < sb + 1; i++) {	/* create loop polygon */
		Vect_append_point(sPoints, x[i], y[i], 0);
	    }
	    Vect_find_poly_centroid(sPoints, &px, &py);
	    if (point_in_buf(origPoints, px, py, d)) {	/* is loop in buffer ? */
		npn = sa + 1;
		x[npn] = ix;
		y[npn] = iy;
		j = sb + 1;
		npn++;
		if (lcount == 0) {
		    first = sb;
		}
	    }
	    else {		/* loop is not in buffer */
		first = sb;
		continue;
	    }
	}

	for (i = j; i < Points->n_points; i++) {	/* move points down */
	    x[npn] = x[i];
	    y[npn] = y[i];
	    npn++;
	}
	Points->n_points = npn;
    }

    if (rm_end) {
	/* remove points from start in buffer */
	j = 0;
	for (i = 0; i < Points->n_points - 1; i++) {
	    px = (x[i] + x[i + 1]) / 2;
	    py = (y[i] + y[i + 1]) / 2;
	    if (point_in_buf(origPoints, x[i], y[i], d * 0.9999)
		&& point_in_buf(origPoints, px, py, d * 0.9999)) {
		j++;
	    }
	    else {
		break;
	    }
	}
	if (j > 0) {
	    npn = 0;
	    for (i = j; i < Points->n_points; i++) {
		x[npn] = x[i];
		y[npn] = y[i];
		npn++;
	    }
	    Points->n_points = npn;
	}
	/* remove points from end in buffer */
	j = 0;
	for (i = Points->n_points - 1; i >= 1; i--) {
	    px = (x[i] + x[i - 1]) / 2;
	    py = (y[i] + y[i - 1]) / 2;
	    if (point_in_buf(origPoints, x[i], y[i], d * 0.9999)
		&& point_in_buf(origPoints, px, py, d * 0.9999)) {
		j++;
	    }
	    else {
		break;
	    }
	}
	if (j > 0) {
	    Points->n_points -= j;
	}
    }
}
示例#10
0
int thin_streams(void)
{
    int i, j, r, c, done;
    CELL stream_id;
    int next_node;
    struct sstack
    {
	int stream_id;
	int next_trib;
    } *nodestack;
    int top = 0, stack_step = 1000;
    int n_trib_total;
    int n_thinned = 0;

    G_message(_("Thinning stream segments..."));

    nodestack = (struct sstack *)G_malloc(stack_step * sizeof(struct sstack));

    for (i = 0; i < n_outlets; i++) {
	G_percent(i, n_outlets, 2);
	r = outlets[i].r;
	c = outlets[i].c;
	cseg_get(&stream, &stream_id, r, c);

	if (stream_id == 0)
	    continue;

	/* add root node to stack */
	G_debug(2, "add root node");
	top = 0;
	nodestack[top].stream_id = stream_id;
	nodestack[top].next_trib = 0;

	/* depth first post order traversal */
	G_debug(2, "traverse");
	while (top >= 0) {

	    done = 1;
	    stream_id = nodestack[top].stream_id;
	    G_debug(3, "stream_id %d, top %d", stream_id, top);
	    if (nodestack[top].next_trib < stream_node[stream_id].n_trib) {
		/* add to stack */
		G_debug(3, "get next node");
		next_node =
		    stream_node[stream_id].trib[nodestack[top].next_trib];
		G_debug(3, "add to stack: next %d, trib %d, n trib %d",
			next_node, nodestack[top].next_trib,
			stream_node[stream_id].n_trib);
		nodestack[top].next_trib++;
		top++;
		if (top >= stack_step) {
		    /* need more space */
		    stack_step += 1000;
		    nodestack =
			(struct sstack *)G_realloc(nodestack,
						   stack_step *
						   sizeof(struct sstack));
		}

		nodestack[top].next_trib = 0;
		nodestack[top].stream_id = next_node;
		done = 0;
		G_debug(3, "go further down");
	    }
	    if (done) {
		/* thin stream segment */
		G_debug(3, "thin stream segment %d", stream_id);

		if (thin_seg(stream_id) == 0)
		    G_debug(3, "segment %d not thinned", stream_id);
		else {
		    G_debug(3, "segment %d thinned", stream_id);
		    n_thinned++;
		}

		top--;
		/* count tributaries */
		if (top >= 0) {
		    n_trib_total = 0;
		    stream_id = nodestack[top].stream_id;
		    for (j = 0; j < stream_node[stream_id].n_trib; j++) {
			/* intermediate */
			if (stream_node[stream_node[stream_id].trib[j]].
			    n_trib > 0)
			    n_trib_total +=
				stream_node[stream_node[stream_id].trib[j]].
				n_trib_total;
			/* start */
			else
			    n_trib_total++;
		    }
		    stream_node[stream_id].n_trib_total = n_trib_total;
		}
	    }
	}
    }
    G_percent(n_outlets, n_outlets, 1);	/* finish it */

    G_free(nodestack);
    
    G_verbose_message(_("%d of %lld stream segments were thinned"), n_thinned, n_stream_nodes);

    return 1;
}
示例#11
0
文件: clump.c 项目: caomw/grass
CELL clump(int in_fd, int out_fd, int diag, int print)
{
    register int col;
    register int n;
    CELL NEW, OLD;
    CELL *temp_cell, *temp_clump;
    CELL *prev_in, *cur_in, *out_cell;
    CELL *prev_clump, *cur_clump;
    CELL X, LEFT;
    CELL *index, *renumber;
    CELL label;
    int nrows, ncols;
    int row;
    int len;
    int nalloc;
    long cur_time;
    char *cname;
    int cfd, csize;
    CELL cat;

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

    /* allocate clump index */
    nalloc = INCR;
    index = (CELL *) G_malloc(nalloc * sizeof(CELL));
    index[0] = 0;
    renumber = NULL;

    /* allocate CELL buffers two columns larger than current window */
    len = (ncols + 2) * sizeof(CELL);
    prev_in = (CELL *) G_malloc(len);
    cur_in = (CELL *) G_malloc(len);
    prev_clump = (CELL *) G_malloc(len);
    cur_clump = (CELL *) G_malloc(len);
    out_cell = (CELL *) G_malloc(len);

    /* temp file for initial clump IDs */
    cname = G_tempfile();
    if ((cfd = open(cname, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0)
	G_fatal_error(_("Unable to open temp file"));
    csize = ncols * sizeof(CELL);

    time(&cur_time);

    /* fake a previous row which is all NULL */
    Rast_set_c_null_value(prev_in, ncols + 2);

    /* set left and right edge to NULL */
    Rast_set_c_null_value(&cur_in[0], 1);
    Rast_set_c_null_value(&cur_in[ncols + 1], 1);

    /* initialize clump labels */
    G_zero(cur_clump, len);
    G_zero(prev_clump, len);
    label = 0;

    /****************************************************
     *                      PASS 1                      *
     * pass thru the input, create initial clump labels *
     ****************************************************/

    G_message(_("Pass 1 of 2..."));
    for (row = 0; row < nrows; row++) {
	Rast_get_c_row(in_fd, cur_in + 1, row);

	G_percent(row, nrows, 4);
	Rast_set_c_null_value(&X, 1);
	for (col = 1; col <= ncols; col++) {
	    LEFT = X;
	    X = cur_in[col];
	    if (Rast_is_c_null_value(&X)) {	/* don't clump NULL data */
		cur_clump[col] = 0;
		continue;
	    }

	    /*
	     * if the cell value is different to the left and above
	     * (diagonal: and above left and above right)
	     * then we must start a new clump
	     *
	     * this new clump may eventually collide with another
	     * clump and will have to be merged
	     */

	    /* try to connect the current cell to an existing clump */
	    OLD = NEW = 0;
	    /* same clump as to the left */
	    if (X == LEFT) {
		OLD = cur_clump[col] = cur_clump[col - 1];
	    }

	    if (diag) {
		/* check above right, center, left, in that order */
		n = 2;
		temp_clump = prev_clump + col + 1;
		temp_cell = prev_in + col + 1;
		do {
		    if (X == *temp_cell) {
			cur_clump[col] = *temp_clump;
			if (OLD == 0) {
			    OLD = *temp_clump;
			    }
			else {
			    NEW = *temp_clump;
			    break;
			}
		    }
		    temp_cell--;
		    temp_clump--;
		} while (n-- > 0);
	    }
	    else {
		/* check above */
		if (X == prev_in[col]) {
		    temp_clump = prev_clump + col;
		    cur_clump[col] = *temp_clump;
		    if (OLD == 0) {
			OLD = *temp_clump;
			}
		    else {
			NEW = *temp_clump;
		    }
		}
	    }

	    if (NEW == 0 || OLD == NEW) {	/* ok */
		if (OLD == 0) {
		    /* start a new clump */
		    label++;
		    cur_clump[col] = label;
		    if (label >= nalloc) {
			nalloc += INCR;
			index =
			    (CELL *) G_realloc(index,
					       nalloc * sizeof(CELL));
		    }
		    index[label] = label;
		}
		continue;
	    }

	    /* conflict! preserve NEW clump ID and change OLD clump ID.
	     * Must go back to the left in the current row and to the right
	     * in the previous row to change all the clump values as well.
	     */

	    /* left of the current row from 1 to col - 1 */
	    temp_clump = cur_clump;
	    n = col - 1;
	    while (n-- > 0) {
		temp_clump++;	/* skip left edge */
		if (*temp_clump == OLD)
		    *temp_clump = NEW;
	    }

	    /* right of previous row from col + 1 to ncols */
	    temp_clump = prev_clump;
	    temp_clump += col;
	    n = ncols - col;
	    while (n-- > 0) {
		temp_clump++;	/* skip col */
		if (*temp_clump == OLD)
		    *temp_clump = NEW;
	    }

	    /* modify the OLD index */
	    index[OLD] = NEW;
	}

	/* write initial clump IDs */
	/* this works also with writing out cur_clump, but only 
	 * prev_clump is complete and will not change any more */
	if (row > 0) {
	    if (write(cfd, prev_clump + 1, csize) != csize)
		G_fatal_error(_("Unable to write to temp file"));
	}

	/* switch the buffers so that the current buffer becomes the previous */
	temp_cell = cur_in;
	cur_in = prev_in;
	prev_in = temp_cell;

	temp_clump = cur_clump;
	cur_clump = prev_clump;
	prev_clump = temp_clump;
    }
    /* write last row with initial clump IDs */
    if (write(cfd, prev_clump + 1, csize) != csize)
	G_fatal_error(_("Unable to write to temp file"));
    G_percent(1, 1, 1);

    /* generate a renumbering scheme */
    G_message(_("Generating renumbering scheme..."));
    G_debug(1, "%d initial labels", label);
    /* allocate final clump ID */
    renumber = (CELL *) G_malloc((label + 1) * sizeof(CELL));
    renumber[0] = 0;
    cat = 1;
    G_percent(0, label, 1);
    for (n = 1; n <= label; n++) {
	G_percent(n, label, 1);
	OLD = n;
	NEW = index[n];
	if (OLD != NEW) {
	    renumber[n] = 0;
	    /* find valid clump ID */
	    while (OLD != NEW) {
		OLD = NEW;
		NEW = index[OLD];
	    }
	    index[n] = NEW;
	}
	else
	    /* set final clump id */
	    renumber[n] = cat++;
    }
    
    /* rewind temp file */
    lseek(cfd, 0, SEEK_SET);

    if (print) {
	fprintf(stdout, "clumps=%d\n", cat - 1);
    }
    else {
	/****************************************************
	 *                      PASS 2                      *
	 * apply renumbering scheme to initial clump labels *
	 ****************************************************/

	/* the input raster is no longer needed, 
	 * using instead the temp file with initial clump labels */

	G_message(_("Pass 2 of 2..."));
	for (row = 0; row < nrows; row++) {

	    G_percent(row, nrows, 4);
	
	    if (read(cfd, cur_clump, csize) != csize)
		G_fatal_error(_("Unable to read from temp file"));

	    temp_clump = cur_clump;
	    temp_cell = out_cell;

	    for (col = 0; col < ncols; col++) {
		*temp_cell = renumber[index[*temp_clump]];
		if (*temp_cell == 0)
		    Rast_set_c_null_value(temp_cell, 1);
		temp_clump++;
		temp_cell++;
	    }
	    Rast_put_row(out_fd, out_cell, CELL_TYPE);
	}
	G_percent(1, 1, 1);
    }

    close(cfd);
    unlink(cname);

    print_time(&cur_time);

    return 0;
}
示例#12
0
int query(struct Map_info *Map)
{
    int i, j, idx, cat_no, nlines, type;
    register int line_num;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct field_info *Fi;
    dbString stmt, value_string;
    dbDriver *driver;

    /* Initialize the Point struct */
    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    G_message(_("Reading features..."));

    /* Cycle through all lines and make a list of categories of 'qfield' for each category given by 'field' */
    nlines = Vect_get_num_lines(Map);
    for (line_num = 1; line_num <= nlines; line_num++) {
	type = Vect_read_line(Map, Points, Cats, line_num);
	if (!(type & options.type))
	    continue;

	for (i = 0; i < Cats->n_cats; i++) {
	    if (Cats->field[i] == options.field) {

		cat_no = Cats->cat[i];

		idx = find_cat(cat_no, 1);

		for (j = 0; j < Cats->n_cats; j++) {
		    if (Cats->field[j] == options.qfield) {	/* Add to list */
			if (Values[idx].nqcats == Values[idx].aqcats) {	/* Alloc space */
			    Values[idx].aqcats += 2;
			    Values[idx].qcat =
				(int *)G_realloc(Values[idx].qcat,
						 Values[idx].aqcats *
						 sizeof(int));
			}
			Values[idx].qcat[Values[idx].nqcats] = Cats->cat[j];
			Values[idx].nqcats++;
		    }
		}
	    }
	}

	/* If there is no field cat add cat -1, values for cat -1 are reported at the end  */
	Vect_cat_get(Cats, options.field, &cat_no);

	if (cat_no == -1) {
	    idx = find_cat(cat_no, 1);

	    for (j = 0; j < Cats->n_cats; j++) {
		if (Cats->field[j] == options.qfield) {	/* Add to list */
		    if (Values[idx].nqcats == Values[idx].aqcats) {	/* Alloc space */
			Values[idx].aqcats += 2;
			Values[idx].qcat =
			    (int *)G_realloc(Values[idx].qcat,
					     Values[idx].aqcats *
					     sizeof(int));
		    }
		    Values[idx].qcat[Values[idx].nqcats] = Cats->cat[j];
		    Values[idx].nqcats++;
		}
	    }
	}

	G_percent(line_num, nlines, 2);
    }

    db_init_string(&stmt);
    db_init_string(&value_string);

    if ((Fi = Vect_get_field(Map, options.qfield)) == NULL)
	G_fatal_error(_("Database connection not defined for layer %d. Use v.db.connect first."),
		      options.qfield);

    /* Open driver */
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);

    /* Query the database for each category */
    G_message(_("Querying database... "));
    for (i = 0; i < vstat.rcat; i++) {
	int j, ctype, nrows, more;
	char buf[2000];
	dbCursor cursor;
	dbTable *table;
	dbColumn *column;
	dbValue *value;

	G_debug(3, "cat %d", Values[i].cat);
	G_percent(i + 1, vstat.rcat, 1);

	/* Skip if cat is zero and large number of query categories (many features without category).
	 * It would cause problems on server side and take long time. Postgres limit is 10000 */
	/* TODO: verify because no category is encoded as cat = -1, not cat = zero */
	if (Values[i].cat == 0 && Values[i].nqcats > 1000) {
	    G_warning(_("Query for category '0' (no category) was not executed because of too many "
		       "(%d) query categories. All later reported values for cat 0 are not valid."),
		      Values[i].nqcats);
	    continue;
	}

	if (Values[i].nqcats > 0) {
	    sprintf(buf, "SELECT %s FROM %s WHERE", options.qcol, Fi->table);
	    db_set_string(&stmt, buf);

	    for (j = 0; j < Values[i].nqcats; j++) {
		G_debug(4, "  qcat %d", Values[i].qcat[j]);

		if (j > 0)
		    db_append_string(&stmt, " OR");

		sprintf(buf, " %s = %d", Fi->key, Values[i].qcat[j]);
		db_append_string(&stmt, buf);
	    }
	    G_debug(4, "  SQL: '%s'", db_get_string(&stmt));

	    if (db_open_select_cursor(driver, &stmt, &cursor, DB_SEQUENTIAL)
		!= DB_OK)
		G_fatal_error("Cannot open cursor: '%s'",
			      db_get_string(&stmt));

	    table = db_get_cursor_table(&cursor);
	    column = db_get_table_column(table, 0);	/* first column */
	    value = db_get_column_value(column);
	    ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	    vstat.qtype = ctype;
	    nrows = db_get_num_rows(&cursor);

	    G_debug(4, "  nrows = %d, columnt type = %d", nrows, ctype);

	    if (nrows != 1) {
		if (nrows > 1) {
		    G_warning(_("Multiple query results, output value set to NULL (category [%d])"),
			      Values[i].cat);
		}
		Values[i].null = 1;
	    }
	    else {
		if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
		    G_fatal_error(_("Unable to fetch record"));

		db_convert_column_value_to_string(column, &stmt);
		G_debug(4, "  value = %s", db_get_string(&stmt));

		if (db_test_value_isnull(value)) {
		    Values[i].null = 1;
		}
		else {
		    switch (ctype) {
		    case (DB_C_TYPE_INT):
			Values[i].i1 = db_get_value_int(value);
			break;
		    case (DB_C_TYPE_DOUBLE):
			Values[i].d1 = db_get_value_double(value);
			break;
		    case (DB_C_TYPE_STRING):
			Values[i].str1 = G_store(db_get_value_string(value));
			break;
		    case (DB_C_TYPE_DATETIME):
			db_convert_column_value_to_string(column,
							  &value_string);
			Values[i].str1 =
			    G_store(db_get_string(&value_string));
		    }
		    Values[i].null = 0;
		}
	    }
	    db_close_cursor(&cursor);
	}
	else {			/* no qcats -> upload NULL */
	    Values[i].null = 1;
	}
    }

    db_close_database_shutdown_driver(driver);

    return 0;
}
示例#13
0
/*!
   \brief Load vector map to memory

   The other alternative may be to load to a tmp file

   \param grassname vector map name
   \param[out] number of loaded features

   \return pointer to geoline struct
   \return NULL on failure
 */
geoline *Gv_load_vect(const char *grassname, int *nlines)
{
    struct Map_info map;
    struct line_pnts *points;
    struct line_cats *Cats = NULL;
    geoline *top, *gln, *prev;
    int np, i, n, nareas, nl = 0, area, type, is3d;
    struct Cell_head wind;
    float vect[2][3];
    const char *mapset;

    mapset = G_find_vector2(grassname, "");
    if (!mapset) {
	G_warning(_("Vector map <%s> not found"), grassname);
	return NULL;
    }

    Vect_set_open_level(2);
    if (Vect_open_old(&map, grassname, "") == -1) {
	G_warning(_("Unable to open vector map <%s>"),
		  G_fully_qualified_name(grassname, mapset));
	return NULL;
    }

    top = gln = (geoline *) G_malloc(sizeof(geoline));	/* G_fatal_error */
    if (!top) {
	return NULL;
    }

    prev = top;

#ifdef TRAK_MEM
    Tot_mem += sizeof(geoline);
#endif

    points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    G_get_set_window(&wind);
    Vect_set_constraint_region(&map, wind.north, wind.south, wind.east,
			       wind.west, PORT_DOUBLE_MAX, -PORT_DOUBLE_MAX);

    is3d = Vect_is_3d(&map);

    /* Read areas */
    n = Vect_get_num_areas(&map);
    nareas = 0;
    G_debug(3, "Reading vector areas (nareas = %d)", n);
    for (area = 1; area <= n; area++) {
	G_debug(3, " area %d", area);
	Vect_get_area_points(&map, area, points);
	if (points->n_points < 3)
	    continue;

	/* initialize style */
	gln->highlighted = 0;

	gln->type = OGSF_POLYGON;
	gln->npts = np = points->n_points;
	G_debug(3, "  np = %d", np);

	if (is3d) {
	    gln->dims = 3;
	    gln->p3 = (Point3 *) G_calloc(np, sizeof(Point3));	/* G_fatal_error */
	    if (!gln->p3) {
		return (NULL);
	    }
#ifdef TRAK_MEM
	    Tot_mem += (np * sizeof(Point3));
#endif
	}
	else {
	    gln->dims = 2;
	    gln->p2 = (Point2 *) G_calloc(np, sizeof(Point2));	/* G_fatal_error */
	    if (!gln->p2) {
		return (NULL);
	    }
#ifdef TRAK_MEM
	    Tot_mem += (np * sizeof(Point2));
#endif
	}

	for (i = 0; i < np; i++) {
	    if (is3d) {
		gln->p3[i][X] = points->x[i];
		gln->p3[i][Y] = points->y[i];
		gln->p3[i][Z] = points->z[i];
	    }
	    else {
		gln->p2[i][X] = points->x[i];
		gln->p2[i][Y] = points->y[i];
	    }
	}
	/* Calc normal (should be average) */
	if (is3d) {
	    vect[0][X] = (float)(gln->p3[0][X] - gln->p3[1][X]);
	    vect[0][Y] = (float)(gln->p3[0][Y] - gln->p3[1][Y]);
	    vect[0][Z] = (float)(gln->p3[0][Z] - gln->p3[1][Z]);
	    vect[1][X] = (float)(gln->p3[2][X] - gln->p3[1][X]);
	    vect[1][Y] = (float)(gln->p3[2][Y] - gln->p3[1][Y]);
	    vect[1][Z] = (float)(gln->p3[2][Z] - gln->p3[1][Z]);
	    GS_v3cross(vect[1], vect[0], gln->norm);

	}

	gln->cats = NULL;
	gln->next = (geoline *) G_malloc(sizeof(geoline));	/* G_fatal_error */
	if (!gln->next) {
	    return (NULL);
	}

#ifdef TRAK_MEM
	Tot_mem += sizeof(geoline);
#endif

	prev = gln;
	gln = gln->next;
	nareas++;
    }
    G_debug(3, "%d areas loaded", nareas);

    /* Read all lines */
    G_debug(3, "Reading vector lines ...");
    while (-1 < (type = Vect_read_next_line(&map, points, Cats))) {
	G_debug(3, "line type = %d", type);
	if (type & (GV_LINES | GV_FACE)) {
	    if (type & (GV_LINES)) {
		gln->type = OGSF_LINE;
	    }
	    else {
		gln->type = OGSF_POLYGON;
		/* Vect_append_point ( points, points->x[0], points->y[0], points->z[0] ); */
	    }

	    /* initialize style */
	    gln->highlighted = 0;

	    gln->npts = np = points->n_points;
	    G_debug(3, "  np = %d", np);

	    if (is3d) {
		gln->dims = 3;
		gln->p3 = (Point3 *) G_calloc(np, sizeof(Point3));	/* G_fatal_error */
		if (!gln->p3) {
		    return (NULL);
		}
#ifdef TRAK_MEM
		Tot_mem += (np * sizeof(Point3));
#endif
	    }
	    else {
		gln->dims = 2;
		gln->p2 = (Point2 *) G_calloc(np, sizeof(Point2));	/* G_fatal_error */
		if (!gln->p2) {
		    return (NULL);
		}
#ifdef TRAK_MEM
		Tot_mem += (np * sizeof(Point2));
#endif
	    }

	    for (i = 0; i < np; i++) {
		if (is3d) {
		    gln->p3[i][X] = points->x[i];
		    gln->p3[i][Y] = points->y[i];
		    gln->p3[i][Z] = points->z[i];
		}
		else {
		    gln->p2[i][X] = points->x[i];
		    gln->p2[i][Y] = points->y[i];
		}
	    }
	    /* Calc normal (should be average) */
	    if (is3d && gln->type == OGSF_POLYGON) {
		vect[0][X] = (float)(gln->p3[0][X] - gln->p3[1][X]);
		vect[0][Y] = (float)(gln->p3[0][Y] - gln->p3[1][Y]);
		vect[0][Z] = (float)(gln->p3[0][Z] - gln->p3[1][Z]);
		vect[1][X] = (float)(gln->p3[2][X] - gln->p3[1][X]);
		vect[1][Y] = (float)(gln->p3[2][Y] - gln->p3[1][Y]);
		vect[1][Z] = (float)(gln->p3[2][Z] - gln->p3[1][Z]);
		GS_v3cross(vect[1], vect[0], gln->norm);
		G_debug(3, "norm %f %f %f", gln->norm[0], gln->norm[1],
			gln->norm[2]);
	    }

	    /* Store category info for thematic display */
	    if (Cats->n_cats > 0) {
		gln->cats = Cats;
		Cats = Vect_new_cats_struct();
	    }
	    else {
		gln->cats = NULL;
		Vect_reset_cats(Cats);
	    }

	    gln->next = (geoline *) G_malloc(sizeof(geoline));	/* G_fatal_error */
	    if (!gln->next) {
		return (NULL);
	    }
#ifdef TRAK_MEM
	    Tot_mem += sizeof(geoline);
#endif

	    prev = gln;
	    gln = gln->next;
	    nl++;
	}
    }
    G_debug(3, "%d lines loaded", nl);

    nl += nareas;

    prev->next = NULL;
    G_free(gln);

#ifdef TRAK_MEM
    Tot_mem -= sizeof(geoline);
#endif

    Vect_close(&map);

    if (!nl) {
	G_warning(_("No features from vector map <%s> fall within current region"),
		  G_fully_qualified_name(grassname, mapset));
	return (NULL);
    }
    else {
	G_message(_("Vector map <%s> loaded (%d features)"),
		  G_fully_qualified_name(grassname, mapset), nl);
    }

    *nlines = nl;

#ifdef TRAK_MEM
    G_debug(3, "Total vect memory = %d Kbytes", Tot_mem / 1000);
#endif

    return (top);
}
示例#14
0
void
asciiToG3d(FILE * fp, RASTER3D_Region * region, int convertNull, char *nullValue)
{
    int x, y, z;
    int col, row, depth;
    double value;
    char buff[256];
    int tileX, tileY, tileZ;

    Rast3d_get_tile_dimensions_map(map, &tileX, &tileY, &tileZ);
    Rast3d_min_unlocked(map, RASTER3D_USE_CACHE_X);

    Rast3d_autolock_on(map);
    Rast3d_unlock_all(map);
    G_message(_("Loading data ...  (%dx%dx%d)"), region->cols, region->rows,
              region->depths);

    G_debug(3,
            "asciiToG3d: writing the 3D raster map, with rows %i cols %i depths %i",
            region->rows, region->cols, region->depths);

    for (z = 0; z < region->depths; z++) {
        G_percent(z, region->depths, 1);

        if ((z % tileZ) == 0)
            Rast3d_unlock_all(map);

        for (y = 0; y < region->rows; y++) /* go south to north */
            for (x = 0; x < region->cols; x++) {

                /* From west to east */
                col = x;
                /* The default is to read rows from north to south */
                row = y;
                /* From bottom to the top */
                depth = z;

                /* Read rows as from south to north */
                if (rowOrder == ROW_ORDER_SOUTH_TO_NORTH)
                    row = region->rows - y - 1;

                /* Read XY layer from top to bottom */
                if (depthOrder == DEPTH_ORDER_TOP_TO_BOTTOM)
                    depth = region->depths - z - 1;

                if (fscanf(fp, "%s", buff) != 1) {
                    if (feof(fp))
                        G_warning(_("End of file reached while still loading data."));
                    G_debug(3,
                            "missing data at col=%d row=%d depth=%d last_value=[%.4f]",
                            x + 1, y + 1, z + 1, value);
                    fatalError("asciiToG3d: read failed");
                }

                /* Check for null value */
                if (convertNull && strncmp(buff, nullValue, strlen(nullValue)) == 0) {
                    Rast3d_set_null_value(&value, 1, DCELL_TYPE);
                } else {
                    if (sscanf(buff, "%lf", &value) != 1) {
                        G_warning(_("Invalid value detected"));
                        G_debug(1, "invalid value at col=%d row=%d depth=%d last_value=[%s]",
                                x + 1, y + 1, z + 1, buff);
                        fatalError("asciiToG3d: read failed");
                    }
                }
                /* Write the data */
                Rast3d_put_double(map, col, row, depth, value);
            }
    }

    if (fscanf(fp, "%lf", &value) == 1) {
        G_warning(_("Data exists in input file after fully importing "
                    "expected data.  [%.4f ...]"), value);
    }

    if (!Rast3d_flush_all_tiles(map))
        fatalError("asciiTog3d: error flushing tiles");

    Rast3d_autolock_off(map);
    Rast3d_unlock_all(map);

    G_percent(1, 1, 1);
}
示例#15
0
/*!
   \brief Calculate normals

   OPTIMIZED for constant dy & dx

   The norm array is always the same size, but diff resolutions
   force resampled data points to have their normals recalculated,
   then only those norms are passed to n3f during drawing.
   Norms are converted to a packed unsigned int for storage,
   must be converted back at time of use.

   \todo fix to correctly calculate norms when mapped to sphere!

   Uses the previous and next cells (when available) for normal 
   calculations to produce smoother normals

   \param gs surface (geosurf)

   \return 1 on success
   \return 0 on failure
 */
int gs_calc_normals(geosurf * gs)
{
    int row, col;
    int xcnt, ycnt;
    int xmod, ymod;

    if (!gs->norm_needupdate || !gs->norms) {
	return (0);
    }

    gs->norm_needupdate = 0;
    gs_update_curmask(gs);

    xmod = gs->x_mod;
    ymod = gs->y_mod;

    xcnt = VCOLS(gs);
    ycnt = VROWS(gs);

    init_vars(gs);

    G_debug(5, "gs_calc_normals(): id=%d", gs->gsurf_id);

    /* first row - just use single cell */
    /* first col - use bottom & right neighbors */
    calc_norm(gs, 0, 0, NBR);

    for (col = 1; col < xcnt; col++) {
	/* turn off top neighbor for first row */
	calc_norm(gs, 0, col * xmod, ~NTOP);
    }

    /* use bottom & left neighbors for last col */
    calc_norm(gs, 0, col * xmod, NBL);

    /* now use four neighboring points for rows 1 - (n-1) */
    for (row = 1; row < ycnt; row++) {
	if (!(row % 100))
	    G_debug(5, "gs_calc_normals(): row=%d", row);

	/* turn off left neighbor for first col */
	calc_norm(gs, row * ymod, 0, ~NLFT);

	/* use all 4 neighbors until last col */
	for (col = 1; col < xcnt; col++) {
	    calc_norm(gs, row * ymod, col * xmod, NALL);
	}

	/* turn off right neighbor for last col */
	calc_norm(gs, row * ymod, col * xmod, ~NRGT);
    }

    /* last row */
    /* use top & right neighbors for first col */
    calc_norm(gs, row * ymod, 0, NTR);

    for (col = 1; col < xcnt; col++) {
	/* turn off bottom neighbor for last row */
	calc_norm(gs, row * ymod, col * xmod, ~NBOT);
    }

    /* use top & left neighbors for last column */
    calc_norm(gs, row * ymod, col * xmod, NTL);

    return (1);
}
示例#16
0
/* parallel_line - remove duplicate points from input line and
 *  creates new parallel line in 'd' offset distance;
 *  'tol' is tolerance between arc and polyline;
 *  this function doesn't care about created loops;
 *
 *  New line is written to existing nPoints structure.
 */
static void parallel_line(struct line_pnts *Points, double d, double tol,
			  struct line_pnts *nPoints)
{
    int i, j, np, na, side;
    double *x, *y, nx, ny, tx, ty, vx, vy, ux, uy, wx, wy;
    double atol, atol2, a, av, aw;

    G_debug(4, "parallel_line()");

    Vect_reset_line(nPoints);

    Vect_line_prune(Points);
    np = Points->n_points;
    x = Points->x;
    y = Points->y;

    if (np == 0)
	return;

    if (np == 1) {
	Vect_append_point(nPoints, x[0], y[0], 0);	/* ? OK, should make circle for points ? */
	return;
    }

    if (d == 0) {
	Vect_copy_xyz_to_pnts(nPoints, x, y, NULL, np);
	return;
    }

    side = (int)(d / fabs(d));
    atol = 2 * acos(1 - tol / fabs(d));

    for (i = 0; i < np - 1; i++) {
	vect(x[i], y[i], x[i + 1], y[i + 1], &tx, &ty);
	vx = ty * d;
	vy = -tx * d;

	nx = x[i] + vx;
	ny = y[i] + vy;
	Vect_append_point(nPoints, nx, ny, 0);

	nx = x[i + 1] + vx;
	ny = y[i + 1] + vy;
	Vect_append_point(nPoints, nx, ny, 0);

	if (i < np - 2) {	/* use polyline instead of arc between line segments */
	    vect(x[i + 1], y[i + 1], x[i + 2], y[i + 2], &ux, &uy);
	    wx = uy * d;
	    wy = -ux * d;
	    av = atan2(vy, vx);
	    aw = atan2(wy, wx);
	    a = (aw - av) * side;
	    if (a < 0)
		a += 2 * PI;

	    /* TODO: a <= PI can probably fail because of representation error */
	    if (a <= PI && a > atol) {
		na = (int)(a / atol);
		atol2 = a / (na + 1) * side;
		for (j = 0; j < na; j++) {
		    av += atol2;
		    nx = x[i + 1] + fabs(d) * cos(av);
		    ny = y[i + 1] + fabs(d) * sin(av);
		    Vect_append_point(nPoints, nx, ny, 0);
		}
	    }
	}
    }
    Vect_line_prune(nPoints);
}
示例#17
0
/* Same as path() but get start/stop from the command line (for non-interactive use)
   Hamish Bowman March 2007 */
int coor_path(struct Map_info *Map, const struct color_rgb *hcolor,
	      int be_bold, double start_x, double start_y,
	      double end_x, double end_y)
{
    int ret;
    double nx, ny, fx, fy, tx, ty, msize, maxdist;
    struct line_pnts *Points;
    int start_node, end_node;
    double fdist, tdist, cost;

    Points = Vect_new_line_struct();

    msize = 10 * (D_d_to_u_col(2.0) - D_d_to_u_col(1.0));	/* do it better */
    G_debug(1, "msize = %f\n", msize);

    /*
       x1 = D_d_to_u_col ((double)(screen_x-WDTH));
       y1 = D_d_to_u_row ((double)(screen_y-WDTH));
       x2 = D_d_to_u_col ((double)(screen_x+WDTH));
       y2 = D_d_to_u_row ((double)(screen_y+WDTH));

       x1 = fabs ( x2 - x1 );
       y1 = fabs ( y2 - y1 );

       if ( x1 > y1 ) maxdist = x1;
       else maxdist = y1;
     */

/**  maxdist = 10 pixels on the display (WDTH*2); ?
 **   ie related to zoom level ??  just use msize ?? **/
    maxdist = msize;

    G_debug(1, "Maximum distance in map units = %f\n", maxdist);


    /* Vect_find_node(): find number of nearest node, 0 if not found */
    start_node = Vect_find_node(Map, start_x, start_y, 0.0, maxdist, 0);
    if (start_node > 0) {
	Vect_get_node_coor(Map, start_node, &nx, &ny, NULL);
	fprintf(stderr, _("Node %d: %f %f\n"), start_node, nx, ny);
    }
    if (start_node > 0) {
	fx = nx;
	fy = ny;
    }
    else {
	fx = start_x;
	fy = start_y;
    }
    D_RGB_color(hcolor->r, hcolor->g, hcolor->b);
    D_plot_icon(fx, fy, G_ICON_BOX, 0.0, msize);


    end_node = Vect_find_node(Map, end_x, end_y, 0.0, maxdist, 0);
    if (end_node > 0) {
	Vect_get_node_coor(Map, end_node, &nx, &ny, NULL);
	fprintf(stderr, _("Node %d: %f %f\n"), end_node, nx, ny);
    }
    if (end_node > 0) {
	tx = nx;
	ty = ny;
    }
    else {
	tx = end_x;
	ty = end_y;
    }
    D_RGB_color(hcolor->r, hcolor->g, hcolor->b);
    D_plot_icon(tx, ty, G_ICON_CROSS, 0.0, msize);


    G_debug(2, "find path %f %f -> %f %f", fx, fy, tx, ty);

    ret =
	Vect_net_shortest_path_coor(Map, fx, fy, 0.0, tx, ty, 0.0,
				    5 * maxdist, 5 * maxdist, &cost, Points,
				    NULL, NULL, NULL, &fdist, &tdist);
    if (ret == 0) {
	fprintf(stdout, _("Destination unreachable\n"));
    }
    else {
	fprintf(stdout, _("Costs on the network = %f\n"), cost);
	fprintf(stdout, _("  Distance to the network = %f, "
			  "distance from the network = %f\n\n"),
		fdist, tdist);

	display(Map, Points, hcolor, 1, 1, be_bold);
    }

    return 0;
}
示例#18
0
文件: main.c 项目: GRASS-GIS/grass-ci
int main(int argc, char *argv[])
{
    char *terrainmap, *seedmap, *lakemap;
    int rows, cols, in_terran_fd, out_fd, lake_fd, row, col, pases, pass;
    int lastcount, curcount, start_col = 0, start_row = 0;
    double east, north, area = 0, volume = 0;
    FCELL **in_terran, **out_water, water_level, max_depth = 0, min_depth = 0;
    FCELL water_window[3][3];
    struct Option *tmap_opt, *smap_opt, *wlvl_opt, *lake_opt, *sdxy_opt;
    struct Flag *negative_flag, *overwrite_flag;
    struct GModule *module;
    struct Colors colr;
    struct Cell_head window;
    struct History history;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("hydrology"));
    G_add_keyword(_("hazard"));
    G_add_keyword(_("flood"));
    module->description = _("Fills lake at given point to given level.");

    tmap_opt = G_define_standard_option(G_OPT_R_ELEV);

    wlvl_opt = G_define_option();
    wlvl_opt->key = "water_level";
    wlvl_opt->description = _("Water level");
    wlvl_opt->type = TYPE_DOUBLE;
    wlvl_opt->required = YES;

    lake_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    lake_opt->key = "lake";
    lake_opt->required = NO;
    lake_opt->guisection = _("Output");

    sdxy_opt = G_define_standard_option(G_OPT_M_COORDS);
    sdxy_opt->label = _("Seed point coordinates");
    sdxy_opt->description = _("Either this coordinates pair or a seed"
	" map have to be specified");
    sdxy_opt->required = NO;
    sdxy_opt->multiple = NO;
    sdxy_opt->guisection = _("Seed");

    smap_opt = G_define_standard_option(G_OPT_R_MAP);
    smap_opt->key = "seed";
    smap_opt->label =
	_("Input raster map with given starting point(s) (at least 1 cell > 0)");
    smap_opt->description =
	_("Either this parameter or a coordinates pair have to be specified");
    smap_opt->required = NO;
    smap_opt->guisection = _("Seed");

    negative_flag = G_define_flag();
    negative_flag->key = 'n';
    negative_flag->description =
	_("Use negative depth values for lake raster map");

    overwrite_flag = G_define_flag();
    overwrite_flag->key = 'o';
    overwrite_flag->description =
	_("Overwrite seed map with result (lake) map");
    overwrite_flag->guisection = _("Output");

    if (G_parser(argc, argv))	/* Returns 0 if successful, non-zero otherwise */
	exit(EXIT_FAILURE);

    if (smap_opt->answer && sdxy_opt->answer)
	G_fatal_error(_("Both seed map and coordinates cannot be specified"));

    if (!smap_opt->answer && !sdxy_opt->answer)
	G_fatal_error(_("Seed map or seed coordinates must be set!"));

    if (sdxy_opt->answer && !lake_opt->answer)
	G_fatal_error(_("Seed coordinates and output map lake= must be set!"));

    if (lake_opt->answer && overwrite_flag->answer)
	G_fatal_error(_("Both lake and overwrite cannot be specified"));

    if (!lake_opt->answer && !overwrite_flag->answer)
	G_fatal_error(_("Output lake map or overwrite flag must be set!"));

    terrainmap = tmap_opt->answer;
    seedmap = smap_opt->answer;
    sscanf(wlvl_opt->answer, "%f", &water_level);
    lakemap = lake_opt->answer;

    /* If lakemap is set, write to it, else is set overwrite flag and we should write to seedmap. */
    if (lakemap)
	lake_fd = Rast_open_new(lakemap, 1);

    rows = Rast_window_rows();
    cols = Rast_window_cols();

    /* If we use x,y as seed... */
    if (sdxy_opt->answer) {
	G_get_window(&window);
	east = window.east;
	north = window.north;

	G_scan_easting(sdxy_opt->answers[0], &east, G_projection());
	G_scan_northing(sdxy_opt->answers[1], &north, G_projection());
	start_col = (int)Rast_easting_to_col(east, &window);
	start_row = (int)Rast_northing_to_row(north, &window);

	if (start_row < 0 || start_row > rows ||
	    start_col < 0 || start_col > cols)
	    G_fatal_error(_("Seed point outside the current region"));
    }

    /* Open terrain map */
    in_terran_fd = Rast_open_old(terrainmap, "");

    /* Open seed map */
    if (smap_opt->answer)
	out_fd = Rast_open_old(seedmap, "");

    /* Pointers to rows. Row = ptr to 'col' size array. */
    in_terran = (FCELL **) G_malloc(rows * sizeof(FCELL *));
    out_water = (FCELL **) G_malloc(rows * sizeof(FCELL *));
    if (in_terran == NULL || out_water == NULL)
	G_fatal_error(_("G_malloc: out of memory"));


    G_debug(1, "Loading maps...");
    /* foo_rows[row] == array with data (2d array). */
    for (row = 0; row < rows; row++) {
	in_terran[row] = (FCELL *) G_malloc(cols * sizeof(FCELL));
	out_water[row] = (FCELL *) G_calloc(cols, sizeof(FCELL));

	/* In newly created space load data from file. */
	Rast_get_f_row(in_terran_fd, in_terran[row], row);

	if (smap_opt->answer)
	    Rast_get_f_row(out_fd, out_water[row], row);

	G_percent(row + 1, rows, 5);
    }

    /* Set seed point */
    if (sdxy_opt->answer)
	/* Check is water level higher than seed point */
	if (in_terran[start_row][start_col] >= water_level)
	    G_fatal_error(_("Given water level at seed point is below earth surface. "
			   "Increase water level or move seed point."));
    out_water[start_row][start_col] = 1;

    /* Close seed map for reading. */
    if (smap_opt->answer)
	Rast_close(out_fd);

    /* Open output map for writing. */
    if (lakemap)
	out_fd = lake_fd;
    else
	out_fd = Rast_open_new(seedmap, 1);

    /* More pases are renudant. Real pases count is controlled by altered cell count. */
    pases = (int)(rows * cols) / 2;

    G_debug(1,
	    "Starting lake filling at level of %8.4f in %d passes. Percent done:",
	    water_level, pases);

    lastcount = 0;

    for (pass = 0; pass < pases; pass++) {
	G_debug(3, "Pass: %d", pass);
	curcount = 0;
	/* Move from left upper corner to right lower corner. */
	for (row = 0; row < rows; row++) {
	    for (col = 0; col < cols; col++) {
		/* Loading water data into window. */
		load_window_values(out_water, water_window, rows, cols, row,
				   col);

		/* Cheking presence of water. */
		if (is_near_water(water_window) == 1) {
		    if (in_terran[row][col] < water_level) {
			out_water[row][col] =
			    water_level - in_terran[row][col];
			curcount++;
		    }
		    else {
			out_water[row][col] = 0;	/* Cell is higher than water level -> NULL. */
		    }
		}
	    }
	}
	if (curcount == lastcount)
	    break;		/* We done. */
	lastcount = curcount;
	curcount = 0;
	/* Move backwards - from lower right corner to upper left corner. */
	for (row = rows - 1; row >= 0; row--) {
	    for (col = cols - 1; col >= 0; col--) {
		load_window_values(out_water, water_window, rows, cols, row,
				   col);

		if (is_near_water(water_window) == 1) {
		    if (in_terran[row][col] < water_level) {
			out_water[row][col] =
			    water_level - in_terran[row][col];
			curcount++;
		    }
		    else {
			out_water[row][col] = 0;
		    }
		}
	    }
	}
	G_percent(pass + 1, pases, 10);
	if (curcount == lastcount)
	    break;		/* We done. */
	lastcount = curcount;
    }				/*pases */

    G_percent(pases, pases, 10);	/* Show 100%. */

    save_map(out_water, out_fd, rows, cols, negative_flag->answer, &min_depth,
	     &max_depth, &area, &volume);

    G_message(_("Lake depth from %f to %f (specified water level is taken as zero)"), min_depth, max_depth);
    G_message(_("Lake area %f square meters"), area);
    G_message(_("Lake volume %f cubic meters"), volume);
    G_important_message(_("Volume is correct only if lake depth (terrain raster map) is in meters"));

    /* Close all files. Lake map gets written only now. */
    Rast_close(in_terran_fd);
    Rast_close(out_fd);

    /* Add blue color gradient from light bank to dark depth */
    Rast_init_colors(&colr);
    if (negative_flag->answer == 1) {
	Rast_add_f_color_rule(&max_depth, 0, 240, 255,
				  &min_depth, 0, 50, 170, &colr);
    }
    else {
	Rast_add_f_color_rule(&min_depth, 0, 240, 255,
				  &max_depth, 0, 50, 170, &colr);
    }

    Rast_write_colors(lakemap, G_mapset(), &colr);

    Rast_short_history(lakemap, "raster", &history);
    Rast_command_history(&history);
    Rast_write_history(lakemap, &history);

    return EXIT_SUCCESS;
}
示例#19
0
文件: plus_struct.c 项目: caomw/grass
int dig_Rd_P_line(struct Plus_head *Plus, int n, struct gvfile * fp)
{
    int n_edges;
    char tp;
    struct P_line *ptr;

    G_debug(4, "dig_Rd_P_line()");

    if (0 >= dig__fread_port_C(&tp, 1, fp))
	return (-1);

    if (tp == 0) {		/* dead */
	G_debug(4, "    line is dead");
	Plus->Line[n] = NULL;
	return 0;
    }

    ptr = dig_alloc_line();

    /* type */
    ptr->type = dig_type_from_store(tp);
    G_debug(5, "    line type  %d -> %d", tp, ptr->type);

    /* offset */
    if (0 >= dig__fread_port_O(&(ptr->offset), 1, fp, Plus->off_t_size))
	return (-1);

    if (ptr->type == GV_POINT) {
	ptr->topo = NULL;
    }
    else {
	ptr->topo = dig_alloc_topo(ptr->type);
    }

    /* centroids */
    if (ptr->type & GV_CENTROID) {
	struct P_topo_c *topo = (struct P_topo_c *)ptr->topo;

	if (0 >= dig__fread_port_P(&(topo->area), 1, fp))
	    return -1;
    }
    /* lines */
    else if (ptr->type & GV_LINE) {
	struct P_topo_l *topo = (struct P_topo_l *)ptr->topo;

	if (0 >= dig__fread_port_P(&(topo->N1), 1, fp))
	    return -1;
	if (0 >= dig__fread_port_P(&(topo->N2), 1, fp))
	    return -1;
    }
    /* boundaries */
    else if (ptr->type & GV_BOUNDARY) {
	struct P_topo_b *topo = (struct P_topo_b *)ptr->topo;

	if (0 >= dig__fread_port_P(&(topo->N1), 1, fp))
	    return -1;
	if (0 >= dig__fread_port_P(&(topo->N2), 1, fp))
	    return -1;
	if (0 >= dig__fread_port_P(&(topo->left), 1, fp))
	    return -1;
	if (0 >= dig__fread_port_P(&(topo->right), 1, fp))
	    return -1;
    }
    /* faces */
    else if ((ptr->type & GV_FACE) && Plus->with_z) {	/* reserved for face edges */
	struct P_topo_f *topo = (struct P_topo_f *)ptr->topo;

	if (0 >= dig__fread_port_I(&n_edges, 1, fp))
	    return -1;

	/* here will be list of edges */

	/* left / right volume */
	if (0 >= dig__fread_port_P(&(topo->left), 1, fp))
	    return -1;
	if (0 >= dig__fread_port_P(&(topo->left), 1, fp))
	    return -1;
    }
    /* kernels */
    else if ((ptr->type & GV_KERNEL) && Plus->with_z) {	/* reserved for kernel (volume number) */
	struct P_topo_k *topo = (struct P_topo_k *)ptr->topo;

	if (0 >= dig__fread_port_P(&(topo->volume), 1, fp))
	    return -1;
    }

    Plus->Line[n] = ptr;

    return (0);
}
示例#20
0
/* ************************************************************************* */
void write_vtk_points(input_maps * in, FILE * fp, RASTER3D_Region region, int dp,
                      int type, double scale)
{
    int x, y, z, percentage = 0;
    int rows, cols, depths;
    void *rast_top = NULL;
    void *rast_bottom = NULL;
    void *ptr_top = NULL;
    void *ptr_bottom = NULL;
    double topval = 0, bottomval = 0;
    double zcoor, ycoor, xcoor;
    double zcoor1, ycoor1, xcoor1;

    rows = region.rows;
    cols = region.cols;
    depths = region.depths;

    rast_top = Rast_allocate_buf(in->topMapType);
    rast_bottom = Rast_allocate_buf(in->bottomMapType);

    G_debug(3, _("write_vtk_points: Writing point coordinates"));

    for (z = 0; z < depths; z++) {

        for (y = 0; y < rows; y++) {
            G_percent(percentage, (rows * depths - 1), 10);
            percentage++;

            Rast_get_row(in->top, rast_top, y, in->topMapType);

            Rast_get_row(in->bottom, rast_bottom, y, in->bottomMapType);

            for (x = 0, ptr_top = rast_top, ptr_bottom = rast_bottom;
                    x < cols;
                    x++, ptr_top =
                        G_incr_void_ptr(ptr_top, Rast_cell_size(in->topMapType)),
                    ptr_bottom =
                        G_incr_void_ptr(ptr_bottom,
                                        Rast_cell_size(in->bottomMapType))) {

                /*Get the values */
                topval =
                    get_raster_value_as_double(in->topMapType, ptr_top, 0.0);
                bottomval =
                    get_raster_value_as_double(in->bottomMapType, ptr_bottom,
                                               0.0);

                if (type == 1) { /*Structured Grid */
                    /*Calculate the coordinates */
                    xcoor =
                        region.west + (region.ew_res / 2 +
                                       region.ew_res * (x));
                    /* Here the raster3d north->south coordinate system is used */
                    ycoor =
                        region.north - (region.ns_res / 2 +
                                        region.ns_res * (y));
                    zcoor =
                        (bottomval +
                         z * (topval - bottomval) / (depths - 1)) * scale;

                    xcoor -= x_extent;
                    ycoor -= y_extent;

                    fprintf(fp, "%.*f ", dp, xcoor);
                    fprintf(fp, "%.*f ", dp, ycoor);
                    fprintf(fp, "%.*f\n", dp, zcoor);
                } else { /*Unstructured Grid */
                    /*Write for every cell the coordinates for a hexahedron -> 8 points */
                    /*VTK Hexaeder */
                    /* bottom
                     * 3 --- 2
                     * |     |
                     * 0 --- 1

                     * top
                     * 7 --- 6
                     * |     |
                     * 4 --- 5

                     */
                    xcoor = region.west + (region.ew_res * (x)); /*0, 3, 4, 7 */
                    /* Here the raster3d north->south coordinate system is used */
                    ycoor = region.north - (region.ns_res * (y)); /*2, 3, 6, 7 */
                    zcoor = (bottomval + z * (topval - bottomval) / (depths)) * scale; /*0, 1, 2, 3 */

                    xcoor1 = region.west + (region.ew_res + region.ew_res * (x)); /*1, 2, 5, 6 */
                    /* Here the raster3d north->south coordinate system is used */
                    ycoor1 = region.north - (region.ns_res + region.ns_res * (y)); /*0, 1, 4, 5 */
                    zcoor1 = (bottomval + z * (topval - bottomval) / (depths) + (topval - bottomval) / (depths)) * scale; /*4, 5, ,6 ,7 */

                    xcoor -= x_extent;
                    ycoor -= y_extent;

                    xcoor1 -= x_extent;
                    ycoor1 -= y_extent;


                    /*0 */
                    fprintf(fp, "%.*f ", dp, xcoor);
                    fprintf(fp, "%.*f ", dp, ycoor1);
                    fprintf(fp, "%.*f\n", dp, zcoor);
                    /*1 */
                    fprintf(fp, "%.*f ", dp, xcoor1);
                    fprintf(fp, "%.*f ", dp, ycoor1);
                    fprintf(fp, "%.*f\n", dp, zcoor);
                    /*2 */
                    fprintf(fp, "%.*f ", dp, xcoor1);
                    fprintf(fp, "%.*f ", dp, ycoor);
                    fprintf(fp, "%.*f\n", dp, zcoor);
                    /*3 */
                    fprintf(fp, "%.*f ", dp, xcoor);
                    fprintf(fp, "%.*f ", dp, ycoor);
                    fprintf(fp, "%.*f\n", dp, zcoor);

                    /*4 */
                    fprintf(fp, "%.*f ", dp, xcoor);
                    fprintf(fp, "%.*f ", dp, ycoor1);
                    fprintf(fp, "%.*f\n", dp, zcoor1);
                    /*5 */
                    fprintf(fp, "%.*f ", dp, xcoor1);
                    fprintf(fp, "%.*f ", dp, ycoor1);
                    fprintf(fp, "%.*f\n", dp, zcoor1);
                    /*6 */
                    fprintf(fp, "%.*f ", dp, xcoor1);
                    fprintf(fp, "%.*f ", dp, ycoor);
                    fprintf(fp, "%.*f\n", dp, zcoor1);
                    /*7 */
                    fprintf(fp, "%.*f ", dp, xcoor);
                    fprintf(fp, "%.*f ", dp, ycoor);
                    fprintf(fp, "%.*f\n", dp, zcoor1);
                }
            }
        }
    }

    if (type == 1)
        fprintf(fp, "POINT_DATA %i\n", region.cols * region.rows * region.depths); /*We have pointdata */

    return;
}
示例#21
0
文件: plus_struct.c 项目: caomw/grass
/*!
  \brief Read Plus_head from file

  \param fp pointer to gvfile structure
  \param[in,out] ptr pointer to Plus_head structure

  \return -1 error
  \return  0 OK 
*/
int dig_Rd_Plus_head(struct gvfile * fp, struct Plus_head *ptr)
{
    unsigned char buf[5];
    int byte_order;

    dig_rewind(fp);

    /* bytes 1 - 5 */
    if (0 >= dig__fread_port_C((char *)buf, 5, fp))
	return (-1);
    ptr->version.topo.major = buf[0];
    ptr->version.topo.minor = buf[1];
    ptr->version.topo.back_major = buf[2];
    ptr->version.topo.back_minor = buf[3];
    byte_order = buf[4];

    G_debug(2,
	    "Topo header: file version %d.%d , supported from GRASS version %d.%d",
	    ptr->version.topo.major, ptr->version.topo.minor, ptr->version.topo.back_major,
	    ptr->version.topo.back_minor);

    G_debug(2, "  byte order %d", byte_order);

    /* check version numbers */
    if (ptr->version.topo.major > GV_TOPO_VER_MAJOR ||
	ptr->version.topo.minor > GV_TOPO_VER_MINOR) {
	/* The file was created by GRASS library with higher version than this one */

	if (ptr->version.topo.back_major > GV_TOPO_VER_MAJOR ||
	    ptr->version.topo.back_minor > GV_TOPO_VER_MINOR) {
	    /* This version of GRASS lib is lower than the oldest which can read this format */
	    G_debug(1, "Topology format version %d.%d",
		    ptr->version.topo.major, ptr->version.topo.minor);
	    G_fatal_error
		(_("This version of GRASS (%d.%d) is too old to read this topology format."
		 " Try to rebuild topology or upgrade GRASS to at least version %d."),
		 GRASS_VERSION_MAJOR, GRASS_VERSION_MINOR, GRASS_VERSION_MAJOR + 1);
	    return (-1);
	}

	G_warning(_("Your GRASS version does not fully support topology format %d.%d of the vector."
		    " Consider to rebuild topology or upgrade GRASS."),
		  ptr->version.topo.major, ptr->version.topo.minor);
    }
    if (ptr->version.topo.major < GV_TOPO_VER_MAJOR ||
	(ptr->version.topo.major == GV_TOPO_VER_MAJOR &&
	 ptr->version.topo.minor < GV_TOPO_VER_MINOR)) {
	/* The file was created by GRASS library with lower version than this one */

	/* This version of GRASS lib can not read this old format */
	G_warning(_("Old topology format version %d.%d is not supported by this release."
		    " Try to rebuild topology."),
		  ptr->version.topo.major, ptr->version.topo.minor);
	return (-1);
    }

    /* init Port_info structure and set as default */
    dig_init_portable(&(ptr->port), byte_order);
    dig_set_cur_port(&(ptr->port));

    /* bytes 6 - 9 : header size */
    if (0 >= dig__fread_port_L(&(ptr->head_size), 1, fp))
	return (-1);
    G_debug(2, "  header size %ld", ptr->head_size);

    /* determine required offset size from header size */
    /* this is not safe in case new fields get added in later versions */
    /* better: add a new field with off_t_size after byte_order? */
    if (ptr->head_size >= 142 + 32) /* keep in sync with dig_Wr_Plus_head() */
	ptr->off_t_size = 8;
    else
	ptr->off_t_size = 4;

    if (sizeof(off_t) < ptr->off_t_size) {
	G_warning(_("Vector exceeds supported file size limit"));
	return (-1);
    }

    G_debug(2, "topo off_t size = %d", ptr->off_t_size);

    /* byte 10 : dimension 2D or 3D */
    if (0 >= dig__fread_port_C((char *)buf, 1, fp))
	return (-1);
    ptr->with_z = buf[0];
    G_debug(2, "  with_z %d", ptr->with_z);

    /* bytes 11 - 58 : bound box */
    if (0 >= dig__fread_port_D(&(ptr->box.N), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_D(&(ptr->box.S), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_D(&(ptr->box.E), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_D(&(ptr->box.W), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_D(&(ptr->box.T), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_D(&(ptr->box.B), 1, fp))
	return (-1);

    /* bytes 59 - 86 : number of structures */
    if (0 >= dig__fread_port_P(&(ptr->n_nodes), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_edges), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_lines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_areas), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_isles), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_volumes), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_holes), 1, fp))
	return (-1);

    /* bytes 87 - 110 : number of line types */
    if (0 >= dig__fread_port_P(&(ptr->n_plines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_llines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_blines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_clines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_flines), 1, fp))
	return (-1);
    if (0 >= dig__fread_port_P(&(ptr->n_klines), 1, fp))
	return (-1);

    /* bytes 111 - 138 : Offset */
    if (0 >= dig__fread_port_O(&(ptr->Node_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Edge_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Line_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Area_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Isle_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Volume_offset), 1, fp, ptr->off_t_size))
	return (-1);
    if (0 >= dig__fread_port_O(&(ptr->Hole_offset), 1, fp, ptr->off_t_size))
	return (-1);

    /* bytes 139 - 142 : Coor size and time */
    if (0 >= dig__fread_port_O(&(ptr->coor_size), 1, fp, ptr->off_t_size))
	return (-1);

    G_debug(2, "  coor size %"PRI_OFF_T, ptr->coor_size);

    dig_fseek(fp, ptr->head_size, SEEK_SET);

    return (0);
}
示例#22
0
/* ************************************************************************* */
void write_vtk_unstructured_grid_cells(FILE * fp, RASTER3D_Region region)
{
    int x, y, z, percentage;
    int rows, cols, depths, count;

    rows = region.rows;
    cols = region.cols;
    depths = region.depths;

    G_debug(3, _("write_vtk_unstructured_grid_cells: Writing the cells"));

    fprintf(fp, "CELLS %i %i\n", region.cols * region.rows * region.depths,
            region.cols * region.rows * region.depths * 9);

    count = 0;
    percentage = 0;

    /*The point - cell links */
    for (z = 0; z < depths; z++) {
        for (y = 0; y < rows; y++) {
            G_percent(percentage, (rows * depths - 1), 10);
            percentage++;

            for (x = 0; x < cols; x++) {
                /*Voxel */
                fprintf(fp, "%i %i %i %i %i %i %i %i %i\n", 8,
                        count * 8, count * 8 + 1, count * 8 + 3,
                        count * 8 + 2, count * 8 + 4, count * 8 + 5,
                        count * 8 + 7, count * 8 + 6);

                /*Hexaeder
                 * fprintf(fp, "%i %i %i %i %i %i %i %i %i\n", 8,
                 * count * 8, count * 8 + 1, count * 8 + 2, count * 8 + 3,
                 * count * 8 + 4, count * 8 + 5, count * 8 + 6,
                 * count * 8 + 7);
                 */
                count++;
            }
        }
    }
    percentage = 0;

    fprintf(fp, "CELL_TYPES %i\n", region.cols * region.rows * region.depths);
    /*the cell types */
    for (z = 0; z < depths; z++) {
        for (y = 0; y < rows; y++) {
            G_percent(percentage, (rows * depths - 1), 10);
            percentage++;

            for (x = 0; x < cols; x++) {
                /*Voxel */
                fprintf(fp, "11\n");
                /*Hexaeder
                 * fprintf(fp, "12\n");
                 */
            }
        }
    }

    fprintf(fp, "CELL_DATA %i\n", region.cols * region.rows * region.depths); /*We have celldata  */

    return;
}
示例#23
0
/*
 * This function generates parallel line (with loops, but not like the old ones).
 * It is not to be used directly for creating buffers.
 * + added elliptical buffers/par.lines support
 *
 * dalpha - direction of elliptical buffer major axis in degrees
 * da - distance along major axis
 * db: distance along minor (perp.) axis
 * side: side >= 0 - right side, side < 0 - left side
 * when (da == db) we have plain distances (old case)
 * round - 1 for round corners, 0 for sharp corners. (tol is used only if round == 1)
 */
static void parallel_line(struct line_pnts *Points, double da, double db,
			  double dalpha, int side, int round, int caps, int looped,
			  double tol, struct line_pnts *nPoints)
{
    int i, j, res, np;
    double *x, *y;
    double tx, ty, vx, vy, wx, wy, nx, ny, mx, my, rx, ry;
    double vx1, vy1, wx1, wy1;
    double a0, b0, c0, a1, b1, c1;
    double phi1, phi2, delta_phi;
    double nsegments, angular_tol, angular_step;
    int inner_corner, turns360;

    G_debug(3, "parallel_line()");

    if (looped && 0) {
	/* start point != end point */
	return;
    }

    Vect_reset_line(nPoints);

    if (looped) {
	Vect_append_point(Points, Points->x[1], Points->y[1], Points->z[1]);
    }
    np = Points->n_points;
    x = Points->x;
    y = Points->y;

    if ((np == 0) || (np == 1))
	return;

    if ((da == 0) || (db == 0)) {
	Vect_copy_xyz_to_pnts(nPoints, x, y, NULL, np);
	return;
    }

    side = (side >= 0) ? (1) : (-1);	/* normalize variable */
    dalpha *= PI / 180;		/* convert dalpha from degrees to radians */
    angular_tol = angular_tolerance(tol, da, db);

    for (i = 0; i < np - 1; i++) {
	/* save the old values */
	a0 = a1;
	b0 = b1;
	c0 = c1;
	wx = vx;
	wy = vy;


	norm_vector(x[i], y[i], x[i + 1], y[i + 1], &tx, &ty);
	if ((tx == 0) && (ty == 0))
	    continue;

	elliptic_tangent(side * tx, side * ty, da, db, dalpha, &vx, &vy);

	nx = x[i] + vx;
	ny = y[i] + vy;

	mx = x[i + 1] + vx;
	my = y[i + 1] + vy;

	line_coefficients(nx, ny, mx, my, &a1, &b1, &c1);

	if (i == 0) {
	    if (!looped)
		Vect_append_point(nPoints, nx, ny, 0);
	    continue;
	}

	delta_phi = atan2(ty, tx) - atan2(y[i] - y[i - 1], x[i] - x[i - 1]);
	if (delta_phi > PI)
	    delta_phi -= 2 * PI;
	else if (delta_phi <= -PI)
	    delta_phi += 2 * PI;
	/* now delta_phi is in [-pi;pi] */
	turns360 = (fabs(fabs(delta_phi) - PI) < 1e-15);
	inner_corner = (side * delta_phi <= 0) && (!turns360);

	if ((turns360) && (!(caps && round))) {
	    if (caps) {
		norm_vector(0, 0, vx, vy, &tx, &ty);
		elliptic_tangent(side * tx, side * ty, da, db, dalpha, &tx,
				 &ty);
	    }
	    else {
		tx = 0;
		ty = 0;
	    }
	    Vect_append_point(nPoints, x[i] + wx + tx, y[i] + wy + ty, 0);
	    Vect_append_point(nPoints, nx + tx, ny + ty, 0);	/* nx == x[i] + vx, ny == y[i] + vy */
	}
	else if ((!round) || inner_corner) {
	    res = line_intersection(a0, b0, c0, a1, b1, c1, &rx, &ry);
	    /*                if (res == 0) {
	       G_debug(4, "a0=%.18f, b0=%.18f, c0=%.18f, a1=%.18f, b1=%.18f, c1=%.18f", a0, b0, c0, a1, b1, c1);
	       G_fatal_error("Two consequtive line segments are parallel, but not on one straight line! This should never happen.");
	       return;
	       }  */
	    if (res == 1) {
		if (!round)
		    Vect_append_point(nPoints, rx, ry, 0);
		else {
		    /*                    d = dig_distance2_point_to_line(rx, ry, 0, x[i-1], y[i-1], 0, x[i], y[i], 0,
		       0, NULL, NULL, NULL, NULL, NULL);
		       if ( */
		    Vect_append_point(nPoints, rx, ry, 0);
		}
	    }
	}
	else {
	    /* we should draw elliptical arc for outside corner */

	    /* inverse transforms */
	    elliptic_transform(wx, wy, 1 / da, 1 / db, dalpha, &wx1, &wy1);
	    elliptic_transform(vx, vy, 1 / da, 1 / db, dalpha, &vx1, &vy1);

	    phi1 = atan2(wy1, wx1);
	    phi2 = atan2(vy1, vx1);
	    delta_phi = side * (phi2 - phi1);

	    /* make delta_phi in [0, 2pi] */
	    if (delta_phi < 0)
		delta_phi += 2 * PI;

	    nsegments = (int)(delta_phi / angular_tol) + 1;
	    angular_step = side * (delta_phi / nsegments);

	    for (j = 0; j <= nsegments; j++) {
		elliptic_transform(cos(phi1), sin(phi1), da, db, dalpha, &tx,
				   &ty);
		Vect_append_point(nPoints, x[i] + tx, y[i] + ty, 0);
		phi1 += angular_step;
	    }
	}

	if ((!looped) && (i == np - 2)) {
	    Vect_append_point(nPoints, mx, my, 0);
	}
    }

    if (looped) {
	Vect_append_point(nPoints, nPoints->x[0], nPoints->y[0],
			  nPoints->z[0]);
    }

    Vect_line_prune(nPoints);

    if (looped) {
	Vect_line_delete_point(Points, Points->n_points - 1);
    }
}
示例#24
0
/* ************************************************************************* */
void write_vtk_data(FILE * fp, void *map, RASTER3D_Region region, char *varname,
                    int dp)
{
    double value;
    double nullvalue;
    int x, y, z, percentage;
    int rows, cols, depths, typeIntern;

    rows = region.rows;
    cols = region.cols;
    depths = region.depths;

    /*the nullvalue */
    if (!sscanf(param.null_val->answer, "%lf", &nullvalue)) {
        G_warning("Null value is not valid, using 0 instead.");
        nullvalue = 0;
    }

    G_debug(3,
            _("write_vtk_data: Writing Celldata %s with rows %i cols %i depths %i to vtk-ascii file"),
            varname, rows, cols, depths);

    fprintf(fp, "SCALARS %s float 1\n", varname);
    fprintf(fp, "LOOKUP_TABLE default\n");

    typeIntern = Rast3d_tile_type_map(map);

    percentage = 0;

    for (z = 0; z < depths; z++) {
        /* In case of structured grid data, the point/cell coordinates
           are computed based on the default north->south raster3d coordinate system.
           We need to compute south -> north ordering for image data.
         */
        if (!param.structgrid->answer) {
            for (y = rows - 1; y >= 0; y--) {
                G_percent(percentage, (rows * depths - 1), 10);
                percentage++;

                for (x = 0; x < cols; x++) {
                    value =
                        get_g3d_raster_value_as_double(map, x, y, z,
                                                       typeIntern, nullvalue);
                    fprintf(fp, "%.*f ", dp, value);
                }
                fprintf(fp, "\n");
            }
        } else {
            for (y = 0; y < rows; y++) {
                G_percent(percentage, (rows * depths - 1), 10);
                percentage++;

                for (x = 0; x < cols; x++) {
                    value =
                        get_g3d_raster_value_as_double(map, x, y, z,
                                                       typeIntern, nullvalue);
                    fprintf(fp, "%.*f ", dp, value);
                }
                fprintf(fp, "\n");
            }
        }
    }
}
示例#25
0
/*
 * side: side >= 0 - extracts contour on right side of edge, side < 0 - extracts contour on left side of edge
 * if the extracted contour is the outer contour, it is returned in ccw order
 * else if it is inner contour, it is returned in cw order
 */
static void extract_contour(struct planar_graph *pg, struct pg_edge *first,
			    int side, int winding, int stop_at_line_end,
			    struct line_pnts *nPoints)
{
    int j;
    int v;			/* current vertex number */
    int v0;
    int eside;			/* side of the current edge */
    double eangle;		/* current edge angle with Ox (according to the current direction) */
    struct pg_vertex *vert;	/* current vertex */
    struct pg_vertex *vert0;	/* last vertex */
    struct pg_edge *edge;	/* current edge; must be edge of vert */

    /*    int cs; *//* on which side are we turning along the contour */
    /* we will always turn right and dont need that one */
    double opt_angle, tangle;
    int opt_j, opt_side, opt_flag;

    G_debug(3, "extract_contour(): v1=%d, v2=%d, side=%d, stop_at_line_end=%d",
	    first->v1, first->v2, side, stop_at_line_end);

    Vect_reset_line(nPoints);

    edge = first;
    if (side >= 0) {
	eside = 1;
	v0 = edge->v1;
	v = edge->v2;
    }
    else {
	eside = -1;
	v0 = edge->v2;
	v = edge->v1;
    }
    vert0 = &(pg->v[v0]);
    vert = &(pg->v[v]);
    eangle = atan2(vert->y - vert0->y, vert->x - vert0->x);

    while (1) {
	Vect_append_point(nPoints, vert0->x, vert0->y, 0);
	G_debug(4, "ec: v0=%d, v=%d, eside=%d, edge->v1=%d, edge->v2=%d", v0,
		v, eside, edge->v1, edge->v2);
	G_debug(4, "ec: append point x=%.18f y=%.18f", vert0->x, vert0->y);

	/* mark current edge as visited on the appropriate side */
	if (eside == 1) {
	    edge->visited_right = 1;
	    edge->winding_right = winding;
	}
	else {
	    edge->visited_left = 1;
	    edge->winding_left = winding;
	}

	opt_flag = 1;
	for (j = 0; j < vert->ecount; j++) {
	    /* exclude current edge */
	    if (vert->edges[j] != edge) {
		tangle = vert->angles[j] - eangle;
		if (tangle < -PI)
		    tangle += 2 * PI;
		else if (tangle > PI)
		    tangle -= 2 * PI;
		/* now tangle is in (-PI, PI) */

		if (opt_flag || (tangle < opt_angle)) {
		    opt_j = j;
		    opt_side = (vert->edges[j]->v1 == v) ? (1) : (-1);
		    opt_angle = tangle;
		    opt_flag = 0;
		}
	    }
	}

	/* 
	G_debug(4, "ec: opt: side=%d opt_flag=%d opt_angle=%.18f opt_j=%d opt_step=%d",
	        side, opt_flag, opt_angle, opt_j, opt_step);
	*/

	/* if line end is reached (no other edges at curr vertex) */
	if (opt_flag) {
	    if (stop_at_line_end) {
		G_debug(3, "    end has been reached, will stop here");
		break;
	    }
	    else {
		opt_j = 0;	/* the only edge of vert is vert->edges[0] */
		opt_side = -eside;	/* go to the other side of the current edge */
		G_debug(3, "    end has been reached, turning around");
	    }
	}

	/* break condition */
	if ((vert->edges[opt_j] == first) && (opt_side == side))
	    break;
	if (opt_side == 1) {
	    if (vert->edges[opt_j]->visited_right) {
		G_warning(_("Next edge was visited (right) but it is not the first one !!! breaking loop"));
		G_debug(4,
			"ec: v0=%d, v=%d, eside=%d, edge->v1=%d, edge->v2=%d",
			v, (edge->v1 == v) ? (edge->v2) : (edge->v1),
			opt_side, vert->edges[opt_j]->v1,
			vert->edges[opt_j]->v2);
		break;
	    }
	}
	else {
	    if (vert->edges[opt_j]->visited_left) {
		G_warning(_("Next edge was visited (left) but it is not the first one !!! breaking loop"));
		G_debug(4,
			"ec: v0=%d, v=%d, eside=%d, edge->v1=%d, edge->v2=%d",
			v, (edge->v1 == v) ? (edge->v2) : (edge->v1),
			opt_side, vert->edges[opt_j]->v1,
			vert->edges[opt_j]->v2);
		break;
	    }
	}

	edge = vert->edges[opt_j];
	eside = opt_side;
	v0 = v;
	v = (edge->v1 == v) ? (edge->v2) : (edge->v1);
	vert0 = vert;
	vert = &(pg->v[v]);
	eangle = vert0->angles[opt_j];
    }
    Vect_append_point(nPoints, vert->x, vert->y, 0);
    Vect_line_prune(nPoints);
    G_debug(4, "ec: append point x=%.18f y=%.18f", vert->x, vert->y);

    return;
}
示例#26
0
/* ************************************************************************* */
void write_vtk_rgb_data(void *map_r, void *map_g, void *map_b,
                        FILE * fp, const char *varname,
                        RASTER3D_Region region, int dp)
{
    double value = 0;
    int x, y, z, percentage, k;
    int rows, cols, depths;
    int typeIntern[3];
    void *maprgb = NULL;

    G_debug(3, "write_vtk_rgb_data: Writing RGB data");

    rows = region.rows;
    cols = region.cols;
    depths = region.depths;

    typeIntern[0] = Rast3d_tile_type_map(map_r);
    typeIntern[1] = Rast3d_tile_type_map(map_g);
    typeIntern[2] = Rast3d_tile_type_map(map_b);

    percentage = 0;

    /********************** WRITE RGB VOXEL DATA; CELL OR POINT ****************/
    fprintf(fp, "COLOR_SCALARS %s 3\n", varname);

    for (z = 0; z < depths; z++) {
        for (y = 0; y < rows; y++) {
            G_percent(percentage, (rows * depths - 1), 10);
            percentage++;

            for (x = 0; x < cols; x++) {
                for (k = 0; k < 3; k++) {

                    if (k == 0)
                        maprgb = map_r;
                    if (k == 1)
                        maprgb = map_g;
                    if (k == 2)
                        maprgb = map_b;

                    /* In case of structured grid data, the point/cell coordinates
                       are computed based on the default north->south raster3d coordinate system.
                       We need to compute south -> north ordering for image data.
                     */
                    if (!param.structgrid->answer)
                        value =
                            get_g3d_raster_value_as_double(maprgb, x, rows - y - 1, z,
                                                           typeIntern[k],
                                                           0.0);
                    else
                        value =
                            get_g3d_raster_value_as_double(maprgb, x, y, z,
                                                           typeIntern[k],
                                                           0.0);
                    /*Test of value range, the data should be 1 byte gray values */
                    if (value > 255 || value < 0) {
                        G_warning(_("Wrong 3D raster map values! Values should in between 0 and 255!"));
                        fprintf(fp, "0 ");
                    } else {

                        fprintf(fp, "%.*f ", dp, (value / 255));
                    }
                }
                fprintf(fp, "\n");
            }
        }
    }
    return;
}
示例#27
0
/* area_outer and area_isles[i] must be closed non self-intersecting lines
   side: 0 - auto, 1 - right, -1 left
 */
static void buffer_lines(struct line_pnts *area_outer, struct line_pnts **area_isles,
			 int isles_count, int side, double da, double db,
			 double dalpha, int round, int caps, double tol,
			 struct line_pnts **oPoints, struct line_pnts ***iPoints,
			 int *inner_count)
{
    struct planar_graph *pg2;
    struct line_pnts *sPoints, *cPoints;
    struct line_pnts **arrPoints;
    int i, count = 0;
    int res, winding;
    int auto_side;
    int more = 8;
    int allocated = 0;
    double px, py;

    G_debug(3, "buffer_lines()");

    auto_side = (side == 0);

    /* initializations */
    sPoints = Vect_new_line_struct();
    cPoints = Vect_new_line_struct();
    arrPoints = NULL;

    /* outer contour */
    G_debug(3, "    processing outer contour");
    *oPoints = Vect_new_line_struct();
    if (auto_side)
	side =
	    get_polygon_orientation(area_outer->x, area_outer->y,
				    area_outer->n_points -
				    1) ? LEFT_SIDE : RIGHT_SIDE;
    convolution_line(area_outer, da, db, dalpha, side, round, caps, tol,
		     sPoints);
    pg2 = pg_create(sPoints);
    extract_outer_contour(pg2, 0, *oPoints);
    res = extract_inner_contour(pg2, &winding, cPoints);
    while (res != 0) {
	if (winding == 0) {
	    int check_poly = 1;
	    double area_size;

	    dig_find_area_poly(cPoints, &area_size);
	    if (area_size == 0) {
		G_warning(_("zero area size"));
		check_poly = 0;
	    }
	    if (cPoints->x[0] != cPoints->x[cPoints->n_points - 1] ||
		cPoints->y[0] != cPoints->y[cPoints->n_points - 1]) {

		G_warning(_("Line was not closed"));
		check_poly = 0;
	    }

	    if (check_poly && !Vect_point_in_poly(cPoints->x[0], cPoints->y[0], area_outer)) {
		if (Vect_get_point_in_poly(cPoints, &px, &py) == 0) {
		    if (!point_in_buf(area_outer, px, py, da, db, dalpha)) {
			add_line_to_array(cPoints, &arrPoints, &count, &allocated,
					  more);
			cPoints = Vect_new_line_struct();
		    }
		}
		else {
		    G_warning(_("Vect_get_point_in_poly() failed"));
		}
	    }
	}
	res = extract_inner_contour(pg2, &winding, cPoints);
    }
    pg_destroy_struct(pg2);

    /* inner contours */
    G_debug(3, "    processing inner contours");
    for (i = 0; i < isles_count; i++) {
	if (auto_side)
	    side =
		get_polygon_orientation(area_isles[i]->x, area_isles[i]->y,
					area_isles[i]->n_points -
					1) ? RIGHT_SIDE : LEFT_SIDE;
	convolution_line(area_isles[i], da, db, dalpha, side, round, caps,
			 tol, sPoints);
	pg2 = pg_create(sPoints);
	extract_outer_contour(pg2, 0, cPoints);
	res = extract_inner_contour(pg2, &winding, cPoints);
	while (res != 0) {
	    if (winding == -1) {
		int check_poly = 1;
		double area_size;

		dig_find_area_poly(cPoints, &area_size);
		if (area_size == 0) {
		    G_warning(_("zero area size"));
		    check_poly = 0;
		}
		if (cPoints->x[0] != cPoints->x[cPoints->n_points - 1] ||
		    cPoints->y[0] != cPoints->y[cPoints->n_points - 1]) {

		    G_warning(_("Line was not closed"));
		    check_poly = 0;
		}

		/* we need to check if the area is in the buffer.
		   I've simplfied convolution_line(), so that it runs faster,
		   however that leads to ocasional problems */
		if (check_poly && Vect_point_in_poly
		    (cPoints->x[0], cPoints->y[0], area_isles[i])) {
		    if (Vect_get_point_in_poly(cPoints, &px, &py) == 0) {
			if (!point_in_buf(area_isles[i], px, py, da, db, dalpha)) {
			    add_line_to_array(cPoints, &arrPoints, &count,
					      &allocated, more);
			    cPoints = Vect_new_line_struct();
			}
		    }
		    else {
			G_warning(_("Vect_get_point_in_poly() failed"));
		    }
		}
	    }
	    res = extract_inner_contour(pg2, &winding, cPoints);
	}
	pg_destroy_struct(pg2);
    }

    arrPoints = G_realloc(arrPoints, count * sizeof(struct line_pnts *));
    *inner_count = count;
    *iPoints = arrPoints;

    Vect_destroy_line_struct(sPoints);
    Vect_destroy_line_struct(cPoints);

    G_debug(3, "buffer_lines() ... done");

    return;
}
示例#28
0
/* ************************************************************************* */
void write_vtk_vector_data(void *map_x, void *map_y, void *map_z,
                           FILE * fp, const char *varname,
                           RASTER3D_Region region, int dp)
{
    double value = 0;
    int x, y, z, percentage, k;
    int rows, cols, depths;
    int typeIntern[3];
    void *mapvect = NULL;

    G_debug(3, "write_vtk_vector_data: Writing vector data");

    rows = region.rows;
    cols = region.cols;
    depths = region.depths;

    typeIntern[0] = Rast3d_tile_type_map(map_x);
    typeIntern[1] = Rast3d_tile_type_map(map_y);
    typeIntern[2] = Rast3d_tile_type_map(map_z);

    percentage = 0;

    /********************** WRITE VECTOR DATA; CELL OR POINT ****************/
    fprintf(fp, "VECTORS %s float\n", varname);

    for (z = 0; z < depths; z++) { /*From the bottom to the top */
        for (y = 0; y < rows; y++) {
            G_percent(percentage, (rows * depths - 1), 10);
            percentage++;

            for (x = 0; x < cols; x++) {
                for (k = 0; k < 3; k++) {

                    if (k == 0)
                        mapvect = map_x;
                    if (k == 1)
                        mapvect = map_y;
                    if (k == 2)
                        mapvect = map_z;

                    /* In case of structured grid data, the point/cell coordinates
                       are computed based on the default north->south raster3d coordinate system.
                       We need to compute south -> north ordering for image data.
                     */
                    if (!param.structgrid->answer)
                        value =
                            get_g3d_raster_value_as_double(mapvect, x, rows - y - 1, z,
                                                           typeIntern[k],
                                                           0.0);
                    else
                        value =
                            get_g3d_raster_value_as_double(mapvect, x, y, z,
                                                           typeIntern[k],
                                                           0.0);
                    fprintf(fp, "%.*f ", dp, value);
                }
                fprintf(fp, "\n");
            }
        }
    }
    return;
}
示例#29
0
/*--------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* Variables declarations */
    int nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row;
    int subregion = 0, nsubregions = 0;
    double N_extension, E_extension, edgeE, edgeN;
    int dim_vect, nparameters, BW, npoints;
    double mean, lambda;
    const char *dvr, *db, *mapset;
    char table_name[GNAME_MAX];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    int last_row, last_column, flag_auxiliar = FALSE;
    int filter_mode;

    int *lineVect;
    double *TN, *Q, *parVect;	/* Interpolating and least-square vectors */
    double **N, **obsVect;	/* Interpolation and least-square matrix */

    /* Structs declarations */
    struct Map_info In, Out, Outlier, Qgis;
    struct Option *in_opt, *out_opt, *outlier_opt, *qgis_opt, *stepE_opt,
	*stepN_opt, *lambda_f_opt, *Thres_O_opt, *filter_opt;
    struct Flag *spline_step_flag;
    struct GModule *module;

    struct Reg_dimens dims;
    struct Cell_head elaboration_reg, original_reg;
    struct bound_box general_box, overlap_box;

    struct Point *observ;

    dbDriver *driver;

    /*----------------------------------------------------------------*/
    /* Options declaration */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("statistics"));
    G_add_keyword(_("extract"));
    G_add_keyword(_("select"));
    G_add_keyword(_("filter"));
    module->description = _("Removes outliers from vector point data.");

    spline_step_flag = G_define_flag();
    spline_step_flag->key = 'e';
    spline_step_flag->label = _("Estimate point density and distance");
    spline_step_flag->description =
	_("Estimate point density and distance for the input vector points within the current region extends and quit");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);

    outlier_opt = G_define_option();
    outlier_opt->key = "outlier";
    outlier_opt->type = TYPE_STRING;
    outlier_opt->key_desc = "name";
    outlier_opt->required = YES;
    outlier_opt->gisprompt = "new,vector,vector";
    outlier_opt->description = _("Name of output outlier vector map");

    qgis_opt = G_define_option();
    qgis_opt->key = "qgis";
    qgis_opt->type = TYPE_STRING;
    qgis_opt->key_desc = "name";
    qgis_opt->required = NO;
    qgis_opt->gisprompt = "new,vector,vector";
    qgis_opt->description = _("Name of vector map for visualization in QGIS");

    stepE_opt = G_define_option();
    stepE_opt->key = "ew_step";
    stepE_opt->type = TYPE_DOUBLE;
    stepE_opt->required = NO;
    stepE_opt->answer = "10";
    stepE_opt->description =
	_("Length of each spline step in the east-west direction");
    stepE_opt->guisection = _("Settings");

    stepN_opt = G_define_option();
    stepN_opt->key = "ns_step";
    stepN_opt->type = TYPE_DOUBLE;
    stepN_opt->required = NO;
    stepN_opt->answer = "10";
    stepN_opt->description =
	_("Length of each spline step in the north-south direction");
    stepN_opt->guisection = _("Settings");

    lambda_f_opt = G_define_option();
    lambda_f_opt->key = "lambda";
    lambda_f_opt->type = TYPE_DOUBLE;
    lambda_f_opt->required = NO;
    lambda_f_opt->description = _("Tykhonov regularization weight");
    lambda_f_opt->answer = "0.1";
    lambda_f_opt->guisection = _("Settings");

    Thres_O_opt = G_define_option();
    Thres_O_opt->key = "threshold";
    Thres_O_opt->type = TYPE_DOUBLE;
    Thres_O_opt->required = NO;
    Thres_O_opt->description = _("Threshold for the outliers");
    Thres_O_opt->answer = "50";

    filter_opt = G_define_option();
    filter_opt->key = "filter";
    filter_opt->type = TYPE_STRING;
    filter_opt->required = NO;
    filter_opt->description = _("Filtering option");
    filter_opt->options = "both,positive,negative";
    filter_opt->answer = "both";

    /* Parsing */
    G_gisinit(argv[0]);
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (!(db = G_getenv_nofatal2("DB_DATABASE", G_VAR_MAPSET)))
	G_fatal_error(_("Unable to read name of database"));

    if (!(dvr = G_getenv_nofatal2("DB_DRIVER", G_VAR_MAPSET)))
	G_fatal_error(_("Unable to read name of driver"));

    stepN = atof(stepN_opt->answer);
    stepE = atof(stepE_opt->answer);
    lambda = atof(lambda_f_opt->answer);
    Thres_Outlier = atof(Thres_O_opt->answer);

    filter_mode = 0;
    if (strcmp(filter_opt->answer, "positive") == 0)
	filter_mode = 1;
    else if (strcmp(filter_opt->answer, "negative") == 0)
	filter_mode = -1;
    P_set_outlier_fn(filter_mode);

    flag_auxiliar = FALSE;

    /* Checking vector names */
    Vect_check_input_output_name(in_opt->answer, out_opt->answer,
				 G_FATAL_EXIT);

    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) {
	G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);
    }

    /* Setting auxiliar table's name */
    if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) {
	sprintf(table_name, "%s_aux", xname);
    }
    else
	sprintf(table_name, "%s_aux", out_opt->answer);

    /* Something went wrong in a previous v.outlier execution */
    if (db_table_exists(dvr, db, table_name)) {
	/* Start driver and open db */
	driver = db_start_driver_open_database(dvr, db);
	if (driver == NULL)
	    G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
			  dvr);
        db_set_error_handler_driver(driver);

	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_fatal_error(_("Old auxiliar table could not be dropped"));
	db_close_database_shutdown_driver(driver);
    }

    /* Open input vector */
    Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
    if (1 > Vect_open_old(&In, in_opt->answer, mapset))
	G_fatal_error(_("Unable to open vector map <%s> at the topological level"),
		      in_opt->answer);

    /* Input vector must be 3D */
    if (!Vect_is_3d(&In))
	G_fatal_error(_("Input vector map <%s> is not 3D!"), in_opt->answer);

    /* Estimate point density and mean distance for current region */
    if (spline_step_flag->answer) {
	double dens, dist;
	if (P_estimate_splinestep(&In, &dens, &dist) == 0) {
	    G_message("Estimated point density: %.4g", dens);
	    G_message("Estimated mean distance between points: %.4g", dist);
	}
	else
	    G_warning(_("No points in current region!"));
	
	Vect_close(&In);
	exit(EXIT_SUCCESS);
    }

    /* Open output vector */
    if (qgis_opt->answer)
	if (0 > Vect_open_new(&Qgis, qgis_opt->answer, WITHOUT_Z))
	    G_fatal_error(_("Unable to create vector map <%s>"),
			  qgis_opt->answer);

    if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) {
	Vect_close(&Qgis);
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);
    }

    if (0 > Vect_open_new(&Outlier, outlier_opt->answer, WITH_Z)) {
	Vect_close(&Out);
	Vect_close(&Qgis);
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);
    }

    /* Copy vector Head File */
    Vect_copy_head_data(&In, &Out);
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);

    Vect_copy_head_data(&In, &Outlier);
    Vect_hist_copy(&In, &Outlier);
    Vect_hist_command(&Outlier);

    if (qgis_opt->answer) {
	Vect_copy_head_data(&In, &Qgis);
	Vect_hist_copy(&In, &Qgis);
	Vect_hist_command(&Qgis);
    }

    /* Open driver and database */
    driver = db_start_driver_open_database(dvr, db);
    if (driver == NULL)
	G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
		      dvr);
    db_set_error_handler_driver(driver);

    /* Create auxiliar table */
    if ((flag_auxiliar =
	 P_Create_Aux2_Table(driver, table_name)) == FALSE)
	G_fatal_error(_("It was impossible to create <%s> table."), table_name);

    db_create_index2(driver, table_name, "ID");
    /* sqlite likes that ??? */
    db_close_database_shutdown_driver(driver);
    driver = db_start_driver_open_database(dvr, db);

    /* Setting regions and boxes */
    G_get_set_window(&original_reg);
    G_get_set_window(&elaboration_reg);
    Vect_region_box(&elaboration_reg, &overlap_box);
    Vect_region_box(&elaboration_reg, &general_box);

    /*------------------------------------------------------------------
      | Subdividing and working with tiles: 									
      | Each original region will be divided into several subregions. 
      | Each one will be overlaped by its neighbouring subregions. 
      | The overlapping is calculated as a fixed OVERLAP_SIZE times
      | the largest spline step plus 2 * edge
      ----------------------------------------------------------------*/

    /* Fixing parameters of the elaboration region */
    P_zero_dim(&dims);		/* Set dim struct to zero */

    nsplx_adj = NSPLX_MAX;
    nsply_adj = NSPLY_MAX;
    if (stepN > stepE)
	dims.overlap = OVERLAP_SIZE * stepN;
    else
	dims.overlap = OVERLAP_SIZE * stepE;
    P_get_edge(P_BILINEAR, &dims, stepE, stepN);
    P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj);

    G_verbose_message(_("Adjusted EW splines %d"), nsplx_adj);
    G_verbose_message(_("Adjusted NS splines %d"), nsply_adj);

    /* calculate number of subregions */
    edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v;
    edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h;

    N_extension = original_reg.north - original_reg.south;
    E_extension = original_reg.east - original_reg.west;

    nsubregion_col = ceil(E_extension / edgeE) + 0.5;
    nsubregion_row = ceil(N_extension / edgeN) + 0.5;

    if (nsubregion_col < 0)
	nsubregion_col = 0;
    if (nsubregion_row < 0)
	nsubregion_row = 0;

    nsubregions = nsubregion_row * nsubregion_col;

    elaboration_reg.south = original_reg.north;
    last_row = FALSE;

    while (last_row == FALSE) {	/* For each row */

	P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
		      GENERAL_ROW);

	if (elaboration_reg.north > original_reg.north) {	/* First row */

	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  FIRST_ROW);
	}

	if (elaboration_reg.south <= original_reg.south) {	/* Last row */

	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  LAST_ROW);
	    last_row = TRUE;
	}

	nsply =
	    ceil((elaboration_reg.north -
		  elaboration_reg.south) / stepN) + 0.5;
	/*
	if (nsply > NSPLY_MAX)
	    nsply = NSPLY_MAX;
	*/
	G_debug(1, "nsply = %d", nsply);

	elaboration_reg.east = original_reg.west;
	last_column = FALSE;

	while (last_column == FALSE) {	/* For each column */

	    subregion++;
	    if (nsubregions > 1)
		G_message(_("Processing subregion %d of %d..."), subregion, nsubregions);
	    else /* v.outlier -e will report mean point distance: */
		G_warning(_("No subregions found! Check values for 'ew_step' and 'ns_step' parameters"));

	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  GENERAL_COLUMN);

	    if (elaboration_reg.west < original_reg.west) {	/* First column */

		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, FIRST_COLUMN);
	    }

	    if (elaboration_reg.east >= original_reg.east) {	/* Last column */

		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, LAST_COLUMN);
		last_column = TRUE;
	    }
	    nsplx =
		ceil((elaboration_reg.east -
		      elaboration_reg.west) / stepE) + 0.5;
	    /*
	    if (nsplx > NSPLX_MAX)
		nsplx = NSPLX_MAX;
	    */
	    G_debug(1, "nsplx = %d", nsplx);

	    /*Setting the active region */
	    dim_vect = nsplx * nsply;
	    observ =
		P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints,
					 dim_vect, 1);

	    if (npoints > 0) {	/* If there is any point falling into elaboration_reg... */
		int i;

		nparameters = nsplx * nsply;

		/* Mean calculation */
		mean = P_Mean_Calc(&elaboration_reg, observ, npoints);

		/* Least Squares system */
		G_debug(1, "Allocation memory for bilinear interpolation");
		BW = P_get_BandWidth(P_BILINEAR, nsply);	/* Bilinear interpolation */
		N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
		TN = G_alloc_vector(nparameters);	/* vector */
		parVect = G_alloc_vector(nparameters);	/* Bicubic parameters vector */
		obsVect = G_alloc_matrix(npoints, 3);	/* Observation vector */
		Q = G_alloc_vector(npoints);	/* "a priori" var-cov matrix */
		lineVect = G_alloc_ivector(npoints);

		/* Setting obsVect vector & Q matrix */
		for (i = 0; i < npoints; i++) {
		    obsVect[i][0] = observ[i].coordX;
		    obsVect[i][1] = observ[i].coordY;
		    obsVect[i][2] = observ[i].coordZ - mean;
		    lineVect[i] = observ[i].lineID;
		    Q[i] = 1;	/* Q=I */
		}

		G_free(observ);

		G_verbose_message(_("Bilinear interpolation"));
		normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx,
			       nsply, elaboration_reg.west,
			       elaboration_reg.south, npoints, nparameters,
			       BW);
		nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
		G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW);

		G_free_matrix(N);
		G_free_vector(TN);
		G_free_vector(Q);

		G_verbose_message(_("Outlier detection"));
		if (qgis_opt->answer)
		    P_Outlier(&Out, &Outlier, &Qgis, elaboration_reg,
			      general_box, overlap_box, obsVect, parVect,
			      mean, dims.overlap, lineVect, npoints,
			      driver, table_name);
		else
		    P_Outlier(&Out, &Outlier, NULL, elaboration_reg,
			      general_box, overlap_box, obsVect, parVect,
			      mean, dims.overlap, lineVect, npoints,
			      driver, table_name);


		G_free_vector(parVect);
		G_free_matrix(obsVect);
		G_free_ivector(lineVect);

	    }			/*! END IF; npoints > 0 */
	    else {
		G_free(observ);
		G_warning(_("No data within this subregion. "
			    "Consider increasing spline step values."));
	    }
	}			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    /* Drop auxiliar table */
    if (npoints > 0) {
	G_debug(1, "%s: Dropping <%s>", argv[0], table_name);
	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_fatal_error(_("Auxiliary table could not be dropped"));
    }

    db_close_database_shutdown_driver(driver);

    Vect_close(&In);
    Vect_close(&Out);
    Vect_close(&Outlier);
    if (qgis_opt->answer) {
	Vect_build(&Qgis);
	Vect_close(&Qgis);
    }

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*END MAIN */
示例#30
0
文件: main.cpp 项目: rkrug/grass-ci
/* Process the raster and do atmospheric corrections.
   Params:
   * INPUT FILE
   ifd: input file descriptor
   iref: input file has radiance values (default is reflectance) ?
   iscale: input file's range (default is min = 0, max = 255)
   ialt_fd: height map file descriptor, negative if global value is used
   ivis_fd: visibility map file descriptor, negative if global value is used

   * OUTPUT FILE
   ofd: output file descriptor
   oflt: if true use FCELL_TYPE for output
   oscale: output file's range (default is min = 0, max = 255)
 */
static void process_raster(int ifd, InputMask imask, ScaleRange iscale,
			   int ialt_fd, int ivis_fd, int ofd, bool oint,
			   ScaleRange oscale)
{
    FCELL *buf;			/* buffer for the input values */
    FCELL *alt = NULL;		/* buffer for the elevation values */
    FCELL *vis = NULL;		/* buffer for the visibility values */
    FCELL prev_alt = -1.f;
    FCELL prev_vis = -1.f;
    int row, col, nrows, ncols;
    /* switch on optimization automatically if elevation and/or visibility map is given */
    bool optimize = (ialt_fd >= 0 || ivis_fd >= 0);
    
#ifdef _NO_OPTIMIZE_
    optimize = false;
#endif

    /* do initial computation with global elevation and visibility values */
    TransformInput ti;

    ti = compute();

    /* use a cache to increase computation speed when an elevation map 
     * and/or a visibility map is given */
    TICache ticache;

    /* allocate memory for buffers */
    buf = (FCELL *) Rast_allocate_buf(FCELL_TYPE);
    if (ialt_fd >= 0)
	alt = (FCELL *) Rast_allocate_buf(FCELL_TYPE);
    if (ivis_fd >= 0)
	vis = (FCELL *) Rast_allocate_buf(FCELL_TYPE);

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

    for (row = 0; row < nrows; row++) {
	G_percent(row, nrows, 1);	/* keep the user informed of our progress */

	/* read the next row */
	Rast_get_row(ifd, buf, row, FCELL_TYPE);

	/* read the next row of elevation values */
	if (ialt_fd >= 0)
	    Rast_get_row(ialt_fd, alt, row, FCELL_TYPE);

	/* read the next row of elevation values */
	if (ivis_fd >= 0)
	    Rast_get_row(ivis_fd, vis, row, FCELL_TYPE);

	/* loop over all the values in the row */
	for (col = 0; col < ncols; col++) {
	    if ((vis && Rast_is_f_null_value(&vis[col])) ||
		(alt && Rast_is_f_null_value(&alt[col])) ||
		Rast_is_f_null_value(&buf[col])) {
		Rast_set_f_null_value(&buf[col], 1);
		continue;
	    }
	    if (ialt_fd >= 0) {
		if (alt[col] < 0)
		    alt[col] = 0; /* on or below sea level, all the same for 6S */
		else
		    alt[col] /= 1000.0f;	/* converting to km from input which should be in meter */

		/* round to nearest altitude bin */
		/* rounding result: watch out for fp representation error */
		alt[col] = ((int) (alt[col] * BIN_ALT + 0.5)) / BIN_ALT;
	    }
	    if (ivis_fd >= 0) {
		if (vis[col] < 0)
		    vis[col] = 0; /* negative visibility is invalid, print a WARNING ? */

		/* round to nearest visibility bin */
		/* rounding result: watch out for fp representation error */
		vis[col] = ((int) (vis[col] + 0.5));
	    }

	    /* check if both maps are active and if whether any value has changed */
	    if ((ialt_fd >= 0) && (ivis_fd >= 0) &&
		((prev_vis != vis[col]) || (prev_alt != alt[col]))) {
		prev_alt = alt[col];	/* update new values */
		prev_vis = vis[col];
		if (optimize) {
		    int in_cache = ticache.search(alt[col], vis[col], &ti);

		    if (!in_cache) {
			pre_compute_hv(alt[col], vis[col]);	/* re-compute transformation inputs */
			ti = compute();	/* ... */

			ticache.add(ti, alt[col], vis[col]);
		    }
		}
		else {
		    pre_compute_hv(alt[col], vis[col]);	/* re-compute transformation inputs */
		    ti = compute();	/* ... */
		}
	    }
	    else {		/* only one of the maps is being used */

		if ((ivis_fd >= 0) && (prev_vis != vis[col])) {
		    prev_vis = vis[col];	/* keep track of previous visibility */

		    if (optimize) {
			int in_cache = ticache.search(0, vis[col], &ti);

			if (!in_cache) {
			    pre_compute_v(vis[col]);	/* re-compute transformation inputs */
			    ti = compute();	/* ... */

			    ticache.add(ti, 0, vis[col]);
			}
		    }
		    else {
			pre_compute_v(vis[col]);	/* re-compute transformation inputs */
			ti = compute();	/* ... */
		    }
		}

		if ((ialt_fd >= 0) && (prev_alt != alt[col])) {
		    prev_alt = alt[col];	/* keep track of previous altitude */

		    if (optimize) {
			int in_cache = ticache.search(alt[col], 0, &ti);

			if (!in_cache) {
			    pre_compute_h(alt[col]);	/* re-compute transformation inputs */
			    ti = compute();	/* ... */

			    ticache.add(ti, alt[col], 0);
			}
		    }
		    else {
			pre_compute_h(alt[col]);	/* re-compute transformation inputs */
			ti = compute();	/* ... */
		    }
		}
	    }
	    G_debug(3, "Computed r%d (%d), c%d (%d)", row, nrows, col, ncols);
	    /* transform from iscale.[min,max] to [0,1] */
	    buf[col] =
		(buf[col] - iscale.min) / ((float)iscale.max -
					   (float)iscale.min);
	    buf[col] = transform(ti, imask, buf[col]);
	    /* transform from [0,1] to oscale.[min,max] */
	    buf[col] =
		buf[col] * ((float)oscale.max - (float)oscale.min) +
		oscale.min;

	    if (oint && (buf[col] > (float)oscale.max))
		G_warning(_("The output data will overflow. Reflectance > 100%%"));
	}

	/* write output */
	if (oint)
	    write_fp_to_cell(ofd, buf);
	else
	    Rast_put_row(ofd, buf, FCELL_TYPE);
    }
    G_percent(1, 1, 1);

    /* free allocated memory */
    G_free(buf);
    if (ialt_fd >= 0)
	G_free(alt);
    if (ivis_fd >= 0)
	G_free(vis);
}