Пример #1
0
/* read line coordinates */
void read_coor(FILE * fp, SYMBEL * e)
{
    char buf[501];
    double x, y;

    G_debug(5, "    read_coor()");

    while (G_getl2(buf, 500, fp) != 0) {
	G_chop(buf);

	/* skip empty and comment lines */
	if ((buf[0] == '#') || (buf[0] == '\0'))
	    continue;

	get_key_data(buf);

	if (strcmp(key, "END") == 0) {
	    G_debug(5, "    LINE END");
	    return;
	}

	if (sscanf(buf, "%lf %lf", &x, &y) != 2) {
	    G_warning(_("Cannot read symbol line coordinates: %s"), buf);
	    return;
	}
	G_debug(5, "      x = %f y = %f", x, y);
	add_point(e, x, y);
    }
}
Пример #2
0
static int get_stmt(FILE * fd, dbString * stmt)
{
    char buf[4000], buf2[4000];
    int len, row = 0;

    db_init_string(stmt);

    while (fgets(buf, 4000, fd) != NULL) {
	strcpy(buf2, buf);
	G_chop(buf2);
	len = strlen(buf2);

	if (buf2[len - 1] == ';') {	/* end of statement */
	    buf2[len - 1] = 0;	        /* truncate ';' */
	    /* append truncated */
	    db_append_string(stmt, buf2);	
	    return 1;
	}
	else {
	    /* append not truncated string (\n may be part of value) */
	    db_append_string(stmt, buf);	
	}
	row++;
    }

    if (row > 0)
	return 1;

    return 0;
}
Пример #3
0
static void add_rule(struct context *ctx, int type, const char *data)
{
    char **tokens;
    int ntokens;
    void **opts;
    int i;

    tokens = G_tokenize(data, ",");
    ntokens = G_number_of_tokens(tokens);
    opts = G_malloc(ntokens * sizeof(void *));

    for (i = 0; i < ntokens; i++) {
	char buf[256];
	char *name;

	strcpy(buf, tokens[i]);
	name = G_chop(buf);
	opts[i] = (name[0] == '-')
	    ? find_flag(ctx, name[1])
	    : find_option(ctx, name);
    }

    G_free_tokens(tokens);

    G__option_rule(type, ntokens, opts);
}
Пример #4
0
/*!
   \brief Fetches list of DB column names and types of vector map attribute table

   \param Map vector map
   \param field layer number

   \return list of column(s) types on success
   \retutn NULL on error 
 */
const char *Vect_get_column_names_types(struct Map_info *Map, int field)
{
    int num_dblinks, ncols, col;
    struct field_info *fi;
    dbDriver *driver = NULL;
    dbHandle handle;
    dbString table_name;
    dbTable *table;
    char buf[2000], temp_buf[2000];


    num_dblinks = Vect_get_num_dblinks(Map);
    if (num_dblinks <= 0)
	return (NULL);

    G_debug(3,
	    "Displaying column types for database connection of layer %d:",
	    field);
    if ((fi = Vect_get_field(Map, field)) == NULL)
	return (NULL);
    driver = db_start_driver(fi->driver);
    if (driver == NULL)
	return (NULL);
    db_init_handle(&handle);
    db_set_handle(&handle, fi->database, NULL);
    if (db_open_database(driver, &handle) != DB_OK)
	return (NULL);
    db_init_string(&table_name);
    db_set_string(&table_name, fi->table);
    if (db_describe_table(driver, &table_name, &table) != DB_OK)
	return (NULL);

    ncols = db_get_table_number_of_columns(table);
    sprintf(buf, " ");
    for (col = 0; col < ncols; col++) {
	if (col == 0)
	    sprintf(buf, "%s(%s)",
		    db_get_column_name(db_get_table_column(table, col)),
		    db_sqltype_name(db_get_column_sqltype
				    (db_get_table_column(table, col))));
	else {
	    sprintf(temp_buf, ",%s(%s)",
		    db_get_column_name(db_get_table_column(table, col)),
		    db_sqltype_name(db_get_column_sqltype
				    (db_get_table_column(table, col))));
	    strcat(buf, temp_buf);
	}
    }
    G_debug(3, "%s", buf);

    db_close_database(driver);
    db_shutdown_driver(driver);

    return G_store(G_chop(buf));
}
Пример #5
0
/*
  \brief Parse connection string in form:
  1) 'database_name'
  2) 'host=xx,port=xx,dbname=xx'
  
  \returns DB_OK on success
  \return DB_FAILED on failure
*/
int parse_conn(const char *str, PGCONN * pgconn)
{
    int i;
    char **tokens, delm[2];

    /* reset */
    G_zero(pgconn, sizeof(PGCONN));

    G_debug(3, "parse_conn: '%s'", str);

    if (strchr(str, '=') == NULL) {	/* db name only */
	pgconn->dbname = G_store(str);
    }
    else {
	delm[0] = ',';
	delm[1] = '\0';
	tokens = G_tokenize(str, delm);
	i = 0;
	while (tokens[i]) {
	    G_chop(tokens[i]);
	    G_debug(3, "token %d : %s", i, tokens[i]);
	    if (strncmp(tokens[i], "host", 4) == 0)
		pgconn->host = G_store(tokens[i] + 5);
	    else if (strncmp(tokens[i], "port", 4) == 0)
		pgconn->port = G_store(tokens[i] + 5);
	    else if (strncmp(tokens[i], "options", 7) == 0)
		pgconn->options = G_store(tokens[i] + 8);
	    else if (strncmp(tokens[i], "tty", 3) == 0)
		pgconn->tty = G_store(tokens[i] + 4);
	    else if (strncmp(tokens[i], "dbname", 6) == 0)
		pgconn->dbname = G_store(tokens[i] + 7);
	    else if (strncmp(tokens[i], "user", 4) == 0)
		G_warning(_("'user' in database definition is not supported, use db.login"));
	    /* pgconn->user = G_store ( tokens[i] + 5 ); */
	    else if (strncmp(tokens[i], "password", 8) == 0)
		/* pgconn->password = G_store ( tokens[i] + 9 ); */
		G_warning(_("'password' in database definition is not supported, use db.login"));
	    else if (strncmp(tokens[i], "schema", 6) == 0)
		pgconn->schema = G_store(tokens[i] + 7);
	    else {
		db_d_append_error("%s %s",
				  _("Unknown option in database definition "
				    "for PostgreSQL: "),
				  tokens[i]);
		return DB_FAILED;
	    }
	    i++;
	}
	G_free_tokens(tokens);
    }

    return DB_OK;
}
Пример #6
0
/*
   Read the DB login file if it exists
   return: -1 error (cannot read file)
   number of items (0 also if file does not exist)
 */
static int read_file(LOGIN * login)
{
    int ret;
    const char *file;
    FILE *fd;
    char buf[2001], dr[500], db[500], usr[500], pwd[500], host[500], port[500];

    login->n = 0;
    file = login_filename();

    G_debug(3, "read_file(): DB login file = <%s>", file);

    if (access(file, F_OK) != 0) {
	G_debug(3, "login file does not exist");
	return 0;
    }

    fd = fopen(file, "r");
    if (fd == NULL) {
        G_warning(_("Unable to read file '%s'"), file);
	return -1;
    }

    while (G_getl2(buf, 2000, fd)) {
	G_chop(buf);

	usr[0] = pwd[0] = host[0] = port[0] = '\0';
	ret = sscanf(buf, "%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^\n]",
                     dr, db, usr, pwd, host, port);

	G_debug(3, "ret = %d : drv=[%s] db=[%s] usr=[%s] pwd=[%s] host=[%s], port=[%s]",
		ret, dr, db, usr, pwd, host, port);

	if (ret < 2) {
	    G_warning(_("Login file (%s) corrupted (line: %s)"), file, buf);
	    continue;
	}

	add_login(login, dr, db, usr, pwd, host, port, -1);
    }

    fclose(fd);

    return (login->n);
}
Пример #7
0
/*
   Read the DB login file if it exists
   return: -1 error (cannot read file)
   number of items (0 also if file does not exist)
 */
