Beispiel #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);
    }
}
Beispiel #2
0
static int I_read_control_points(FILE * fd, struct Control_Points *cp)
{
    char buf[100];
    double e1, e2, n1, n2;
    int status;

    cp->count = 0;

    /* read the control point lines. format is:
       image_east image_north  target_east target_north  status
     */
    cp->e1 = NULL;
    cp->e2 = NULL;
    cp->n1 = NULL;
    cp->n2 = NULL;
    cp->status = NULL;

    while (G_getl2(buf, sizeof buf, fd)) {
	G_strip(buf);
	if (*buf == '#' || *buf == 0)
	    continue;
	if (sscanf(buf, "%lf%lf%lf%lf%d", &e1, &n1, &e2, &n2, &status) == 5)
	    I_new_control_point(cp, e1, n1, e2, n2, status);
	else
	    return -4;
    }

    return 1;
}
Beispiel #3
0
/*!
 * \brief Read the first line of a file in cell_misc/
 *
 * Read the first line of data from a cell_misc/ meta-data file.
 *
 * \param element  metadata component filename
 * \param name
 * \param mapset
 * \param *str  string to be populated with data
 * \return 0 on success
 * \return -1, EOF (fclose() result) on error
 */
int G__raster_misc_read_line(const char *elem, const char *name,
			     const char *mapset, char *str)
{
    FILE *fd;
    char buff[GNAME_MAX];

    buff[0] = '\0';

    if (G_find_file2_misc("cell_misc", elem, name, mapset) == NULL)
	return -1;

    fd = G_fopen_old_misc("cell_misc", elem, name, mapset);
    if (!fd) {
	G_warning(_("Can't read %s for [%s in %s]"), elem, name, mapset);
	return -1;
    }
    if (G_getl2(buff, sizeof(buff) - 1, fd) == 0) {
	/* file is empty */
	return fclose(fd);
    }

    strcpy(str, buff);

    return fclose(fd);
}
/*!
 * \brief Read the first line of a file in cell_misc/
 *
 * Read the first line of data from a cell_misc/ meta-data file.
 *
 * \param element  metadata component filename
 * \param name
 * \param mapset
 * \param *str  string to be populated with data
 * \return dynamically-allocated string on success
 * \return NULL on error
 */