int read_file(LOGIN * login)
{
    int ret;
    const char *file;
    struct stat info;
    FILE *fd;
    char buf[2001], dr[500], db[500], usr[500], pwd[500];

    login->n = 0;
    file = login_filename();

    G_debug(3, "DB login file = <%s>", file);

    if (stat(file, &info) != 0) {
	G_debug(3, "login file does not exist");
	return 0;
    }

    fd = fopen(file, "r");
    if (fd == NULL)
	return -1;

    while (G_getl2(buf, 2000, fd)) {
	G_chop(buf);

	usr[0] = pwd[0] = '\0';
	ret = sscanf(buf, "%[^|]|%[^|]|%[^|]|%[^\n]", dr, db, usr, pwd);

	G_debug(3, "ret = %d : drv=[%s] db=[%s] usr=[%s] pwd=[%s]",
		ret, dr, db, usr, pwd);

	if (ret < 2) {
	    G_warning(_("Login file corrupted"));
	    continue;
	}

	add_login(login, dr, db, usr, pwd);
    }

    fclose(fd);

    return (login->n);
}
Пример #8
0
/* stores input to key an data */
void get_key_data(char *buf)
{
    char *p;

    G_debug(3, "  get_key_data(): %s", buf);

    data[0] = '\0';

    strcpy(key, buf);
    p = strchr(key, ' ');
    if (p == NULL)
	return;

    p[0] = '\0';

    p++;
    if (strlen(p) > 0) {
	strcpy(data, p);
	G_chop(data);
    }
    G_debug(3, "  key = %s data = %s", key, data);
}
Пример #9
0
Файл: main.c Проект: caomw/grass
int get_stmt(FILE * fd, dbString * stmt)
{
    char buf[DB_SQL_MAX], buf2[DB_SQL_MAX];
    size_t len;
    
    db_zero_string(stmt);
    
    if (G_getl2(buf, sizeof(buf), fd) == 0)
        return 0;
        
    strcpy(buf2, buf);
    G_chop(buf2);
    len = strlen(buf2);
        
    if (buf2[len - 1] == ';') { /* end of statement */
        buf2[len - 1] = 0;      /* truncate ';' */
    }
    
    db_set_string(stmt, buf);
    
    return 1;
}
Пример #10
0
int db__driver_open_database(dbHandle * handle)
{
    const char *name;
    int len;
    dbConnection connection;
    char buf[1024];
    DIR *dir;
    struct dirent *ent;
    char **tokens;
    int no_tokens, n;

    G_debug(2, "DBF: db__driver_open_database() name = '%s'",
	    db_get_handle_dbname(handle));

    db.name[0] = '\0';
    db.tables = NULL;
    db.atables = 0;
    db.ntables = 0;

    db_get_connection(&connection);
    name = db_get_handle_dbname(handle);

    /* if name is empty use connection.databaseName */
    if (strlen(name) == 0) {
	name = connection.databaseName;
    }

    strcpy(db.name, name);

    /* open database dir and read table ( *.dbf files ) names 
     * to structure */

    /* parse variables in db.name if present */
    if (db.name[0] == '$') {
	tokens = G_tokenize(db.name, "/");
	no_tokens = G_number_of_tokens(tokens);
	db.name[0] = '\0';	/* re-init */

	for (n = 0; n < no_tokens; n++) {
	    G_debug(3, "tokens[%d] = %s", n, tokens[n]);
	    if (tokens[n][0] == '$') {
		G_strchg(tokens[n], '$', ' ');
		G_chop(tokens[n]);
		strcat(db.name, G__getenv(tokens[n]));
		G_debug(3, "   -> %s", G__getenv(tokens[n]));
	    }
	    else
		strcat(db.name, tokens[n]);

	    strcat(db.name, "/");
	}
	G_free_tokens(tokens);
    }

    G_debug(2, "db.name = %s", db.name);

    errno = 0;
    dir = opendir(db.name);
    if (dir == NULL) {
	if (errno == ENOENT) {
	    int status;

	    status = G_mkdir(db.name);
	    if (status != 0) {	/* mkdir failed */
		append_error("Cannot create dbf database: %s\n", name);
		report_error();
		return DB_FAILED;
	    }
	}
	else {			/* some other problem */
	    append_error("Cannot open dbf database: %s\n", name);
	    report_error();
	    return DB_FAILED;
	}
    }

    while ((ent = readdir(dir))) {
	len = strlen(ent->d_name) - 4;
	if ((len > 0) && (G_strcasecmp(ent->d_name + len, ".dbf") == 0)) {
	    strcpy(buf, ent->d_name);
	    buf[len] = '\0';
	    add_table(buf, ent->d_name);
	}
    }

    closedir(dir);
    return DB_OK;
}
Пример #11
0
int read_eps(double e, double n)
{
    char buf[1024], eps_file[GPATH_MAX];
    char *eps;
    double scale, rotate;
    int have_eps;
    char *key, *data;
    int masked;
    FILE *fp;

    static char *help[] = {
	"epsfile EPS file",
	"scale   #",
	"rotate   #",
	"masked [y|n]",
	""
    };

    scale = 1.0;
    rotate = 0.0;
    have_eps = 0;
    masked = 0;

    while (input(2, buf, help)) {
	if (!key_data(buf, &key, &data))
	    continue;

	if (KEY("masked")) {
	    masked = yesno(key, data);
	    if (masked)
		PS.mask_needed = 1;
	    continue;
	}

	if (KEY("epsfile")) {
	    G_chop(data);

	    /* expand "$GISBASE" if present */
	    if (strncmp(data, "$GISBASE", 8) != 0)
		strcpy(eps_file, data);
	    else {
		strcpy(eps_file, G_gisbase());
		data += 8;
		strcat(eps_file, data);
	    }

	    eps = G_store(eps_file);

	    /* test if file is accessible */
	    if ((fp = fopen(eps, "r")) == NULL)
		error(key, data, _("Can't open eps file"));

	    have_eps = 1;
	    fclose(fp);
	    continue;
	}

	if (KEY("scale")) {
	    if (sscanf(data, "%lf", &scale) != 1 || scale <= 0.0) {
		scale = 1.0;
		error(key, data, "illegal scale request");
	    }
	    continue;
	}

	if (KEY("rotate")) {
	    if (sscanf(data, "%lf", &rotate) != 1) {
		rotate = 0.0;
		error(key, data, "illegal rotate request");
	    }
	    continue;
	}

	error(key, data, "illegal eps request");
    }
    if (have_eps) {
	sprintf(buf, "E %d %f %f %f %f %s", masked, e, n, scale, rotate, eps);
    }
    add_to_plfile(buf);

    return 0;
}
Пример #12
0
/* 
 *  Read symbol specified by name.
 *  Name: group/name | group/name@mapset 
 *        (later add syntax to prefer symbol from GISBASE)
 *  S_read() searches first in mapsets (standard GRASS search) and
 *   then in GISBASE/etc/symbol/ 
 */