static char *misc_read_line(const char *elem,
			    const char *name, const char *mapset)
{
    char buff[GNAME_MAX];
    FILE *fp;

    buff[0] = '\0';

    if (G_find_file2_misc("cell_misc", elem, name, mapset) == NULL)
	return NULL;

    fp = G_fopen_old_misc("cell_misc", elem, name, mapset);
    if (!fp) {
	G_warning(_("Unable to read <%s> for raster map <%s@%s>"),
		  elem, name, mapset);
	return NULL;
    }
    if (G_getl2(buff, sizeof(buff) - 1, fp) == 0) {
	/* file is empty */
	*buff = '\0';
    }

    if (fclose(fp) != 0)
	G_fatal_error(_("Error closing <%s> metadata file for raster map <%s@%s>"),
		      elem, name, mapset);

    return *buff ? G_store(buff) : NULL;
}
Beispiel #5
0
int do_poly(char *buff, FILE * infile)
{
    int num;
    char origcmd[64];
    float xper, yper;
    char *fgets();
    int to_return;

    sscanf(buff, "%s", origcmd);

    num = 0;

    for (;;) {
	if ((to_return = G_getl2(buff, 128, infile)) != 1)
	    break;

	if (2 != sscanf(buff, "%f %f", &xper, &yper)) {

	    if ('#' == buff[0]) {
		G_debug(3, " skipping comment line [%s]", buff);
		continue;
	    }

	    G_debug(3, "coordinate pair not found. ending polygon. [%s]",
		    buff);
	    break;
	}

	if (!mapunits) {
	    if (xper < 0. || yper < 0. || xper > 100. || yper > 100.)
		break;
	}
	check_alloc(num + 1);

	if (mapunits) {
	    xarray[num] = (int)(D_u_to_d_col(xper) + 0.5);
	    yarray[num] = (int)(D_u_to_d_row(yper) + 0.5);
	}
	else {
	    xarray[num] = l + (int)(xper * xincr);
	    yarray[num] = b - (int)(yper * yincr);
	}

	num++;
    }

    if (num) {
	/* this check is here so you can use the "polyline" command 
	   to make an unfilled polygon */
	if (!strcmp(origcmd, "polygon"))
	    R_polygon_abs(xarray, yarray, num);
	else
	    R_polyline_abs(xarray, yarray, num);
    }

    return (to_return);
}
Beispiel #6
0
int read_header_file(char *date)
{
    char buf[1024];

    while (G_getl2(buf, sizeof buf, hdr.fp))
	output(buf, date);
    fclose(hdr.fp);

    return 0;
}
Beispiel #7
0
/*!
  \brief Read header of GRASS ASCII vector format

  \param dascii pointer to the ASCII file
  \param Map    pointer to Map_info structure

  \return 0 on success
  \return -1 on error
*/
int Vect_read_ascii_head(FILE *dascii, struct Map_info *Map)
{
    char buff[1024];
    char *ptr;

    for (;;) {
	if (0 == G_getl2(buff, sizeof(buff) - 1, dascii))
	    return (0);

	/* Last line of header */
	if (strncmp(buff, "VERTI:", 6) == 0)
	    return (0);

	if (!(ptr = strchr(buff, ':'))) {
	    G_warning(_("Unexpected data in vector header:\n[%s]"), buff);
            return -1;
        }

	ptr++;			/* Search for the start of text */
	while (*ptr == ' ')
	    ptr++;

	if (strncmp(buff, "ORGANIZATION:", 12) == 0)
	    Vect_set_organization(Map, ptr);
	else if (strncmp(buff, "DIGIT DATE:", 11) == 0)
	    Vect_set_date(Map, ptr);
	else if (strncmp(buff, "DIGIT NAME:", 11) == 0)
	    Vect_set_person(Map, ptr);
	else if (strncmp(buff, "MAP NAME:", 9) == 0)
	    Vect_set_map_name(Map, ptr);
	else if (strncmp(buff, "MAP DATE:", 9) == 0)
	    Vect_set_map_date(Map, ptr);
	else if (strncmp(buff, "MAP SCALE:", 10) == 0)
	    Vect_set_scale(Map, atoi(ptr));
	else if (strncmp(buff, "OTHER INFO:", 11) == 0)
	    Vect_set_comment(Map, ptr);
	else if (strncmp(buff, "ZONE:", 5) == 0 ||
		 strncmp(buff, "UTM ZONE:", 9) == 0)
	    Vect_set_zone(Map, atoi(ptr));
	else if (strncmp(buff, "WEST EDGE:", 10) == 0) {
	}
	else if (strncmp(buff, "EAST EDGE:", 10) == 0) {
	}
	else if (strncmp(buff, "SOUTH EDGE:", 11) == 0) {
	}
	else if (strncmp(buff, "NORTH EDGE:", 11) == 0) {
	}
	else if (strncmp(buff, "MAP THRESH:", 11) == 0)
	    Vect_set_thresh(Map, atof(ptr));
	else {
	    G_warning(_("Unknown keyword <%s> in vector head"), buff);
	}
    }
    /* NOTREACHED */
}
Beispiel #8
0
/**
 * \brief Create network arcs (edge) based on given point vector map (nodes)
 *
 * \param file input file defining arcs
 * \param Points input vector point map
 * \param Out output vector map
 * \param afield arcs layer 
 * \param nfield nodes layer 
 *
 * \return number of new arcs
 */
int create_arcs(FILE * file, struct Map_info *Pnts,
		struct Map_info *Out, int afield, int nfield)
{
    char buff[1024];
    int lcat, fcat, tcat;
    int node1, node2;
    int narcs;

    struct line_pnts *points, *points2;
    struct line_cats *cats;

    points = Vect_new_line_struct();
    points2 = Vect_new_line_struct();
    points = Vect_new_line_struct();
    cats = Vect_new_cats_struct();

    narcs = 0;

    while (G_getl2(buff, sizeof(buff) - 1, file)) {
	if (sscanf(buff, "%d%d%d", &lcat, &fcat, &tcat) != 3)
	    G_fatal_error(_("Error reading file: '%s'"), buff);

	node1 = find_node(Pnts, afield, fcat);
	node2 = find_node(Pnts, afield, tcat);

	if (node1 < 1 || node2 < 1) {
	    G_warning(_("Skipping arc %d"), lcat);
	    continue;
	}

	/* geometry */
	Vect_read_line(Pnts, points, cats, node1);
	field2n(cats, nfield);
	Vect_write_line(Out, GV_POINT, points, cats);
	Vect_read_line(Pnts, points2, cats, node2);
	field2n(cats, nfield);
	Vect_write_line(Out, GV_POINT, points2, cats);
	Vect_append_points(points, points2, GV_FORWARD);

	/* category */
	Vect_reset_cats(cats);
	Vect_cat_set(cats, afield, lcat);
	Vect_write_line(Out, GV_LINE, points, cats);

	narcs++;
    }

    Vect_destroy_line_struct(points);
    Vect_destroy_cats_struct(cats);

    return narcs;
}
Beispiel #9
0
void readHeaderString(FILE * fp, char *valueString, double *value)
{
    static char format[100];
    char line_buff[1024];

    /* to avoid buffer overflows we use G_snprintf */
    G_snprintf(format, 100, "%s %%lf", valueString);
    G_getl2(line_buff, 1024, fp);
    if (sscanf(line_buff, format, value) != 1) {
        G_debug(3, "bad value for [%s]", valueString);
        fatalError("readHeaderString: header value invalid");
    }
}
Beispiel #10
0
struct datum_list *read_datum_table(void)
{
    FILE *fd;
    char file[GPATH_MAX];
    char buf[4096];
    int line;
    struct datum_list *current = NULL, *outputlist = NULL;
    int count = 0;

    sprintf(file, "%s%s", G_gisbase(), DATUMTABLE);

    fd = fopen(file, "r");
    if (!fd) {
	G_warning(_("Unable to open datum table file <%s>"), file);
	return NULL;
    }

    for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
	char name[100], descr[1024], ellps[100];
	double dx, dy, dz;

	G_strip(buf);
	if (*buf == '\0' || *buf == '#')
	    continue;

	if (sscanf(buf, "%s \"%1023[^\"]\" %s dx=%lf dy=%lf dz=%lf",
		   name, descr, ellps, &dx, &dy, &dz) != 6) {
	    G_warning(_("Error in datum table file <%s>, line %d"), file,
		      line);
	    continue;
	}

	if (current == NULL)
	    current = outputlist = G_malloc(sizeof(struct datum_list));
	else
	    current = current->next = G_malloc(sizeof(struct datum_list));
	current->name = G_store(name);
	current->longname = G_store(descr);
	current->ellps = G_store(ellps);
	current->dx = dx;
	current->dy = dy;
	current->dz = dz;
	current->next = NULL;

	count++;
    }

    fclose(fd);

    return outputlist;
}
Beispiel #11
0
void G_read_datum_table(void)
{
    FILE *fd;
    char file[GPATH_MAX];
    char buf[1024];
    int line;

    if (G_is_initialized(&table.initialized))
	return;

    sprintf(file, "%s%s", G_gisbase(), DATUMTABLE);

    fd = fopen(file, "r");
    if (!fd) {
	G_warning(_("unable to open datum table file: %s"), file);
	G_initialize_done(&table.initialized);
	return;
    }

    for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
	char name[100], descr[100], ellps[100];
	struct datum *t;

	G_strip(buf);
	if (*buf == '\0' || *buf == '#')
	    continue;

	if (table.count >= table.size) {
	    table.size += 50;
	    table.datums = G_realloc(table.datums, table.size * sizeof(struct datum));
	}

	t = &table.datums[table.count];

	if (sscanf(buf, "%s \"%99[^\"]\" %s dx=%lf dy=%lf dz=%lf",
		   name, descr, ellps, &t->dx, &t->dy, &t->dz) != 6) {
	    G_warning(_("error in datum table file, line %d"), line);
	    continue;
	}

	t->name = G_store(name);
	t->descr = G_store(descr);
	t->ellps = G_store(ellps);

	table.count++;
    }

    qsort(table.datums, table.count, sizeof(struct datum), compare_table_names);

    G_initialize_done(&table.initialized);
}
Beispiel #12
0
int I_get_group_title(const char *group, char *title, int n)
{
    FILE *fd;

    *title = 0;
    G_suppress_warnings(1);
    fd = I_fopen_group_file_old(group, "TITLE");
    G_suppress_warnings(0);
    if (fd != NULL) {
	G_getl2(title, n, fd);
	fclose(fd);
    }

    return (fd != NULL);
}
Beispiel #13
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);
}
Beispiel #14
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);
}
Beispiel #15
0
/* Return the camera name from the group file CAMERA */
int I_get_group_camera(char *group, char *camera)
{
    char buf[200];
    FILE *fd;

    G_suppress_warnings(1);
    fd = I_fopen_group_camera_old(group);
    G_suppress_warnings(0);
    if (!fd) {
	sprintf(buf,
		_("Unable to open camera file for group <%s> in mapset <%s>"),
		group, G_mapset());
	G_warning("%s", buf);
	return 0;
    }
    G_getl2(buf, sizeof(buf), fd);
    sscanf(buf, "%s", camera);
    return 1;
}
Beispiel #16
0
static void parse_env(FILE *fd, int loc)
{    
    char buf[200];
    char *name;
    char *value;

    while (G_getl2(buf, sizeof buf, fd)) {
	    for (name = value = buf; *value; value++)
		if (*value == ':')
		    break;
	    if (*value == 0)
		continue;

	    *value++ = 0;
	    G_strip(name);
	    G_strip(value);
	    if (*name && *value)
		set_env(name, value, loc);
	}
}
Beispiel #17
0
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;
}
Beispiel #18
0
static void do_pt_xforms(void)
{
    double easting, northing;
    int ret;
    FILE *fp;

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

    for (;;) {
    	char buf[64];

    	if (!G_getl2(buf, sizeof(buf), fp))
    	    break;

    	if ((buf[0] == '#') || (buf[0] == '\0'))
    	    continue;

    	/* ? sscanf(buf, "%s %s", &east_str, &north_str)
    	    ? G_scan_easting(,,-1)
    	    ? G_scan_northing(,,-1) */
    	/* ? muliple delims with sscanf(buf, "%[ ,|\t]", &dummy) ? */

    	ret = sscanf(buf, "%lf %lf", &easting, &northing);
    	if (ret != 2)
    	    G_fatal_error(_("Invalid coordinates: [%s]"), buf);

    	xform_value(easting, northing);
    }

    if (fp != stdin)
    	fclose(fp);
}
Beispiel #19
0
int read_env_file(const char *path)
{
    FILE *fd;
    char buf[1024];
    char **token;
    
    fd = fopen(path, "r");
    if (!fd)
	return -1;

    token = NULL;
    while (G_getl2(buf, sizeof(buf) - 1, fd) != 0) {
	token = G_tokenize(buf, "=");
	if (G_number_of_tokens(token) != 2)
	    continue;
	G_debug(3, "\tread_env_file(): %s=%s", token[0], token[1]);
	G_putenv(token[0], token[1]);
	G_free_tokens(token);
	token = NULL;
    }

    return 0;
}
Beispiel #20
0
/* list related commands for given monitor */
void list_cmd(const char *name, FILE *fd_out)
{
    char buf[1024];
    char *cmd_name;
    const char *cmd_value;
    FILE *fd;

    cmd_name = NULL;
    G_asprintf(&cmd_name, "MONITOR_%s_CMDFILE", G_store_upper(name));
    cmd_value = G__getenv(cmd_name);
    if (!cmd_value)
	G_fatal_error(_("Command file not found"));
    
    fd = fopen(cmd_value, "r");
    if (!fd)
	G_fatal_error(_("Unable to read command file"));

    while (G_getl2(buf, sizeof(buf) - 1, fd) != 0) {
	fprintf(fd_out, "%s\n", buf);
    }
    
    fclose(fd);
}
Beispiel #21
0
struct proj_desc *get_proj_desc(const char *arg)
{
    char buf[4096];
    struct proj_desc *res;
    FILE *fp;