SYMBOL *S_read(const char *sname)
{
    int i, j, k, l;
    FILE *fp;
    char group[500], name[500], buf[2001];
    const char *ms;
    char *c;
    double x, y, x2, y2, rad, ang1, ang2;
    int r, g, b;
    double fr, fg, fb;
    int ret;
    char clock;
    SYMBOL *symb;
    int current;		/* current part_type */
    SYMBPART *part;		/* current part */
    SYMBCHAIN *chain;		/* current chain */
    SYMBEL *elem;		/* current element */

    G_debug(3, "S_read(): sname = %s", sname);

    /* Find file */
    /* Get group and name */
    strcpy(group, sname);
    c = strchr(group, '/');
    if (c == NULL) {
	G_warning(_("Incorrect symbol name: '%s' (should be: group/name or group/name@mapset)"),
		  sname);
	return NULL;
    }
    c[0] = '\0';

    c++;
    strcpy(name, c);

    G_debug(3, "  group: '%s' name: '%s'", group, name);

    /* Search in mapsets */
    sprintf(buf, "symbol/%s", group);
    ms = G_find_file(buf, name, NULL);

    if (ms != NULL) {		/* Found in mapsets */
	fp = G_fopen_old(buf, name, ms);
    }
    else {			/* Search in GISBASE */
	sprintf(buf, "%s/etc/symbol/%s", G_gisbase(), sname);
	fp = fopen(buf, "r");
    }

    if (fp == NULL) {
	G_warning(_("Cannot find/open symbol: '%s'"), sname);
	return NULL;
    }

    /* create new symbol */
    symb = new_symbol();

    current = OBJ_NONE;		/* no part */

    /* read file */
    while (G_getl2(buf, 2000, fp) != 0) {
	G_chop(buf);
	G_debug(3, "  BUF: [%s]", buf);

	/* skip empty and comment lines */
	if ((buf[0] == '#') || (buf[0] == '\0'))
	    continue;

	get_key_data(buf);

	if (strcmp(key, "VERSION") == 0) {
	    if (strcmp(data, "1.0") != 0) {
		sprintf(buf, "Wrong symbol version: '%s'", data);
		return (err(fp, symb, buf));
	    }
	}
	else if (strcmp(key, "BOX") == 0) {
	    if (sscanf(data, "%lf %lf %lf %lf", &x, &y, &x2, &y2) != 4) {
		sprintf(buf, "Incorrect box definition: '%s'", data);
		return (err(fp, symb, buf));
	    }
	    symb->xscale = 1 / (x2 - x);
	    symb->yscale = 1 / (y2 - y);
	    if (x2 - x > y2 - y) {
		symb->scale = symb->xscale;
	    }
	    else {
		symb->scale = symb->yscale;
	    }
	}
	else if (strcmp(key, "STRING") == 0) {
	    G_debug(4, "  STRING >");
	    current = OBJ_STRING;
	    part = new_part(S_STRING);
	    add_part(symb, part);

	    chain = new_chain();
	    add_chain(part, chain);
	}
	else if (strcmp(key, "POLYGON") == 0) {
	    G_debug(4, "  POLYGON >");
	    current = OBJ_POLYGON;
	    part = new_part(S_POLYGON);
	    add_part(symb, part);

	}
	else if (strcmp(key, "RING") == 0) {
	    G_debug(4, "  RING >");
	    current = OBJ_RING;
	    chain = new_chain();
	    add_chain(part, chain);

	}
	else if (strcmp(key, "LINE") == 0) {
	    G_debug(4, "    LINE >");
	    elem = new_line();
	    add_element(chain, elem);
	    read_coor(fp, elem);

	}
	else if (strcmp(key, "ARC") == 0) {
	    G_debug(4, "    ARC");
	    ret =
		sscanf(data, "%lf %lf %lf %lf %lf %c", &x, &y, &rad, &ang1,
		       &ang2, &clock);
	    if (ret < 5) {
		sprintf(buf, "Incorrect arc definition: '%s'", buf);
		return (err(fp, symb, buf));
	    }
	    if (ret == 6 && (clock == 'c' || clock == 'C'))
		i = 1;
	    else
		i = 0;
	    elem = new_arc(x, y, rad, ang1, ang2, i);
	    add_element(chain, elem);

	}
	else if (strcmp(key, "END") == 0) {
	    switch (current) {
	    case OBJ_STRING:
		G_debug(4, "  STRING END");
		current = OBJ_NONE;
		break;
	    case OBJ_POLYGON:
		G_debug(4, "  POLYGON END");
		current = OBJ_NONE;
		break;
	    case OBJ_RING:
		G_debug(4, "  RING END");
		current = OBJ_POLYGON;
		break;
	    }
	}
	else if (strcmp(key, "COLOR") == 0) {
	    if (G_strcasecmp(data, "NONE") == 0) {
		part->color.color = S_COL_NONE;
	    }
	    else if (sscanf(data, "%d %d %d", &r, &g, &b) == 3) {
		if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
		    G_warning(_("Incorrect symbol color: '%s', using default."),
			      buf);
		else {
		    fr = r / 255.0;
		    fg = g / 255.0;
		    fb = b / 255.0;
		    part->color.color = S_COL_DEFINED;
		    part->color.r = r;
		    part->color.g = g;
		    part->color.b = b;
		    part->color.fr = fr;
		    part->color.fg = fg;
		    part->color.fb = fb;
		    G_debug(4, "  color [%d %d %d] = [%.3f %.3f %.3f]", r, g,
			    b, fr, fg, fb);
		}
	    }
	    else {
		G_warning(_("Incorrect symbol color: '%s', using default."),
			  buf);
	    }
	}
	else if (strcmp(key, "FCOLOR") == 0) {
	    if (G_strcasecmp(data, "NONE") == 0) {
		part->fcolor.color = S_COL_NONE;
	    }
	    else if (sscanf(data, "%d %d %d", &r, &g, &b) == 3) {
		if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
		    G_warning(_("Incorrect symbol color: '%s', using default."),
			      buf);
		else {
		    fr = r / 255.0;
		    fg = g / 255.0;
		    fb = b / 255.0;
		    part->fcolor.color = S_COL_DEFINED;
		    part->fcolor.r = r;
		    part->fcolor.g = g;
		    part->fcolor.b = b;
		    part->fcolor.fr = fr;
		    part->fcolor.fg = fg;
		    part->fcolor.fb = fb;
		    G_debug(4, "  color [%d %d %d] = [%.3f %.3f %.3f]", r, g,
			    b, fr, fg, fb);
		}
	    }
	    else {
		G_warning(_("Incorrect symbol color: '%s', using default."),
			  buf);
	    }
	}
	else {
	    sprintf(buf, "Unknown keyword in symbol: '%s'", buf);
	    return (err(fp, symb, buf));
	    break;
	}
    }

    /* Debug output */

    G_debug(3, "Number of parts: %d", symb->count);
    for (i = 0; i < symb->count; i++) {
	part = symb->part[i];
	G_debug(4, "  Part %d: type: %d number of chains: %d", i, part->type,
		part->count);
	G_debug(4, "           color: %d: fcolor: %d", part->color.color,
		part->fcolor.color);
	for (j = 0; j < part->count; j++) {
	    chain = part->chain[j];
	    G_debug(4, "    Chain %d: number of elements: %d", j,
		    chain->count);
	    for (k = 0; k < chain->count; k++) {
		elem = chain->elem[k];
		G_debug(4, "      Element %d: type: %d", k, elem->type);
		if (elem->type == S_LINE) {
		    G_debug(4, "        Number of points %d",
			    elem->coor.line.count);
		    for (l = 0; l < elem->coor.line.count; l++) {
			G_debug(4, "        x, y: %f %f",
				elem->coor.line.x[l], elem->coor.line.y[l]);
		    }
		}
		else {
		    G_debug(4, "        arc r = %f", elem->coor.arc.r);
		}
	    }
	}
    }

    fclose(fp);

    return symb;
}
Пример #13
0
static int read_dblinks_nat(struct Map_info *Map)
{
    FILE *fd;
    char file[1024], buf[2001];
    char tab[1024], col[1024], db[1024], drv[1024], fldstr[1024], *fldname;
    int fld;
    char *c, *path;
    int row, rule;
    struct dblinks *dbl;
    char **tokens;
    int ntok, i;

    dbl = Map->dblnk;

    /* Read dblink for native format */
    path = Vect__get_path(Map);
    fd = G_fopen_old(path, GV_DBLN_ELEMENT, Map->mapset);
    G_free(path);
    if (fd == NULL) {		/* This may be correct, no tables defined */
	G_debug(1, "Cannot open vector database definition file");
	return -1;
    }

    row = 0;
    rule = 0;
    while (G_getl2(buf, 2000, fd)) {
	row++;
	G_chop(buf);
	G_debug(1, "dbln: %s", buf);

	c = (char *)strchr(buf, '#');
	if (c != NULL)
	    *c = '\0';

	if (strlen(buf) == 0)
	    continue;

#ifdef NOT_ABLE_TO_READ_GRASS_6
	int ndef;
	ndef = sscanf(buf, "%s|%s|%s|%s|%s", fldstr, tab, col, db, drv);

        if (ndef < 2 || (ndef < 5 && rule < 1)) {
            G_warning(_("Error in rule on row %d in <%s>"), row, file);
            continue;
        }
#else
	tokens = G_tokenize(buf, " |");
	ntok = G_number_of_tokens(tokens);

	if (ntok < 2 || (ntok < 5 && rule < 1)) {
	    G_warning(_("Error in rule on row %d in <%s>"), row, file);
	    continue;
	}

	strcpy(fldstr, tokens[0]);
	strcpy(tab, tokens[1]);
	if (ntok > 2) {
	    strcpy(col, tokens[2]);
	    if (ntok > 3) {
		strcpy(db, tokens[3]);
		/* allow for spaces in path names */
		for (i=4; i < ntok-1; i++) {
		    strcat(db, " ");
		    strcat(db, tokens[i]);
		}

		strcpy(drv, tokens[ntok-1]);
	    }
	}
	G_free_tokens(tokens);
#endif

	/* get field and field name */
	fldname = strchr(fldstr, '/');
	if (fldname != NULL) {	/* field has name */
	    fldname[0] = 0;
	    fldname++;
	}
	fld = atoi(fldstr);

	Vect_add_dblink(dbl, fld, fldname, tab, col, db, drv);

	G_debug(1,
		"field = %d name = %s, table = %s, key = %s, database = %s, driver = %s",
		fld, fldname, tab, col, db, drv);

	rule++;
    }
    fclose(fd);

    G_debug(1, "Dblinks read");
    
    return rule;
}
Пример #14
0
int main(int argc, char *argv[])
{

    FILE *in_fp;
    int out_fd;
    char *infile, *outmap;
    int xcol, ycol, zcol, max_col, percent;
    int do_zfilter;
    int method = -1;
    int bin_n, bin_min, bin_max, bin_sum, bin_sumsq, bin_index;
    double zrange_min, zrange_max, d_tmp;
    char *fs;			/* field delim */
    off_t filesize;
    int linesize;
    long estimated_lines;
    int from_stdin;
    int can_seek;

    RASTER_MAP_TYPE rtype;
    struct History history;
    char title[64];
    void *n_array, *min_array, *max_array, *sum_array, *sumsq_array,
	*index_array;
    void *raster_row, *ptr;
    struct Cell_head region;
    int rows, cols;		/* scan box size */
    int row, col;		/* counters */

    int pass, npasses;
    unsigned long line;
    char buff[BUFFSIZE];
    double x, y, z;
    char **tokens;
    int ntokens;		/* number of tokens */
    double pass_north, pass_south;
    int arr_row, arr_col;
    unsigned long count, count_total;

    double min = 0.0 / 0.0;	/* init as nan */
    double max = 0.0 / 0.0;	/* init as nan */
    double zscale = 1.0;
    size_t offset, n_offset;
    int n = 0;
    double sum = 0.;
    double sumsq = 0.;
    double variance, mean, skew, sumdev;
    int pth = 0;
    double trim = 0.0;

    int j, k;
    int head_id, node_id;
    int r_low, r_up;

    struct GModule *module;
    struct Option *input_opt, *output_opt, *delim_opt, *percent_opt,
	*type_opt;
    struct Option *method_opt, *xcol_opt, *ycol_opt, *zcol_opt, *zrange_opt,
	*zscale_opt;
    struct Option *trim_opt, *pth_opt;
    struct Flag *scan_flag, *shell_style, *skipline;


    G_gisinit(argv[0]);

    module = G_define_module();
    module->keywords = _("raster, import, LIDAR");
    module->description =
	_("Create a raster map from an assemblage of many coordinates using univariate statistics.");

    input_opt = G_define_standard_option(G_OPT_F_INPUT);
    input_opt->description =
	_("ASCII file containing input data (or \"-\" to read from stdin)");

    output_opt = G_define_standard_option(G_OPT_R_OUTPUT);

    method_opt = G_define_option();
    method_opt->key = "method";
    method_opt->type = TYPE_STRING;
    method_opt->required = NO;
    method_opt->description = _("Statistic to use for raster values");
    method_opt->options =
	"n,min,max,range,sum,mean,stddev,variance,coeff_var,median,percentile,skewness,trimmean";
    method_opt->answer = "mean";
    method_opt->guisection = _("Statistic");

    type_opt = G_define_option();
    type_opt->key = "type";
    type_opt->type = TYPE_STRING;
    type_opt->required = NO;
    type_opt->options = "CELL,FCELL,DCELL";
    type_opt->answer = "FCELL";
    type_opt->description = _("Storage type for resultant raster map");

    delim_opt = G_define_standard_option(G_OPT_F_SEP);
    delim_opt->guisection = _("Input");

    xcol_opt = G_define_option();
    xcol_opt->key = "x";
    xcol_opt->type = TYPE_INTEGER;
    xcol_opt->required = NO;
    xcol_opt->answer = "1";
    xcol_opt->description =
	_("Column number of x coordinates in input file (first column is 1)");
    xcol_opt->guisection = _("Input");

    ycol_opt = G_define_option();
    ycol_opt->key = "y";
    ycol_opt->type = TYPE_INTEGER;
    ycol_opt->required = NO;
    ycol_opt->answer = "2";
    ycol_opt->description = _("Column number of y coordinates in input file");
    ycol_opt->guisection = _("Input");

    zcol_opt = G_define_option();
    zcol_opt->key = "z";
    zcol_opt->type = TYPE_INTEGER;
    zcol_opt->required = NO;
    zcol_opt->answer = "3";
    zcol_opt->description = _("Column number of data values in input file");
    zcol_opt->guisection = _("Input");

    zrange_opt = G_define_option();
    zrange_opt->key = "zrange";
    zrange_opt->type = TYPE_DOUBLE;
    zrange_opt->required = NO;
    zrange_opt->key_desc = "min,max";
    zrange_opt->description = _("Filter range for z data (min,max)");

    zscale_opt = G_define_option();
    zscale_opt->key = "zscale";
    zscale_opt->type = TYPE_DOUBLE;
    zscale_opt->required = NO;
    zscale_opt->answer = "1.0";
    zscale_opt->description = _("Scale to apply to z data");

    percent_opt = G_define_option();
    percent_opt->key = "percent";
    percent_opt->type = TYPE_INTEGER;
    percent_opt->required = NO;
    percent_opt->answer = "100";
    percent_opt->options = "1-100";
    percent_opt->description = _("Percent of map to keep in memory");

    pth_opt = G_define_option();
    pth_opt->key = "pth";
    pth_opt->type = TYPE_INTEGER;
    pth_opt->required = NO;
    pth_opt->options = "1-100";
    pth_opt->description = _("pth percentile of the values");
    pth_opt->guisection = _("Statistic");

    trim_opt = G_define_option();
    trim_opt->key = "trim";
    trim_opt->type = TYPE_DOUBLE;
    trim_opt->required = NO;
    trim_opt->options = "0-50";
    trim_opt->description =
	_("Discard <trim> percent of the smallest and <trim> percent of the largest observations");
    trim_opt->guisection = _("Statistic");

    scan_flag = G_define_flag();
    scan_flag->key = 's';
    scan_flag->description = _("Scan data file for extent then exit");

    shell_style = G_define_flag();
    shell_style->key = 'g';
    shell_style->description =
	_("In scan mode, print using shell script style");

    skipline = G_define_flag();
    skipline->key = 'i';
    skipline->description = _("Ignore broken lines");

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


    /* parse input values */
    infile = input_opt->answer;
    outmap = output_opt->answer;

    if (shell_style->answer && !scan_flag->answer) {
	scan_flag->answer = 1;
    }

    fs = delim_opt->answer;
    if (strcmp(fs, "\\t") == 0)
	fs = "\t";
    if (strcmp(fs, "tab") == 0)
	fs = "\t";
    if (strcmp(fs, "space") == 0)
	fs = " ";

    xcol = atoi(xcol_opt->answer);
    ycol = atoi(ycol_opt->answer);
    zcol = atoi(zcol_opt->answer);
    if ((xcol < 0) || (ycol < 0) || (zcol < 0))
	G_fatal_error(_("Please specify a reasonable column number."));
    max_col = (xcol > ycol) ? xcol : ycol;
    max_col = (zcol > max_col) ? zcol : max_col;

    percent = atoi(percent_opt->answer);
    zscale = atof(zscale_opt->answer);

    /* parse zrange */
    do_zfilter = FALSE;
    if (zrange_opt->answer != NULL) {
	if (zrange_opt->answers[0] == NULL)
	    G_fatal_error(_("Invalid zrange"));

	sscanf(zrange_opt->answers[0], "%lf", &zrange_min);
	sscanf(zrange_opt->answers[1], "%lf", &zrange_max);
	do_zfilter = TRUE;

	if (zrange_min > zrange_max) {
	    d_tmp = zrange_max;
	    zrange_max = zrange_min;
	    zrange_min = d_tmp;
	}
    }

    /* figure out what maps we need in memory */
    /*  n               n
       min              min
       max              max
       range            min max         max - min
       sum              sum
       mean             sum n           sum/n
       stddev           sum sumsq n     sqrt((sumsq - sum*sum/n)/n)
       variance         sum sumsq n     (sumsq - sum*sum/n)/n
       coeff_var        sum sumsq n     sqrt((sumsq - sum*sum/n)/n) / (sum/n)
       median           n               array index to linked list
       percentile       n               array index to linked list
       skewness         n               array index to linked list
       trimmean         n               array index to linked list
     */
    bin_n = FALSE;
    bin_min = FALSE;
    bin_max = FALSE;
    bin_sum = FALSE;
    bin_sumsq = FALSE;
    bin_index = FALSE;

    if (strcmp(method_opt->answer, "n") == 0) {
	method = METHOD_N;
	bin_n = TRUE;
    }
    if (strcmp(method_opt->answer, "min") == 0) {
	method = METHOD_MIN;
	bin_min = TRUE;
    }
    if (strcmp(method_opt->answer, "max") == 0) {
	method = METHOD_MAX;
	bin_max = TRUE;
    }
    if (strcmp(method_opt->answer, "range") == 0) {
	method = METHOD_RANGE;
	bin_min = TRUE;
	bin_max = TRUE;
    }
    if (strcmp(method_opt->answer, "sum") == 0) {
	method = METHOD_SUM;
	bin_sum = TRUE;
    }
    if (strcmp(method_opt->answer, "mean") == 0) {
	method = METHOD_MEAN;
	bin_sum = TRUE;
	bin_n = TRUE;
    }
    if (strcmp(method_opt->answer, "stddev") == 0) {
	method = METHOD_STDDEV;
	bin_sum = TRUE;
	bin_sumsq = TRUE;
	bin_n = TRUE;
    }
    if (strcmp(method_opt->answer, "variance") == 0) {
	method = METHOD_VARIANCE;
	bin_sum = TRUE;
	bin_sumsq = TRUE;
	bin_n = TRUE;
    }
    if (strcmp(method_opt->answer, "coeff_var") == 0) {
	method = METHOD_COEFF_VAR;
	bin_sum = TRUE;
	bin_sumsq = TRUE;
	bin_n = TRUE;
    }
    if (strcmp(method_opt->answer, "median") == 0) {
	method = METHOD_MEDIAN;
	bin_index = TRUE;
    }
    if (strcmp(method_opt->answer, "percentile") == 0) {
	if (pth_opt->answer != NULL)
	    pth = atoi(pth_opt->answer);
	else
	    G_fatal_error(_("Unable to calculate percentile without the pth option specified!"));
	method = METHOD_PERCENTILE;
	bin_index = TRUE;
    }
    if (strcmp(method_opt->answer, "skewness") == 0) {
	method = METHOD_SKEWNESS;
	bin_index = TRUE;
    }
    if (strcmp(method_opt->answer, "trimmean") == 0) {
	if (trim_opt->answer != NULL)
	    trim = atof(trim_opt->answer) / 100.0;
	else
	    G_fatal_error(_("Unable to calculate trimmed mean without the trim option specified!"));
	method = METHOD_TRIMMEAN;
	bin_index = TRUE;
    }

    if (strcmp("CELL", type_opt->answer) == 0)
	rtype = CELL_TYPE;
    else if (strcmp("DCELL", type_opt->answer) == 0)
	rtype = DCELL_TYPE;
    else
	rtype = FCELL_TYPE;

    if (method == METHOD_N)
	rtype = CELL_TYPE;


    G_get_window(&region);
    rows = (int)(region.rows * (percent / 100.0));
    cols = region.cols;

    G_debug(2, "region.n=%f  region.s=%f  region.ns_res=%f", region.north,
	    region.south, region.ns_res);
    G_debug(2, "region.rows=%d  [box_rows=%d]  region.cols=%d", region.rows,
	    rows, region.cols);

    npasses = (int)ceil(1.0 * region.rows / rows);

    if (!scan_flag->answer) {
	/* allocate memory (test for enough before we start) */
	if (bin_n)
	    n_array = G_calloc(rows * (cols + 1), G_raster_size(CELL_TYPE));
	if (bin_min)
	    min_array = G_calloc(rows * (cols + 1), G_raster_size(rtype));
	if (bin_max)
	    max_array = G_calloc(rows * (cols + 1), G_raster_size(rtype));
	if (bin_sum)
	    sum_array = G_calloc(rows * (cols + 1), G_raster_size(rtype));
	if (bin_sumsq)
	    sumsq_array = G_calloc(rows * (cols + 1), G_raster_size(rtype));
	if (bin_index)
	    index_array =
		G_calloc(rows * (cols + 1), G_raster_size(CELL_TYPE));

	/* and then free it again */
	if (bin_n)
	    G_free(n_array);
	if (bin_min)
	    G_free(min_array);
	if (bin_max)
	    G_free(max_array);
	if (bin_sum)
	    G_free(sum_array);
	if (bin_sumsq)
	    G_free(sumsq_array);
	if (bin_index)
	    G_free(index_array);

	/** end memory test **/
    }


    /* open input file */
    if (strcmp("-", infile) == 0) {
	from_stdin = TRUE;
	in_fp = stdin;
	infile = G_store("stdin");	/* filename for history metadata */
    }
    else {
	if ((in_fp = fopen(infile, "r")) == NULL)
	    G_fatal_error(_("Unable to open input file <%s>"), infile);
    }

    can_seek = fseek(in_fp, 0, SEEK_SET) == 0;

    /* can't rewind() non-files */
    if (!can_seek && npasses != 1) {
	G_warning(_("If input is not from a file it is only possible to perform a single pass."));
	npasses = 1;
    }

    if (scan_flag->answer) {
	if (zrange_opt->answer)
	    G_warning(_("zrange will not be taken into account during scan"));

	scan_bounds(in_fp, xcol, ycol, zcol, fs, shell_style->answer,
		    skipline->answer, zscale);

	if (!from_stdin)
	    fclose(in_fp);

	exit(EXIT_SUCCESS);
    }


    /* open output map */
    out_fd = G_open_raster_new(outmap, rtype);
    if (out_fd < 0)
	G_fatal_error(_("Unable to create raster map <%s>"), outmap);

    if (can_seek) {
	/* guess at number of lines in the file without actually reading it all in */
	for (line = 0; line < 10; line++) {	/* arbitrarily use 10th line for guess */
	    if (0 == G_getl2(buff, BUFFSIZE - 1, in_fp))
		break;
	    linesize = strlen(buff) + 1;
	}
	fseek(in_fp, 0L, SEEK_END);
	filesize = ftell(in_fp);
	rewind(in_fp);
	if (linesize < 6)	/* min possible: "0,0,0\n" */
	    linesize = 6;
	estimated_lines = filesize / linesize;
	G_debug(2, "estimated number of lines in file: %ld", estimated_lines);
    }
    else
	estimated_lines = -1;

    /* allocate memory for a single row of output data */
    raster_row = G_allocate_raster_buf(rtype);

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

    count_total = 0;

    /* main binning loop(s) */
    for (pass = 1; pass <= npasses; pass++) {
	if (npasses > 1)
	    G_message(_("Pass #%d (of %d) ..."), pass, npasses);

	if (can_seek)
	    rewind(in_fp);

	/* figure out segmentation */
	pass_north = region.north - (pass - 1) * rows * region.ns_res;
	if (pass == npasses)
	    rows = region.rows - (pass - 1) * rows;
	pass_south = pass_north - rows * region.ns_res;

	G_debug(2, "pass=%d/%d  pass_n=%f  pass_s=%f  rows=%d",
		pass, npasses, pass_north, pass_south, rows);


	if (bin_n) {
	    G_debug(2, "allocating n_array");
	    n_array = G_calloc(rows * (cols + 1), G_raster_size(CELL_TYPE));
	    blank_array(n_array, rows, cols, CELL_TYPE, 0);
	}
	if (bin_min) {
	    G_debug(2, "allocating min_array");
	    min_array = G_calloc(rows * (cols + 1), G_raster_size(rtype));
	    blank_array(min_array, rows, cols, rtype, -1);	/* fill with NULLs */
	}
	if (bin_max) {
	    G_debug(2, "allocating max_array");
	    max_array = G_calloc(rows * (cols + 1), G_raster_size(rtype));
	    blank_array(max_array, rows, cols, rtype, -1);	/* fill with NULLs */
	}
	if (bin_sum) {
	    G_debug(2, "allocating sum_array");
	    sum_array = G_calloc(rows * (cols + 1), G_raster_size(rtype));
	    blank_array(sum_array, rows, cols, rtype, 0);
	}
	if (bin_sumsq) {
	    G_debug(2, "allocating sumsq_array");
	    sumsq_array = G_calloc(rows * (cols + 1), G_raster_size(rtype));
	    blank_array(sumsq_array, rows, cols, rtype, 0);
	}
	if (bin_index) {
	    G_debug(2, "allocating index_array");
	    index_array =
		G_calloc(rows * (cols + 1), G_raster_size(CELL_TYPE));
	    blank_array(index_array, rows, cols, CELL_TYPE, -1);	/* fill with NULLs */
	}

	line = 0;
	count = 0;
	G_percent_reset();

	while (0 != G_getl2(buff, BUFFSIZE - 1, in_fp)) {
	    line++;

	    if (line % 10000 == 0) {	/* mod for speed */
		if (!can_seek)
		    G_clicker();
		else if (line < estimated_lines)
		    G_percent(line, estimated_lines, 3);
	    }

	    if ((buff[0] == '#') || (buff[0] == '\0')) {
		continue;	/* line is a comment or blank */
	    }

	    G_chop(buff);	/* remove leading and trailing whitespace from the string.  unneded?? */
	    tokens = G_tokenize(buff, fs);
	    ntokens = G_number_of_tokens(tokens);

	    if ((ntokens < 3) || (max_col > ntokens)) {
		if (skipline->answer) {
		    G_warning(_("Not enough data columns. "
				"Incorrect delimiter or column number? "
				"Found the following character(s) in row %lu:\n[%s]"),
			      line, buff);
		    G_warning(_("Line ignored as requested"));
		    continue;	/* line is garbage */
		}
		else {
		    G_fatal_error(_("Not enough data columns. "
				    "Incorrect delimiter or column number? "
				    "Found the following character(s) in row %lu:\n[%s]"),
				  line, buff);
		}
	    }

	    /* too slow?
	       if ( G_projection() == PROJECTION_LL ) {
	       G_scan_easting( tokens[xcol-1], &x, region.proj);
	       G_scan_northing( tokens[ycol-1], &y, region.proj);
	       }
	       else {
	     */
	    if (1 != sscanf(tokens[ycol - 1], "%lf", &y))
		G_fatal_error(_("Bad y-coordinate line %lu column %d. <%s>"),
			      line, ycol, tokens[ycol - 1]);
	    if (y <= pass_south || y > pass_north) {
		G_free_tokens(tokens);
		continue;
	    }
	    if (1 != sscanf(tokens[xcol - 1], "%lf", &x))
		G_fatal_error(_("Bad x-coordinate line %lu column %d. <%s>"),
			      line, xcol, tokens[xcol - 1]);
	    if (x < region.west || x > region.east) {
		G_free_tokens(tokens);
		continue;
	    }
	    if (1 != sscanf(tokens[zcol - 1], "%lf", &z))
		G_fatal_error(_("Bad z-coordinate line %lu column %d. <%s>"),
			      line, zcol, tokens[zcol - 1]);

	    z = z * zscale;

	    if (zrange_opt->answer) {
		if (z < zrange_min || z > zrange_max) {
		    G_free_tokens(tokens);
		    continue;
		}
	    }

	    count++;
	    /*          G_debug(5, "x: %f, y: %f, z: %f", x, y, z); */
	    G_free_tokens(tokens);

	    /* find the bin in the current array box */
	    arr_row = (int)((pass_north - y) / region.ns_res);
	    arr_col = (int)((x - region.west) / region.ew_res);

	    /*          G_debug(5, "arr_row: %d   arr_col: %d", arr_row, arr_col); */

	    /* The range should be [0,cols-1]. We use (int) to round down,
	       but if the point exactly on eastern edge arr_col will be /just/
	       on the max edge .0000000 and end up on the next row.
	       We could make above bounds check "if(x>=region.east) continue;"
	       But instead we go to all sorts of trouble so that not one single
	       data point is lost. GE is too small to catch them all.
	       We don't try to make y happy as percent segmenting will make some
	       points happen twice that way; so instead we use the y<= test above.
	     */
	    if (arr_col >= cols) {
		if (((x - region.west) / region.ew_res) - cols <
		    10 * GRASS_EPSILON)
		    arr_col--;
		else {		/* oh well, we tried. */
		    G_debug(3,
			    "skipping extraneous data point [%.3f], column %d of %d",
			    x, arr_col, cols);
		    continue;
		}
	    }

	    if (bin_n)
		update_n(n_array, cols, arr_row, arr_col);
	    if (bin_min)
		update_min(min_array, cols, arr_row, arr_col, rtype, z);
	    if (bin_max)
		update_max(max_array, cols, arr_row, arr_col, rtype, z);
	    if (bin_sum)
		update_sum(sum_array, cols, arr_row, arr_col, rtype, z);
	    if (bin_sumsq)
		update_sumsq(sumsq_array, cols, arr_row, arr_col, rtype, z);
	    if (bin_index) {
		ptr = index_array;
		ptr =
		    G_incr_void_ptr(ptr,
				    ((arr_row * cols) +
				     arr_col) * G_raster_size(CELL_TYPE));

		if (G_is_null_value(ptr, CELL_TYPE)) {	/* first node */
		    head_id = new_node();
		    nodes[head_id].next = -1;
		    nodes[head_id].z = z;
		    G_set_raster_value_c(ptr, head_id, CELL_TYPE);	/* store index to head */
		}
		else {		/* head is already there */

		    head_id = G_get_raster_value_c(ptr, CELL_TYPE);	/* get index to head */
		    head_id = add_node(head_id, z);
		    if (head_id != -1)
			G_set_raster_value_c(ptr, head_id, CELL_TYPE);	/* store index to head */
		}
	    }
	}			/* while !EOF */

	G_percent(1, 1, 1);	/* flush */
	G_debug(2, "pass %d finished, %lu coordinates in box", pass, count);
	count_total += count;


	/* calc stats and output */
	G_message(_("Writing to map ..."));
	for (row = 0; row < rows; row++) {

	    switch (method) {
	    case METHOD_N:	/* n is a straight copy */
		G_raster_cpy(raster_row,
			     n_array +
			     (row * cols * G_raster_size(CELL_TYPE)), cols,
			     CELL_TYPE);
		break;

	    case METHOD_MIN:
		G_raster_cpy(raster_row,
			     min_array + (row * cols * G_raster_size(rtype)),
			     cols, rtype);
		break;

	    case METHOD_MAX:
		G_raster_cpy(raster_row,
			     max_array + (row * cols * G_raster_size(rtype)),
			     cols, rtype);
		break;

	    case METHOD_SUM:
		G_raster_cpy(raster_row,
			     sum_array + (row * cols * G_raster_size(rtype)),
			     cols, rtype);
		break;

	    case METHOD_RANGE:	/* (max-min) */
		ptr = raster_row;
		for (col = 0; col < cols; col++) {
		    offset = (row * cols + col) * G_raster_size(rtype);
		    min = G_get_raster_value_d(min_array + offset, rtype);
		    max = G_get_raster_value_d(max_array + offset, rtype);
		    G_set_raster_value_d(ptr, max - min, rtype);
		    ptr = G_incr_void_ptr(ptr, G_raster_size(rtype));
		}
		break;

	    case METHOD_MEAN:	/* (sum / n) */
		ptr = raster_row;
		for (col = 0; col < cols; col++) {
		    offset = (row * cols + col) * G_raster_size(rtype);
		    n_offset = (row * cols + col) * G_raster_size(CELL_TYPE);
		    n = G_get_raster_value_c(n_array + n_offset, CELL_TYPE);
		    sum = G_get_raster_value_d(sum_array + offset, rtype);

		    if (n == 0)
			G_set_null_value(ptr, 1, rtype);
		    else
			G_set_raster_value_d(ptr, (sum / n), rtype);

		    ptr = G_incr_void_ptr(ptr, G_raster_size(rtype));
		}
		break;

	    case METHOD_STDDEV:	/*  sqrt(variance)        */
	    case METHOD_VARIANCE:	/*  (sumsq - sum*sum/n)/n */
	    case METHOD_COEFF_VAR:	/*  100 * stdev / mean    */
		ptr = raster_row;
		for (col = 0; col < cols; col++) {
		    offset = (row * cols + col) * G_raster_size(rtype);
		    n_offset = (row * cols + col) * G_raster_size(CELL_TYPE);
		    n = G_get_raster_value_c(n_array + n_offset, CELL_TYPE);
		    sum = G_get_raster_value_d(sum_array + offset, rtype);
		    sumsq = G_get_raster_value_d(sumsq_array + offset, rtype);

		    if (n == 0)
			G_set_null_value(ptr, 1, rtype);
		    else {
			variance = (sumsq - sum * sum / n) / n;
			if (variance < GRASS_EPSILON)
			    variance = 0.0;

			if (method == METHOD_STDDEV)
			    G_set_raster_value_d(ptr, sqrt(variance), rtype);

			else if (method == METHOD_VARIANCE)
			    G_set_raster_value_d(ptr, variance, rtype);

			else if (method == METHOD_COEFF_VAR)
			    G_set_raster_value_d(ptr,
						 100 * sqrt(variance) / (sum /
									 n),
						 rtype);

		    }
		    ptr = G_incr_void_ptr(ptr, G_raster_size(rtype));
		}
		break;
	    case METHOD_MEDIAN:	/* median, if only one point in cell we will use that */
		ptr = raster_row;
		for (col = 0; col < cols; col++) {
		    n_offset = (row * cols + col) * G_raster_size(CELL_TYPE);
		    if (G_is_null_value(index_array + n_offset, CELL_TYPE))	/* no points in cell */
			G_set_null_value(ptr, 1, rtype);
		    else {	/* one or more points in cell */

			head_id =
			    G_get_raster_value_c(index_array + n_offset,
						 CELL_TYPE);
			node_id = head_id;

			n = 0;

			while (node_id != -1) {	/* count number of points in cell */
			    n++;
			    node_id = nodes[node_id].next;
			}

			if (n == 1)	/* only one point, use that */
			    G_set_raster_value_d(ptr, nodes[head_id].z,
						 rtype);
			else if (n % 2 != 0) {	/* odd number of points: median_i = (n + 1) / 2 */
			    n = (n + 1) / 2;
			    node_id = head_id;
			    for (j = 1; j < n; j++)	/* get "median element" */
				node_id = nodes[node_id].next;

			    G_set_raster_value_d(ptr, nodes[node_id].z,
						 rtype);
			}
			else {	/* even number of points: median = (val_below + val_above) / 2 */

			    z = (n + 1) / 2.0;
			    n = floor(z);
			    node_id = head_id;
			    for (j = 1; j < n; j++)	/* get element "below" */
				node_id = nodes[node_id].next;

			    z = (nodes[node_id].z +
				 nodes[nodes[node_id].next].z) / 2;
			    G_set_raster_value_d(ptr, z, rtype);
			}
		    }
		    ptr = G_incr_void_ptr(ptr, G_raster_size(rtype));
		}
		break;
	    case METHOD_PERCENTILE:	/* rank = (pth*(n+1))/100; interpolate linearly */
		ptr = raster_row;
		for (col = 0; col < cols; col++) {
		    n_offset = (row * cols + col) * G_raster_size(CELL_TYPE);
		    if (G_is_null_value(index_array + n_offset, CELL_TYPE))	/* no points in cell */
			G_set_null_value(ptr, 1, rtype);
		    else {
			head_id =
			    G_get_raster_value_c(index_array + n_offset,
						 CELL_TYPE);
			node_id = head_id;
			n = 0;

			while (node_id != -1) {	/* count number of points in cell */
			    n++;
			    node_id = nodes[node_id].next;
			}

			z = (pth * (n + 1)) / 100.0;
			r_low = floor(z);	/* lower rank */
			if (r_low < 1)
			    r_low = 1;
			else if (r_low > n)
			    r_low = n;

			r_up = ceil(z);	/* upper rank */
			if (r_up > n)
			    r_up = n;

			node_id = head_id;
			for (j = 1; j < r_low; j++)	/* search lower value */
			    node_id = nodes[node_id].next;

			z = nodes[node_id].z;	/* save lower value */
			node_id = head_id;
			for (j = 1; j < r_up; j++)	/* search upper value */
			    node_id = nodes[node_id].next;

			z = (z + nodes[node_id].z) / 2;
			G_set_raster_value_d(ptr, z, rtype);
		    }
		    ptr = G_incr_void_ptr(ptr, G_raster_size(rtype));
		}
		break;
	    case METHOD_SKEWNESS:	/* skewness = sum(xi-mean)^3/(N-1)*s^3 */
		ptr = raster_row;
		for (col = 0; col < cols; col++) {
		    n_offset = (row * cols + col) * G_raster_size(CELL_TYPE);
		    if (G_is_null_value(index_array + n_offset, CELL_TYPE))	/* no points in cell */
			G_set_null_value(ptr, 1, rtype);
		    else {
			head_id =
			    G_get_raster_value_c(index_array + n_offset,
						 CELL_TYPE);
			node_id = head_id;

			n = 0;	/* count */
			sum = 0.0;	/* sum */
			sumsq = 0.0;	/* sum of squares */
			sumdev = 0.0;	/* sum of (xi - mean)^3 */
			skew = 0.0;	/* skewness */

			while (node_id != -1) {
			    z = nodes[node_id].z;
			    n++;
			    sum += z;
			    sumsq += (z * z);
			    node_id = nodes[node_id].next;
			}

			if (n > 1) {	/* if n == 1, skew is "0.0" */
			    mean = sum / n;
			    node_id = head_id;
			    while (node_id != -1) {
				z = nodes[node_id].z;
				sumdev += pow((z - mean), 3);
				node_id = nodes[node_id].next;
			    }

			    variance = (sumsq - sum * sum / n) / n;
			    if (variance < GRASS_EPSILON)
				skew = 0.0;
			    else
				skew =
				    sumdev / ((n - 1) *
					      pow(sqrt(variance), 3));
			}
			G_set_raster_value_d(ptr, skew, rtype);
		    }
		    ptr = G_incr_void_ptr(ptr, G_raster_size(rtype));
		}
		break;
	    case METHOD_TRIMMEAN:
		ptr = raster_row;
		for (col = 0; col < cols; col++) {
		    n_offset = (row * cols + col) * G_raster_size(CELL_TYPE);
		    if (G_is_null_value(index_array + n_offset, CELL_TYPE))	/* no points in cell */
			G_set_null_value(ptr, 1, rtype);
		    else {
			head_id =
			    G_get_raster_value_c(index_array + n_offset,
						 CELL_TYPE);

			node_id = head_id;
			n = 0;
			while (node_id != -1) {	/* count number of points in cell */
			    n++;
			    node_id = nodes[node_id].next;
			}

			if (1 == n)
			    mean = nodes[head_id].z;
			else {
			    k = floor(trim * n + 0.5);	/* number of ranks to discard on each tail */

			    if (k > 0 && (n - 2 * k) > 0) {	/* enough elements to discard */
				node_id = head_id;
				for (j = 0; j < k; j++)	/* move to first rank to consider */
				    node_id = nodes[node_id].next;

				j = k + 1;
				k = n - k;
				n = 0;
				sum = 0.0;

				while (j <= k) {	/* get values in interval */
				    n++;
				    sum += nodes[node_id].z;
				    node_id = nodes[node_id].next;
				    j++;
				}
			    }
			    else {
				node_id = head_id;
				n = 0;
				sum = 0.0;
				while (node_id != -1) {
				    n++;
				    sum += nodes[node_id].z;
				    node_id = nodes[node_id].next;
				}
			    }
			    mean = sum / n;
			}
			G_set_raster_value_d(ptr, mean, rtype);
		    }
		    ptr = G_incr_void_ptr(ptr, G_raster_size(rtype));
		}
		break;

	    default:
		G_fatal_error("?");
	    }

	    /* write out line of raster data */
	    if (1 != G_put_raster_row(out_fd, raster_row, rtype)) {
		G_close_cell(out_fd);
		G_fatal_error(_("Writing map, row %d"),
			      ((pass - 1) * rows) + row);
	    }
	}

	/* free memory */
	if (bin_n)
	    G_free(n_array);
	if (bin_min)
	    G_free(min_array);
	if (bin_max)
	    G_free(max_array);
	if (bin_sum)
	    G_free(sum_array);
	if (bin_sumsq)
	    G_free(sumsq_array);
	if (bin_index) {
	    G_free(index_array);
	    G_free(nodes);
	    num_nodes = 0;
	    max_nodes = 0;
	    nodes = NULL;
	}

    }				/* passes loop */

    G_percent(1, 1, 1);		/* flush */
    G_free(raster_row);

    /* close input file */
    if (!from_stdin)
	fclose(in_fp);

    /* close raster file & write history */
    G_close_cell(out_fd);

    sprintf(title, "Raw x,y,z data binned into a raster grid by cell %s",
	    method_opt->answer);
    G_put_cell_title(outmap, title);

    G_short_history(outmap, "raster", &history);
    G_command_history(&history);
    strncpy(history.datsrc_1, infile, RECORD_LEN);
    history.datsrc_1[RECORD_LEN - 1] = '\0';	/* strncpy() doesn't null terminate if maxfill */
    G_write_history(outmap, &history);


    sprintf(buff, _("%lu points found in region."), count_total);
    G_done_msg(buff);
    G_debug(1, "Processed %lu lines.", line);

    exit(EXIT_SUCCESS);

}
Пример #15
0
int read_rules(const char *filename)
{
    char buf[1024];
    DCELL dLow, dHigh;
    CELL iLow, iHigh;
    int line, n, nrules = 0;
    int first = 1;
    DCELL dmin, dmax;
    CELL cmin, cmax;
    FILE *fp;

    if (strcmp(filename, "-") == 0)
        fp = stdin;
    else {
        fp = fopen(filename, "r");
        if (!fp)
            G_fatal_error(_("unable to open input file <%s>"), filename);
    }

    read_range();
    report_range();
    if (isatty(fileno(fp)))
        fprintf(stderr, _("\nEnter the rule or 'help' for the format description or 'end' to exit:\n"));
    Rast_quant_init(&quant_struct);
    for (line = 1;; line++) {
        if (isatty(fileno(fp)))
            fprintf(stderr, "> ");
        if (!G_getl2(buf, sizeof(buf), fp))
            break;
        for (n = 0; buf[n]; n++)
            if (buf[n] == ',')
                buf[n] = ' ';
        G_strip(buf);
        G_chop(buf);
        if (*buf == 0)
            continue;
        if (*buf == '#')
            continue;
        if (strcmp(buf, "end") == 0) {
            if (nrules == 0)
                break;		/* if no new rules have been specified */

            /* give warning when quant rules do not cover the whole range of map */
            Rast_quant_get_limits(&quant_struct, &dmin, &dmax, &cmin, &cmax);
            if ((dmin > old_dmin || dmax < old_dmax) && !first)
                G_warning(_("quant rules do not cover the whole range map"));
            break;
        }

        if (strcmp(buf, "help") == 0) {
            fprintf(stderr,
                    "Enter a rule in one of these formats:\n"
                    "float_low:float_high:int_low:int_high\n"
                    "float_low:float_high:int_val  (i.e. int_high == int_low)\n"
                    "*:float_val:int_val           (interval [inf, float_val])\n"
                    "float_val:*:int_val           (interval [float_val, inf])\n");
        }

        /* we read and record into quant table all values, even int as doubles
           we convert the range and domain values to the right format when we
           lookup the values in the quant table */
        switch (sscanf(buf, "%lf:%lf:%d:%d", &dLow, &dHigh, &iLow, &iHigh)) {
        case 3:
            Rast_quant_add_rule(&quant_struct, dLow, dHigh, iLow, iLow);
            nrules++;
            first = 0;
            break;

        case 4:
            Rast_quant_add_rule(&quant_struct, dLow, dHigh, iLow, iHigh);
            nrules++;
            first = 0;
            break;

        default:
            if (sscanf(buf, "%lf:*:%d", &dLow, &iLow) == 2) {
                Rast_quant_set_pos_infinite_rule(&quant_struct, dLow, iLow);
                nrules++;
                first = 0;
            }

            else if (sscanf(buf, "*:%lf:%d", &dHigh, &iLow) == 2) {
                Rast_quant_set_neg_infinite_rule(&quant_struct, dHigh, iLow);
                nrules++;
                first = 0;
            }

            else if (strcmp(buf, "help") == 0)
                break;

            else
                G_warning(_("%s is not a valid rule"), buf);
            break;
        }			/* switch */
    }				/* loop */

    if (fp != stdin)
        fclose(fp);

    return nrules;
}
Пример #16
0
int read_vpoints(char *name, char *mapset)
{
    char fullname[100];
    char buf[1024];
    char *key, *data;
    double width, size, scale, rotate;
    int itmp, vec;
    int r, g, b;
    int ret;
    struct Map_info Map;

    vector_alloc();		/* allocate space */

    sprintf(fullname, "%s in %s", name, mapset);

    Vect_set_open_level(2);
    Vect_set_fatal_error(GV_FATAL_PRINT);
    if (2 > Vect_open_old(&Map, name, mapset)) {
	error(fullname, "", "can't open vector map");
	gobble_input();
	return 0;
    }
    Vect_close(&Map);

    vec = vector.count;

    vector.layer[vec].type = VPOINTS;
    vector.layer[vec].name = G_store(name);
    vector.layer[vec].mapset = G_store(mapset);
    vector.layer[vec].ltype = GV_POINT;
    vector.layer[vec].masked = 0;

    vector.layer[vec].field = 1;
    vector.layer[vec].cats = NULL;
    vector.layer[vec].where = NULL;

    vector.layer[vec].width = 1.;
    set_color(&(vector.layer[vec].color), 0, 0, 0);
    set_color(&(vector.layer[vec].fcolor), 255, 0, 0);
    vector.layer[vec].rgbcol = NULL;

    vector.layer[vec].label = NULL;
    vector.layer[vec].lpos = -1;
    vector.layer[vec].symbol = G_store("basic/diamond");

    vector.layer[vec].size = 6.0;
    vector.layer[vec].sizecol = NULL;
    vector.layer[vec].scale = 1.0;

    vector.layer[vec].rotate = 0.0;
    vector.layer[vec].rotcol = NULL;
    vector.layer[vec].epstype = 0;


    while (input(2, buf, help)) {
	if (!key_data(buf, &key, &data))
	    continue;

	if (KEY("masked")) {
	    vector.layer[vec].masked = yesno(key, data);
	    if (vector.layer[vec].masked)
		PS.mask_needed = 1;
	    continue;
	}

	if (KEY("type")) {
	    G_strip(data);
	    vector.layer[vec].ltype = 0;

	    if (strstr(data, "point"))
		vector.layer[vec].ltype |= GV_POINT;

	    if (strstr(data, "centroid"))
		vector.layer[vec].ltype |= GV_CENTROID;

	    continue;
	}

	if (KEY("layer")) {
	    G_strip(data);
	    vector.layer[vec].field = atoi(data);
	    continue;
	}

	if (KEY("cats")) {
	    G_strip(data);
	    vector.layer[vec].cats = G_store(data);
	    continue;
	}

	if (KEY("where")) {
	    G_strip(data);
	    vector.layer[vec].where = G_store(data);
	    continue;
	}

	if (KEY("width")) {
	    width = -1.;
	    *mapset = 0;
	    if (sscanf(data, "%lf%s", &width, mapset) < 1 || width < 0.) {
		width = 1.;
		error(key, data, "illegal width (vpoints)");
		continue;
	    }
	    if (mapset[0] == 'i')
		width = width / 72.;
	    vector.layer[vec].width = width;
	    continue;
	}

	if (KEY("color")) {
	    ret = G_str_to_color(data, &r, &g, &b);
	    if (ret == 1)
		set_color(&(vector.layer[vec].color), r, g, b);
	    else if (ret == 2)
		unset_color(&(vector.layer[vec].color));
	    else
		error(key, data, "illegal color request");

	    continue;
	}

	if (KEY("fcolor")) {	/* fill color */
	    ret = G_str_to_color(data, &r, &g, &b);
	    if (ret == 1)
		set_color(&(vector.layer[vec].fcolor), r, g, b);
	    else if (ret == 2)
		unset_color(&(vector.layer[vec].fcolor));
	    else
		error(key, data, "illegal color request (vpoints)");

	    continue;
	}

	if (KEY("rgbcolumn")) {
	    G_strip(data);
	    vector.layer[vec].rgbcol = G_store(data);
	    continue;
	}

	if (KEY("label")) {	/* map legend label */
	    G_strip(data);
	    vector.layer[vec].label = G_store(data);
	    continue;
	}

	if (KEY("lpos")) {
	    if (sscanf(data, "%d", &itmp) < 1 || itmp < 0) {
		itmp = -1;
		error(key, data, "illegal lpos");
		continue;
	    }
	    vector.layer[vec].lpos = itmp;
	    continue;
	}

	if (KEY("symbol")) {
	    /* TODO: test here if isymbol exists */
	    vector.layer[vec].symbol = G_store(data);
	    continue;
	}

	if (KEY("eps")) {
	    char *cc;

	    G_chop(data);
	    vector.layer[vec].epspre = G_store(data);

	    /* epstype: 0 - no eps, 1 - common eps, 2 - eps for each category */
	    vector.layer[vec].epstype = 1;

	    /* find dynamic filename by cat number character */
	    /* pre is filename before the $, suf is filename after the $ */
	    cc = (char *)strchr(vector.layer[vec].epspre, '$');
	    if (cc != NULL) {
		*cc = '\0';
		vector.layer[vec].epssuf = G_store(cc + sizeof(char));
		vector.layer[vec].epstype = 2;

		G_debug(2, "epstype=%d, pre=[%s], suf=[%s]",
			vector.layer[vec].epstype, vector.layer[vec].epspre,
			vector.layer[vec].epssuf);
	    }
	    else {
		G_debug(2, "epstype=%d, eps file=[%s]",
			vector.layer[vec].epstype, vector.layer[vec].epspre);
	    }
	    continue;
	}

	if (KEY("size")) {
	    if (sscanf(data, "%lf", &size) != 1 || size <= 0.0) {
		size = 1.0;
		error(key, data, "illegal size request (vpoints)");
	    }
	    vector.layer[vec].size = size;
	    continue;
	}

	/* 
	   GRASS 6.3: sizecol renamed to sizecolumn
	   remove sizecol test and the warning in GRASS7
	 */
	if (KEY("sizecol")) {
	    G_warning(_("The mapping instruction <%s> will be renamed to <%s> "
		       "in future versions of GRASS. Please use <%s> instead."),
		      "sizecol", "sizecolumn", "sizecolumn");
	}
	if (KEY("sizecol") || KEY("sizecolumn")) {
	    G_strip(data);
	    vector.layer[vec].sizecol = G_store(data);
	    continue;
	}

	if (KEY("scale")) {
	    if (sscanf(data, "%lf", &scale) != 1 || scale <= 0.0) {
		scale = 1.0;
		error(key, data, "illegal scale request (vpoints)");
	    }
	    vector.layer[vec].scale = scale;
	    continue;
	}

	if (KEY("rotate")) {
	    if (sscanf(data, "%lf", &rotate) != 1) {
		rotate = 0.0;
		error(key, data, "illegal rotation request (vpoints)");
	    }
	    vector.layer[vec].rotate = rotate;
	    continue;
	}

	if (KEY("rotatecolumn")) {
	    G_strip(data);
	    vector.layer[vec].rotcol = G_store(data);
	    continue;
	}

	error(key, "", "illegal request (vpoints)");
    }

    vector.count++;
    return 1;
}
Пример #17
0
/*!
  \brief Read data in GRASS ASCII vector format

  \param ascii    pointer to the input ASCII file
  \param[out] Map pointer to the output Map_info structure

  \return number of read features
  \return -1 on error
*/
int Vect_read_ascii(FILE *ascii, struct Map_info *Map)
{
    char ctype;
    char buff[BUFFSIZE];
    char east_str[256], north_str[256];
    double *xarray;
    double *yarray;
    double *zarray;
    double *x, *y, *z;
    int i, n_points, n_coors, n_cats, n_lines;
    int type, with_z, skip_feat, nskipped_3d;
    int alloc_points;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int catn, cat;

    /* Must always use this to create an initialized  line_pnts structure */
    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    /*alloc_points     = 1000 ; */
    alloc_points = 1;
    xarray = (double *)G_calloc(alloc_points, sizeof(double));
    yarray = (double *)G_calloc(alloc_points, sizeof(double));
    zarray = (double *)G_calloc(alloc_points, sizeof(double));

    n_lines = nskipped_3d = 0;

    with_z = Vect_is_3d(Map);

    while (G_getl2(buff, BUFFSIZE - 1, ascii) != 0) {
	n_cats = 0;
        skip_feat = FALSE;
	if (buff[0] == '\0') {
	    G_debug(3, "a2b: skipping blank line");
	    continue;
	}

	if (sscanf(buff, "%1c%d%d", &ctype, &n_coors, &n_cats) < 2 ||
	    n_coors < 0 || n_cats < 0) {
	    if (ctype == '#') {
		G_debug(2, "a2b: skipping commented line");
		continue;
	    }
	    G_warning(_("Error reading ASCII file: (bad type) [%s]"),
                      buff);
            return -1;
	}
	if (ctype == '#') {
	    G_debug(2, "a2b: Skipping commented line");
	    continue;
	}

	switch (ctype) {
	case 'A':
	    type = GV_BOUNDARY;
	    break;
	case 'B':
	    type = GV_BOUNDARY;
	    break;
	case 'C':
	    type = GV_CENTROID;
	    break;
	case 'L':
	    type = GV_LINE;
	    break;
	case 'P':
	    type = GV_POINT;
	    break;
	case 'F':
	    type = GV_FACE;
	    break;
	case 'K':
	    type = GV_KERNEL;
	    break;
	case 'a':
	case 'b':
	case 'c':
	case 'l':
	case 'p':
	    type = 0;		/* dead -> ignore */
	    break;
	default: {
	    G_warning(_("Error reading ASCII file: (unknown type) [%s]"),
                      buff);
            return -1;
        }
	}
	G_debug(5, "feature type = %d", type);
        
        if ((type & (GV_FACE | GV_KERNEL)) && !with_z) {
            skip_feat = TRUE;
            nskipped_3d++;
        }
        
	n_points = 0;
	x = xarray;
	y = yarray;
	z = zarray;

	/* Collect the points */
	for (i = 0; i < n_coors; i++) {
	    if (G_getl2(buff, BUFFSIZE - 1, ascii) == 0) {
		G_warning(_("End of ASCII file reached before end of coordinates"));
                return -1;
            }
	    if (buff[0] == '\0') {
		G_debug(3, "a2b: skipping blank line while reading vertices");
		i--;
		continue;
	    }

	    *z = 0;
	    if (sscanf(buff, "%lf%lf%lf", x, y, z) < 2) {
		if (sscanf(buff, " %s %s %lf", east_str, north_str, z) < 2) {
		    G_warning(_("Error reading ASCII file: (bad point) [%s]"),
                              buff);
                    return -1;
		} else {
		    if (!G_scan_easting(east_str, x, G_projection())) {
			G_warning(_("Unparsable longitude value: [%s]"),
                                  east_str);
                        return -1;
                    }
		    if (!G_scan_northing(north_str, y, G_projection())) {
			G_warning(_("Unparsable latitude value: [%s]"),
                                  north_str);
                        return -1;
                    }
		}
	    }

	    G_debug(5, "coor in: %s -> x = %f y = %f z = %f", G_chop(buff),
		    *x, *y, *z);

	    n_points++;
	    x++;
	    y++;
	    z++;

	    if (n_points >= alloc_points) {
		alloc_points = n_points + 1000;
		xarray =
		    (double *)G_realloc((void *)xarray,
					alloc_points * sizeof(double));
		yarray =
		    (double *)G_realloc((void *)yarray,
					alloc_points * sizeof(double));
		zarray =
		    (double *)G_realloc((void *)zarray,
					alloc_points * sizeof(double));
		x = xarray + n_points;
		y = yarray + n_points;
		z = zarray + n_points;
	    }
	}

	/* Collect the cats */
	Vect_reset_cats(Cats);
	for (i = 0; i < n_cats; i++) {
	    if (G_getl2(buff, BUFFSIZE - 1, ascii) == 0) {
		G_warning(_("End of ASCII file reached before end of categories"));
                return -1;
            }
	    if (buff[0] == '\0') {
		G_debug(3,
			"a2b: skipping blank line while reading category info");
		i--;
		continue;
	    }

	    if (sscanf(buff, "%u%u", &catn, &cat) != 2) {
		G_warning(_("Error reading categories: [%s]"), buff);
                return -1;
            }

	    Vect_cat_set(Cats, catn, cat);
	}

        if (skip_feat)
            continue;
        
	/* Allocation is handled for line_pnts */
	if (0 >
	    Vect_copy_xyz_to_pnts(Points, xarray, yarray, zarray, n_points)) {
	    G_warning(_("Unable to copy points"));
            return -1;
        }

	if (type > 0) {
	    if (-1 == Vect_write_line(Map, type, Points, Cats)) {
		return -1;
	    }
	    n_lines++;
	}
    }

    if (nskipped_3d > 0)
        G_warning(_("Vector map <%s> is 2D. %d 3D features (faces or kernels) skipped."),
                  Vect_get_name(Map), nskipped_3d);
    
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return n_lines;
}
Пример #18
0
int scan_bounds(FILE * fp, int xcol, int ycol, int zcol, char *fs,
		int shell_style, int skipline, double zscale)
{
    unsigned long line;
    int first, max_col;
    char buff[BUFFSIZE];
    double min_x, max_x, min_y, max_y, min_z, max_z;
    char **tokens;
    int ntokens;		/* number of tokens */
    double x, y, z;

    max_col = (xcol > ycol) ? xcol : ycol;
    max_col = (zcol > max_col) ? zcol : max_col;

    line = 0;
    first = TRUE;

    G_verbose_message(_("Scanning data ..."));

    while (0 != G_getl2(buff, BUFFSIZE - 1, fp)) {
	line++;

	if ((buff[0] == '#') || (buff[0] == '\0')) {
	    continue;		/* line is a comment or blank */
	}

	G_chop(buff);		/* remove leading and trailing whitespace. unneded?? */
	tokens = G_tokenize(buff, fs);
	ntokens = G_number_of_tokens(tokens);

	if ((ntokens < 3) || (max_col > ntokens)) {
	    if (skipline) {
		G_warning(_("Not enough data columns. "
			    "Incorrect delimiter or column number? "
			    "Found the following character(s) in row %lu:\n[%s]"),
			  line, buff);
		G_warning(_("Line ignored as requested"));
		continue;	/* line is garbage */
	    }
	    else {
		G_fatal_error(_("Not enough data columns. "
				"Incorrect delimiter or column number? "
				"Found the following character(s) in row %lu:\n[%s]"),
			      line, buff);
	    }
	}

	/* too slow?
	   if ( G_projection() == PROJECTION_LL ) {
	   G_scan_easting( tokens[xcol-1], &x, region.proj);
	   G_scan_northing( tokens[ycol-1], &y, region.proj);
	   }
	   else {
	 */
	if (1 != sscanf(tokens[xcol - 1], "%lf", &x))
	    G_fatal_error(_("Bad x-coordinate line %lu column %d. <%s>"), line,
			  xcol, tokens[xcol - 1]);

	if (first) {
	    min_x = x;
	    max_x = x;
	}
	else {
	    if (x < min_x)
		min_x = x;
	    if (x > max_x)
		max_x = x;
	}

	if (1 != sscanf(tokens[ycol - 1], "%lf", &y))
	    G_fatal_error(_("Bad y-coordinate line %lu column %d. <%s>"), line,
			  ycol, tokens[ycol - 1]);

	if (first) {
	    min_y = y;
	    max_y = y;
	}
	else {
	    if (y < min_y)
		min_y = y;
	    if (y > max_y)
		max_y = y;
	}

	if (1 != sscanf(tokens[zcol - 1], "%lf", &z))
	    G_fatal_error(_("Bad z-coordinate line %lu column %d. <%s>"), line,
			  zcol, tokens[zcol - 1]);

	if (first) {
	    min_z = z;
	    max_z = z;
	    first = FALSE;
	}
	else {
	    if (z < min_z)
		min_z = z;
	    if (z > max_z)
		max_z = z;
	}


	G_free_tokens(tokens);
    }

    if (!shell_style) {
	fprintf(stderr, _("Range:     min         max\n"));
	fprintf(stdout, "x: %11f %11f\n", min_x, max_x);
	fprintf(stdout, "y: %11f %11f\n", min_y, max_y);
	fprintf(stdout, "z: %11f %11f\n", min_z * zscale, max_z * zscale);
    }
    else
	fprintf(stdout, "n=%f s=%f e=%f w=%f b=%f t=%f\n",
		max_y, min_y, max_x, min_x, min_z * zscale, max_z * zscale);

    G_debug(1, "Processed %lu lines.", line);
    G_debug(1, "region template: g.region n=%f s=%f e=%f w=%f",
	    max_y, min_y, max_x, min_x);

    return 0;
}
Пример #19
0
/* Evaluate node recursively.
 *
 * Returns: 
 *    NODE_NULL  result/value is unknown   
 *    NODE_TRUE   
 *    NODE_FALSE  
 *    NODE_VALUE result is a value stored in 'value' 
 *               (if value is not NULL otherwise NODE_NULL is returned and value is not set)
 *    NODE_ERROR e.g. division by 0
 *
 * If results is NODE_VALUE, the 'value' is set, if value is type SQLP_S the string is not duplicated
 * and only pointer is set -> do not free value->s 
 */