    sprintf(buf, "%s/etc/proj/desc.table", G_gisbase());

    fp = fopen(buf, "r");
    if (!fp)
	return NULL;

    for (res = NULL; !res;) {
	char name[16], type[16], key[16], desc[100];

	if (!G_getl2(buf, sizeof(buf), fp))
	    break;

	if (sscanf(buf, "%[^:]:%[^:]:%[^:]:%[^\n]", name, type, key, desc) !=
	    4)
	    continue;

	if (G_strcasecmp(arg, name) != 0)
	    continue;

	res = G_malloc(sizeof(struct proj_desc));

	res->name = G_store(name);
	res->type = G_store(type);
	res->key = G_store(key);
	res->desc = G_store(desc);
    }

    fclose(fp);

    return res;
}
Beispiel #22
0
struct proj_unit *get_proj_unit(const char *arg)
{
    char buf[4096];
    struct proj_unit *unit;
    FILE *fp;

    sprintf(buf, "%s/etc/proj/units.table", G_gisbase());

    fp = fopen(buf, "r");
    if (!fp)
	return NULL;

    for (unit = NULL; !unit;) {
	char plural[16], singular[16];
	double factor;
	struct proj_unit *unit;

	if (!G_getl2(buf, sizeof(buf), fp))
	    break;

	if (sscanf(buf, "%[^:]:%[^:]:%lf", plural, singular, &factor) != 3)
	    continue;

	if (G_strcasecmp(arg, plural) != 0)
	    continue;

	unit = G_malloc(sizeof(struct proj_unit));

	unit->units = G_store(plural);
	unit->unit = G_store(singular);
	unit->fact = factor;
    }

    fclose(fp);

    return unit;
}
Beispiel #23
0
int main(int argc, char *argv[])
{
    const char *name;
    const char *mapset;

    long x, y;
    double dx;
    RASTER_MAP_TYPE map_type;
    int i;
    int from_stdin = FALSE;
    struct GModule *module;

    struct
    {
	struct Option *map, *fs, *cats, *vals, *raster, *file, *fmt_str,
	    *fmt_coeff;
    } parm;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("category"));
    module->description =
	_("Manages category values and labels associated "
	  "with user-specified raster map layers.");

    parm.map = G_define_standard_option(G_OPT_R_MAP);

    parm.cats = G_define_standard_option(G_OPT_V_CATS);
    parm.cats->multiple = YES;
    parm.cats->guisection = _("Selection");

    parm.vals = G_define_option();
    parm.vals->key = "vals";
    parm.vals->type = TYPE_DOUBLE;
    parm.vals->multiple = YES;
    parm.vals->required = NO;
    parm.vals->label = _("Comma separated value list");
    parm.vals->description = _("Example: 1.4,3.8,13");
    parm.vals->guisection = _("Selection");

    parm.fs = G_define_standard_option(G_OPT_F_SEP);
    parm.fs->answer = "tab";

    parm.raster = G_define_standard_option(G_OPT_R_INPUT);
    parm.raster->key = "raster";
    parm.raster->required = NO;
    parm.raster->description =
	_("Raster map from which to copy category table");
    parm.raster->guisection = _("Define");

    parm.file = G_define_standard_option(G_OPT_F_INPUT);
    parm.file->key = "rules";
    parm.file->required = NO;
    parm.file->description =
	_("File containing category label rules (or \"-\" to read from stdin)");
    parm.file->guisection = _("Define");

    parm.fmt_str = G_define_option();
    parm.fmt_str->key = "format";
    parm.fmt_str->type = TYPE_STRING;
    parm.fmt_str->required = NO;
    parm.fmt_str->label =
	_("Default label or format string for dynamic labeling");
    parm.fmt_str->description =
	_("Used when no explicit label exists for the category");

    parm.fmt_coeff = G_define_option();
    parm.fmt_coeff->key = "coefficients";
    parm.fmt_coeff->type = TYPE_DOUBLE;
    parm.fmt_coeff->required = NO;
    parm.fmt_coeff->key_desc = "mult1,offset1,mult2,offset2";
    /*    parm.fmt_coeff->answer   = "0.0,0.0,0.0,0.0"; */
    parm.fmt_coeff->label = _("Dynamic label coefficients");
    parm.fmt_coeff->description =
	_("Two pairs of category multiplier and offsets, for $1 and $2");

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


    name = parm.map->answer;

    fs = G_option_to_separator(parm.fs);
    
    mapset = G_find_raster2(name, "");
    if (mapset == NULL)
	G_fatal_error(_("Raster map <%s> not found"), name);

    map_type = Rast_map_type(name, mapset);


    /* create category labels */
    if (parm.raster->answer || parm.file->answer ||
	parm.fmt_str->answer || parm.fmt_coeff->answer) {

	/* restrict editing to current mapset */
	if (strcmp(mapset, G_mapset()) != 0)
	    G_fatal_error(_("Raster map <%s> not found in current mapset"),
			  name);

	/* use cats from another map */
	if (parm.raster->answer) {
	    int fd;
	    const char *cmapset;

	    cmapset = G_find_raster2(parm.raster->answer, "");
	    if (cmapset == NULL)
		G_fatal_error(_("Raster map <%s> not found"),
			      parm.raster->answer);

	    fd = Rast_open_old(name, mapset);

	    Rast_init_cats("", &cats);

	    if (0 > Rast_read_cats(parm.raster->answer, cmapset, &cats))
		G_fatal_error(_("Unable to read category file of raster map <%s@%s>"),
			      parm.raster->answer, cmapset);

	    Rast_write_cats(name, &cats);
	    G_message(_("Category table for <%s> set from <%s>"),
		      name, parm.raster->answer);

	    Rast_close(fd);
	}

	/* load cats from rules file */
	if (parm.file->answer) {
	    FILE *fp;
	    char **tokens;
	    int ntokens;
	    char *e1;
	    char *e2;

	    if (strcmp("-", parm.file->answer) == 0) {
		from_stdin = TRUE;
		fp = stdin;
	    }
	    else {
		fp = fopen(parm.file->answer, "r");
		if (!fp)
		    G_fatal_error(_("Unable to open file <%s>"),
				  parm.file->answer);
	    }

	    Rast_init_cats("", &cats);

	    for (;;) {
		char buf[1024];
		DCELL d1, d2;
		int parse_error = 0;

		if (!G_getl2(buf, sizeof(buf), fp))
		    break;

		tokens = G_tokenize(buf, fs);
		ntokens = G_number_of_tokens(tokens);

		if (ntokens == 3) {
		    d1 = strtod(tokens[0], &e1);
		    d2 = strtod(tokens[1], &e2);
		    if (*e1 == 0 && *e2 == 0)
			Rast_set_d_cat(&d1, &d2, tokens[2], &cats);
		    else
			parse_error = 1;
		}
		else if (ntokens == 2) {
		    d1 = strtod(tokens[0], &e1);
		    if (*e1 == 0)
			Rast_set_d_cat(&d1, &d1, tokens[1], &cats);
		    else
			parse_error = 1;
		}
		else if (!strlen(buf))
		    continue;
		else
		    parse_error = 1;

		if (parse_error)
		    G_fatal_error(_("Incorrect format of input rules. "
				    "Check separators. Invalid line is:\n%s"), buf);
	    }
	    G_free_tokens(tokens);
	    Rast_write_cats(name, &cats);

	    if (!from_stdin)
		fclose(fp);
	}

	/* set dynamic cat rules for cats without explicit labels */
	if (parm.fmt_str->answer || parm.fmt_coeff->answer) {
	    char *fmt_str;
	    double m1, a1, m2, a2;

	    /* read existing values */
	    Rast_init_cats("", &cats);

	    if (0 > Rast_read_cats(name, G_mapset(), &cats))
		G_warning(_("Unable to read category file of raster map <%s@%s>"),
			  name, G_mapset());

	    if (parm.fmt_str->answer) {
		fmt_str =
		    G_malloc(strlen(parm.fmt_str->answer) > strlen(cats.fmt)
			     ? strlen(parm.fmt_str->answer) +
			     1 : strlen(cats.fmt) + 1);
		strcpy(fmt_str, parm.fmt_str->answer);
	    }
	    else {
		fmt_str = G_malloc(strlen(cats.fmt) + 1);
		strcpy(fmt_str, cats.fmt);
	    }

	    m1 = cats.m1;
	    a1 = cats.a1;
	    m2 = cats.m2;
	    a2 = cats.a2;

	    if (parm.fmt_coeff->answer) {
		m1 = atof(parm.fmt_coeff->answers[0]);
		a1 = atof(parm.fmt_coeff->answers[1]);
		m2 = atof(parm.fmt_coeff->answers[2]);
		a2 = atof(parm.fmt_coeff->answers[3]);
	    }

	    Rast_set_cats_fmt(fmt_str, m1, a1, m2, a2, &cats);

	    Rast_write_cats(name, &cats);
	}

	Rast_free_cats(&cats);
	exit(EXIT_SUCCESS);
    }
    else {
	if (Rast_read_cats(name, mapset, &cats) < 0)
	    G_fatal_error(_("Unable to read category file of raster map <%s> in <%s>"),
			  name, mapset);
    }

    /* describe the category labels */
    /* if no cats requested, use r.describe to get the cats */
    if (parm.cats->answer == NULL) {
	if (map_type == CELL_TYPE) {
	    get_cats(name, mapset);
	    while (next_cat(&x))
		print_label(x);
	    exit(EXIT_SUCCESS);
	}
    }
    else {
	if (map_type != CELL_TYPE)
	    G_warning(_("The map is floating point! Ignoring cats list, using vals list"));
	else {			/* integer map */

	    for (i = 0; parm.cats->answers[i]; i++)
		if (!scan_cats(parm.cats->answers[i], &x, &y)) {
		    G_usage();
		    exit(EXIT_FAILURE);
		}
	    for (i = 0; parm.cats->answers[i]; i++) {
		scan_cats(parm.cats->answers[i], &x, &y);
		while (x <= y)
		    print_label(x++);
	    }
	    exit(EXIT_SUCCESS);
	}
    }
    if (parm.vals->answer == NULL)
	G_fatal_error(_("vals argument is required for floating point map!"));
    for (i = 0; parm.vals->answers[i]; i++)
	if (!scan_vals(parm.vals->answers[i], &dx)) {
	    G_usage();
	    exit(EXIT_FAILURE);
	}
    for (i = 0; parm.vals->answers[i]; i++) {
	scan_vals(parm.vals->answers[i], &dx);
	print_d_label(dx);
    }
    exit(EXIT_SUCCESS);
}
Beispiel #24
0
int get_item(FILE * fd, int *type, long *cat, double **x, double **y,
	     int *count, struct Categories *labels)
{
    static double *X = NULL;
    static double *Y = NULL;
    static int nalloc = 0;
    char buf[1024];
    char lbl[1024];
    char east[256], north[256];
    double e, n;
    long offset;

    *cat = 0;
    *count = 0;
    *type = 0;

    /* scan until we find the start of a new feature */
    while (G_getl2(buf, sizeof buf, fd)) {
	/* skip comments and blank lines */
	if ((*buf == '#') || (*buf == '\0'))
	    continue;

	G_strip(buf);
	if (*buf == 'A' || *buf == 'a') {
	    *type = 'A';
	    break;
	}
	if (*buf == 'L' || *buf == 'l') {
	    *type = 'L';
	    break;
	}
	if (*buf == 'P' || *buf == 'p') {
	    *type = 'P';
	    break;
	}
    }
    if (*type == 0)
	return 0;

    /* read the feature's data */
    while (1) {
	offset = G_ftell(fd);

	if (!G_getl2(buf, (sizeof buf) - 1, fd))
	    break;

	/* skip comments and blank lines */
	if ((*buf == '#') || (*buf == '\0'))
	    continue;

	G_strip(buf);

	/* if we've found the next feature, rewind to the start of it and complete */
	if (*buf == 'A' || *buf == 'a' ||
	    *buf == 'L' || *buf == 'l' || *buf == 'P' || *buf == 'p') {
	    G_fseek(fd, offset, 0);
	    break;
	}

	/* if we found a cat (and optionally a label), read them and continue to scan */
	if (*buf == '=') {
	    if (sscanf(buf + 1, "%ld", cat) != 1)
		continue;
	    /* probably change this as G_getl2() doesn't store the new line (?) */
	    if (sscanf(buf + 1, "%ld%[^\n]", cat, lbl) == 2) {
		G_strip(lbl);
		Rast_set_c_cat((CELL*) cat, (CELL *) cat, lbl, labels);
	    }
	    continue;
	}
	if (sscanf(buf, "%s %s", east, north) != 2) {
	    G_warning(_("Illegal coordinate <%s, %s>, skipping."), east, north);
	    continue;
	}

	if (!G_scan_northing(north, &n, G_projection())) {
	    G_warning(_("Illegal north coordinate <%s>, skipping."), north);
	    continue;
	}

	if (!G_scan_easting(east, &e, G_projection())) {
	    G_warning(_("Illegal east coordinate <%s>, skipping."), east);
	    continue;
	}

	if (*count >= nalloc) {
	    nalloc += 32;
	    X = (double *)G_realloc(X, nalloc * sizeof(double));
	    Y = (double *)G_realloc(Y, nalloc * sizeof(double));
	}
	X[*count] = e;
	Y[*count] = n;
	(*count)++;
    }
    *x = X;
    *y = Y;
    return 1;
}
Beispiel #25
0
struct gpj_datum_transform_list *GPJ_get_datum_transform_by_name(const char
								 *inputname)
{
    FILE *fd;
    char file[GPATH_MAX];
    char buf[1024];
    int line;
    struct gpj_datum_transform_list *current = NULL, *outputlist = NULL;
    struct gpj_datum dstruct;
    int count = 0;

    GPJ_get_datum_by_name(inputname, &dstruct);
    if (dstruct.dx < 99999 && dstruct.dy < 99999 && dstruct.dz < 99999) {
	/* Include the old-style dx dy dz parameters from datum.table at the 
	 * start of the list, unless these have been set to all 99999 to 
	 * indicate only entries in datumtransform.table should be used */
	if (current == NULL)
	    current = outputlist =
		G_malloc(sizeof(struct gpj_datum_transform_list));
	else
	    current = current->next =
		G_malloc(sizeof(struct gpj_datum_transform_list));
	G_asprintf(&(current->params), "towgs84=%.3f,%.3f,%.3f", dstruct.dx,
		   dstruct.dy, dstruct.dz);
	G_asprintf(&(current->where_used), "whole %s region", inputname);
	G_asprintf(&(current->comment),
		   "Default 3-Parameter Transformation (May not be optimum for "
		   "older datums; use this only if no more appropriate options "
		   "are available.)");
	count++;
	current->count = count;
	current->next = NULL;
    }
    GPJ_free_datum(&dstruct);

    /* Now check for additional parameters in datumtransform.table */

    sprintf(file, "%s%s", G_gisbase(), DATUMTRANSFORMTABLE);

    fd = fopen(file, "r");
    if (!fd) {
	G_warning(_("Unable to open datum table file <%s>"), file);
	return outputlist;
    }

    for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
	char name[100], params[1024], where_used[1024], comment[1024];

	G_strip(buf);
	if (*buf == '\0' || *buf == '#')
	    continue;

	if (sscanf(buf, "%99s \"%1023[^\"]\" \"%1023[^\"]\" \"%1023[^\"]\"",
		   name, params, where_used, comment) != 4) {
	    G_warning(_("Error in datum table file <%s>, line %d"), file,
		      line);
	    continue;
	}

	if (G_strcasecmp(inputname, name) == 0) {
	    /* If the datum name in this line matches the one we are 
	     * looking for, add an entry to the linked list */
	    if (current == NULL)
		current = outputlist =
		    G_malloc(sizeof(struct gpj_datum_transform_list));
	    else
		current = current->next =
		    G_malloc(sizeof(struct gpj_datum_transform_list));
	    current->params = G_store(params);
	    current->where_used = G_store(where_used);
	    current->comment = G_store(comment);
	    count++;
	    current->count = count;
	    current->next = NULL;
	}
    }

    fclose(fd);

    return outputlist;

}
Beispiel #26
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;
}
Beispiel #27
0
int read_rules(FILE * fp)
{
    char buf[1024];
    DCELL oLow, oHigh, nLow, nHigh;
    int line, n;

    in_type = DCELL_TYPE;
    out_type = CELL_TYPE;

    rules = (char **)G_malloc(INCR * sizeof(char *));
    rule_size = INCR;

    if (isatty(fileno(fp))) {
	report_range();
	G_message(_("Enter the rule or 'help' for the format description"));
    }
    Rast_fpreclass_init(&rcl_struct);
    for (line = 1;; line++) {
	if (isatty(fileno(fp)))
	    fprintf(stderr, "> ");

	if (!G_getl2(buf, 1024, fp))
	    return nrules;

	G_debug(5, "buf = [%s], strlen(buf)=%d", buf, strlen(buf));

	for (n = 0; buf[n]; n++)
	    if (buf[n] == ',')
		buf[n] = ' ';
	G_strip(buf);
	if (*buf == 0)
	    continue;
	if (*buf == '#')
	    continue;
	if (strcmp(buf, "end") == 0)
	    break;

	if (strcmp(buf, "help") == 0) {
	    G_message(_("Enter a rule in one of these formats:"));
	    G_message(" ");
	    G_message(_("old_low:old_high:new_low:new_high"));
	    G_message(_("old_low:old_high:new_val      (i.e. new_high == new_low)"));
	    G_message(_("*:old_val:new_val             (interval [inf, old_val])"));
	    G_message(_("old_val:*:new_val             (interval [old_val, inf])"));
	    G_message(" ");
	    G_message(_("When finished type \"end\"."));

	    continue;
	}

	/* 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:%lf:%lf", &oLow, &oHigh, &nLow, &nHigh)) {
	case 3:
	    update_type(&out_type, nLow);
	    update_rules(buf);
	    Rast_fpreclass_add_rule(&rcl_struct, oLow, oHigh, nLow, nLow);
	    break;

	case 4:
	    update_type(&out_type, nLow);
	    update_type(&out_type, nHigh);
	    update_rules(buf);
	    Rast_fpreclass_add_rule(&rcl_struct, oLow, oHigh, nLow, nHigh);
	    break;

	default:
	    if (sscanf(buf, "%lf:*:%lf", &oLow, &nLow) == 2) {
		update_type(&out_type, nLow);
		update_rules(buf);
		Rast_fpreclass_set_pos_infinite_rule(&rcl_struct, oLow, nLow);
	    }
	    else if (sscanf(buf, "*:%lf:%lf", &oHigh, &nLow) == 2) {
		update_type(&out_type, nLow);
		update_rules(buf);
		Rast_fpreclass_set_neg_infinite_rule(&rcl_struct, oHigh, nLow);
	    }
	    else
		G_message(_("%s is not a valid rule"), buf);
	    break;
	}			/* switch */
    }				/* loop */
    return nrules;
}
Beispiel #28
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;
}
Beispiel #29
0
struct proj_parm *get_proj_parms(const char *arg)
{
    char buf[4096];
    struct proj_parm *parm_table = NULL;
    int parm_num = 0;
    int parm_max = 0;
    char *data;
    int done;
    FILE *fp;