double eval_node(SQLPNODE * nptr, int tab, int row, SQLPVALUE * value)
{
    int left, right;
    SQLPVALUE left_value, right_value;
    int ccol;
    COLUMN *col;
    VALUE *val;
    double left_dval, right_dval, dval;
    char *rightbuf;

    /* Note: node types were previously checked by eval_node_type */

    G_debug(4, "eval_node node_type = %d", nptr->node_type);

    switch (nptr->node_type) {
    case SQLP_NODE_VALUE:
	if (nptr->value.type == SQLP_NULL)
	    return NODE_NULL;

	value->type = nptr->value.type;
	value->s = nptr->value.s;
	value->i = nptr->value.i;
	value->d = nptr->value.d;
	return NODE_VALUE;
	break;

    case SQLP_NODE_COLUMN:
	ccol = find_column(tab, nptr->column_name);
	col = &(db.tables[tab].cols[ccol]);
	val = &(db.tables[tab].rows[row].values[ccol]);

	if (val->is_null)
	    return NODE_NULL;

	switch (col->type) {
	case DBF_CHAR:
	    value->s = val->c;
	    value->type = SQLP_S;
	    break;
	case DBF_INT:
	    value->i = val->i;
	    value->type = SQLP_I;
	    break;
	case DBF_DOUBLE:
	    value->d = val->d;
	    value->type = SQLP_D;
	    break;
	}
	return NODE_VALUE;
	break;

    case SQLP_NODE_EXPRESSION:
	/* Note: Some expressions (e.g. NOT) have only one side */
	if (nptr->left) {
	    left = eval_node(nptr->left, tab, row, &left_value);
	    G_debug(4, "    left = %d", left);

	    if (left == NODE_ERROR)
		return NODE_ERROR;

	    if (left != NODE_NULL) {
		if (left_value.type == SQLP_I)
		    left_dval = left_value.i;
		else
		    left_dval = left_value.d;

		G_debug(4, "    left_dval = %f", left_dval);
	    }
	}

	if (nptr->right) {
	    right = eval_node(nptr->right, tab, row, &right_value);
	    G_debug(4, "    right = %d", right);

	    if (right == NODE_ERROR)
		return NODE_ERROR;

	    if (right != NODE_NULL) {
		if (right_value.type == SQLP_I)
		    right_dval = right_value.i;
		else
		    right_dval = right_value.d;

		G_debug(4, "    right_dval = %f", right_dval);
	    }
	}

	G_debug(4, "    operator = %d", nptr->oper);

	switch (nptr->oper) {
	    /* Arithmetical */
	case SQLP_ADD:
	case SQLP_SUBTR:
	case SQLP_MLTP:
	case SQLP_DIV:
	    if (left == NODE_NULL || right == NODE_NULL)
		return NODE_NULL;

	    switch (nptr->oper) {
	    case SQLP_ADD:
		dval = left_dval + right_dval;
		break;
	    case SQLP_SUBTR:
		dval = left_dval - right_dval;
		break;
	    case SQLP_MLTP:
		dval = left_dval * right_dval;
		break;
	    case SQLP_DIV:
		if (right_dval != 0.0) {
		    dval = left_dval / right_dval;
		}
		else {
		    append_error("Division by zero\n");
		    return NODE_ERROR;
		}
		break;
	    }

	    if (left_value.type == SQLP_I && right_value.type == SQLP_I &&
		(nptr->oper == SQLP_ADD || nptr->oper == SQLP_SUBTR ||
		 nptr->oper == SQLP_MLTP)) {
		value->type = SQLP_I;
		value->i = (int)dval;
	    }
	    else {
		value->type = SQLP_D;
		value->d = dval;
	    }
	    return NODE_VALUE;

	    break;

	    /* Comparison */
	    /* Operators valid for all type */
	case SQLP_EQ:
	    if (left == NODE_NULL || right == NODE_NULL) {
		return NODE_NULL;
	    }
	    else if (left_value.type == SQLP_S) {	/* we checked before if right is also string */
		if (left_value.s && right_value.s &&
		    strcmp(left_value.s, right_value.s) == 0)
		    return NODE_TRUE;
		else
		    return NODE_FALSE;
	    }
	    else {		/* numbers */
		if (left_dval == right_dval)
		    return NODE_TRUE;
		else
		    return NODE_FALSE;
	    }
	    break;

	case SQLP_NE:
	    if (left == NODE_NULL || right == NODE_NULL) {
		return NODE_NULL;
	    }
	    else if (left_value.type == SQLP_S) {	/* we checked before if right is also string */
		if (left_value.s && right_value.s &&
		    strcmp(left_value.s, right_value.s) != 0)
		    return NODE_TRUE;
		else
		    return NODE_FALSE;
	    }
	    else {		/* numbers */
		if (left_dval != right_dval)
		    return NODE_TRUE;
		else
		    return NODE_FALSE;
	    }

	    /* Operators valid for numbers */
	case SQLP_LT:
	    if (left == NODE_NULL || right == NODE_NULL) {
		return NODE_NULL;
	    }
	    else {
		if (left_dval < right_dval)
		    return NODE_TRUE;
		else
		    return NODE_FALSE;
	    }

	case SQLP_LE:
	    if (left == NODE_NULL || right == NODE_NULL) {
		return NODE_NULL;
	    }
	    else {
		if (left_dval <= right_dval)
		    return NODE_TRUE;
		else
		    return NODE_FALSE;
	    }

	case SQLP_GT:
	    if (left == NODE_NULL || right == NODE_NULL) {
		return NODE_NULL;
	    }
	    else {
		if (left_dval > right_dval)
		    return NODE_TRUE;
		else
		    return NODE_FALSE;
	    }

	case SQLP_GE:
	    if (left == NODE_NULL || right == NODE_NULL) {
		return NODE_NULL;
	    }
	    else {
		if (left_dval >= right_dval)
		    return NODE_TRUE;
		else
		    return NODE_FALSE;
	    }

	    /* Operator valid for string */
	case SQLP_MTCH:
	    if (left == NODE_NULL || right == NODE_NULL) {
		return NODE_NULL;
	    }
	    else {
		/* hack to get '%substring' and 'substring%' working */
		rightbuf = G_str_replace(right_value.s, "%", "");
		G_chop(rightbuf);
		if (left_value.s && right_value.s &&
		    strstr(left_value.s, rightbuf) != NULL) {
		    G_free(rightbuf);
		    return NODE_TRUE;
		}
		else {
		    G_free(rightbuf);
		    return NODE_FALSE;
		}
	    }

	case SQLP_ISNULL:
	    return right == NODE_NULL ? NODE_TRUE : NODE_FALSE;

	case SQLP_NOTNULL:
	    return right != NODE_NULL ? NODE_TRUE : NODE_FALSE;

	    /* Logical */
	case SQLP_AND:
	    if (left == NODE_NULL || right == NODE_NULL) {
		return NODE_NULL;
	    }
	    else if (left == NODE_TRUE && right == NODE_TRUE) {
		return NODE_TRUE;
	    }
	    else if (left == NODE_VALUE || right == NODE_VALUE) {	/* Should not happen */
		append_error("Value operand for AND\n");
		return NODE_ERROR;
	    }
	    else {
		return NODE_FALSE;
	    }
	case SQLP_OR:
	    if (left == NODE_NULL && right == NODE_NULL) {
		return NODE_NULL;
	    }
	    else if (left == NODE_TRUE || right == NODE_TRUE) {
		return NODE_TRUE;
	    }
	    else if (left == NODE_VALUE || right == NODE_VALUE) {	/* Should not happen */
		append_error("Value operand for OR\n");
		return NODE_ERROR;
	    }
	    else {
		return NODE_FALSE;
	    }
	case SQLP_NOT:
	    /* sub node stored on the right side */
	    if (right == NODE_NULL) {
		return NODE_NULL;
	    }
	    else if (right == NODE_TRUE) {
		return NODE_FALSE;
	    }
	    else if (right == NODE_VALUE) {	/* Should not happen */
		append_error("Value operand for NOT\n");
		return NODE_ERROR;
	    }
	    else {
		return NODE_TRUE;
	    }

	default:
	    append_error("Unknown operator %d\n", nptr->oper);
	    return NODE_FALSE;
	}
    }

    return NODE_ERROR;		/* Not reached */
}