    sprintf(buf, "%s/etc/proj/parms.table", G_gisbase());

    fp = fopen(buf, "r");
    if (!fp)
	return NULL;

    for (data = NULL; !data;) {
	char *p;

	if (!G_getl2(buf, sizeof(buf), fp))
	    break;

	for (p = buf; *p && *p != ':'; p++) ;

	if (*p != ':')
	    break;

	*p++ = '\0';

	if (G_strcasecmp(buf, arg) != 0)
	    continue;

	for (; *p && *p != ':'; p++) ;

	if (*p != ':')
	    break;

	*p++ = '\0';

	data = p;
    }

    fclose(fp);

    if (!data)
	return NULL;

    for (done = 0; !done;) {
	char name[16], ask[8], dfl[32];
	struct proj_parm *parm;
	char *p;

	for (p = data; *p && *p != ';'; p++) ;

	if (*p == ';')
	    *p++ = '\0';
	else
	    done = 1;

	if (sscanf(data, "%[^=]=%[^,],%s", name, ask, dfl) != 3) {
	    data = p;
	    continue;
	}

	data = p;

	if (parm_num + 1 >= parm_max) {
	    parm_max += 16;
	    parm_table =
		G_realloc(parm_table, parm_max * sizeof(struct proj_parm));
	}

	parm = &parm_table[parm_num++];

	parm->name = G_store(name);

	if (strcmp(ask, "ask") == 0)
	    parm->ask = 1;
	else if (strcmp(ask, "noask") == 0)
	    parm->ask = 0;
	else {
	    parm->ask = 1;
	    G_warning(_("Unrecognized 'ask' value in parms.table: %s"),
		      ask);
	}

	if (strcmp(dfl, "nodfl") == 0)
	    parm->def_exists = 0;
	else if (sscanf(dfl, "%lf", &parm->deflt) == 1)
	    parm->def_exists = 1;
	else {
	    parm->def_exists = 0;
	    G_warning(_("Unrecognized default value in parms.table: %s"),
		      dfl);
	}
    }

    parm_table[parm_num].name = NULL;

    return parm_table;
}
Beispiel #30
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);

}