Esempio n. 1
0
static void create_table(struct Map_info *flowline_vec,
			 struct field_info **f_info, dbDriver ** driver,
			 int write_scalar, int use_sampled_map)
{
    dbString sql;
    char buf[200];
    dbDriver *drvr;
    struct field_info *fi;

    db_init_string(&sql);
    fi = Vect_default_field_info(flowline_vec, 1, NULL, GV_1TABLE);
    *f_info = fi;
    Vect_map_add_dblink(flowline_vec, 1, NULL, fi->table, GV_KEY_COLUMN,
			fi->database, fi->driver);
    drvr = db_start_driver_open_database(fi->driver,
					 Vect_subst_var(fi->database,
							flowline_vec));
    if (drvr == NULL) {
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Vect_subst_var(fi->database, flowline_vec), fi->driver);
    }
    db_set_error_handler_driver(drvr);

    *driver = drvr;
    sprintf(buf, "create table %s (cat integer, velocity double precision",
	    fi->table);
    db_set_string(&sql, buf);
    if (write_scalar)
	db_append_string(&sql, ", input double precision");
    if (use_sampled_map)
	db_append_string(&sql, ", sampled double precision");
    db_append_string(&sql, ")");

    db_begin_transaction(drvr);
    /* Create table */
    if (db_execute_immediate(drvr, &sql) != DB_OK) {
	G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql));
    }
    if (db_create_index2(drvr, fi->table, fi->key) != DB_OK)
	G_warning(_("Unable to create index for table <%s>, key <%s>"),
		  fi->table, fi->key);
    /* Grant */
    if (db_grant_on_table
	(drvr, fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) {
	G_fatal_error(_("Unable to grant privileges on table <%s>"),
		      fi->table);
    }
}
Esempio n. 2
0
int vect_to_rast(const char *vector_map, const char *raster_map, const char *field_name,
		 const char *column, int cache_mb, int use, double value,
		 int value_type, const char *rgbcolumn, const char *labelcolumn,
		 int ftype, char *where, char *cats, int dense)
{
    struct Map_info Map;
    struct line_pnts *Points;
    int i, field;
    struct cat_list *cat_list = NULL;
    int fd;			/* for raster map */
    int nareas, nlines;		/* number of converted features */
    int nareas_all, nplines_all;	/* number of all areas, points/lines */
    int stat;
    int format;
    int pass, npasses;

    /* Attributes */
    int nrec;
    int ctype = 0;
    struct field_info *Fi;
    dbDriver *Driver;
    dbCatValArray cvarr;
    int is_fp = 0;

    nareas = 0;

    G_verbose_message(_("Loading data..."));
    Vect_set_open_level(2);
    if (Vect_open_old2(&Map, vector_map, "", field_name) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), vector_map);

    field = Vect_get_field_number(&Map, field_name);

    if (field > 0)
	cat_list = Vect_cats_set_constraint(&Map, field, where, cats);


    if ((use == USE_Z) && !(Vect_is_3d(&Map)))
	G_fatal_error(_("Vector map <%s> is not 3D"),
		      Vect_get_full_name(&Map));

    switch (use) {
    case USE_ATTR:
	db_CatValArray_init(&cvarr);
	if (!(Fi = Vect_get_field(&Map, field)))
	    G_fatal_error(_("Database connection not defined for layer <%s>"),
			  field_name);

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

	/* Note do not check if the column exists in the table because it may be expression */

	if ((nrec =
	     db_select_CatValArray(Driver, Fi->table, Fi->key, column, NULL,
				   &cvarr)) == -1)
	    G_fatal_error(_("Column <%s> not found"), column);
	G_debug(3, "nrec = %d", nrec);

	ctype = cvarr.ctype;
	if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
	    G_fatal_error(_("Column type (%s) not supported (did you mean 'labelcolumn'?)"),
			  db_sqltype_name(ctype));

	if (nrec < 0)
	    G_fatal_error(_("No records selected from table <%s>"),
			  Fi->table);

	G_debug(1, "%d records selected from table", nrec);

	db_close_database_shutdown_driver(Driver);

	for (i = 0; i < cvarr.n_values; i++) {
	    if (ctype == DB_C_TYPE_INT) {
		G_debug(3, "cat = %d val = %d", cvarr.value[i].cat,
			cvarr.value[i].val.i);
	    }
	    else if (ctype == DB_C_TYPE_DOUBLE) {
		G_debug(3, "cat = %d val = %f", cvarr.value[i].cat,
			cvarr.value[i].val.d);
	    }
	}
	
	switch (ctype) {
	case DB_C_TYPE_INT:
	    format = CELL_TYPE;
	    break;
	case DB_C_TYPE_DOUBLE:
	    format = DCELL_TYPE;
	    break;
	default:
	    G_fatal_error(_("Unable to use column <%s>"), column);
	    break;
	}
	break;
    case USE_CAT:
	format = CELL_TYPE;
	break;
    case USE_VAL:
	format = value_type;
	break;
    case USE_Z:
	format = DCELL_TYPE;
	is_fp = 1;
	break;
    case USE_D:
	format = DCELL_TYPE;
	break;
    default:
	G_fatal_error(_("Unknown use type: %d"), use);
    }

    fd = Rast_open_new(raster_map, format);

    Points = Vect_new_line_struct();

    if (use != USE_Z && use != USE_D && (ftype & GV_AREA)) {
	if ((nareas = sort_areas(&Map, Points, field, cat_list)) == 0)
	    G_warning(_("No areas selected from vector map <%s>"),
			  vector_map);

	G_debug(1, "%d areas sorted", nareas);
    }
    if (nareas > 0 && dense) {
	G_warning(_("Area conversion and line densification are mutually exclusive, disabling line densification."));
	dense = 0;
    }

    nlines = Vect_get_num_primitives(&Map, ftype);
    nplines_all = nlines;
    npasses = begin_rasterization(cache_mb, format, dense);
    pass = 0;

    nareas_all = Vect_get_num_areas(&Map);

    do {
	pass++;

	if (npasses > 1)
	    G_message(_("Pass %d of %d:"), pass, npasses);

	stat = 0;

	if ((use != USE_Z && use != USE_D) && nareas) {
	    if (do_areas
		(&Map, Points, &cvarr, ctype, use, value,
		 value_type) < 0) {
		G_warning(_("Problem processing areas from vector map <%s>, continuing..."),
			  vector_map);
		stat = -1;
		break;
	    }
	}

	if (nlines) {
	    if ((nlines =
		 do_lines(&Map, Points, &cvarr, ctype, field, cat_list, 
		          use, value, value_type, ftype,
			  &nplines_all, dense)) < 0) {
		G_warning(_("Problem processing lines from vector map <%s>, continuing..."),
			  vector_map);
		stat = -1;
		break;
	    }
	}

	G_important_message(_("Writing raster map..."));

	stat = output_raster(fd);
    } while (stat == 0);

    G_suppress_warnings(0);
    /* stat: 0 == repeat; 1 == done; -1 == error; */

    Vect_destroy_line_struct(Points);

    if (stat < 0) {
	Rast_unopen(fd);

	return 1;
    }

    Vect_close(&Map);

    G_verbose_message(_("Creating support files for raster map..."));
    Rast_close(fd);
    update_hist(raster_map, vector_map, Map.head.orig_scale);

    /* colors */
    if (rgbcolumn) {
	if (use != USE_ATTR && use != USE_CAT) {
	    G_warning(_("Color can be updated from database only if use=attr"));
	    update_colors(raster_map);
	}
	else {
	  update_dbcolors(raster_map, vector_map, field, rgbcolumn, is_fp,
			  column);
	}
    }
    else if (use == USE_D)
	update_fcolors(raster_map);
    else
	update_colors(raster_map);

    update_cats(raster_map);

    /* labels */
    update_labels(raster_map, vector_map, field, labelcolumn, use, value,
		  column);

#if 0
    /* maximum possible numer of areas: number of centroids
     * actual number of areas, currently unknown:
     * number of areas with centroid that are within cat constraint
     * and overlap with current region */
    if (nareas_all > 0)
	G_message(_("Converted areas: %d of %d"), nareas,
	          Vect_get_num_primitives(&Map, GV_CENTROID));
    /* maximum possible numer of lines: number of GV_LINE + GV_POINT
     * actual number of lines, currently unknown:
     * number of lines are within cat constraint
     * and overlap with current region */
    if (nlines > 0 && nplines_all > 0)
	G_message(_("Converted points/lines: %d of %d"), nlines, nplines_all);
#endif

    return 0;
}
Esempio n. 3
0
int close_streamvect(char *stream_vect)
{
    int r, c, r_nbr, c_nbr, done;
    GW_LARGE_INT i;
    CELL stream_id, stream_nbr;
    ASP_FLAG af;
    int next_node;
    struct sstack
    {
	int stream_id;
	int next_trib;
    } *nodestack;
    int top = 0, stack_step = 1000;
    int asp_r[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 };
    int asp_c[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 };
    struct Map_info Out;
    static struct line_pnts *Points;
    struct line_cats *Cats;
    dbDriver *driver;
    dbHandle handle;
    dbString table_name, dbsql, valstr;
    struct field_info *Fi;
    char *cat_col_name = "cat", buf[2000];
    struct Cell_head window;
    double north_offset, west_offset, ns_res, ew_res;
    int next_cat;

    G_message(_("Writing vector map <%s>..."), stream_vect);

    if (Vect_open_new(&Out, stream_vect, 0) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"), stream_vect);
    
    nodestack = (struct sstack *)G_malloc(stack_step * sizeof(struct sstack));

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    G_get_set_window(&window);
    ns_res = window.ns_res;
    ew_res = window.ew_res;
    north_offset = window.north - 0.5 * ns_res;
    west_offset = window.west + 0.5 * ew_res;

    next_cat = n_stream_nodes + 1;

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

	if (!stream_id)
	    continue;

	Vect_reset_line(Points);
	Vect_reset_cats(Cats);

	/* outlet */
	Vect_cat_set(Cats, 1, stream_id);
	Vect_cat_set(Cats, 2, 2);
	Vect_append_point(Points, west_offset + c * ew_res,
			  north_offset - r * ns_res, 0);
	Vect_write_line(&Out, GV_POINT, Points, Cats);

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

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

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

		Vect_reset_line(Points);
		Vect_reset_cats(Cats);

		r_nbr = stream_node[stream_id].r;
		c_nbr = stream_node[stream_id].c;

		cseg_get(&stream, &stream_nbr, r_nbr, c_nbr);
		if (stream_nbr <= 0)
                    G_fatal_error(_("Stream id %d not set, top is %d, parent is %d"),
                                  stream_id, top, nodestack[top - 1].stream_id);

		Vect_cat_set(Cats, 1, stream_id);
		if (stream_node[stream_id].n_trib == 0)
		    Vect_cat_set(Cats, 2, 0);
		else
		    Vect_cat_set(Cats, 2, 1);

		Vect_append_point(Points, west_offset + c_nbr * ew_res,
				  north_offset - r_nbr * ns_res, 0);

		Vect_write_line(&Out, GV_POINT, Points, Cats);

		seg_get(&aspflag, (char *)&af, r_nbr, c_nbr);
		while (af.asp > 0) {
		    r_nbr = r_nbr + asp_r[(int)af.asp];
		    c_nbr = c_nbr + asp_c[(int)af.asp];
		    
		    cseg_get(&stream, &stream_nbr, r_nbr, c_nbr);
		    if (stream_nbr <= 0)
			G_fatal_error(_("Stream id not set while tracing"));

		    Vect_append_point(Points, west_offset + c_nbr * ew_res,
				      north_offset - r_nbr * ns_res, 0);
		    if (stream_nbr != stream_id) {
			/* first point of parent stream */
			break;
		    }
		    seg_get(&aspflag, (char *)&af, r_nbr, c_nbr);
		}

		Vect_write_line(&Out, GV_LINE, Points, Cats);

		top--;
	    }
	}
    }
    G_percent(n_outlets, n_outlets, 1);	/* finish it */

    G_message(_("Writing attribute data..."));

    /* Prepeare strings for use in db_* calls */
    db_init_string(&dbsql);
    db_init_string(&valstr);
    db_init_string(&table_name);
    db_init_handle(&handle);

    /* Preparing database for use */
    /* Create database for new vector map */
    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
    driver = db_start_driver_open_database(Fi->driver,
					   Vect_subst_var(Fi->database,
							          &Out));
    if (driver == NULL) {
	G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
    }
    db_set_error_handler_driver(driver);

    G_debug(1, "table: %s", Fi->table);
    G_debug(1, "driver: %s", Fi->driver);
    G_debug(1, "database: %s", Fi->database);

    sprintf(buf,
	    "create table %s (%s integer, stream_type varchar(20), type_code integer)",
	    Fi->table, cat_col_name);
    db_set_string(&dbsql, buf);

    if (db_execute_immediate(driver, &dbsql) != DB_OK) {
	db_close_database(driver);
	db_shutdown_driver(driver);
	G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&dbsql));
    }

    if (db_create_index2(driver, Fi->table, cat_col_name) != DB_OK)
	G_warning(_("Unable to create index on table <%s>"), Fi->table);

    if (db_grant_on_table(driver, Fi->table, DB_PRIV_SELECT,
			  DB_GROUP | DB_PUBLIC) != DB_OK)
	G_fatal_error(_("Unable to grant privileges on table <%s>"), Fi->table);

    db_begin_transaction(driver);

    /* stream nodes */
    for (i = 1; i <= n_stream_nodes; i++) {

	sprintf(buf, "insert into %s values ( %lld, \'%s\', %d )",
		Fi->table, i,
		(stream_node[i].n_trib > 0 ? "intermediate" : "start"),
		(stream_node[i].n_trib > 0));

	db_set_string(&dbsql, buf);

	if (db_execute_immediate(driver, &dbsql) != DB_OK) {
	    db_close_database(driver);
	    db_shutdown_driver(driver);
	    G_fatal_error(_("Unable to insert new row: '%s'"),
			  db_get_string(&dbsql));
	}
    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

    Vect_map_add_dblink(&Out, 1, NULL, Fi->table,
			cat_col_name, Fi->database, Fi->driver);

    G_debug(1, "close vector");

    Vect_hist_command(&Out);
    Vect_build(&Out);
    Vect_close(&Out);

    G_free(nodestack);

    return 1;
}
Esempio n. 4
0
int update(struct Map_info *Map)
{
    int i, *catexst, *cex, upd, fcat;
    char buf1[2000], buf2[2000], left[20], right[20];
    struct field_info *qFi, *Fi;
    dbString stmt;
    dbDriver *driver;

    vstat.dupl = 0;
    vstat.exist = 0;
    vstat.notexist = 0;
    vstat.update = 0;
    vstat.error = 0;

    db_init_string(&stmt);

    /* layer to find table to read from */
    qFi = Vect_get_field(Map, options.qfield);
    if (options.option == O_QUERY && qFi == NULL)
        G_fatal_error(_("Database connection not defined for layer %d. Use v.db.connect first."),
                      options.qfield);
    /* layer to find table to write to */
    if ((Fi = Vect_get_field(Map, options.field)) == NULL)
	G_fatal_error(_("Database connection not defined for layer %d. Use v.db.connect first."),
		      options.field);
    if (qFi) {
      G_debug(3, "Reading from map <%s>, query layer %d (table <%s>): updating table <%s>, column <%s>", 
	      options.name, options.qfield, qFi->table, Fi->table, Fi->key);
    }
    else {
      G_debug(3, "Reading from map <%s>, updating table <%s>, column <%s>", 
	      options.name, Fi->table, Fi->key);
    }

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

    db_begin_transaction(driver);

    /* select existing categories (layer) to array (array is sorted) */
    vstat.select = db_select_int(driver, Fi->table, Fi->key, NULL, &catexst);
    G_debug(3, "Existing categories: %d", vstat.select);
    
    /* create beginning of stmt */
    switch (options.option) {
    case O_CAT:
	sprintf(buf1, "insert into %s ( %s ) values ", Fi->table, Fi->key);
	break;
    case O_COUNT:
    case O_LENGTH:
    case O_AREA:
    case O_QUERY:
    case O_COMPACT:
    case O_FD:
    case O_PERIMETER:
    case O_SLOPE:
    case O_SINUOUS:
    case O_AZIMUTH:
	sprintf(buf1, "update %s set %s =", Fi->table, options.col[0]);
	break;
    case O_COOR:
    case O_START:
    case O_END:
    case O_SIDES:
	sprintf(buf1, "update %s set ", Fi->table);
	break;
    }

    /* update */
    G_message(_("Updating database..."));
    for (i = 0; i < vstat.rcat; i++) {
	G_percent(i, vstat.rcat, 2);

	fcat = Values[i].cat;	
	if (fcat < 0)
	    continue;
	switch (options.option) {
	case O_CAT:
	    sprintf(buf2, "%s ( %d )", buf1, Values[i].cat);
	    break;

	case O_COUNT:
	    sprintf(buf2, "%s %d where %s = %d", buf1, Values[i].count1,
		    Fi->key, Values[i].cat);
	    break;

	case O_LENGTH:
	case O_AREA:
	case O_COMPACT:
	case O_FD:
	case O_PERIMETER:
	case O_SLOPE:
	case O_SINUOUS:
	case O_AZIMUTH:
	    sprintf(buf2, "%s %f where %s = %d", buf1, Values[i].d1, Fi->key,
		    Values[i].cat);
	    break;

	case O_COOR:
	case O_START:
	case O_END:
	    if (Values[i].count1 > 1) {
		G_warning(_("More elements of category %d, nothing loaded to database"),
			  Values[i].cat);
		vstat.dupl++;
		continue;
	    }
	    if (Values[i].count1 < 1) {	/* No points */
		continue;
	    }
	    if (options.col[2]) {
		sprintf(buf2,
			"%s %s = %.15g, %s = %.15g, %s = %.15g where %s = %d",
			buf1, options.col[0], Values[i].d1, options.col[1],
			Values[i].d2, options.col[2], Values[i].d3, Fi->key,
			Values[i].cat);
	    }
	    else {
		sprintf(buf2, "%s %s = %.15g, %s = %.15g  where %s = %d",
			buf1, options.col[0], Values[i].d1, options.col[1],
			Values[i].d2, Fi->key, Values[i].cat);
	    }
	    break;

	case O_SIDES:
	    if (Values[i].count1 == 1) {
		if (Values[i].i1 >= 0)
		    sprintf(left, "%d", Values[i].i1);
		else
		    sprintf(left, "-1");	/* NULL, no area/cat */
	    }
	    else if (Values[i].count1 > 1) {
		sprintf(left, "null");
	    }
	    else {		/* Values[i].count1 == 0 */
		/* It can be OK if the category is assigned to an element
		   type which is not GV_BOUNDARY */
		/* -> TODO: print only if there is boundary with that cat */
		sprintf(left, "null");
	    }

	    if (Values[i].count2 == 1) {
		if (Values[i].i2 >= 0)
		    sprintf(right, "%d", Values[i].i2);
		else
		    sprintf(right, "-1");	/* NULL, no area/cat */
	    }
	    else if (Values[i].count2 > 1) {
		sprintf(right, "null");
	    }
	    else {		/* Values[i].count1 == 0 */
		sprintf(right, "null");
	    }

	    sprintf(buf2, "%s %s = %s, %s = %s  where %s = %d", buf1,
		    options.col[0], left, options.col[1], right, Fi->key,
		    Values[i].cat);

	    break;

	case O_QUERY:
	    if (Values[i].null) {
		sprintf(buf2, "%s null where %s = %d", buf1, Fi->key,
			Values[i].cat);
	    }
	    else {
		switch (vstat.qtype) {
		case (DB_C_TYPE_INT):
		    sprintf(buf2, "%s %d where %s = %d", buf1, Values[i].i1,
			    Fi->key, Values[i].cat);
		    break;
		case (DB_C_TYPE_DOUBLE):
		    sprintf(buf2, "%s %f where %s = %d", buf1, Values[i].d1,
			    Fi->key, Values[i].cat);
		    break;
		case (DB_C_TYPE_STRING):
		    sprintf(buf2, "%s '%s' where %s = %d", buf1,
			    Values[i].str1, Fi->key, Values[i].cat);
		    break;
		case (DB_C_TYPE_DATETIME):
		    sprintf(buf2, "%s '%s' where %s = %d", buf1,
			    Values[i].str1, Fi->key, Values[i].cat);
		    break;
		}
	    }
	}

	G_debug(3, "SQL: %s", buf2);
	db_set_string(&stmt, buf2);

	/* category exist in DB table ? */
	cex = (int *)bsearch((void *)&fcat, catexst, vstat.select, sizeof(int),
			     srch);
	
	if (options.option == O_CAT) {
	    if (cex == NULL) {	/* cat does not exist in DB */
		upd = 1;
		vstat.notexist++;
	    }
	    else {		/* cat exists in DB */
		G_warning(_("Record (cat %d) already exists (not inserted)"),
			  fcat);
		upd = 0;
		vstat.exist++;
	    }
	}
	else {
	    if (cex == NULL) {	/* cat does not exist in DB */
		G_warning(_("Record (cat %d) does not exist (not updated)"),
			  fcat);
		upd = 0;
		vstat.notexist++;
	    }
	    else {		/* cat exists in DB */
		upd = 1;
		vstat.exist++;
	    }
	}

	if (upd == 1) {
	    if (options.sql) {
		fprintf(stdout, "%s\n", db_get_string(&stmt));
	    }
	    else {
		if (db_execute_immediate(driver, &stmt) == DB_OK) {
		    vstat.update++;
		}
		else {
		    vstat.error++;
		}
	    }
	}
    }
    G_percent(1, 1, 1);

    db_commit_transaction(driver);

    G_free(catexst);
    
    db_close_database_shutdown_driver(driver);
    db_free_string(&stmt);

    return 0;
}
Esempio n. 5
0
/*--------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* Variable declarations */
    int nsply, nsplx, nrows, ncols, nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row, subregion_row, subregion_col;
    int subregion = 0, nsubregions = 0;
    int last_row, last_column, grid, bilin, ext, flag_auxiliar, cross;	/* booleans */
    double stepN, stepE, lambda, mean;
    double N_extension, E_extension, edgeE, edgeN;

    const char *mapset, *drv, *db, *vector, *map;
    char table_name[GNAME_MAX], title[64];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    int dim_vect, nparameters, BW;
    int *lineVect;		/* Vector restoring primitive's ID */
    double *TN, *Q, *parVect;	/* Interpolating and least-square vectors */
    double **N, **obsVect;	/* Interpolation and least-square matrix */

    SEGMENT out_seg, mask_seg;
    const char *out_file, *mask_file;
    int out_fd, mask_fd;
    double seg_size;
    int seg_mb, segments_in_memory;
    int have_mask;

    /* Structs declarations */
    int raster;
    struct Map_info In, In_ext, Out;
    struct History history;

    struct GModule *module;
    struct Option *in_opt, *in_ext_opt, *out_opt, *out_map_opt, *stepE_opt,
               *stepN_opt, *lambda_f_opt, *type_opt, *dfield_opt, *col_opt, *mask_opt,
               *memory_opt, *solver, *error, *iter;
    struct Flag *cross_corr_flag, *spline_step_flag;

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

    struct Point *observ;
    struct line_cats *Cats;
    dbCatValArray cvarr;

    int with_z;
    int nrec, ctype = 0;
    struct field_info *Fi;
    dbDriver *driver, *driver_cats;

    /*----------------------------------------------------------------*/
    /* Options declarations */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("surface"));
    G_add_keyword(_("interpolation"));
    G_add_keyword(_("LIDAR"));
    module->description =
        _("Performs bicubic or bilinear spline interpolation with Tykhonov regularization.");

    cross_corr_flag = G_define_flag();
    cross_corr_flag->key = 'c';
    cross_corr_flag->description =
        _("Find the best Tykhonov regularizing parameter using a \"leave-one-out\" cross validation method");

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

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_opt->label = _("Name of input vector point map");

    dfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    dfield_opt->guisection = _("Settings");

    col_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    col_opt->required = NO;
    col_opt->label =
        _("Name of the attribute column with values to be used for approximation");
    col_opt->description = _("If not given and input is 3D vector map then z-coordinates are used.");
    col_opt->guisection = _("Settings");

    in_ext_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_ext_opt->key = "sparse_input";
    in_ext_opt->required = NO;
    in_ext_opt->label =
        _("Name of input vector map with sparse points");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    out_opt->required = NO;
    out_opt->guisection = _("Outputs");

    out_map_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_map_opt->key = "raster_output";
    out_map_opt->required = NO;
    out_map_opt->guisection = _("Outputs");

    mask_opt = G_define_standard_option(G_OPT_R_INPUT);
    mask_opt->key = "mask";
    mask_opt->label = _("Raster map to use for masking (applies to raster output only)");
    mask_opt->description = _("Only cells that are not NULL and not zero are interpolated");
    mask_opt->required = NO;

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

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

    type_opt = G_define_option();
    type_opt->key = "method";
    type_opt->description = _("Spline interpolation algorithm");
    type_opt->type = TYPE_STRING;
    type_opt->options = "bilinear,bicubic";
    type_opt->answer = "bilinear";
    type_opt->guisection = _("Settings");
    G_asprintf((char **) &(type_opt->descriptions),
               "bilinear;%s;bicubic;%s",
               _("Bilinear interpolation"),
               _("Bicubic interpolation"));

    lambda_f_opt = G_define_option();
    lambda_f_opt->key = "lambda_i";
    lambda_f_opt->type = TYPE_DOUBLE;
    lambda_f_opt->required = NO;
    lambda_f_opt->description = _("Tykhonov regularization parameter (affects smoothing)");
    lambda_f_opt->answer = "0.01";
    lambda_f_opt->guisection = _("Settings");

    solver = N_define_standard_option(N_OPT_SOLVER_SYMM);
    solver->options = "cholesky,cg";
    solver->answer = "cholesky";

    iter = N_define_standard_option(N_OPT_MAX_ITERATIONS);

    error = N_define_standard_option(N_OPT_ITERATION_ERROR);

    memory_opt = G_define_option();
    memory_opt->key = "memory";
    memory_opt->type = TYPE_INTEGER;
    memory_opt->required = NO;
    memory_opt->answer = "300";
    memory_opt->label = _("Maximum memory to be used (in MB)");
    memory_opt->description = _("Cache size for raster rows");

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

    vector = out_opt->answer;
    map = out_map_opt->answer;

    if (vector && map)
        G_fatal_error(_("Choose either vector or raster output, not both"));

    if (!vector && !map && !cross_corr_flag->answer)
        G_fatal_error(_("No raster or vector or cross-validation output"));

    if (!strcmp(type_opt->answer, "linear"))
        bilin = P_BILINEAR;
    else
        bilin = P_BICUBIC;

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

    flag_auxiliar = FALSE;

    drv = db_get_default_driver_name();
    if (!drv) {
        if (db_set_default_connection() != DB_OK)
            G_fatal_error(_("Unable to set default DB connection"));
        drv = db_get_default_driver_name();
    }
    db = db_get_default_database_name();
    if (!db)
        G_fatal_error(_("No default DB defined"));

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

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

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

    /* Open input vector */
    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL)
        G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);

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

    bspline_field = 0; /* assume 3D input */
    bspline_column = col_opt->answer;

    with_z = !bspline_column && Vect_is_3d(&In);

    if (Vect_is_3d(&In)) {
        if (!with_z)
            G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation"));
        else
            G_verbose_message(_("Input is 3D: using z-coordinates for approximation"));
    }
    else { /* 2D */
        if (!bspline_column)
            G_fatal_error(_("Input vector map is 2D. Parameter <%s> required."), col_opt->key);
    }

    if (!with_z) {
        bspline_field = Vect_get_field_number(&In, dfield_opt->answer);
    }

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

        Vect_close(&In);
        exit(EXIT_SUCCESS);
    }

    /*----------------------------------------------------------------*/
    /* Cross-correlation begins */
    if (cross_corr_flag->answer) {
        G_debug(1, "CrossCorrelation()");
        cross = cross_correlation(&In, stepE, stepN);

        if (cross != TRUE)
            G_fatal_error(_("Cross validation didn't finish correctly"));
        else {
            G_debug(1, "Cross validation finished correctly");

            Vect_close(&In);

            G_done_msg(_("Cross validation finished for ew_step = %f and ns_step = %f"), stepE, stepN);
            exit(EXIT_SUCCESS);
        }
    }

    /* Open input ext vector */
    ext = FALSE;
    if (in_ext_opt->answer) {
        ext = TRUE;
        G_message(_("Vector map <%s> of sparse points will be interpolated"),
                  in_ext_opt->answer);

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

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

    /* Open output map */
    /* vector output */
    if (vector && !map) {
        if (strcmp(drv, "dbf") == 0)
            G_fatal_error(_("Sorry, the <%s> driver is not compatible with "
                            "the vector output of this module. "
                            "Try with raster output or another driver."), drv);

        Vect_check_input_output_name(in_opt->answer, out_opt->answer,
                                     G_FATAL_EXIT);
        grid = FALSE;

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

        /* Copy vector Head File */
        if (ext == FALSE) {
            Vect_copy_head_data(&In, &Out);
            Vect_hist_copy(&In, &Out);
        }
        else {
            Vect_copy_head_data(&In_ext, &Out);
            Vect_hist_copy(&In_ext, &Out);
        }
        Vect_hist_command(&Out);

        G_verbose_message(_("Points in input vector map <%s> will be interpolated"),
                          vector);
    }


    /* read z values from attribute table */
    if (bspline_field > 0) {
        G_message(_("Reading values from attribute table..."));
        db_CatValArray_init(&cvarr);
        Fi = Vect_get_field(&In, bspline_field);
        if (Fi == NULL)
            G_fatal_error(_("Cannot read layer info"));

        driver_cats = db_start_driver_open_database(Fi->driver, Fi->database);
        /*G_debug (0, _("driver=%s db=%s"), Fi->driver, Fi->database); */

        if (driver_cats == NULL)
            G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
                          Fi->database, Fi->driver);
        db_set_error_handler_driver(driver_cats);

        nrec =
            db_select_CatValArray(driver_cats, Fi->table, Fi->key,
                                  col_opt->answer, NULL, &cvarr);
        G_debug(3, "nrec = %d", nrec);

        ctype = cvarr.ctype;
        if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
            G_fatal_error(_("Column type not supported"));

        if (nrec < 0)
            G_fatal_error(_("Unable to select data from table"));

        G_verbose_message(_("%d records selected from table"), nrec);

        db_close_database_shutdown_driver(driver_cats);
    }

    /*----------------------------------------------------------------*/
    /* Interpolation begins */
    G_debug(1, "Interpolation()");

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

    /* Create auxiliary table */
    if (vector) {
        if ((flag_auxiliar = P_Create_Aux4_Table(driver, table_name)) == FALSE) {
            P_Drop_Aux_Table(driver, table_name);
            G_fatal_error(_("Interpolation: Creating table: "
                            "It was impossible to create table <%s>."),
                          table_name);
        }
        /* db_create_index2(driver, table_name, "ID"); */
        /* sqlite likes that ??? */
        db_close_database_shutdown_driver(driver);
        driver = db_start_driver_open_database(drv, db);
    }

    /* raster output */
    raster = -1;
    Rast_set_fp_type(DCELL_TYPE);
    if (!vector && map) {
        grid = TRUE;
        raster = Rast_open_fp_new(out_map_opt->answer);

        G_verbose_message(_("Cells for raster map <%s> will be interpolated"),
                          map);
    }

    /* Setting regions and boxes */
    G_debug(1, "Interpolation: Setting regions and boxes");
    G_get_window(&original_reg);
    G_get_window(&elaboration_reg);
    Vect_region_box(&original_reg, &original_box);
    Vect_region_box(&elaboration_reg, &overlap_box);
    Vect_region_box(&elaboration_reg, &general_box);

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

    /* Alloc raster matrix */
    have_mask = 0;
    out_file = mask_file = NULL;
    out_fd = mask_fd = -1;
    if (grid == TRUE) {
        int row;
        DCELL *drastbuf;

        seg_mb = atoi(memory_opt->answer);
        if (seg_mb < 3)
            G_fatal_error(_("Memory in MB must be >= 3"));

        if (mask_opt->answer)
            seg_size = sizeof(double) + sizeof(char);
        else
            seg_size = sizeof(double);

        seg_size = (seg_size * SEGSIZE * SEGSIZE) / (1 << 20);
        segments_in_memory = seg_mb / seg_size + 0.5;
        G_debug(1, "%d %dx%d segments held in memory", segments_in_memory, SEGSIZE, SEGSIZE);

        out_file = G_tempfile();
        out_fd = creat(out_file, 0666);
        if (Segment_format(out_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(double)) != 1)
            G_fatal_error(_("Can not create temporary file"));
        close(out_fd);

        out_fd = open(out_file, 2);
        if (Segment_init(&out_seg, out_fd, segments_in_memory) != 1)
            G_fatal_error(_("Can not initialize temporary file"));

        /* initialize output */
        G_message(_("Initializing output..."));

        drastbuf = Rast_allocate_buf(DCELL_TYPE);
        Rast_set_d_null_value(drastbuf, ncols);
        for (row = 0; row < nrows; row++) {
            G_percent(row, nrows, 2);
            Segment_put_row(&out_seg, drastbuf, row);
        }
        G_percent(row, nrows, 2);

        if (mask_opt->answer) {
            int row, col, maskfd;
            DCELL dval, *drastbuf;
            char mask_val;

            G_message(_("Load masking map"));

            mask_file = G_tempfile();
            mask_fd = creat(mask_file, 0666);
            if (Segment_format(mask_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(char)) != 1)
                G_fatal_error(_("Can not create temporary file"));
            close(mask_fd);

            mask_fd = open(mask_file, 2);
            if (Segment_init(&mask_seg, mask_fd, segments_in_memory) != 1)
                G_fatal_error(_("Can not initialize temporary file"));

            maskfd = Rast_open_old(mask_opt->answer, "");
            drastbuf = Rast_allocate_buf(DCELL_TYPE);

            for (row = 0; row < nrows; row++) {
                G_percent(row, nrows, 2);
                Rast_get_d_row(maskfd, drastbuf, row);
                for (col = 0; col < ncols; col++) {
                    dval = drastbuf[col];
                    if (Rast_is_d_null_value(&dval) || dval == 0)
                        mask_val = 0;
                    else
                        mask_val = 1;

                    Segment_put(&mask_seg, &mask_val, row, col);
                }
            }

            G_percent(row, nrows, 2);
            G_free(drastbuf);
            Rast_close(maskfd);

            have_mask = 1;
        }
    }

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

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

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

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

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

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

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

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

    nsubregions = nsubregion_row * nsubregion_col;

    /* Creating line and categories structs */
    Cats = Vect_new_cats_struct();
    Vect_cat_set(Cats, 1, 0);

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

    while (last_row == FALSE) {	/* For each subregion row */
        subregion_row++;
        P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                      GENERAL_ROW);

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

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

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

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

        nsply =
            ceil((elaboration_reg.north -
                  elaboration_reg.south) / stepN) + 0.5;
        G_debug(1, "Interpolation: nsply = %d", nsply);
        /*
        if (nsply > NSPLY_MAX)
            nsply = NSPLY_MAX;
        */
        elaboration_reg.east = original_reg.west;
        last_column = FALSE;
        subregion_col = 0;

        /* TODO: process each subregion using its own thread (via OpenMP or pthreads) */
        /*     I'm not sure about pthreads, but you can tell OpenMP to start all at the
        	same time and it will keep num_workers supplied with the next job as free
        	cpus become available */
        while (last_column == FALSE) {	/* For each subregion column */
            int npoints = 0;
            /* needed for sparse points interpolation */
            int npoints_ext, *lineVect_ext = NULL;
            double **obsVect_ext;	/*, mean_ext = .0; */
            struct Point *observ_ext;

            subregion_col++;
            subregion++;
            if (nsubregions > 1)
                G_message(_("Processing subregion %d of %d..."), subregion, nsubregions);

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

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

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

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

                P_set_regions(&elaboration_reg, &general_box, &overlap_box,
                              dims, LAST_COLUMN);
                last_column = TRUE;
            }
            nsplx =
                ceil((elaboration_reg.east -
                      elaboration_reg.west) / stepE) + 0.5;
            G_debug(1, "Interpolation: nsplx = %d", nsplx);
            /*
            if (nsplx > NSPLX_MAX)
            nsplx = NSPLX_MAX;
            */
            G_debug(1, "Interpolation: (%d,%d): subregion bounds",
                    subregion_row, subregion_col);
            G_debug(1, "Interpolation: \t\tNORTH:%.2f\t",
                    elaboration_reg.north);
            G_debug(1, "Interpolation: WEST:%.2f\t\tEAST:%.2f",
                    elaboration_reg.west, elaboration_reg.east);
            G_debug(1, "Interpolation: \t\tSOUTH:%.2f",
                    elaboration_reg.south);

#ifdef DEBUG_SUBREGIONS
            fprintf(stdout, "B 5\n");
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.north);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.south);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.south);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north);
            fprintf(stdout, "C 1 1\n");
            fprintf(stdout, " %.11g %.11g\n", (elaboration_reg.west + elaboration_reg.east) / 2,
                    (elaboration_reg.south + elaboration_reg.north) / 2);
            fprintf(stdout, " 1 %d\n", subregion);
#endif



            /* reading points in interpolation region */
            dim_vect = nsplx * nsply;
            observ_ext = NULL;
            if (grid == FALSE && ext == TRUE) {
                observ_ext =
                    P_Read_Vector_Region_Map(&In_ext,
                                             &elaboration_reg,
                                             &npoints_ext, dim_vect,
                                             1);
            }
            else
                npoints_ext = 1;

            if (grid == TRUE && have_mask) {
                /* any unmasked cells in general region ? */
                mean = 0;
                observ_ext =
                    P_Read_Raster_Region_masked(&mask_seg, &original_reg,
                                                original_box, general_box,
                                                &npoints_ext, dim_vect, mean);
            }

            observ = NULL;
            if (npoints_ext > 0) {
                observ =
                    P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints,
                                             dim_vect, bspline_field);
            }
            else
                npoints = 1;

            G_debug(1,
                    "Interpolation: (%d,%d): Number of points in <elaboration_box> is %d",
                    subregion_row, subregion_col, npoints);
            if (npoints > 0)
                G_verbose_message(_("%d points found in this subregion"), npoints);
            /* only interpolate if there are any points in current subregion */
            if (npoints > 0 && npoints_ext > 0) {
                int i;

                nparameters = nsplx * nsply;
                BW = P_get_BandWidth(bilin, nsply);

                /* Least Squares system */
                N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
                TN = G_alloc_vector(nparameters);	/* vector */
                parVect = G_alloc_vector(nparameters);	/* Parameters vector */
                obsVect = G_alloc_matrix(npoints, 3);	/* Observation vector */
                Q = G_alloc_vector(npoints);	/* "a priori" var-cov matrix */
                lineVect = G_alloc_ivector(npoints);	/*  */

                for (i = 0; i < npoints; i++) {	/* Setting obsVect vector & Q matrix */
                    double dval;

                    Q[i] = 1;	/* Q=I */
                    lineVect[i] = observ[i].lineID;
                    obsVect[i][0] = observ[i].coordX;
                    obsVect[i][1] = observ[i].coordY;

                    /* read z coordinates from attribute table */
                    if (bspline_field > 0) {
                        int cat, ival, ret;

                        cat = observ[i].cat;
                        if (cat < 0)
                            continue;

                        if (ctype == DB_C_TYPE_INT) {
                            ret =
                                db_CatValArray_get_value_int(&cvarr, cat,
                                                             &ival);
                            obsVect[i][2] = ival;
                            observ[i].coordZ = ival;
                        }
                        else {	/* DB_C_TYPE_DOUBLE */
                            ret =
                                db_CatValArray_get_value_double(&cvarr, cat,
                                                                &dval);
                            obsVect[i][2] = dval;
                            observ[i].coordZ = dval;
                        }
                        if (ret != DB_OK) {
                            G_warning(_("Interpolation: (%d,%d): No record for point (cat = %d)"),
                                      subregion_row, subregion_col, cat);
                            continue;
                        }
                    }
                    /* use z coordinates of 3D vector */
                    else {
                        obsVect[i][2] = observ[i].coordZ;
                    }
                }

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

                G_debug(1, "Interpolation: (%d,%d): mean=%lf",
                        subregion_row, subregion_col, mean);

                G_free(observ);

                for (i = 0; i < npoints; i++)
                    obsVect[i][2] -= mean;

                /* Bilinear interpolation */
                if (bilin) {
                    G_debug(1,
                            "Interpolation: (%d,%d): Bilinear interpolation...",
                            subregion_row, subregion_col);
                    normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx,
                                   nsply, elaboration_reg.west,
                                   elaboration_reg.south, npoints,
                                   nparameters, BW);
                    nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
                }
                /* Bicubic interpolation */
                else {
                    G_debug(1,
                            "Interpolation: (%d,%d): Bicubic interpolation...",
                            subregion_row, subregion_col);
                    normalDefBicubic(N, TN, Q, obsVect, stepE, stepN, nsplx,
                                     nsply, elaboration_reg.west,
                                     elaboration_reg.south, npoints,
                                     nparameters, BW);
                    nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
                }

                if(G_strncasecmp(solver->answer, "cg", 2) == 0)
                    G_math_solver_cg_sband(N, parVect, TN, nparameters, BW, atoi(iter->answer), atof(error->answer));
                else
                    G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW);


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

                if (grid == TRUE) {	/* GRID INTERPOLATION ==> INTERPOLATION INTO A RASTER */
                    G_debug(1, "Interpolation: (%d,%d): Regular_Points...",
                            subregion_row, subregion_col);

                    if (!have_mask) {
                        P_Regular_Points(&elaboration_reg, &original_reg, general_box,
                                         overlap_box, &out_seg, parVect,
                                         stepN, stepE, dims.overlap, mean,
                                         nsplx, nsply, nrows, ncols, bilin);
                    }
                    else {
                        P_Sparse_Raster_Points(&out_seg,
                                               &elaboration_reg, &original_reg,
                                               general_box, overlap_box,
                                               observ_ext, parVect,
                                               stepE, stepN,
                                               dims.overlap, nsplx, nsply,
                                               npoints_ext, bilin, mean);
                    }
                }
                else {		/* OBSERVATION POINTS INTERPOLATION */
                    if (ext == FALSE) {
                        G_debug(1, "Interpolation: (%d,%d): Sparse_Points...",
                                subregion_row, subregion_col);
                        P_Sparse_Points(&Out, &elaboration_reg, general_box,
                                        overlap_box, obsVect, parVect,
                                        lineVect, stepE, stepN,
                                        dims.overlap, nsplx, nsply, npoints,
                                        bilin, Cats, driver, mean,
                                        table_name);
                    }
                    else {	/* FLAG_EXT == TRUE */

                        /* done that earlier */
                        /*
                        int npoints_ext, *lineVect_ext = NULL;
                        double **obsVect_ext;
                        struct Point *observ_ext;

                        observ_ext =
                            P_Read_Vector_Region_Map(&In_ext,
                        			     &elaboration_reg,
                        			     &npoints_ext, dim_vect,
                        			     1);
                        */

                        obsVect_ext = G_alloc_matrix(npoints_ext, 3);	/* Observation vector_ext */
                        lineVect_ext = G_alloc_ivector(npoints_ext);

                        for (i = 0; i < npoints_ext; i++) {	/* Setting obsVect_ext vector & Q matrix */
                            obsVect_ext[i][0] = observ_ext[i].coordX;
                            obsVect_ext[i][1] = observ_ext[i].coordY;
                            obsVect_ext[i][2] = observ_ext[i].coordZ - mean;
                            lineVect_ext[i] = observ_ext[i].lineID;
                        }

                        G_free(observ_ext);

                        G_debug(1, "Interpolation: (%d,%d): Sparse_Points...",
                                subregion_row, subregion_col);
                        P_Sparse_Points(&Out, &elaboration_reg, general_box,
                                        overlap_box, obsVect_ext, parVect,
                                        lineVect_ext, stepE, stepN,
                                        dims.overlap, nsplx, nsply,
                                        npoints_ext, bilin, Cats, driver,
                                        mean, table_name);

                        G_free_matrix(obsVect_ext);
                        G_free_ivector(lineVect_ext);
                    }		/* END FLAG_EXT == TRUE */
                }		/* END GRID == FALSE */
                G_free_vector(parVect);
                G_free_matrix(obsVect);
                G_free_ivector(lineVect);
            }
            else {
                if (observ)
                    G_free(observ);
                if (observ_ext)
                    G_free(observ_ext);
                if (npoints == 0)
                    G_warning(_("No data within this subregion. "
                                "Consider increasing spline step values."));
            }
        }			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    G_verbose_message(_("Writing output..."));
    /* Writing the output raster map */
    if (grid == TRUE) {
        int row, col;
        DCELL *drastbuf, dval;


        if (have_mask) {
            Segment_release(&mask_seg);	/* release memory  */
            close(mask_fd);
            unlink(mask_file);
        }

        drastbuf = Rast_allocate_buf(DCELL_TYPE);
        for (row = 0; row < nrows; row++) {
            G_percent(row, nrows, 2);
            for (col = 0; col < ncols; col++) {
                Segment_get(&out_seg, &dval, row, col);
                drastbuf[col] = dval;
            }
            Rast_put_d_row(raster, drastbuf);
        }

        Rast_close(raster);

        Segment_release(&out_seg);	/* release memory  */
        close(out_fd);
        unlink(out_file);
        /* set map title */
        sprintf(title, "%s interpolation with Tykhonov regularization",
                type_opt->answer);
        Rast_put_cell_title(out_map_opt->answer, title);
        /* write map history */
        Rast_short_history(out_map_opt->answer, "raster", &history);
        Rast_command_history(&history);
        Rast_write_history(out_map_opt->answer, &history);
    }
    /* Writing to the output vector map the points from the overlapping zones */
    else if (flag_auxiliar == TRUE) {
        if (ext == FALSE)
            P_Aux_to_Vector(&In, &Out, driver, table_name);
        else
            P_Aux_to_Vector(&In_ext, &Out, driver, table_name);

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

    db_close_database_shutdown_driver(driver);

    Vect_close(&In);
    if (ext != FALSE)
        Vect_close(&In_ext);
    if (vector)
        Vect_close(&Out);

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*END MAIN */
Esempio n. 6
0
/*!
   \brief transform 2d vector features to 3d

   \param In input vector
   \param Out output vector
   \param type feature type to be transformed
   \param height fixed height (used only if column is NULL)
   \param field layer number
   \param column attribute column used for height
 */
void trans2d(struct Map_info *In, struct Map_info *Out, int type,
	    double height, const char *field_name, const char *column)
{
    int i, ltype, line, field;
    int cat;
    int ret, ctype;

    struct line_pnts *Points;
    struct line_cats *Cats;

    dbCatValArray cvarr;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    db_CatValArray_init(&cvarr);

    field = Vect_get_field_number(In, field_name);
    
    if (column) {
	struct field_info *Fi;

	dbDriver *driver;

        if (field == -1) {
            G_warning(_("Invalid layer number %d, assuming 1"), field);
            field = 1;
        }

	Fi = Vect_get_field(In, field);
	if (!Fi) {
	    G_fatal_error(_("Database connection not defined for layer <%s>"),
                          field_name);
	}

	driver = db_start_driver_open_database(Fi->driver, Fi->database);
	if (!driver) {
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
                          Fi->database, Fi->driver);
	}
        db_set_error_handler_driver(driver);
        
	/* column type must numeric */
	ctype = db_column_Ctype(driver, Fi->table, column);
	if (ctype == -1) {
	    G_fatal_error(_("Column <%s> not found in table <%s>"),
                          column, Fi->table);
	}
	if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) {
	    G_fatal_error(_("Column must be numeric"));
	}

        G_message(_("Fetching height from <%s> column..."), column);
	db_select_CatValArray(driver, Fi->table, Fi->key,
			      column, NULL, &cvarr);

	G_debug(3, "%d records selected", cvarr.n_values);

	db_close_database_shutdown_driver(driver);
    }

    G_message(_("Transforming features..."));
    line = 1;
    while (1) {
	ltype = Vect_read_next_line(In, Points, Cats);
	if (ltype == -1) {
	    G_fatal_error(_("Unable to read vector map"));
	}
	if (ltype == -2) {	/* EOF */
	    break;
	}

        G_progress(line, 1000);
        
	if (!(ltype & type))
	    continue;

	if (field != -1 && !Vect_cat_get(Cats, field, &cat))
	    continue;
	
	if (column) {
	    Vect_cat_get(Cats, field, &cat);
	    if (cat < 0) {
		G_warning(_("Skipping feature without category"));
		continue;
	    }

	    if (ctype == DB_C_TYPE_DOUBLE)
		ret = db_CatValArray_get_value_double(&cvarr, cat, &height);
	    else {		/* integer */

		int height_i;

		ret = db_CatValArray_get_value_int(&cvarr, cat, &height_i);
		height = (double)height_i;
	    }

	    if (ret != DB_OK)
		G_warning(_("Unable to get height for feature category %d"),
			  cat);
	}

	for (i = 0; i < Points->n_points; i++) {
	    Points->z[i] = height;
	}

	Vect_write_line(Out, ltype, Points, Cats);

	line++;
    }
    G_progress(1, 1);
    
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);
}
Esempio n. 7
0
void write_rgb_values(const struct Map_info *Map, int layer, const char *column_name,
		      struct Colors *colors)
{
    int ctype, nrec, i;
    int red, grn, blu;
    int *pval;
    char buf[1024];
    struct field_info *fi;
    dbDriver *driver;
    dbString stmt;

    fi = Vect_get_field(Map, layer);
    if (!fi)
	G_fatal_error(_("Database connection not defined for layer %d"),
		      layer);

    driver = db_start_driver_open_database(fi->driver, fi->database);
    if (!driver)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database, fi->driver);
    db_set_error_handler_driver(driver);

    db_init_string(&stmt);
    
    ctype = db_column_Ctype(driver, fi->table, column_name);
    if (ctype == -1) {
	sprintf(buf, "ALTER TABLE %s ADD COLUMN %s VARCHAR(11)",
		fi->table, column_name);
	db_set_string(&stmt, buf);
	if (db_execute_immediate(driver, &stmt) != DB_OK)
	    G_fatal_error(_("Unable to add column <%s> to table <%s>"),
			  column_name, fi->table);

	/*
	  db_add_column needs to be implemented for DB drivers first...
	  
	  dbString table;
	  dbColumn column;
	  
	  db_init_column(&column);
	  db_set_column_name(&column, column_name);
	  db_set_column_sqltype(&column, DB_SQL_TYPE_CHARACTER);
	  db_set_column_null_allowed(&column);
	  db_set_column_length(&column, 11);
	  
	  db_init_string(&table);
	  db_set_string(&table, fi->table);
	  if (db_add_column(driver, &table, &column) != DB_OK)
	  G_fatal_error(_("Unable to add column <%s> to table <%s>"),
	  column_name, fi->table);
	  db_free_column(&column);
	*/

	G_important_message(_("Column <%s> added to table <%s>"),
			     column_name, fi->table);
    }
    else if (ctype != DB_C_TYPE_STRING)
	G_fatal_error(_("Data type of column <%s> must be char"), column_name);
	
    nrec = db_select_int(driver, fi->table, fi->key, NULL, &pval);
    if (nrec < 1) {
	G_warning(_("No categories found"));
	return;
    }
    
    db_begin_transaction(driver);
    
    for (i = 0; i < nrec; i++) {
	G_percent(i, nrec, 2);
	if (Rast_get_c_color((const CELL *) &(pval[i]), &red, &grn, &blu,
			     colors) == 0)
	    G_warning(_("No color value defined for category %d"), pval[i]);

	sprintf(buf, "UPDATE %s SET %s='%d:%d:%d' WHERE %s=%d", fi->table,
		   column_name, red, grn, blu, fi->key, pval[i]);
	G_debug(3, "\tSQL: %s", buf);

	db_set_string(&stmt, buf);
	if (db_execute_immediate(driver, &stmt) != DB_OK)
	    G_fatal_error(_("Unable to update RGB values"));
    }
    G_percent(1, 1, 1);
    
    db_commit_transaction(driver);
    
    db_close_database_shutdown_driver(driver);
}
Esempio n. 8
0
File: main.c Progetto: caomw/grass
int main(int argc, char **argv)
{
    dbString stmt;
    dbDriver *driver;
    dbHandle handle;
    int stat;
    FILE *fd;

    parse_command_line(argc, argv);

    if (parms.table) {
	if (!db_table_exists(parms.driver, parms.database, parms.table)) {
	    G_warning(_("Table <%s> not found in database <%s> using driver <%s>"),
		       parms.table, parms.database, parms.driver);
	    exit(EXIT_FAILURE);
	}
    }

    /* read from file or stdin ? */
    if (parms.input && strcmp(parms.input, "-") != 0) {
	fd = fopen(parms.input, "r");
	if (fd == NULL) {
	    G_fatal_error(_("Unable to open file <%s>: %s"),
                          parms.input, strerror(errno));
	}
    }
    else
	fd = stdin;

    /* open DB connection */
    db_init_string(&stmt);

    driver = db_start_driver(parms.driver);
    if (driver == NULL) {
	G_fatal_error(_("Unable to start driver <%s>"), parms.driver);
    }

    db_init_handle(&handle);
    db_set_handle(&handle, parms.database, NULL);
    if (db_open_database(driver, &handle) != DB_OK)
	G_fatal_error(_("Unable to open database <%s>"), parms.database);
    db_set_error_handler_driver(driver);
 
    /* check for sql, table, and input */
    if (parms.sql) {
        /* parms.sql */
        db_set_string(&stmt, parms.sql);
        stat = sel(driver, &stmt);
    }
    else if (parms.table) {
        /* parms.table */
	db_set_string(&stmt, "SELECT * FROM ");
	db_append_string(&stmt, parms.table);
	stat = sel(driver, &stmt);
    }
    else { /* -> parms.input */
        stat = DB_OK;
        while (stat == DB_OK && get_stmt(fd, &stmt)) {
            if (!stmt_is_empty(&stmt))
                stat = sel(driver, &stmt);
        }
    }

    if (parms.test_only)
	G_verbose_message(_("Test %s."), stat ? _("failed") : _("succeeded"));

    db_close_database(driver);
    db_shutdown_driver(driver);

    exit(stat == DB_OK ? EXIT_SUCCESS : EXIT_FAILURE);
}
Esempio n. 9
0
/*!
   \brief Check vector map

   \param params parameters
   \param index answers array index
   \param vlines TRUE for lines otherwise points
   \param[out] field number
   \param[out] WITH_Z for 3D maps

   \return 0 on success otherwise 1
 */
int check_map(const struct GParams *params, int index, int vlines,
	      int *field, int *with_z)
{
    int type;
    struct Map_info Map;
    const char *map, *layer, *color, *size, *width, *marker;
    struct field_info *Fi;

    dbDriver *driver;
    dbColumn *column;

    Fi = NULL;
    driver = NULL;

    if (vlines) {
	map = params->vlines->answers[index];
	layer = params->vline_layer->answers[index];
	color = params->vline_color_column->answers ?
	    params->vline_color_column->answers[index] : NULL;
	size = NULL;
	width = params->vline_width_column->answers ?
	    params->vline_width_column->answers[index] : NULL;
	marker = NULL;
    }
    else {
	map = params->vpoints->answers[index];
	layer = params->vpoint_layer->answers[index];
	color = params->vpoint_color_column->answers ?
	    params->vpoint_color_column->answers[index] : NULL;
	size = params->vpoint_size_column->answers ?
	    params->vpoint_size_column->answers[index] : NULL;
	width = params->vpoint_width_column->answers ?
	    params->vpoint_width_column->answers[index] : NULL;
	marker = params->vpoint_marker_column->answers ?
	    params->vpoint_marker_column->answers[index] : NULL;
    }

    if (!map)
	return 1;

    if (1 > Vect_open_old(&Map, map, ""))
	G_fatal_error(_("Unable to open vector map <%s>"), map);
    Vect_set_error_handler_io(&Map, NULL);

    if (with_z)
	*with_z = Vect_is_3d(&Map);

    *field = -1;
    Fi = Vect_get_field2(&Map, layer);
    if (Fi) {
	*field = Fi->number;

	driver = db_start_driver_open_database(Fi->driver, Fi->database);
	if (!driver)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Fi->database, Fi->driver);
        db_set_error_handler_driver(driver);

	if (color) {
	    db_get_column(driver, Fi->table, color, &column);
	    if (!column)
		G_fatal_error(_("Column <%s> in table <%s> not found"),
			      color, Fi->table);

	    if (db_column_Ctype(driver, Fi->table, color) != DB_C_TYPE_STRING)
		G_fatal_error(_("Data type of color column must be character"));
	}
	if (size) {
	    db_get_column(driver, Fi->table, size, &column);
	    if (!column)
		G_fatal_error(_("Column <%s> in table <%s> not found"),
			      size, Fi->table);

	    type = db_column_Ctype(driver, Fi->table, size);
	    if (type != DB_C_TYPE_INT && type != DB_C_TYPE_DOUBLE)
		G_fatal_error(_("Data type of size column must be numeric"));
	}
	if (width) {
	    db_get_column(driver, Fi->table, width, &column);
	    if (!column)
		G_fatal_error(_("Column <%s> in table <%s> not found"),
			      width, Fi->table);

	    type = db_column_Ctype(driver, Fi->table, width);
	    if (type != DB_C_TYPE_INT && type != DB_C_TYPE_DOUBLE)
		G_fatal_error(_("Data type of width column must be numeric"));
	}
	if (marker) {
	    db_get_column(driver, Fi->table, marker, &column);
	    if (!column)
		G_fatal_error(_("Column <%s> in table <%s> not found"),
			      marker, Fi->table);

	    type = db_column_Ctype(driver, Fi->table, marker);
	    if (db_column_Ctype(driver, Fi->table, marker) !=
		DB_C_TYPE_STRING)
		G_fatal_error(_("Data type of marker column must be character"));
	}

	db_close_database_shutdown_driver(driver);
    }

    Vect_close(&Map);

    return 0;
}
Esempio n. 10
0
File: main.c Progetto: caomw/grass
int main(int argc, char *argv[])
{
    char *output, buf[DB_SQL_MAX];
    double (*rng)(void) = G_drand48;
    double zmin, zmax;
    int seed;
    int i, j, k, n, type, usefloat;
    int area, nareas, field;
    struct boxlist *List = NULL;
    BOX_SIZE *size_list = NULL;
    int alloc_size_list = 0;
    struct Map_info In, Out;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct cat_list *cat_list;
    struct bound_box box;
    struct Cell_head window;
    struct GModule *module;
    struct
    {
	struct Option *input, *field, *cats, *where, *output, *nsites,
		      *zmin, *zmax, *zcol, *ztype, *seed;
    } parm;
    struct
    {
	struct Flag *z, *notopo, *a;
    } flag;
    struct field_info *Fi;
    dbDriver *driver;
    dbTable *table;
    dbString sql;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("sampling"));
    G_add_keyword(_("statistics"));
    G_add_keyword(_("random"));
    module->description = _("Generates random 2D/3D vector points.");

    parm.output = G_define_standard_option(G_OPT_V_OUTPUT);

    parm.nsites = G_define_option();
    parm.nsites->key = "n";
    parm.nsites->type = TYPE_INTEGER;
    parm.nsites->required = YES;
    parm.nsites->description = _("Number of points to be created");

    parm.input = G_define_standard_option(G_OPT_V_INPUT);
    parm.input->required = NO;
    parm.input->description = _("Restrict points to areas in input vector");
    parm.input->guisection = _("Selection");

    parm.field = G_define_standard_option(G_OPT_V_FIELD_ALL);
    parm.field->guisection = _("Selection");

    parm.cats = G_define_standard_option(G_OPT_V_CATS);
    parm.cats->guisection = _("Selection");
    
    parm.where = G_define_standard_option(G_OPT_DB_WHERE);
    parm.where->guisection = _("Selection");

    parm.zmin = G_define_option();
    parm.zmin->key = "zmin";
    parm.zmin->type = TYPE_DOUBLE;
    parm.zmin->required = NO;
    parm.zmin->description =
	_("Minimum z height (needs -z flag or column name)");
    parm.zmin->answer = "0.0";
    parm.zmin->guisection = _("3D output");

    parm.zmax = G_define_option();
    parm.zmax->key = "zmax";
    parm.zmax->type = TYPE_DOUBLE;
    parm.zmax->required = NO;
    parm.zmax->description =
	_("Maximum z height (needs -z flag or column name)");
    parm.zmax->answer = "0.0";
    parm.zmax->guisection = _("3D output");

    parm.seed = G_define_option();
    parm.seed->key = "seed";
    parm.seed->type = TYPE_INTEGER;
    parm.seed->required = NO;
    parm.seed->description =
	_("The seed to initialize the random generator. If not set the process ID is used");

    parm.zcol = G_define_standard_option(G_OPT_DB_COLUMN);
    parm.zcol->label = _("Name of column for z values");
    parm.zcol->description =
	_("Writes z values to column");
    parm.zcol->guisection = _("3D output");

    parm.ztype = G_define_option();
    parm.ztype->key = "column_type";
    parm.ztype->type = TYPE_STRING;
    parm.ztype->required = NO;
    parm.ztype->multiple = NO;
    parm.ztype->description = _("Type of column for z values");
    parm.ztype->options = "integer,double precision";
    parm.ztype->answer = "double precision";
    parm.ztype->guisection = _("3D output");

    flag.z = G_define_flag();
    flag.z->key = 'z';
    flag.z->description = _("Create 3D output");
    flag.z->guisection = _("3D output");

    flag.a = G_define_flag();
    flag.a->key = 'a';
    flag.a->description = _("Generate n points for each individual area");

    flag.notopo = G_define_standard_flag(G_FLG_V_TOPO);

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

    output = parm.output->answer;
    n = atoi(parm.nsites->answer);
    
    if(parm.seed->answer)
        seed = atoi(parm.seed->answer);

    if (n <= 0) {
	G_fatal_error(_("Number of points must be > 0 (%d given)"), n);
    }

    nareas = 0;
    cat_list = NULL;
    field = -1;
    if (parm.input->answer) {
	Vect_set_open_level(2); /* topology required */
	if (2 > Vect_open_old2(&In, parm.input->answer, "", parm.field->answer))
	    G_fatal_error(_("Unable to open vector map <%s>"),
			  parm.input->answer);

	if (parm.field->answer)
	    field = Vect_get_field_number(&In, parm.field->answer);

	if ((parm.cats->answer || parm.where->answer) && field == -1) {
	    G_warning(_("Invalid layer number (%d). Parameter '%s' or '%s' specified, assuming layer '1'."),
		      field, parm.cats->key, parm.where->key);
	    field = 1;
	}
	if (field > 0)
	    cat_list = Vect_cats_set_constraint(&In, field, parm.where->answer,
						parm.cats->answer);
	nareas = Vect_get_num_areas(&In);
	if (nareas == 0) {
	    Vect_close(&In);
	    G_fatal_error(_("No areas in vector map <%s>"), parm.input->answer);
	}
    }
    else {
	if (flag.a->answer)
	    G_fatal_error(_("The <-%c> flag requires an input vector with areas"),
	                  flag.a->key);
    }

    /* create new vector map */
    if (-1 == Vect_open_new(&Out, output, flag.z->answer ? WITH_Z : WITHOUT_Z))
        G_fatal_error(_("Unable to create vector map <%s>"), output);
    Vect_set_error_handler_io(NULL, &Out);

    /* Do we need to write random values into attribute table? */
    usefloat = -1;
    if (parm.zcol->answer) {
	Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
	driver =
	    db_start_driver_open_database(Fi->driver,
					  Vect_subst_var(Fi->database, &Out));
	if (driver == NULL) {
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Vect_subst_var(Fi->database, &Out), Fi->driver);
	}
        db_set_error_handler_driver(driver);
        
	db_begin_transaction(driver);

	db_init_string(&sql);
	sprintf(buf, "create table %s (%s integer, %s %s)", Fi->table, GV_KEY_COLUMN,
		parm.zcol->answer, parm.ztype->answer);
	db_set_string(&sql, buf);
	Vect_map_add_dblink(&Out, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			    Fi->driver);

	/* Create table */
	G_debug(3, db_get_string(&sql));
	if (db_execute_immediate(driver, &sql) != DB_OK) {
	    G_fatal_error(_("Unable to create table: %s"),
			  db_get_string(&sql));
	}

	/* Create index */
	if (db_create_index2(driver, Fi->table, Fi->key) != DB_OK)
	    G_warning(_("Unable to create index"));

	/* Grant */
	if (db_grant_on_table
	    (driver, Fi->table, DB_PRIV_SELECT,
	     DB_GROUP | DB_PUBLIC) != DB_OK) {
	    G_fatal_error(_("Unable to grant privileges on table <%s>"),
			  Fi->table);
	}

	/* OK. Let's check what type of column user has created */
	db_set_string(&sql, Fi->table);
	if (db_describe_table(driver, &sql, &table) != DB_OK) {
	    G_fatal_error(_("Unable to describe table <%s>"), Fi->table);
	}

	if (db_get_table_number_of_columns(table) != 2) {
	    G_fatal_error(_("Table should contain only two columns"));
	}

	type = db_get_column_sqltype(db_get_table_column(table, 1));
	if (type == DB_SQL_TYPE_SMALLINT || type == DB_SQL_TYPE_INTEGER)
	    usefloat = 0;
	if (type == DB_SQL_TYPE_REAL || type == DB_SQL_TYPE_DOUBLE_PRECISION)
	    usefloat = 1;
	if (usefloat < 0) {
	    G_fatal_error(_("You have created unsupported column type. This module supports only INTEGER"
			   " and DOUBLE PRECISION column types."));
	}
    }

    Vect_hist_command(&Out);

    /* Init the random seed */
    if(parm.seed->answer)
	G_srand48(seed);
    else
	G_srand48_auto();

    G_get_window(&window);

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    if (nareas > 0) {
	int first = 1, count;
	struct bound_box abox, bbox;

	box.W = window.west;
	box.E = window.east;
	box.S = window.south;
	box.N = window.north;
	box.B = -PORT_DOUBLE_MAX;
	box.T = PORT_DOUBLE_MAX;

	count = 0;

	for (i = 1; i <= nareas; i++) {
	    
	    if (!Vect_get_area_centroid(&In, i))
		continue;

	    if (field > 0) {
		if (Vect_get_area_cats(&In, i, Cats))
		    continue;

		if (!Vect_cats_in_constraint(Cats, field, cat_list))
		    continue;
	    }

	    Vect_get_area_box(&In, i, &abox);
	    if (!Vect_box_overlap(&abox, &box))
		continue;

	    if (first) {
		Vect_box_copy(&bbox, &abox);
		first = 0;
	    }
	    else
		Vect_box_extend(&bbox, &abox);
	    count++;
	}
	if (count == 0) {
	    Vect_close(&In);
	    Vect_close(&Out);
	    Vect_delete(output);
	    G_fatal_error(_("Selected areas in input vector <%s> do not overlap with the current region"),
			  parm.input->answer);
	}
	Vect_box_copy(&box, &bbox);

	/* does the vector overlap with the current region ? */
	if (box.W >= window.east || box.E <= window.west ||
	    box.S >= window.north || box.N <= window.south) {

	    Vect_close(&In);
	    Vect_close(&Out);
	    Vect_delete(output);
	    G_fatal_error(_("Input vector <%s> does not overlap with the current region"),
	                  parm.input->answer);
	}

	/* try to reduce the current region */
	if (window.east > box.E)
	    window.east = box.E;
	if (window.west < box.W)
	    window.west = box.W;
	if (window.north > box.N)
	    window.north = box.N;
	if (window.south < box.S)
	    window.south = box.S;

	List = Vect_new_boxlist(1);
	alloc_size_list = 10;
	size_list = G_malloc(alloc_size_list * sizeof(BOX_SIZE));
    }

    zmin = zmax = 0;
    if (flag.z->answer || parm.zcol->answer) {
	zmax = atof(parm.zmax->answer);
	zmin = atof(parm.zmin->answer);
    }

    G_message(_("Generating points..."));
    if (flag.a->answer && nareas > 0) {
	struct bound_box abox, bbox;
	int cat = 1;

	/* n points for each area */
	nareas = Vect_get_num_areas(&In);
	
	G_percent(0, nareas, 1);
	for (area = 1; area <= nareas; area++) {

	    G_percent(area, nareas, 1);

	    if (!Vect_get_area_centroid(&In, area))
		continue;

	    if (field > 0) {
		if (Vect_get_area_cats(&In, area, Cats))
		    continue;

		if (!Vect_cats_in_constraint(Cats, field, cat_list)) {
		    continue;
		}
	    }

	    box.W = window.west;
	    box.E = window.east;
	    box.S = window.south;
	    box.N = window.north;
	    box.B = -PORT_DOUBLE_MAX;
	    box.T = PORT_DOUBLE_MAX;
	    
	    Vect_get_area_box(&In, area, &abox);
	    if (!Vect_box_overlap(&box, &abox))
		continue;
		
	    bbox = abox;
	    if (bbox.W < box.W)
		bbox.W = box.W;
	    if (bbox.E > box.E)
		bbox.E = box.E;
	    if (bbox.S < box.S)
		bbox.S = box.S;
	    if (bbox.N > box.N)
		bbox.N = box.N;

	    for (i = 0; i < n; ++i) {
		double x, y, z;
		int outside = 1;
		int ret;

		Vect_reset_line(Points);
		Vect_reset_cats(Cats);

		while (outside) {
		    x = rng() * (bbox.W - bbox.E) + bbox.E;
		    y = rng() * (bbox.N - bbox.S) + bbox.S;
		    z = rng() * (zmax - zmin) + zmin;

		    ret = Vect_point_in_area(x, y, &In, area, &abox);

		    G_debug(3, "    area = %d Vect_point_in_area() = %d", area, ret);

		    if (ret >= 1) {
			outside = 0;
		    }
		}

		if (flag.z->answer)
		    Vect_append_point(Points, x, y, z);
		else
		    Vect_append_point(Points, x, y, 0.0);

		if (parm.zcol->answer) {
		    sprintf(buf, "insert into %s values ( %d, ", Fi->table, i + 1);
		    db_set_string(&sql, buf);
		    /* Round random value if column is integer type */
		    if (usefloat)
			sprintf(buf, "%f )", z);
		    else
			sprintf(buf, "%.0f )", z);
		    db_append_string(&sql, buf);

		    G_debug(3, db_get_string(&sql));
		    if (db_execute_immediate(driver, &sql) != DB_OK) {
			G_fatal_error(_("Cannot insert new row: %s"),
				      db_get_string(&sql));
		    }
		}

		Vect_cat_set(Cats, 1, cat++);
		Vect_write_line(&Out, GV_POINT, Points, Cats);
	    }
	}
    }
    else {
	/* n points in total */
	for (i = 0; i < n; ++i) {
	    double x, y, z;

	    G_percent(i, n, 4);

	    Vect_reset_line(Points);
	    Vect_reset_cats(Cats);

	    x = rng() * (window.west - window.east) + window.east;
	    y = rng() * (window.north - window.south) + window.south;
	    z = rng() * (zmax - zmin) + zmin;
	    
	    if (nareas) {
		int outside = 1;

		do {
		    /* select areas by box */
		    box.E = x;
		    box.W = x;
		    box.N = y;
		    box.S = y;
		    box.T = PORT_DOUBLE_MAX;
		    box.B = -PORT_DOUBLE_MAX;
		    Vect_select_areas_by_box(&In, &box, List);
		    G_debug(3, "  %d areas selected by box", List->n_values);

		    /* sort areas by size, the smallest is likely to be the nearest */
		    if (alloc_size_list < List->n_values) {
			alloc_size_list = List->n_values;
			size_list = G_realloc(size_list, alloc_size_list * sizeof(BOX_SIZE));
		    }

		    k = 0;
		    for (j = 0; j < List->n_values; j++) {
			area = List->id[j];

			if (!Vect_get_area_centroid(&In, area))
			    continue;

			if (field > 0) {
			    if (Vect_get_area_cats(&In, area, Cats))
				continue;

			    if (!Vect_cats_in_constraint(Cats, field, cat_list)) {
				continue;
			    }
			}

			List->id[k] = List->id[j];
			List->box[k] = List->box[j];
			size_list[k].i = List->id[k];
			box = List->box[k];
			size_list[k].box = List->box[k];
			size_list[k].size = (box.N - box.S) * (box.E - box.W);
			k++;
		    }
		    List->n_values = k;
		    
		    if (List->n_values == 2) {
			/* simple swap */
			if (size_list[1].size < size_list[0].size) {
			    size_list[0].i = List->id[1];
			    size_list[1].i = List->id[0];
			    size_list[0].box = List->box[1];
			    size_list[1].box = List->box[0];
			}
		    }
		    else if (List->n_values > 2)
			qsort(size_list, List->n_values, sizeof(BOX_SIZE), sort_by_size);

		    for (j = 0; j < List->n_values; j++) {
			int ret;

			area = size_list[j].i;
			ret = Vect_point_in_area(x, y, &In, area, &size_list[j].box);

			G_debug(3, "    area = %d Vect_point_in_area() = %d", area, ret);

			if (ret >= 1) {
			    outside = 0;
			    break;
			}
		    }
		    if (outside) {
			x = rng() * (window.west - window.east) + window.east;
			y = rng() * (window.north - window.south) + window.south;
			z = rng() * (zmax - zmin) + zmin;
		    }
		} while (outside);
	    }

	    if (flag.z->answer)
		Vect_append_point(Points, x, y, z);
	    else
		Vect_append_point(Points, x, y, 0.0);

	    if (parm.zcol->answer) {
		sprintf(buf, "insert into %s values ( %d, ", Fi->table, i + 1);
		db_set_string(&sql, buf);
		/* Round random value if column is integer type */
		if (usefloat)
		    sprintf(buf, "%f )", z);
		else
		    sprintf(buf, "%.0f )", z);
		db_append_string(&sql, buf);

		G_debug(3, db_get_string(&sql));
		if (db_execute_immediate(driver, &sql) != DB_OK) {
		    G_fatal_error(_("Cannot insert new row: %s"),
				  db_get_string(&sql));
		}
	    }

	    Vect_cat_set(Cats, 1, i + 1);
	    Vect_write_line(&Out, GV_POINT, Points, Cats);
	}
	G_percent(1, 1, 1);
    }
    
    if (parm.zcol->answer) {
	db_commit_transaction(driver);
	db_close_database_shutdown_driver(driver);
    }

    if (!flag.notopo->answer) {
	Vect_build(&Out);
    }
    Vect_close(&Out);

    exit(EXIT_SUCCESS);
}
Esempio n. 11
0
int main(int argc, char *argv[])
{
    struct Map_info In, Out, cut_map;
    static struct line_pnts *Points;
    struct line_cats *Cats;
    struct GModule *module;	/* GRASS module for parsing arguments */
    struct Option *map_in, *map_out, *cut_out;
    struct Option *afield_opt, *nfield_opt, *abcol, *afcol, *ncol;
    struct Option *catsource_opt, *wheresource_opt;
    struct Option *catsink_opt, *wheresink_opt;
    int with_z;
    int afield, nfield, mask_type;
    struct varray *varray_source, *varray_sink;
    dglGraph_s *graph;
    int i, nlines, *flow, total_flow;
    struct ilist *source_list, *sink_list, *cut;
    int find_cut;

    char buf[2000];

    /* Attribute table */
    dbString sql;
    dbDriver *driver;
    struct field_info *Fi;

    /* initialize GIS environment */
    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */

    /* initialize module */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("network"));
    G_add_keyword(_("flow"));
    module->description =
	_("Computes the maximum flow between two sets of nodes in the network.");

    /* Define the different options as defined in gis.h */
    map_in = G_define_standard_option(G_OPT_V_INPUT);

    afield_opt = G_define_standard_option(G_OPT_V_FIELD);
    afield_opt->key = "arc_layer";
    afield_opt->answer = "1";
    afield_opt->label = _("Arc layer");
    afield_opt->guisection = _("Cost");

    nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    nfield_opt->key = "node_layer";
    nfield_opt->answer = "2";
    nfield_opt->label = _("Node layer");
    nfield_opt->guisection = _("Cost");

    map_out = G_define_standard_option(G_OPT_V_OUTPUT);

    cut_out = G_define_standard_option(G_OPT_V_OUTPUT);
    cut_out->key = "cut";
    cut_out->description =
	_("Name for output vector map containing a minimum cut");

    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
    afcol->key = "arc_column";
    afcol->required = NO;
    afcol->description =
	_("Arc forward/both direction(s) cost column (number)");
    afcol->guisection = _("Cost");

    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
    abcol->key = "arc_backward_column";
    abcol->required = NO;
    abcol->description = _("Arc backward direction cost column (number)");
    abcol->guisection = _("Cost");

    ncol = G_define_standard_option(G_OPT_DB_COLUMN);
    ncol->key = "node_column";
    ncol->required = NO;
    ncol->description = _("Node cost column (number)");
    ncol->guisection = _("Cost");

    catsource_opt = G_define_standard_option(G_OPT_V_CATS);
    catsource_opt->key = "source_cats";
    catsource_opt->label = _("Source category values");
    catsource_opt->guisection = _("Source");

    wheresource_opt = G_define_standard_option(G_OPT_DB_WHERE);
    wheresource_opt->key = "source_where";
    wheresource_opt->label =
	_("Source WHERE conditions of SQL statement without 'where' keyword");
    wheresource_opt->guisection = _("Source");

    catsink_opt = G_define_standard_option(G_OPT_V_CATS);
    catsink_opt->key = "sink_cats";
    catsink_opt->label = _("Sink category values");
    catsink_opt->guisection = _("Sink");

    wheresink_opt = G_define_standard_option(G_OPT_DB_WHERE);
    wheresink_opt->key = "sink_where";
    wheresink_opt->label =
	_("Sink WHERE conditions of SQL statement without 'where' keyword");
    wheresink_opt->guisection = _("Sink");

    /* options and flags parser */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
    find_cut = (cut_out->answer[0]);
    /* TODO: make an option for this */
    mask_type = GV_LINE | GV_BOUNDARY;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    Vect_check_input_output_name(map_in->answer, map_out->answer,
				 G_FATAL_EXIT);

    Vect_set_open_level(2);

    if (1 > Vect_open_old(&In, map_in->answer, ""))
	G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer);

    with_z = Vect_is_3d(&In);

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

    if (find_cut && 0 > Vect_open_new(&cut_map, cut_out->answer, with_z)) {
	Vect_close(&In);
	Vect_close(&Out);
	G_fatal_error(_("Unable to create vector map <%s>"), cut_out->answer);
    }

    /* parse filter option and select appropriate lines */
    afield = Vect_get_field_number(&In, afield_opt->answer);
    nfield = Vect_get_field_number(&In, nfield_opt->answer);

    /* Create table */
    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
    Vect_map_add_dblink(&Out, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			Fi->driver);
    db_init_string(&sql);
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);
    db_set_error_handler_driver(driver);

    sprintf(buf, "create table %s (cat integer, flow double precision)",
	    Fi->table);

    db_set_string(&sql, buf);
    G_debug(2, "%s", db_get_string(&sql));

    if (db_execute_immediate(driver, &sql) != DB_OK) {
	db_close_database_shutdown_driver(driver);
	G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql));
    }

    if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK)
	G_warning(_("Cannot create index"));

    if (db_grant_on_table
	(driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
	G_fatal_error(_("Cannot grant privileges on table <%s>"), Fi->table);

    db_begin_transaction(driver);

    source_list = Vect_new_list();
    sink_list = Vect_new_list();

    if (NetA_initialise_varray
	(&In, nfield, GV_POINT,
	 wheresource_opt->answer, catsource_opt->answer, &varray_source) <= 0) {
	G_fatal_error(_("No source features selected. "
			"Please check options '%s', '%s'."),
			catsource_opt->key, wheresource_opt->key);
    }
    if (NetA_initialise_varray
	(&In, nfield, GV_POINT, wheresink_opt->answer,
	 catsink_opt->answer, &varray_sink) <= 0) {
	G_fatal_error(_("No sink features selected. "
			"Please check options '%s', '%s'."),
			catsink_opt->key, wheresink_opt->key);
    }

    NetA_varray_to_nodes(&In, varray_source, source_list, NULL);
    NetA_varray_to_nodes(&In, varray_sink, sink_list, NULL);

    if (source_list->n_values == 0)
	G_fatal_error(_("No sources"));

    if (sink_list->n_values == 0)
	G_fatal_error(_("No sinks"));

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

    if (0 != Vect_net_build_graph(&In, mask_type, afield, nfield, afcol->answer, abcol->answer,
                                  ncol->answer, 0, 0))
        G_fatal_error(_("Unable to build graph for vector map <%s>"), Vect_get_full_name(&In));
    
    graph = Vect_net_get_graph(&In);
    nlines = Vect_get_num_lines(&In);
    flow = (int *)G_calloc(nlines + 1, sizeof(int));
    if (!flow)
	G_fatal_error(_("Out of memory"));

    total_flow = NetA_flow(graph, source_list, sink_list, flow);
    G_debug(3, "Max flow: %d", total_flow);
    if (find_cut) {
	cut = Vect_new_list();
	total_flow = NetA_min_cut(graph, source_list, sink_list, flow, cut);
	G_debug(3, "Min cut: %d", total_flow);
    }

    G_message(_("Writing the output..."));
    G_percent_reset();
    for (i = 1; i <= nlines; i++) {
	G_percent(i, nlines, 1);
	int type = Vect_read_line(&In, Points, Cats, i);

	Vect_write_line(&Out, type, Points, Cats);
	if (type == GV_LINE) {
	    int cat;

	    Vect_cat_get(Cats, afield, &cat);
	    if (cat == -1)
		continue;	/*TODO: warning? */
	    sprintf(buf, "insert into %s values (%d, %f)", Fi->table, cat,
		    flow[i] / (double)In.dgraph.cost_multip);
	    db_set_string(&sql, buf);
	    G_debug(3, "%s", db_get_string(&sql));

	    if (db_execute_immediate(driver, &sql) != DB_OK) {
		db_close_database_shutdown_driver(driver);
		G_fatal_error(_("Cannot insert new record: %s"),
			      db_get_string(&sql));
	    };
	}
    }

    if (find_cut) {
	for (i = 0; i < cut->n_values; i++) {
	    int type = Vect_read_line(&In, Points, Cats, cut->value[i]);

	    Vect_write_line(&cut_map, type, Points, Cats);
	}
	Vect_destroy_list(cut);

	Vect_build(&cut_map);
	Vect_close(&cut_map);
    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

    G_free(flow);
    Vect_destroy_list(source_list);
    Vect_destroy_list(sink_list);

    Vect_build(&Out);

    Vect_close(&In);
    Vect_close(&Out);

    exit(EXIT_SUCCESS);
}
Esempio n. 12
0
void select_from_database(void)
{
    int nrec, ctype, nlines, line, nareas, area;
    struct line_pnts *Points;

    Fi = Vect_get_field(&Map, ofield);
    if (Fi == NULL) {
	G_fatal_error(_(" Database connection not defined for layer <%s>"), field_opt->answer);
    }

    Driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (Driver == NULL)
	G_fatal_error("Unable to open database <%s> by driver <%s>",
		      Fi->database, Fi->driver);
    db_set_error_handler_driver(Driver);

    /* check if column exists */
    ctype = db_column_Ctype(Driver, Fi->table, col_opt->answer);
    if (ctype == -1)
        G_fatal_error(_("Column <%s> not found in table <%s>"),
                      col_opt->answer, Fi->table);
    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
	G_fatal_error(_("Only numeric column type is supported"));
    
    /* Note do not check if the column exists in the table because it may be an expression */
    db_CatValArray_init(&Cvarr);
    nrec = db_select_CatValArray(Driver, Fi->table, Fi->key, col_opt->answer,
                                 where_opt->answer, &Cvarr);
    G_debug(2, "db_select_CatValArray() nrec = %d", nrec);
    if (nrec < 0)
	G_fatal_error(_("Unable to select data from table"));

    db_close_database_shutdown_driver(Driver);

    Points = Vect_new_line_struct();

    /* Lines */
    nlines = 0;
    if ((otype & GV_POINTS) || (otype & GV_LINES))
	nlines = Vect_get_num_lines(&Map);

    G_debug(1, "select_from_database: %d points", nlines);
    for (line = 1; line <= nlines; line++) {
	int i, type;

	G_debug(3, "line = %d", line);

	G_percent(line, nlines, 2);
	type = Vect_read_line(&Map, Points, Cats, line);
	if (!(type & otype))
	    continue;

	for (i = 0; i < Cats->n_cats; i++) {
	    if (Cats->field[i] == ofield) {
		double val = 0.0;
		dbCatVal *catval;

		G_debug(3, "cat = %d", Cats->cat[i]);

		if (db_CatValArray_get_value(&Cvarr, Cats->cat[i], &catval) !=
		    DB_OK) {
		    G_debug(3, "No record for cat = %d", Cats->cat[i]);
		    nmissing++;
		    continue;
		}

		if (catval->isNull) {
		    G_debug(3, "NULL value for cat = %d", Cats->cat[i]);
		    nnull++;
		    continue;
		}

		if (ctype == DB_C_TYPE_INT) {
		    val = catval->val.i;
		}
		else if (ctype == DB_C_TYPE_DOUBLE) {
		    val = catval->val.d;
		}

		count++;

		if (first) {
		    max = val;
		    min = val;
		    first = 0;
		}
		else {
		    if (val > max)
			max = val;
		    if (val < min)
			min = val;
		}

		if (compatible) {
		    if (type & GV_POINTS) {
			sum += val;
			sumsq += val * val;
			sumcb += val * val * val;
			sumqt += val * val * val * val;
			sum_abs += fabs(val);
		    }
		    else if (type & GV_LINES) {	/* GV_LINES */
			double l = 1.;

			if (weight_flag->answer)
			    l = Vect_line_length(Points);

			sum += l * val;
			sumsq += l * val * val;
			sumcb += l * val * val * val;
			sumqt += l * val * val * val * val;
			sum_abs += l * fabs(val);
			total_size += l;
		    }
		}
		G_debug(3, "sum = %f total_size = %f", sum, total_size);
	    }
	}
    }

    if (otype & GV_AREA) {
	nareas = Vect_get_num_areas(&Map);
	for (area = 1; area <= nareas; area++) {
	    int i, centr;

	    G_debug(3, "area = %d", area);

	    centr = Vect_get_area_centroid(&Map, area);
	    if (centr < 1)
		continue;

	    G_debug(3, "centr = %d", centr);
	    Vect_read_line(&Map, NULL, Cats, centr);

	    for (i = 0; i < Cats->n_cats; i++) {
		if (Cats->field[i] == ofield) {
		    double val = 0.0;
		    dbCatVal *catval;

		    G_debug(3, "cat = %d", Cats->cat[i]);

		    if (db_CatValArray_get_value
			(&Cvarr, Cats->cat[i], &catval) != DB_OK) {
			G_debug(3, "No record for cat = %d", Cats->cat[i]);
			nmissing++;
			continue;
		    }

		    if (catval->isNull) {
			G_debug(3, "NULL value for cat = %d", Cats->cat[i]);
			nnull++;
			continue;
		    }

		    if (ctype == DB_C_TYPE_INT) {
			val = catval->val.i;
		    }
		    else if (ctype == DB_C_TYPE_DOUBLE) {
			val = catval->val.d;
		    }

		    count++;

		    if (first) {
			max = val;
			min = val;
			first = 0;
		    }
		    else {
			if (val > max)
			    max = val;
			if (val < min)
			    min = val;
		    }

		    if (compatible) {
			double a = 1.;

			if (weight_flag->answer)
			    a = Vect_get_area_area(&Map, area);

			sum += a * val;
			sumsq += a * val * val;
			sumcb += a * val * val * val;
			sumqt += a * val * val * val * val;
			sum_abs += a * fabs(val);
			total_size += a;
		    }
		    G_debug(4, "sum = %f total_size = %f", sum, total_size);
		}
	    }
	}
    }

    G_debug(2, "sum = %f total_size = %f", sum, total_size);
}
Esempio n. 13
0
void select_from_geometry(void)
{
    int i, j, k, ncats, *cats;
    int type;
    struct line_pnts *iPoints, *jPoints;

    iPoints = Vect_new_line_struct();
    jPoints = Vect_new_line_struct();

    if (where_opt->answer != NULL) {
	if (ofield < 1) {
	    G_fatal_error(_("'layer' must be > 0 for 'where'."));
	}
	Fi = Vect_get_field(&Map, ofield);
	if (!Fi) {
	    G_fatal_error(_("Database connection not defined for layer %d"),
			  ofield);
	}

	Driver = db_start_driver_open_database(Fi->driver, Fi->database);
	if (Driver == NULL)
	    G_fatal_error("Unable to open database <%s> by driver <%s>",
			  Fi->database, Fi->driver);
        db_set_error_handler_driver(Driver);

	ncats = db_select_int(Driver, Fi->table, Fi->key, where_opt->answer,
			      &cats);
	if (ncats == -1)
		G_fatal_error(_("Unable select categories from table <%s>"), Fi->table);

	db_close_database_shutdown_driver(Driver);

    }
    else
	ncats = 0;

    count = 0;

    nlines = Vect_get_num_lines(&Map);
    G_message(_("Calculating geometric distances between %d primitives..."), nlines);
    /* Start calculating the statistics based on distance to all other primitives.
       Use the centroid of areas and the first point of lines */
    for (i = 1; i <= nlines; i++) {

	G_percent(i, nlines, 2);
	type = Vect_read_line(&Map, iPoints, Cats, i);

	if (!(type & otype))
	    continue;

	if (where_opt->answer) {
	    int ok = FALSE;

	    for (j = 0; j < Cats->n_cats; j++) {
		if (Vect_cat_in_array(Cats->cat[j], cats, ncats)) {
		    ok = TRUE;
		    break;
		}
	    }
	    if (!ok)
	        continue;
	}
	for (j = i + 1; j < nlines; j++) {
	    /* get distance to this object */
	    double val = 0.0;

	    type = Vect_read_line(&Map, jPoints, Cats, j);

	    if (!(type & otype))
		continue;

	    /* now calculate the min distance between each point in line i with line j */
	    for (k = 0; k < iPoints->n_points; k++) {
		double dmin = 0.0;

		Vect_line_distance(jPoints, iPoints->x[k], iPoints->y[k], iPoints->z[k], 1,
				       NULL, NULL, NULL, &dmin, NULL, NULL);
		if((k == 0) || (dmin < val)) {
		    val = dmin;
		}
	    }
	    if (val > 0 && iPoints->n_points > 1) {
		for (k = 0; k < jPoints->n_points; k++) {
		    double dmin = 0.0;

		    Vect_line_distance(iPoints, jPoints->x[k], jPoints->y[k], jPoints->z[k], 1,
					   NULL, NULL, NULL, &dmin, NULL, NULL);
		    if(dmin < val) {
			val = dmin;
		    }
		}
	    }
	    if (val > 0 && iPoints->n_points > 1 && jPoints->n_points > 1) {
		if (Vect_line_check_intersection(iPoints, jPoints, Vect_is_3d(&Map)))
		    val = 0;
	    }
	    if (val == 0) {
		nzero++;
		continue;
	    }
	    if (first) {
		max = val;
		min = val;
		first = 0;
	    }
	    else {
		if (val > max)
		    max = val;
		if (val < min)
		    min = val;
	    }
	    sum += val;
	    sumsq += val * val;
	    sumcb += val * val * val;
	    sumqt += val * val * val * val;
	    sum_abs += fabs(val);
	    count++;
	    G_debug(3, "i=%d j=%d sum = %f val=%f", i, j, sum, val);
	}
    }
}
Esempio n. 14
0
/**
   \brief Select features according to SQL where statement

   \param[in] Map vector map
   \param[in] layer layer number
   \param[in] type feature type
   \param[in] where 'where' statement
   \param[in,out] List list of selected features
 
   \return number of selected lines
*/
int sel_by_where(struct Map_info *Map,
		 int layer, int type, char *where, struct ilist *List)
{
    struct cat_list *cat_list;
    struct ilist *List_tmp;
    struct field_info *Fi;
    dbDriver *driver;
    dbHandle handle;

    int *cats, ncats;

    if (first_selection) {
	List_tmp = List;
	first_selection = 0;
    }
    else {
	List_tmp = Vect_new_list();
    }

    cat_list = Vect_new_cat_list();

    if (layer < 1) {
	G_fatal_error(_("Layer must be > 0 for 'where'"));
    }

    Fi = Vect_get_field(Map, layer);

    if (!Fi) {
	G_fatal_error(_("Database connection not defined for layer %d"),
		      layer);
    }

    driver = db_start_driver(Fi->driver);

    if (!driver)
	G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);

    db_init_handle(&handle);

    db_set_handle(&handle, Fi->database, NULL);

    if (db_open_database(driver, &handle) != DB_OK)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);
    db_set_error_handler_driver(driver);

    ncats = db_select_int(driver, Fi->table, Fi->key, where, &cats);

    db_close_database(driver);
    db_shutdown_driver(driver);

    Vect_array_to_cat_list(cats, ncats, cat_list);

    /* free array of cats */
    if (ncats >= 0)
	G_free(cats);

    sel_by_cat(Map, cat_list, layer, type, NULL, List_tmp);

    G_debug(1, "  %d lines selected (by where)", List_tmp->n_values);

    /* merge lists (only duplicate items) */
    if (List_tmp != List) {
	merge_lists(List, List_tmp);
	Vect_destroy_list(List_tmp);
    }

    Vect_destroy_cat_list(cat_list);

    return List->n_values;
}
Esempio n. 15
0
/*--------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* Variables declarations */
    int nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row;
    int subregion = 0, nsubregions = 0;
    double N_extension, E_extension, edgeE, edgeN;
    int dim_vect, nparameters, BW, npoints;
    double mean, lambda;
    const char *dvr, *db, *mapset;
    char table_name[GNAME_MAX];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

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

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

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

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

    struct Point *observ;

    dbDriver *driver;

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

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

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);

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

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

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

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

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

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

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

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

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

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

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

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

    flag_auxiliar = FALSE;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    nsubregions = nsubregion_row * nsubregion_col;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		nparameters = nsplx * nsply;

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

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

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

		G_free(observ);

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

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

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


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

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

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

    db_close_database_shutdown_driver(driver);

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

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*END MAIN */
Esempio n. 16
0
int main(int argc, char *argv[])
{
    int npmin;
    int ii;
    double x_orig, y_orig, dnorm, deltx, delty, xm, ym;
    char dmaxchar[200];
    char dminchar[200];

    struct quaddata *data;
    struct multfunc *functions;
    struct multtree *tree;
    int open_check, with_z;
    char buf[1024];

    struct GModule *module;
    struct
    {
	struct Option *input, *field, *zcol, *wheresql, *scol, *elev, *slope,
	    *aspect, *pcurv, *tcurv, *mcurv, *treefile, *overfile, *maskmap,
	    *dmin, *dmax, *zmult, *fi, *rsm, *segmax, *npmin, *cvdev, *devi,
	    *theta, *scalex;
    } parm;
    struct
    {
	struct Flag *deriv, *cprght, *cv;
    } flag;


    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("surface"));
    G_add_keyword(_("interpolation"));
    G_add_keyword(_("3D"));
    module->label = _("Performs surface interpolation from vector points map by splines.");
    module->description =
	_("Spatial approximation and topographic analysis from given "
	  "point or isoline data in vector format to floating point "
	  "raster format using regularized spline with tension.");

    flag.cv = G_define_flag();
    flag.cv->key = 'c';
    flag.cv->description =
	_("Perform cross-validation procedure without raster approximation");
    flag.cv->guisection = _("Parameters");

    flag.cprght = G_define_flag();
    flag.cprght->key = 't';
    flag.cprght->description = _("Use scale dependent tension");
    flag.cprght->guisection = _("Parameters");

    flag.deriv = G_define_flag();
    flag.deriv->key = 'd';
    flag.deriv->description =
	_("Output partial derivatives instead of topographic parameters");
    flag.deriv->guisection = _("Outputs");

    parm.input = G_define_standard_option(G_OPT_V_INPUT);
    
    parm.field = G_define_standard_option(G_OPT_V_FIELD);
    parm.field->answer = "1";
    parm.field->guisection = _("Selection");

    parm.zcol = G_define_standard_option(G_OPT_DB_COLUMN);
    parm.zcol->key = "zcolumn";
    parm.zcol->required = NO;
    parm.zcol->label =
	_("Name of the attribute column with values to be used for approximation");
    parm.zcol->description = _("If not given and input is 2D vector map then category values are used. "
                               "If input is 3D vector map then z-coordinates are used.");
    parm.zcol->guisection = _("Parameters");

    parm.wheresql = G_define_standard_option(G_OPT_DB_WHERE);
    parm.wheresql->guisection = _("Selection");

    parm.elev = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.elev->key = "elevation";
    parm.elev->required = NO;
    parm.elev->description = _("Name for output surface elevation raster map");
    parm.elev->guisection = _("Outputs");

    parm.slope = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.slope->key = "slope";
    parm.slope->required = NO;
    parm.slope->description = _("Name for output slope raster map");
    parm.slope->guisection = _("Outputs");

    parm.aspect = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.aspect->key = "aspect";
    parm.aspect->required = NO;
    parm.aspect->description = _("Name for output aspect raster map");
    parm.aspect->guisection = _("Outputs");

    parm.pcurv = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.pcurv->key = "pcurvature";
    parm.pcurv->required = NO;
    parm.pcurv->description = _("Name for output profile curvature raster map");
    parm.pcurv->guisection = _("Outputs");

    parm.tcurv = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.tcurv->key = "tcurvature";
    parm.tcurv->required = NO;
    parm.tcurv->description = _("Name for output tangential curvature raster map");
    parm.tcurv->guisection = _("Outputs");

    parm.mcurv = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.mcurv->key = "mcurvature";
    parm.mcurv->required = NO;
    parm.mcurv->description = _("Name for output mean curvature raster map");
    parm.mcurv->guisection = _("Outputs");

    parm.devi = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.devi->key = "deviations";
    parm.devi->required = NO;
    parm.devi->description = _("Name for output deviations vector point map");
    parm.devi->guisection = _("Outputs");

    parm.cvdev = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.cvdev->key = "cvdev";
    parm.cvdev->required = NO;
    parm.cvdev->description =
	_("Name for output cross-validation errors vector point map");
    parm.cvdev->guisection = _("Outputs");

    parm.treefile = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.treefile->key = "treeseg";
    parm.treefile->required = NO;
    parm.treefile->description =
	_("Name for output vector map showing quadtree segmentation");
    parm.treefile->guisection = _("Outputs");

    parm.overfile = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.overfile->key = "overwin";
    parm.overfile->required = NO;
    parm.overfile->description =
	_("Name for output vector map showing overlapping windows");
    parm.overfile->guisection = _("Outputs");

    parm.maskmap = G_define_standard_option(G_OPT_R_INPUT);
    parm.maskmap->key = "mask";
    parm.maskmap->required = NO;
    parm.maskmap->description = _("Name of raster map used as mask");
    parm.maskmap->guisection = _("Parameters");

    parm.fi = G_define_option();
    parm.fi->key = "tension";
    parm.fi->type = TYPE_DOUBLE;
    parm.fi->answer = TENSION;
    parm.fi->required = NO;
    parm.fi->description = _("Tension parameter");
    parm.fi->guisection = _("Parameters");

    parm.rsm = G_define_option();
    parm.rsm->key = "smooth";
    parm.rsm->type = TYPE_DOUBLE;
    parm.rsm->required = NO;
    parm.rsm->description = _("Smoothing parameter");
    parm.rsm->guisection = _("Parameters");

    parm.scol = G_define_option();
    parm.scol->key = "smooth_column";
    parm.scol->type = TYPE_STRING;
    parm.scol->required = NO;
    parm.scol->description =
	_("Name of the attribute column with smoothing parameters");
    parm.scol->guisection = _("Parameters");

    parm.segmax = G_define_option();
    parm.segmax->key = "segmax";
    parm.segmax->type = TYPE_INTEGER;
    parm.segmax->answer = MAXSEGM;
    parm.segmax->required = NO;
    parm.segmax->description = _("Maximum number of points in a segment");
    parm.segmax->guisection = _("Parameters");

    parm.npmin = G_define_option();
    parm.npmin->key = "npmin";
    parm.npmin->type = TYPE_INTEGER;
    parm.npmin->answer = MINPOINTS;
    parm.npmin->required = NO;
    parm.npmin->description =
	_("Minimum number of points for approximation in a segment (>segmax)");
    parm.npmin->guisection = _("Parameters");

    parm.dmin = G_define_option();
    parm.dmin->key = "dmin";
    parm.dmin->type = TYPE_DOUBLE;
    parm.dmin->required = NO;
    parm.dmin->description =
	_("Minimum distance between points (to remove almost identical points)");
    parm.dmin->guisection = _("Parameters");

    parm.dmax = G_define_option();
    parm.dmax->key = "dmax";
    parm.dmax->type = TYPE_DOUBLE;
    parm.dmax->required = NO;
    parm.dmax->description =
	_("Maximum distance between points on isoline (to insert additional points)");
    parm.dmax->guisection = _("Parameters");

    parm.zmult = G_define_option();
    parm.zmult->key = "zscale";
    parm.zmult->type = TYPE_DOUBLE;
    parm.zmult->answer = ZMULT;
    parm.zmult->required = NO;
    parm.zmult->description =
	_("Conversion factor for values used for approximation");
    parm.zmult->guisection = _("Parameters");

    parm.theta = G_define_option();
    parm.theta->key = "theta";
    parm.theta->type = TYPE_DOUBLE;
    parm.theta->required = NO;
    parm.theta->description =
	_("Anisotropy angle (in degrees counterclockwise from East)");
    parm.theta->guisection = _("Parameters");

    parm.scalex = G_define_option();
    parm.scalex->key = "scalex";
    parm.scalex->type = TYPE_DOUBLE;
    parm.scalex->required = NO;
    parm.scalex->description = _("Anisotropy scaling factor");
    parm.scalex->guisection = _("Parameters");

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

    G_get_set_window(&cellhd);

    ew_res = cellhd.ew_res;
    ns_res = cellhd.ns_res;
    n_cols = cellhd.cols;
    n_rows = cellhd.rows;
    x_orig = cellhd.west;
    y_orig = cellhd.south;
    xm = cellhd.east;
    ym = cellhd.north;
    if (ew_res < ns_res)
	dmin = ew_res / 2;
    else
	dmin = ns_res / 2;
    disk = n_rows * n_cols * sizeof(int);
    sdisk = n_rows * n_cols * sizeof(short int);
    sprintf(dmaxchar, "%f", dmin * 5);
    sprintf(dminchar, "%f", dmin);

    if (!parm.dmin->answer) {
	parm.dmin->answer = G_store(dminchar);
	parm.dmin->answers = (char **) G_malloc(2 * sizeof(char *));
	parm.dmin->answers[0] = G_store(dminchar);
	parm.dmin->answers[1] = NULL;
    }
    if (!parm.dmax->answer) {
	parm.dmax->answer = G_store(dmaxchar);
	parm.dmax->answers = (char **) G_malloc(2 * sizeof(char *));
	parm.dmax->answers[0] = G_store(dmaxchar);
	parm.dmax->answers[1] = NULL;
    }
    
    input = parm.input->answer;
    zcol = parm.zcol->answer;
    scol = parm.scol->answer;
    wheresql = parm.wheresql->answer;
    maskmap = parm.maskmap->answer;
    elev = parm.elev->answer;
    devi = parm.devi->answer;
    cvdev = parm.cvdev->answer;
    slope = parm.slope->answer;
    aspect = parm.aspect->answer;
    pcurv = parm.pcurv->answer;
    tcurv = parm.tcurv->answer;
    mcurv = parm.mcurv->answer;
    treefile = parm.treefile->answer;
    overfile = parm.overfile->answer;

    if (devi) {
	if (Vect_legal_filename(devi) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  devi);
    }
    if (cvdev) {
	if (Vect_legal_filename(cvdev) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  cvdev);
    }
    if (treefile) {
	if (Vect_legal_filename(treefile) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  treefile);
    }
    if (overfile) {
	if (Vect_legal_filename(overfile) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  overfile);
    }
    /*    if (treefile)
       Vect_check_input_output_name(input, treefile, G_FATAL_EXIT);

       if (overfile)
       Vect_check_input_output_name(input, overfile, G_FATAL_EXIT);
     */
    if ((elev == NULL) && (pcurv == NULL) && (tcurv == NULL)
	&& (mcurv == NULL)
	&& (slope == NULL) && (aspect == NULL) && (devi == NULL)
	&& (cvdev == NULL))
	G_warning(_("You are not outputting any raster or vector maps"));
    
    cond2 = ((pcurv != NULL) || (tcurv != NULL) || (mcurv != NULL));
    cond1 = ((slope != NULL) || (aspect != NULL) || cond2);
    deriv = flag.deriv->answer;
    dtens = flag.cprght->answer;
    cv = flag.cv->answer;

    if ((cv && cvdev == NULL) || (!(cv) && cvdev != NULL))
	G_fatal_error(_("Both cross-validation options (-c flag and cvdev vector output) must be specified"));

    if ((elev != NULL || cond1 || cond2 || devi != NULL) && cv)
	G_fatal_error(_("The cross-validation cannot be computed simultaneously with output raster or devi file"));

    ertre = 0.1;
    sscanf(parm.dmax->answer, "%lf", &dmax);
    sscanf(parm.dmin->answer, "%lf", &dmin);
    sscanf(parm.fi->answer, "%lf", &fi);
    sscanf(parm.segmax->answer, "%d", &KMAX);
    sscanf(parm.npmin->answer, "%d", &npmin);
    sscanf(parm.zmult->answer, "%lf", &zmult);

    /* if (fi=0.000000)  G_fatal_error("Tension must be > 0.000000") */

    if (parm.theta->answer)
	sscanf(parm.theta->answer, "%lf", &theta);

    if (parm.scalex->answer) {
	sscanf(parm.scalex->answer, "%lf", &scalex);
	if (!parm.theta->answer)
	    G_fatal_error(_("Using anisotropy - both theta and scalex have to be specified"));
    }

    if (parm.rsm->answer) {
	sscanf(parm.rsm->answer, "%lf", &rsm);
	if (rsm < 0.0)
	    G_fatal_error("Smoothing must be a positive value");
	if (scol != NULL)
	    G_warning(_("Both smatt and smooth options specified - using constant"));
    }
    else {
	sscanf(SMOOTH, "%lf", &rsm);
	if (scol != NULL)
	    rsm = -1;		/* used in InterpLib to indicate variable smoothing */
    }


    if (npmin > MAXPOINTS - 50) {
	G_warning(_("The computation will last too long - lower npmin is suggested"));
	KMAX2 = 2 * npmin;	/* was: KMAX2 = npmin + 50; */
    }
    else
	KMAX2 = 2 * npmin;	/* was: KMAX2 = MAXPOINTS; fixed by JH in 12/01 */

    /* handling of KMAX2 in GRASS4 v.surf.rst
       if (npmin > MAXPOINTS - 50)
       KMAX2 = npmin + 50;
       else
       KMAX2 = MAXPOINTS;
     */

    dmin = dmin * dmin;
    KMIN = npmin;

    az = G_alloc_vector(n_cols + 1);
    if (!az) {
	G_fatal_error(_("Not enough memory for %s"), "az");
    }
    if (cond1) {
	adx = G_alloc_vector(n_cols + 1);
	if (!adx) {
	    G_fatal_error(_("Not enough memory for %s"), "adx");
	}
	ady = G_alloc_vector(n_cols + 1);
	if (!ady) {
	    G_fatal_error(_("Not enough memory for %s"), "ady");
	}
	if (cond2) {
	    adxx = G_alloc_vector(n_cols + 1);
	    if (!adxx) {
		G_fatal_error(_("Not enough memory for %s"), "adxx");
	    }
	    adyy = G_alloc_vector(n_cols + 1);
	    if (!adyy) {
		G_fatal_error(_("Not enough memory for %s"), "adyy");
	    }
	    adxy = G_alloc_vector(n_cols + 1);
	    if (!adxy) {
		G_fatal_error(_("Not enough memory for %s"), "adxy");
	    }
	}
    }
    if ((data =
	 quad_data_new(x_orig, y_orig, xm, ym, n_rows, n_cols, 0,
		       KMAX)) == NULL)
	G_fatal_error(_("Unable to create %s"), "quaddata");
    if ((functions =
	 MT_functions_new(quad_compare, quad_divide_data, quad_add_data,
			  quad_intersect, quad_division_check,
			  quad_get_points)) == NULL)

	G_fatal_error(_("Unable to create %s"), "quadfunc");

    if ((tree = MT_tree_new(data, NULL, NULL, 0)) == NULL)
	G_fatal_error(_("Unable to create %s"), "tree");
    root = tree;

    if ((info = MT_tree_info_new(root, functions, dmin, KMAX)) == NULL)
	G_fatal_error(_("Unable to create %s"), "tree info");

    open_check = Vect_open_old2(&Map, input, "", parm.field->answer);
    if (open_check < 1)
	G_fatal_error(_("Unable to open vector map <%s>"), input);
    /*    if (open_check < 2)
          G_fatal_error(_("You first need to run v.build on vector map <%s>"), input);
    */

    /* get value used for approximation */
    with_z = !parm.zcol->answer && Vect_is_3d(&Map);
    field = Vect_get_field_number(&Map, parm.field->answer);
    if (!with_z && field < 1)
	G_fatal_error(_("Layer <%s> not found"), parm.field->answer);

    if (Vect_is_3d(&Map)) {
        if (!with_z)
            G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation"));
        else
            G_verbose_message(_("Input is 3D: using z-coordinates for approximation"));
    }
    else { /* 2D */
        if (parm.zcol->answer)
            G_verbose_message(_("Input is 2D: using attribute values for approximation"));
        else
            G_verbose_message(_("Input is 2D: using category values for approximation"));
    }
        
    /* we can't read the input file's timestamp as they don't exist in   */
    /*   the new vector format. Even so, a TimeStamp structure is needed */
    /*   for IL_init_params_2d(), so we set it to NULL.                  */
    /* If anyone is ever motivated to add it, the Plus_head struct has   */
    /*  'long coor_mtime' and dig_head has 'char *date; char *source_date;' */
    /*   which could be read in.                                         */

    if (devi != NULL || cvdev != NULL) {

	Pnts = Vect_new_line_struct();
	Cats2 = Vect_new_cats_struct();
	db_init_string(&sql2);

	if (devi != NULL) {
	    if (Vect_open_new(&Map2, devi, 1) < 0)
		G_fatal_error(_("Unable to create vector map <%s>"), devi);
	} else {
	    if (Vect_open_new(&Map2, cvdev, 1) < 0)
		G_fatal_error(_("Unable to create vector map <%s>"), cvdev);
	}
	Vect_hist_command(&Map2);
	ff = Vect_default_field_info(&Map2, 1, NULL, GV_1TABLE);
	Vect_map_add_dblink(&Map2, 1, NULL, ff->table, GV_KEY_COLUMN, ff->database,
			    ff->driver);

	/* Create new table */
	db_zero_string(&sql2);
	sprintf(buf, "create table %s ( ", ff->table);
	db_append_string(&sql2, buf);
	db_append_string(&sql2, "cat integer");
	db_append_string(&sql2, ", flt1 double precision");
	db_append_string(&sql2, ")");
	G_debug(1, "%s", db_get_string(&sql2));
	driver2 = db_start_driver_open_database(ff->driver, ff->database);
	if (driver2 == NULL)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  ff->database, ff->driver);
        db_set_error_handler_driver(driver2);

	if (db_execute_immediate(driver2, &sql2) != DB_OK) {
	    G_fatal_error(_("Unable to create table '%s'"),
			  db_get_string(&sql2));
	}
	db_begin_transaction(driver2);
	count = 1;

    }

    ertot = 0.;
    
    create_temp_files();

    IL_init_params_2d(&params, NULL, 1, 1, zmult, KMIN, KMAX, maskmap, n_rows,
		      n_cols, az, adx, ady, adxx, adyy, adxy, fi, KMAX2,
		      SCIK1, SCIK2, SCIK3, rsm, elev, slope, aspect, pcurv,
		      tcurv, mcurv, dmin, x_orig, y_orig, deriv, theta,
		      scalex, Tmp_fd_z, Tmp_fd_dx, Tmp_fd_dy, Tmp_fd_xx,
		      Tmp_fd_yy, Tmp_fd_xy, devi, NULL, cv,
		      parm.wheresql->answer);

    IL_init_func_2d(&params, IL_grid_calc_2d, IL_matrix_create,
		    IL_check_at_points_2d, IL_secpar_loop_2d, IL_crst,
		    IL_crstg, IL_write_temp_2d);

    totsegm =
	IL_vector_input_data_2d(&params, &Map, with_z ? 0 : field,
				zcol, scol,
				info, &xmin, &xmax,
				&ymin, &ymax, &zmin, &zmax, &NPOINT, &dmax);
    if (totsegm <= 0) {
	clean();
	G_fatal_error(_("Input failed"));
    }

    /*Vect_set_release_support(&Map); */
    Vect_close(&Map);

    if (treefile != NULL) {
	if (0 > Vect_open_new(&TreeMap, treefile, 0)) {
	    clean();
	    G_fatal_error(_("Unable to open vector map <%s>"), treefile);
	}
	Vect_hist_command(&TreeMap);

	/*
	   sprintf (TreeMap.head.your_name, "grass");
	   sprintf (TreeMap.head.map_name, "Quad tree for %s", input);
	   TreeMap.head.orig_scale = 100000;
	   TreeMap.head.plani_zone = G_zone ();
	 */
	print_tree(root, x_orig, y_orig, &TreeMap);
	Vect_build(&TreeMap);
	Vect_close(&TreeMap);
    }

    disk = disk + totsegm * sizeof(int) * 4;
    sdisk = sdisk + totsegm * sizeof(int) * 4;
    if (elev != NULL)
	ddisk += disk;
    if (slope != NULL)
	sddisk += sdisk;
    if (aspect != NULL)
	sddisk += sdisk;
    if (pcurv != NULL)
	ddisk += disk;
    if (tcurv != NULL)
	ddisk += disk;
    if (mcurv != NULL)
	ddisk += disk;
    ddisk += sddisk;
    G_verbose_message(_("Processing all selected output files "
			"will require %d bytes of disk space for temp files"), ddisk);

    deltx = xmax - xmin;
    delty = ymax - ymin;
    dnorm = sqrt((deltx * delty * KMIN) / NPOINT);

    if (dtens) {
	params.fi = params.fi * dnorm / 1000.;
	G_verbose_message("dnorm = %f, rescaled tension = %f", dnorm, params.fi);
    }
    
    bitmask = IL_create_bitmask(&params);
    
    if (totsegm <= 0) {
	clean();
	G_fatal_error(_("Input failed"));
    }

    ertot = 0.;
    G_message(_("Processing segments..."));    
    if (IL_interp_segments_2d(&params, info, info->root, bitmask,
			      zmin, zmax, &zminac, &zmaxac, &gmin, &gmax,
			      &c1min, &c1max, &c2min, &c2max, &ertot, totsegm,
			      n_cols, dnorm) < 0) {
	clean();
	G_fatal_error(_("Interp_segmets failed"));
    }

    G_free_vector(az);
    if (cond1) {
	G_free_vector(adx);
	G_free_vector(ady);
	if (cond2) {
	    G_free_vector(adxx);
	    G_free_vector(adyy);
	    G_free_vector(adxy);
	}
    }
    ii = IL_output_2d(&params, &cellhd, zmin, zmax, zminac, zmaxac, c1min,
		      c1max, c2min, c2max, gmin, gmax, ertot, input, dnorm,
		      dtens, 1, NPOINT);
    if (ii < 0) {
	clean();
	G_fatal_error(_("Unable to write raster maps - try to increase resolution"));
    }

    G_free(zero_array_cell);
    if (elev != NULL)
	fclose(Tmp_fd_z);
    if (slope != NULL)
	fclose(Tmp_fd_dx);
    if (aspect != NULL)
	fclose(Tmp_fd_dy);
    if (pcurv != NULL)
	fclose(Tmp_fd_xx);
    if (tcurv != NULL)
	fclose(Tmp_fd_yy);
    if (mcurv != NULL)
	fclose(Tmp_fd_xy);

    if (overfile != NULL) {
	if (0 > Vect_open_new(&OverMap, overfile, 0)) {
	    clean();
	    G_fatal_error(_("Unable to create vector map <%s>"), overfile);
	}
	Vect_hist_command(&OverMap);

	/*
	   sprintf (OverMap.head.your_name, "grass");
	   sprintf (OverMap.head.map_name, "Overlap segments for %s", input);
	   OverMap.head.orig_scale = 100000;
	   OverMap.head.plani_zone = G_zone ();
	 */
	print_tree(root, x_orig, y_orig, &OverMap);
	Vect_build(&OverMap);
	Vect_close(&OverMap);
    }

    if (elev != NULL)
	unlink(Tmp_file_z);
    if (slope != NULL)
	unlink(Tmp_file_dx);
    if (aspect != NULL)
	unlink(Tmp_file_dy);
    if (pcurv != NULL)
	unlink(Tmp_file_xx);
    if (tcurv != NULL)
	unlink(Tmp_file_yy);
    if (mcurv != NULL)
	unlink(Tmp_file_xy);

    if (cvdev != NULL || devi != NULL) {
	db_commit_transaction(driver2);
	db_close_database_shutdown_driver(driver2);
	Vect_build(&Map2);
	Vect_close(&Map2);
    }

    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}
Esempio n. 17
0
int display_shape(struct Map_info *Map, int type, struct cat_list *Clist, const struct Cell_head *window, 
		  const struct color_rgb *bcolor, const struct color_rgb *fcolor, int chcat,
		  const char *icon, double size, const char *size_column, int sqrt_flag, const char *rot_column, /* lines only */
		  int id_flag, int cats_colors_flag, char *rgb_column,
		  int default_width, char *width_column, double width_scale,
		  char *z_style)
{
    int open_db, field, i, stat;
    dbCatValArray cvarr_rgb, cvarr_width, cvarr_size, cvarr_rot;
    struct field_info *fi;
    dbDriver *driver;
    int nrec_rgb, nrec_width, nrec_size, nrec_rot, have_colors;
    struct Colors colors, zcolors;
    struct bound_box box;
    
    stat = 0;
    nrec_rgb = nrec_width = nrec_size = nrec_rot = 0;
    
    open_db = rgb_column || width_column || size_column || rot_column;
    if (open_db) {
	field = Clist->field > 0 ? Clist->field : 1;
	fi = Vect_get_field(Map, field);
	if (!fi) {
	    G_fatal_error(_("Database connection not defined for layer %d"),
			  field);
	}
	
	driver = db_start_driver_open_database(fi->driver, fi->database);
	if (!driver)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  fi->database, fi->driver);
        db_set_error_handler_driver(driver);
    }
    
    /* fisrt search for color table */
    have_colors = Vect_read_colors(Vect_get_name(Map), Vect_get_mapset(Map),
				   &colors);
    if (have_colors && rgb_column) {
        G_warning(_("Both color table and <%s> option detected. "
                    "Color table will ignored."), "rgb_column");
        have_colors = FALSE;
    }

    if (rgb_column) {
	/* read RRR:GGG:BBB color strings from table */
	db_CatValArray_init(&cvarr_rgb);
	
	nrec_rgb = db_select_CatValArray(driver, fi->table, fi->key,
					 rgb_column, NULL, &cvarr_rgb);
	
	G_debug(3, "nrec_rgb (%s) = %d", rgb_column, nrec_rgb);
	    
	if (cvarr_rgb.ctype != DB_C_TYPE_STRING) {
	    G_warning(_("Color definition column ('%s') not a string. "
			"Column must be of form 'RRR:GGG:BBB' where RGB values range 0-255. "
			"You can use '%s' module to define color rules. "
			"Unable to colorize features."),
		      rgb_column, "v.colors");
            rgb_column = NULL;
        }
	else {
	    if (nrec_rgb < 0)
		G_fatal_error(_("Unable to select data ('%s') from table"),
			      rgb_column);
	    
	    G_debug(2, "\n%d records selected from table", nrec_rgb);
	}
    }
    if (width_column) {
	if (*width_column == '\0')
	    G_fatal_error(_("Line width column not specified"));

	db_CatValArray_init(&cvarr_width);

	nrec_width = db_select_CatValArray(driver, fi->table, fi->key,
					   width_column, NULL, &cvarr_width);

	G_debug(3, "nrec_width (%s) = %d", width_column, nrec_width);

	if (cvarr_width.ctype != DB_C_TYPE_INT &&
	    cvarr_width.ctype != DB_C_TYPE_DOUBLE)
	    G_fatal_error(_("Line width column ('%s') not a number"),
			  width_column);

	if (nrec_width < 0)
	    G_fatal_error(_("Unable to select data ('%s') from table"),
			  width_column);

	G_debug(2, "\n%d records selected from table", nrec_width);

	for (i = 0; i < cvarr_width.n_values; i++) {
	    G_debug(4, "cat = %d  %s = %d", cvarr_width.value[i].cat,
		    width_column,
		    (cvarr_width.ctype ==
		     DB_C_TYPE_INT ? cvarr_width.value[i].val.
		     i : (int)cvarr_width.value[i].val.d));
	}
    }

    if (size_column) {
	if (*size_column == '\0')
	    G_fatal_error(_("Symbol size column not specified"));
	
	db_CatValArray_init(&cvarr_size);

	nrec_size = db_select_CatValArray(driver, fi->table, fi->key,
					  size_column, NULL, &cvarr_size);
	
	G_debug(3, "nrec_size (%s) = %d", size_column, nrec_size);

	if (cvarr_size.ctype != DB_C_TYPE_INT &&
	    cvarr_size.ctype != DB_C_TYPE_DOUBLE)
	    G_fatal_error(_("Symbol size column ('%s') is not numeric"),
			  size_column);

	if (nrec_size < 0)
	    G_fatal_error(_("Unable to select data ('%s') from table"),
			  size_column);

	G_debug(2, " %d records selected from table", nrec_size);

	for (i = 0; i < cvarr_size.n_values; i++) {
	    G_debug(4, "(size) cat = %d  %s = %.2f", cvarr_size.value[i].cat,
		    size_column,
		    (cvarr_size.ctype ==
		     DB_C_TYPE_INT ? (double)cvarr_size.value[i].val.i
		     : cvarr_size.value[i].val.d));
	}
    }

    if (rot_column) {
	if (*rot_column == '\0')
	    G_fatal_error(_("Symbol rotation column not specified"));

	db_CatValArray_init(&cvarr_rot);

	nrec_rot = db_select_CatValArray(driver, fi->table, fi->key,
					 rot_column, NULL, &cvarr_rot);

	G_debug(3, "nrec_rot (%s) = %d", rot_column, nrec_rot);

	if (cvarr_rot.ctype != DB_C_TYPE_INT &&
	    cvarr_rot.ctype != DB_C_TYPE_DOUBLE)
	    G_fatal_error(_("Symbol rotation column ('%s') is not numeric"),
			  rot_column);

	if (nrec_rot < 0)
	    G_fatal_error(_("Unable to select data ('%s') from table"),
			  rot_column);

	G_debug(2, " %d records selected from table", nrec_rot);

	for (i = 0; i < cvarr_rot.n_values; i++) {
	    G_debug(4, "(rot) cat = %d  %s = %.2f", cvarr_rot.value[i].cat,
		    rot_column,
		    (cvarr_rot.ctype ==
		     DB_C_TYPE_INT ? (double)cvarr_rot.value[i].val.i
		     : cvarr_rot.value[i].val.d));
	}
    }

    if (open_db) {
	db_close_database_shutdown_driver(driver);
    }

    if (z_style) {
	if (!Vect_is_3d(Map)) {
	    G_warning(_("Vector map is not 3D. Unable to colorize features based on z-coordinates."));
	    z_style = NULL;
	}
        else if (rgb_column) {
            G_warning(_("%s= and %s= are mutually exclusive. "
                        "%s= will be ignored."), "zcolor", "rgb_column", "zcolor");
	    z_style = NULL;
        }
	else {
	    Vect_get_map_box(Map, &box);
	    Rast_make_fp_colors(&zcolors, z_style, box.B, box.T);
	}
    }

    stat = 0;
    if (type & GV_AREA && Vect_get_num_primitives(Map, GV_CENTROID | GV_BOUNDARY) > 0)
	stat += display_area(Map, Clist, window, 
			     bcolor, fcolor, chcat,
			     id_flag, cats_colors_flag,
			     default_width, width_scale,
			     z_style ? &zcolors : NULL,
			     rgb_column ? &cvarr_rgb : NULL,
			     have_colors ? &colors : NULL,
			     &cvarr_width, nrec_width);
    
    stat += display_lines(Map, type, Clist,
			  bcolor, fcolor, chcat,
			  icon, size, sqrt_flag,
			  id_flag, cats_colors_flag,
			  default_width, width_scale,
			  z_style ? &zcolors : NULL,
			  rgb_column ? &cvarr_rgb : NULL,
			  have_colors ? &colors : NULL,
			  &cvarr_width, nrec_width,
			  &cvarr_size, nrec_size,
			  &cvarr_rot, nrec_rot);
    
    return stat;
}
Esempio n. 18
0
int scan_attr(const struct Map_info *Map, int layer, const char *column_name,
	      const char *style, const char *rules,
	      const struct FPRange *range, struct Colors *colors)
{
    int ctype, is_fp, nrec;
    double fmin, fmax;
    
    struct field_info *fi;
    struct Colors vcolors;
    dbDriver *driver;
    dbCatValArray cvarr;

    Rast_init_colors(colors);
    
    fi = Vect_get_field(Map, layer);
    if (!fi)
	G_fatal_error(_("Database connection not defined for layer %d"),
		      layer);

    driver = db_start_driver_open_database(fi->driver, fi->database);
    if (!driver)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database, fi->driver);
    db_set_error_handler_driver(driver);

    ctype = db_column_Ctype(driver, fi->table, column_name);
    if (ctype == -1)
	G_fatal_error(_("Column <%s> not found in table <%s>"),
		      column_name, fi->table);
    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
	G_fatal_error(_("Column <%s> is not numeric"), column_name);

    is_fp = ctype == DB_C_TYPE_DOUBLE;

    nrec = db_select_CatValArray(driver, fi->table, fi->key, column_name,
				 NULL, &cvarr);
    if (nrec < 1) {
	G_important_message(_("No data selected"));
	return 0;
    }
    
    /* color table for values */
    db_CatValArray_sort_by_value(&cvarr);
    if (is_fp) {
	fmin = cvarr.value[0].val.d;
	fmax = cvarr.value[cvarr.n_values-1].val.d;

	if (range) {
	    if (range->min >= fmin && range->min <= fmax)
		fmin = range->min;
	    else
		G_warning(_("Min value (%f) is out of range %f,%f"),
			  range->min, fmin, fmax);
	    
	    if (range->max <= fmax && range->max >= fmin)
		fmax = range->max;
	    else
		G_warning(_("Max value (%f) is out of range %f,%f"),
			  range->max, fmin, fmax);
	}
    }
    else {
	fmin = cvarr.value[0].val.i;
	fmax = cvarr.value[cvarr.n_values-1].val.i;
	
	if (range) {
	    if (range->min >= fmin && range->min <= fmax)
		fmin = range->min;
	    else
		G_warning(_("Min value (%d) is out of range %d,%d"),
			  (int) range->min, (int) fmin, (int) fmax);
	    
	    if (range->max <= fmax && range->max >= fmin)
		fmax = range->max;
	    else
		G_warning(_("Max value (%d) is out of range %d,%d"),
			  (int) range->max, (int) fmin, (int) fmax);
	}
    }
    if (style)
	make_colors(&vcolors, style, (DCELL) fmin, (DCELL) fmax, is_fp);
    else if (rules)
	load_colors(&vcolors, rules, (DCELL) fmin, (DCELL) fmax, is_fp);

    /* color table for categories */
    color_rules_to_cats(&cvarr, is_fp, &vcolors, colors);

    db_close_database(driver);

    return is_fp;
}
Esempio n. 19
0
int main(int argc, char *argv[])
{
    /* variables */
    DCELL *data_buf;
    CELL *clump_buf;
    CELL i, max;

    int row, col, rows, cols;
    int out_mode, use_MASK, *n, *e;
    long int *count;
    int fd_data, fd_clump;

    const char *datamap, *clumpmap, *centroidsmap;
    
    double avg, vol, total_vol, east, north, *sum;

    struct Cell_head window;

    struct Map_info *fd_centroids;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct field_info *Fi;

    char buf[DB_SQL_MAX];
    dbString sql;
    dbDriver *driver;

    struct GModule *module;
    struct {
        struct Option *input, *clump, *centroids, *output;
    } opt;
    struct {
        struct Flag *report;
    } flag;

    /* define parameters and flags */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("volume"));
    G_add_keyword(_("clumps"));
    module->label =
	_("Calculates the volume of data \"clumps\".");
    module->description = _("Optionally produces a GRASS vector points map "
                            "containing the calculated centroids of these clumps.");

    opt.input = G_define_standard_option(G_OPT_R_INPUT);
    opt.input->description =
	_("Name of input raster map representing data that will be summed within clumps");

    opt.clump = G_define_standard_option(G_OPT_R_INPUT);
    opt.clump->key = "clump";
    opt.clump->required = NO;
    opt.clump->label =
        _("Name of input clump raster map");
    opt.clump->description = _("Preferably the output of r.clump. "
                               "If no clump map is given than MASK is used.");

    opt.centroids = G_define_standard_option(G_OPT_V_OUTPUT);
    opt.centroids->key = "centroids";
    opt.centroids->required = NO;
    opt.centroids->description = _("Name for output vector points map to contain clump centroids");

    opt.output = G_define_standard_option(G_OPT_F_OUTPUT);
    opt.output->required = NO;
    opt.output->label =
	_("Name for output file to hold the report");
    opt.output->description =
	_("If no output file given report is printed to standard output");

    flag.report = G_define_flag();
    flag.report->key = 'f';
    flag.report->description = _("Generate unformatted report (items separated by colon)");

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

    /* get arguments */
    datamap = opt.input->answer;
    
    clumpmap = NULL;
    if (opt.clump->answer)
	clumpmap = opt.clump->answer;
    
    centroidsmap = NULL;
    fd_centroids = NULL;
    Points = NULL;
    Cats = NULL;
    driver = NULL;
    if (opt.centroids->answer) {
	centroidsmap = opt.centroids->answer;
        fd_centroids = G_malloc(sizeof(struct Map_info));
    }
    
    out_mode = (!flag.report->answer);

    /*
     * see if MASK or a separate "clumpmap" raster map is to be used
     * -- it must(!) be one of those two choices.
     */
    use_MASK = 0;
    if (!clumpmap) {
	clumpmap = "MASK";
	use_MASK = 1;
        if (!G_find_raster2(clumpmap, G_mapset()))
            G_fatal_error(_("No MASK found. If no clump map is given than the MASK is required. "
                            "You need to define a clump raster map or create a MASK by r.mask command."));
        G_important_message(_("No clump map given, using MASK"));
    }
    
    /* open input and clump raster maps */
    fd_data = Rast_open_old(datamap, "");
    fd_clump = Rast_open_old(clumpmap, use_MASK ? G_mapset() : "");
    
    /* initialize vector map (for centroids) if needed */
    if (centroidsmap) {
	if (Vect_open_new(fd_centroids, centroidsmap, WITHOUT_Z) < 0)
	    G_fatal_error(_("Unable to create vector map <%s>"), centroidsmap);
        
        Points = Vect_new_line_struct();
        Cats = Vect_new_cats_struct();
        
        /* initialize data structures */
        Vect_append_point(Points, 0., 0., 0.);
        Vect_cat_set(Cats, 1, 1);
    }
    
    /* initialize output file */
    if (opt.output->answer && strcmp(opt.output->answer, "-") != 0) {
	if (freopen(opt.output->answer, "w", stdout) == NULL) {
	    perror(opt.output->answer);
	    exit(EXIT_FAILURE);
	}
    }

    /* initialize data accumulation arrays */
    max = Rast_get_max_c_cat(clumpmap, use_MASK ? G_mapset() : "");

    sum = (double *)G_malloc((max + 1) * sizeof(double));
    count = (long int *)G_malloc((max + 1) * sizeof(long int));

    G_zero(sum, (max + 1) * sizeof(double));
    G_zero(count, (max + 1) * sizeof(long int));
    
    data_buf = Rast_allocate_d_buf();
    clump_buf = Rast_allocate_c_buf();
    
    /* get window size */
    G_get_window(&window);
    rows = window.rows;
    cols = window.cols;

    /* now get the data -- first pass */
    for (row = 0; row < rows; row++) {
	G_percent(row, rows, 2);
	Rast_get_d_row(fd_data, data_buf, row);
	Rast_get_c_row(fd_clump, clump_buf, row);
	for (col = 0; col < cols; col++) {
	    i = clump_buf[col];
	    if (i > max)
		G_fatal_error(_("Invalid category value %d (max=%d): row=%d col=%d"),
                              i, max, row, col);
	    if (i < 1) {
                G_debug(3, "row=%d col=%d: zero or negs ignored", row, col);
		continue;	/* ignore zeros and negs */
            }
	    if (Rast_is_d_null_value(&data_buf[col])) {
                G_debug(3, "row=%d col=%d: NULL ignored", row, col);
		continue;
            }
            
	    sum[i] += data_buf[col];
	    count[i]++;
	}
    }
    G_percent(1, 1, 1);
    
    /* free some buffer space */
    G_free(data_buf);
    G_free(clump_buf);

    /* data lists for centroids of clumps */
    e = (int *)G_malloc((max + 1) * sizeof(int));
    n = (int *)G_malloc((max + 1) * sizeof(int));

    i = centroids(fd_clump, e, n, 1, max);

    /* close raster maps */
    Rast_close(fd_data);
    Rast_close(fd_clump);
    
    /* got everything, now do output */
    if (centroidsmap) {
        G_message(_("Creating vector point map <%s>..."), centroidsmap);
        /* set comment */
	sprintf(buf, _("From '%s' on raster map <%s> using clumps from <%s>"),
                argv[0], datamap, clumpmap);
        Vect_set_comment(fd_centroids, buf);

        /* create attribute table */        
        Fi = Vect_default_field_info(fd_centroids, 1, NULL, GV_1TABLE);
        
        driver = db_start_driver_open_database(Fi->driver,
                                               Vect_subst_var(Fi->database, fd_centroids));
	if (driver == NULL) {
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Vect_subst_var(Fi->database, fd_centroids), Fi->driver);
	}
        db_set_error_handler_driver(driver);
        
	db_begin_transaction(driver);
        
        db_init_string(&sql);
	sprintf(buf, "create table %s (cat integer, volume double precision, "
                "average double precision, sum double precision, count integer)",
                Fi->table);
	db_set_string(&sql, buf);
	Vect_map_add_dblink(fd_centroids, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			    Fi->driver);

	G_debug(3, "%s", db_get_string(&sql));
	if (db_execute_immediate(driver, &sql) != DB_OK) {
	    G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql));
	}
    }

    /* print header */
    if (out_mode) {
	fprintf(stdout, _("\nVolume report on data from <%s> using clumps on <%s> raster map"),
                datamap, clumpmap);
        fprintf(stdout, "\n\n");
	fprintf(stdout,
		_("Category   Average   Data   # Cells        Centroid             Total\n"));
	fprintf(stdout,
		_("Number     in clump  Total  in clump   Easting     Northing     Volume"));
        fprintf(stdout, "\n%s\n", SEP);
    }
    total_vol = 0.0;

    /* print output, write centroids */
    for (i = 1; i <= max; i++) {
	if (count[i]) {
	    avg = sum[i] / (double)count[i];
	    vol = sum[i] * window.ew_res * window.ns_res;
	    total_vol += vol;
	    east = window.west + (e[i] + 0.5) * window.ew_res;
	    north = window.north - (n[i] + 0.5) * window.ns_res;
	    if (fd_centroids) { /* write centroids if requested */
                Points->x[0] = east;
                Points->y[0] = north;
                Cats->cat[0] = i;
                Vect_write_line(fd_centroids, GV_POINT, Points, Cats);
	
                sprintf(buf, "insert into %s values (%d, %f, %f, %f, %ld)",
                        Fi->table, i, vol, avg, sum[i], count[i]);
                db_set_string(&sql, buf);

                if (db_execute_immediate(driver, &sql) != DB_OK)
                    G_fatal_error(_("Cannot insert new row: %s"),
                                  db_get_string(&sql));
	    }
	    if (out_mode)
		fprintf(stdout,
			"%8d%10.2f%10.0f %7ld  %10.2f  %10.2f %16.2f\n", i,
			avg, sum[i], count[i], east, north, vol);
	    else
		fprintf(stdout, "%d:%.2f:%.0f:%ld:%.2f:%.2f:%.2f\n",
			i, avg, sum[i], count[i], east, north, vol);
	}
    }

    /* write centroid attributes and close the map*/
    if (fd_centroids) {
        db_commit_transaction(driver);
        Vect_close(fd_centroids);
    }
    
    /* print total value */
    if (total_vol > 0.0 && out_mode) {
        fprintf(stdout, "%s\n", SEP);
	fprintf(stdout, "%60s = %14.2f", _("Total Volume"), total_vol);
        fprintf(stdout, "\n");
    }

    exit(EXIT_SUCCESS);
} 
Esempio n. 20
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct {
        struct Option *input, *output, *zshift, *height, *elevation, *hcolumn,
            *type, *field, *cats, *where, *interp, *scale, *null;
    } opt;
    struct {
        struct Flag *trace;
    } flag;
    
    struct Map_info In, Out;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct bound_box map_box;

    struct cat_list *cat_list;
    
    struct Cell_head window;
    
    int field;
    int only_type, cat;
    int fdrast, interp_method, trace;
    double objheight, objheight_default, voffset;
    double scale, null_val;
    
    struct field_info *Fi;
    dbDriver *driver = NULL;
    
    char *comment;
    
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    G_add_keyword(_("sampling"));
    G_add_keyword(_("3D"));
    module->label =
	_("Extrudes flat vector features to 3D vector features with defined height.");
    module->description = 
        _("Optionally the height can be derived from sampling of elevation raster map.");
    
    flag.trace = G_define_flag();
    flag.trace->key = 't';
    flag.trace->description = _("Trace elevation");
    flag.trace->guisection = _("Elevation");

    opt.input = G_define_standard_option(G_OPT_V_INPUT);

    opt.field = G_define_standard_option(G_OPT_V_FIELD_ALL);
    opt.field->guisection = _("Selection");

    opt.cats = G_define_standard_option(G_OPT_V_CATS);
    opt.cats->guisection = _("Selection");
    
    opt.where = G_define_standard_option(G_OPT_DB_WHERE);
    opt.where->guisection = _("Selection");

    opt.type = G_define_standard_option(G_OPT_V_TYPE);
    opt.type->answer = "point,line,area";
    opt.type->options = "point,line,area";
    opt.type->guisection = _("Selection");

    opt.output = G_define_standard_option(G_OPT_V_OUTPUT);

    opt.zshift = G_define_option();
    opt.zshift->key = "zshift";
    opt.zshift->description = _("Shifting value for z coordinates");
    opt.zshift->type = TYPE_DOUBLE;
    opt.zshift->required = NO;
    opt.zshift->answer = "0";
    opt.zshift->guisection = _("Height");

    opt.height = G_define_option();
    opt.height->key = "height";
    opt.height->type = TYPE_DOUBLE;
    opt.height->required = NO;
    opt.height->multiple = NO;
    opt.height->description = _("Fixed height for 3D vector features");
    opt.height->guisection = _("Height");

    opt.hcolumn = G_define_standard_option(G_OPT_DB_COLUMN);
    opt.hcolumn->key = "height_column";
    opt.hcolumn->multiple = NO;
    opt.hcolumn->description = _("Name of attribute column with feature height");
    opt.hcolumn->guisection = _("Height");
 
    /* raster sampling */
    opt.elevation = G_define_standard_option(G_OPT_R_ELEV);
    opt.elevation->required = NO;
    opt.elevation->description = _("Elevation raster map for height extraction");
    opt.elevation->guisection = _("Elevation");

    opt.interp = G_define_standard_option(G_OPT_R_INTERP_TYPE);
    opt.interp->answer = "nearest";
    opt.interp->guisection = _("Elevation");

    opt.scale = G_define_option();
    opt.scale->key = "scale";
    opt.scale->type = TYPE_DOUBLE;
    opt.scale->description = _("Scale factor sampled raster values");
    opt.scale->answer = "1.0";
    opt.scale->guisection = _("Elevation");

    opt.null = G_define_option();
    opt.null->key = "null_value";
    opt.null->type = TYPE_DOUBLE;
    opt.null->description =
	_("Height for sampled raster NULL values");
    opt.null->guisection = _("Elevation");

    G_gisinit(argv[0]);

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

    if (!opt.height->answer && !opt.hcolumn->answer) {
	G_fatal_error(_("One of '%s' or '%s' parameters must be set"),
		      opt.height->key, opt.hcolumn->key);
    }

    sscanf(opt.zshift->answer, "%lf", &voffset);
    G_debug(1, "voffset = %f", voffset);
    
    if (opt.height->answer)
	sscanf(opt.height->answer, "%lf", &objheight);
    else
	objheight = 0.;
    G_debug(1, "objheight = %f", objheight);
    objheight_default = objheight;

    only_type = Vect_option_to_types(opt.type);

    /* sampling method */
    interp_method = Rast_option_to_interp_type(opt.interp);

    /* used to scale sampled raster values */
    scale = atof(opt.scale->answer);

    /* is null value defined */
    if (opt.null->answer)
	null_val = atof(opt.null->answer);

    /* trace elevation */
    trace = flag.trace->answer ? TRUE : FALSE;
    
    /* set input vector map name and mapset */
    Vect_check_input_output_name(opt.input->answer, opt.output->answer, G_FATAL_EXIT);

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    Vect_set_open_level(2); /* topology required for input */

    /* opening input vector map */
    if (Vect_open_old2(&In, opt.input->answer, "", opt.field->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), opt.input->answer);

    Vect_set_error_handler_io(&In, &Out);

    /* creating output vector map */
    if (Vect_open_new(&Out, opt.output->answer, WITH_Z) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"),
			opt.output->answer);

    field = Vect_get_field_number(&In, opt.field->answer);

    if ((opt.hcolumn->answer || opt.cats->answer || opt.where->answer) && field == -1) {
        G_warning(_("Invalid layer number (%d). "
                    "Parameter '%s', '%s' or '%s' specified, assuming layer '1'."),
                  field, opt.hcolumn->key, opt.cats->key, opt.where->key);
        field = 1;
    }

    /* set constraint for cats or where */
    cat_list = NULL;
    if (field > 0)
	cat_list = Vect_cats_set_constraint(&In, field, opt.where->answer,
                                            opt.cats->answer);
    
    
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);

    /* opening database connection, if required */
    if (opt.hcolumn->answer) {
        int ctype;
        dbColumn *column;
        
	if ((Fi = Vect_get_field(&In, field)) == NULL)
	    G_fatal_error(_("Database connection not defined for layer %d"),
			  field);

	if ((driver =
	     db_start_driver_open_database(Fi->driver, Fi->database)) == NULL)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Fi->database, Fi->driver);
        db_set_error_handler_driver(driver);
        
	if (db_get_column(driver, Fi->table, opt.hcolumn->answer, &column) != DB_OK)
	    G_fatal_error(_("Column <%s> does not exist"),
			  opt.hcolumn->answer);
	else
	    db_free_column(column);

	ctype = db_column_Ctype(driver, Fi->table, opt.hcolumn->answer);

	if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_STRING &&
	    ctype != DB_C_TYPE_DOUBLE) {
	    G_fatal_error(_("Column <%s>: invalid data type"),
			  opt.hcolumn->answer);
	}
    }

    /* do we work with elevation raster? */
    fdrast = -1;
    if (opt.elevation->answer) {
	/* raster setup */
	G_get_window(&window);

	/* open the elev raster, and check for error condition */
	fdrast = Rast_open_old(opt.elevation->answer, "");
    }

    /* if area */
    if (only_type & GV_AREA) {
        int area, nareas, centroid;
        
        nareas = Vect_get_num_areas(&In);
	G_debug(2, "n_areas = %d", nareas);
	if (nareas > 0)
	    G_message(_("Extruding areas..."));
	for (area = 1; area <= nareas; area++) {
	    G_debug(3, "area = %d", area);
	    G_percent(area, nareas, 2);
            
	    if (!Vect_area_alive(&In, area))
		continue;
            
	    centroid = Vect_get_area_centroid(&In, area);
	    if (!centroid) {
		G_warning(_("Skipping area %d without centroid"), area);
		continue;
	    }

	    Vect_read_line(&In, NULL, Cats, centroid);
	    if (field > 0 && !Vect_cats_in_constraint(Cats, field, cat_list))
		continue;
            
	    /* height attribute */
	    if (opt.hcolumn->answer) {
		cat = Vect_get_area_cat(&In, area, field);
                if (cat == -1) {
                    G_warning(_("No category defined for area %d. Using default fixed height %f."),
                              area, objheight_default);
                    objheight = objheight_default;
                }
                if (get_height(Fi, opt.hcolumn->answer,
                               driver, cat, &objheight) != 0) {
                    G_warning(_("Unable to fetch height from DB for area %d. Using default fixed height %f."),
                              area, objheight_default);
                    objheight = objheight_default;
                }
	    } /* if opt.hcolumn->answer */

	    Vect_get_area_points(&In, area, Points);

	    G_debug(3, "area: %d height: %f", area, objheight);

	    extrude(&In, &Out, Cats, Points,
		    fdrast, trace, interp_method, scale,
                    opt.null->answer ? TRUE : FALSE, null_val,
                    objheight, voffset, &window, GV_AREA,
		    centroid);
	} /* foreach area */

    }

    if (only_type > 0) {
        int line, nlines;
        int type;
        
	G_debug(1, "other than areas");
	/* loop through each line in the dataset */
        nlines = Vect_get_num_lines(&In);
	G_message(_("Extruding features..."));
	for (line = 1; line <= nlines; line++) {
	    /* progress feedback */
	    G_percent(line, nlines, 2);

	    if (!Vect_line_alive(&In, line))
		continue;

	    /* read line */
	    type = Vect_read_line(&In, Points, Cats, line);

	    if (!(type & only_type))
		continue;

	    if (field > 0 && !Vect_cats_in_constraint(Cats, field, cat_list))
		continue;

	    /* height attribute */
	    if (opt.hcolumn->answer) {
		cat = Vect_get_line_cat(&In, line, field);
                if (cat == -1) {
                    G_warning(_("No category defined for feature %d. Using default fixed height %f."),
                              line, objheight_default);
                    objheight = objheight_default;
                }
                if (get_height(Fi, opt.hcolumn->answer,
                               driver, cat, &objheight) != 0) {
                    G_warning(_("Unable to fetch height from DB for line %d. Using default fixed height %f."),
                              line, objheight_default);
                    objheight = objheight_default;
                }
	    } /* if opt.hcolumn->answer */
            
	    extrude(&In, &Out, Cats, Points,
		    fdrast, trace, interp_method, scale,
                    opt.null->answer ? TRUE : FALSE, null_val,
                    objheight, voffset, &window, type, -1);
	} /* for each line */
    }	  /* else if area */

    if (driver) {
	db_close_database(driver);
	db_shutdown_driver(driver);
    }

    G_important_message(_("Copying attribute table..."));
    if (field < 0)
        Vect_copy_tables(&In, &Out, 0);
    else 
        Vect_copy_table_by_cat_list(&In, &Out, field, field, NULL,
                                    GV_1TABLE, cat_list);
    
    Vect_build(&Out);

    /* header */
    G_asprintf(&comment, "Generated by %s from vector map <%s>",
	       G_program_name(), Vect_get_full_name(&In));
    Vect_set_comment(&Out, comment);
    G_free(comment);

    Vect_get_map_box(&Out, &map_box);

    Vect_close(&In);
    Vect_close(&Out);

    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    G_done_msg("T: %f B: %f.", map_box.T, map_box.B);
    
    exit(EXIT_SUCCESS);
}
Esempio n. 21
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *out_opt, *in_opt;
    struct Flag *z_flag, *circle_flag, *l_flag, *int_flag;
    char buf[2000];

    /* DWG */
    char path[2000];
    short initerror, entset, retval;
    AD_OBJHANDLE pspace, mspace;
    PAD_ENT_HDR adenhd;
    PAD_ENT aden;
    AD_VMADDR entlist;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("import"));
    module->description = _("Converts DWG/DXF to GRASS vector map");

    in_opt = G_define_standard_option(G_OPT_F_INPUT);
    in_opt->description = _("Name of DWG or DXF file");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    out_opt->required = YES;

    layers_opt = G_define_option();
    layers_opt->key = "layers";
    layers_opt->type = TYPE_STRING;
    layers_opt->required = NO;
    layers_opt->multiple = YES;
    layers_opt->description = _("List of layers to import");

    invert_flag = G_define_flag();
    invert_flag->key = 'i';
    invert_flag->description =
	_("Invert selection by layers (don't import layers in list)");

    z_flag = G_define_flag();
    z_flag->key = 'z';
    z_flag->description = _("Create 3D vector map");

    circle_flag = G_define_flag();
    circle_flag->key = 'c';
    circle_flag->description = _("Write circles as points (centre)");

    l_flag = G_define_flag();
    l_flag->key = 'l';
    l_flag->description = _("List available layers and exit");

    int_flag = G_define_flag();
    int_flag->key = 'n';
    int_flag->description = _("Use numeric type for attribute \"layer\"");

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

    db_init_string(&sql);
    db_init_string(&str);
    adenhd = (PAD_ENT_HDR) G_malloc(sizeof(AD_ENT_HDR));
    aden = (PAD_ENT) G_malloc(sizeof(AD_ENT));
    Layer = (PAD_LAY) G_malloc(sizeof(AD_LAY));
    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    Block = NULL;

    atrans = 20;		/* nested, recursive levels */
    Trans = (TRANS *) G_malloc(atrans * sizeof(TRANS));

    /* Init OpenDWG */
    sprintf(path, "%s/etc/adinit.dat", G_gisbase());
    if (!adInitAd2(path, &initerror)) {
	sprintf(buf, _("Unable to initialize OpenDWG Toolkit, error: %d: %s."),
		initerror, adErrorStr(initerror));
	if (initerror == AD_UNABLE_TO_OPEN_INIT_FILE)
	    sprintf(buf, _("%s Cannot open %s"), buf, path);
	G_fatal_error(buf);
    }
    adSetupDwgRead();
    adSetupDxfRead();

    /* Open input file */
    if ((dwghandle = adLoadFile(in_opt->answer, AD_PRELOAD_ALL, 1)) == NULL) {
	G_fatal_error(_("Unable to open input file <%s>. Error %d: %s"),
		      in_opt->answer, adError(),
		      adErrorStr(adError()));
    }

    if (l_flag->answer) {	/* List layers */
	PAD_TB adtb;
	AD_DWGHDR adhd;
	int i;
	char on, frozen, vpfrozen, locked;

	adtb = (PAD_TB) G_malloc(sizeof(AD_TB));

	G_debug(2, "%d layers", (int)adNumLayers(dwghandle));
	adReadHeaderBlock(dwghandle, &adhd);
	adStartLayerGet(dwghandle);

	fprintf(stdout, "%d layers:\n", (int)adNumLayers(dwghandle));
	for (i = 0; i < (int)adNumLayers(dwghandle); i++) {
	    adGetLayer(dwghandle, &(adtb->lay));
	    if (!adtb->lay.purgedflag) {
		fprintf(stdout, "%s COLOR %d, ", adtb->lay.name,
			adtb->lay.color);
	    }
	    adGetLayerState(dwghandle, adtb->lay.objhandle, &on, &frozen,
			    &vpfrozen, &locked);
	    if (on)
		fprintf(stdout, "ON, ");
	    else
		fprintf(stdout, "OFF, ");
	    if (frozen)
		fprintf(stdout, "FROZEN, ");
	    else
		fprintf(stdout, "THAWED, ");
	    if (vpfrozen)
		fprintf(stdout, "VPFROZEN, ");
	    else
		fprintf(stdout, "VPTHAWED, ");
	    if (locked)
		fprintf(stdout, "LOCKED\n");
	    else
		fprintf(stdout, "UNLOCKED\n");
	}
	adCloseFile(dwghandle);
	adCloseAd2();
	exit(EXIT_SUCCESS);
    }


    /* open output vector */
    if (Vect_open_new(&Map, out_opt->answer, z_flag->answer) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);

    Vect_hist_command(&Map);

    /* Add DB link */
    Fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);
    Vect_map_add_dblink(&Map, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			Fi->driver);

    driver =
	db_start_driver_open_database(Fi->driver,
				      Vect_subst_var(Fi->database, &Map));
    if (driver == NULL) {
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Vect_subst_var(Fi->database, &Map), Fi->driver);
    }
    db_set_error_handler_driver(driver);

    db_begin_transaction(driver);

    /* Create table */
    if (int_flag->answer) {	/* List layers */
	sprintf(buf,
		"create table %s ( cat integer, entity_name varchar(20), color int, weight int, "
		"layer real, block varchar(100), txt varchar(100) )",
		Fi->table);

    }
    else {
	sprintf(buf,
		"create table %s ( cat integer, entity_name varchar(20), color int, weight int, "
		"layer varchar(100), block varchar(100), txt varchar(100) )",
		Fi->table);
    }
    db_set_string(&sql, buf);
    G_debug(3, db_get_string(&sql));

    if (db_execute_immediate(driver, &sql) != DB_OK) {
	db_close_database(driver);
	db_shutdown_driver(driver);
	G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql));
    }

    if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK)
	G_warning(_("Unable to create index for table <%s>, key <%s>"),
		  Fi->table, GV_KEY_COLUMN);

    if (db_grant_on_table
	(driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
	G_fatal_error(_("Unable to grant privileges on table <%s>"),
		      Fi->table);

    cat = 1;
    n_elements = n_skipped = 0;
    /* Write each entity. Some entities may be composed by other entities (like INSERT or BLOCK) */
    /* Set transformation for first (index 0) level */
    Trans[0].dx = Trans[0].dy = Trans[0].dz = 0;
    Trans[0].xscale = Trans[0].yscale = Trans[0].zscale = 1;
    Trans[0].rotang = 0;
    if (adGetBlockHandle(dwghandle, pspace, AD_PAPERSPACE_HANDLE)) {
	entlist = adEntityList(dwghandle, pspace);
	adStartEntityGet(entlist);
	for (entset = 0; entset < 2; entset++) {
	    do {
		if (!(retval = adGetEntity(entlist, adenhd, aden)))
		    continue;
		wrentity(adenhd, aden, 0, entlist, circle_flag->answer);
	    } while (retval == 1);
	    if (entset == 0) {
		if (adGetBlockHandle(dwghandle, mspace, AD_MODELSPACE_HANDLE)) {
		    entlist = adEntityList(dwghandle, mspace);
		    adStartEntityGet(entlist);
		}
	    }
	}
    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

    adCloseFile(dwghandle);
    adCloseAd2();

    Vect_build(&Map, stderr);
    Vect_close(&Map);
    
    if (n_skipped > 0)
	G_message(_("%d elements skipped (layer name was not in list)"),
		  n_skipped);
    
    G_done_msg(_("%d elements processed"), n_elements);

    exit(EXIT_SUCCESS);
}
Esempio n. 22
0
int main(int argc, char *argv[])
{
    struct Map_info In, Out;
    static struct line_pnts *Points, *PPoints;
    struct line_cats *Cats, *TCats;
    struct ilist *slist;
    struct GModule *module;	/* GRASS module for parsing arguments */
    struct Option *map_in, *map_out;
    struct Option *catf_opt, *fieldf_opt, *wheref_opt;
    struct Option *catt_opt, *fieldt_opt, *wheret_opt, *typet_opt;
    struct Option *afield_opt, *nfield_opt, *abcol, *afcol, *ncol, *atype_opt;
    struct Flag *geo_f, *segments_f;
    int with_z, geo, segments;
    int atype, ttype;
    struct varray *varrayf, *varrayt;
    int flayer, tlayer;
    int afield, nfield;
    dglGraph_s *graph;
    struct ilist *nodest;
    int i, j, nnodes, nlines;
    int *dst, *nodes_to_features;
    int from_nr;			/* 'from' features not reachable */
    dglInt32_t **nxt;
    struct line_cats **on_path;
    char *segdir;
    char buf[2000];

    /* Attribute table */
    dbString sql;
    dbDriver *driver;
    struct field_info *Fi;

    /* initialize GIS environment */
    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */

    /* initialize module */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("network"));
    G_add_keyword(_("shortest path"));
    module->label = _("Computes shortest distance via the network between "
		      "the given sets of features.");
    module->description =
	_("Finds the shortest paths from each 'from' point to the nearest 'to' feature "
	 "and various information about this relation are uploaded to the attribute table.");

    /* Define the different options as defined in gis.h */
    map_in = G_define_standard_option(G_OPT_V_INPUT);
    map_out = G_define_standard_option(G_OPT_V_OUTPUT);

    afield_opt = G_define_standard_option(G_OPT_V_FIELD);
    afield_opt->key = "arc_layer";
    afield_opt->answer = "1";
    afield_opt->label = _("Arc layer");
    afield_opt->guisection = _("Cost");

    atype_opt = G_define_standard_option(G_OPT_V_TYPE);
    atype_opt->key = "arc_type";
    atype_opt->options = "line,boundary";
    atype_opt->answer = "line,boundary";
    atype_opt->label = _("Arc type");
    atype_opt->guisection = _("Cost");

    nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    nfield_opt->key = "node_layer";
    nfield_opt->answer = "2";
    nfield_opt->label = _("Node layer");
    nfield_opt->guisection = _("Cost");

    fieldf_opt = G_define_standard_option(G_OPT_V_FIELD);
    fieldf_opt->key = "from_layer";
    fieldf_opt->label = _("From layer number or name");
    fieldf_opt->guisection = _("From");

    catf_opt = G_define_standard_option(G_OPT_V_CATS);
    catf_opt->key = "from_cats";
    catf_opt->label = _("From category values");
    catf_opt->guisection = _("From");

    wheref_opt = G_define_standard_option(G_OPT_DB_WHERE);
    wheref_opt->key = "from_where";
    wheref_opt->label =
	_("From WHERE conditions of SQL statement without 'where' keyword");
    wheref_opt->guisection = _("From");

    fieldt_opt = G_define_standard_option(G_OPT_V_FIELD);
    fieldt_opt->key = "to_layer";
    fieldt_opt->description = _("To layer number or name");
    fieldt_opt->guisection = _("To");

    typet_opt = G_define_standard_option(G_OPT_V_TYPE);
    typet_opt->key = "to_type";
    typet_opt->options = "point,line,boundary";
    typet_opt->answer = "point";
    typet_opt->description = _("To feature type");
    typet_opt->guisection = _("To");

    catt_opt = G_define_standard_option(G_OPT_V_CATS);
    catt_opt->key = "to_cats";
    catt_opt->label = _("To category values");
    catt_opt->guisection = _("To");

    wheret_opt = G_define_standard_option(G_OPT_DB_WHERE);
    wheret_opt->key = "to_where";
    wheret_opt->label =
	_("To WHERE conditions of SQL statement without 'where' keyword");
    wheret_opt->guisection = _("To");

    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
    afcol->key = "arc_column";
    afcol->required = NO;
    afcol->description =
	_("Arc forward/both direction(s) cost column (number)");
    afcol->guisection = _("Cost");

    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
    abcol->key = "arc_backward_column";
    abcol->required = NO;
    abcol->description = _("Arc backward direction cost column (number)");
    abcol->guisection = _("Cost");

    ncol = G_define_standard_option(G_OPT_DB_COLUMN);
    ncol->key = "node_column";
    ncol->required = NO;
    ncol->description = _("Node cost column (number)");
    ncol->guisection = _("Cost");

    geo_f = G_define_flag();
    geo_f->key = 'g';
    geo_f->description =
	_("Use geodesic calculation for longitude-latitude locations");

    segments_f = G_define_flag();
#if 0
    /* use this to sync with v.net.path */
    segments_f->key = 's';
    segments_f->description = _("Write output as original input segments, "
				"not each path as one line.");
#else
    segments_f->key = 'l';
    segments_f->description = _("Write each output path as one line, "
				"not as original input segments.");
#endif

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

    atype = Vect_option_to_types(atype_opt);
    ttype = Vect_option_to_types(typet_opt);

    Points = Vect_new_line_struct();
    PPoints = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    TCats = Vect_new_cats_struct();
    slist = G_new_ilist();

    Vect_check_input_output_name(map_in->answer, map_out->answer,
				 G_FATAL_EXIT);

    Vect_set_open_level(2);

    if (1 > Vect_open_old(&In, map_in->answer, ""))
	G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer);

    with_z = Vect_is_3d(&In);

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


    if (geo_f->answer) {
	geo = 1;
	if (G_projection() != PROJECTION_LL)
	    G_warning(_("The current projection is not longitude-latitude"));
    }
    else
	geo = 0;

#if 0
    /* use this to sync with v.net.path */
    segments = segments_f->answer;
#else
    segments = !segments_f->answer;
#endif

    nnodes = Vect_get_num_nodes(&In);
    nlines = Vect_get_num_lines(&In);

    dst = (int *)G_calloc(nnodes + 1, sizeof(int));
    nxt = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
    nodes_to_features = (int *)G_calloc(nnodes + 1, sizeof(int));
    on_path =
	(struct line_cats **)G_calloc(nlines + 1, sizeof(struct line_cats *));
    segdir = (char *)G_calloc(nlines + 1, sizeof(char));

    if (!dst || !nxt || !nodes_to_features || !on_path || !segdir)
	G_fatal_error(_("Out of memory"));

    for (i = 1; i <= nlines; i++) {
	on_path[i] = Vect_new_cats_struct();
	segdir[i] = 0;
    }

    /*initialise varrays and nodes list appropriatelly */
    afield = Vect_get_field_number(&In, afield_opt->answer);
    nfield = Vect_get_field_number(&In, nfield_opt->answer);

    flayer = atoi(fieldf_opt->answer);
    tlayer = atoi(fieldt_opt->answer);

    if (NetA_initialise_varray(&In, flayer, GV_POINT, wheref_opt->answer,
			   catf_opt->answer, &varrayf) <= 0) {
	G_fatal_error(_("No 'from' features selected. "
			"Please check options '%s', '%s', '%s'."),
			fieldf_opt->key, wheref_opt->key, catf_opt->key);
    }

    if (NetA_initialise_varray(&In, tlayer, ttype, wheret_opt->answer,
			   catt_opt->answer, &varrayt) <= 0) {
	G_fatal_error(_("No 'to' features selected. "
			"Please check options '%s', '%s', '%s'."),
			fieldt_opt->key, wheret_opt->key, catt_opt->key);
    }

    nodest = Vect_new_list();
    NetA_varray_to_nodes(&In, varrayt, nodest, nodes_to_features);
    
    if (nodest->n_values == 0)
	G_fatal_error(_("No 'to' features"));
    
    if (0 != Vect_net_build_graph(&In, atype, afield, nfield, afcol->answer, abcol->answer,
                                   ncol->answer, geo, 2))
        G_fatal_error(_("Unable to build graph for vector map <%s>"), Vect_get_full_name(&In));

    graph = Vect_net_get_graph(&In);

    G_message(_("Distances to 'to' features ..."));

    NetA_distance_to_points(graph, nodest, dst, nxt);

    /* Create table */
    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
    Vect_map_add_dblink(&Out, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			Fi->driver);
    db_init_string(&sql);
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);
    db_set_error_handler_driver(driver);

    sprintf(buf,
	    "create table %s ( cat integer, tcat integer, dist double precision)",
	    Fi->table);

    db_set_string(&sql, buf);
    G_debug(2, "%s", db_get_string(&sql));

    if (db_execute_immediate(driver, &sql) != DB_OK) {
	G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql));
    }

    if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK)
	G_warning(_("Cannot create index"));

    if (db_grant_on_table
	(driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
	G_fatal_error(_("Cannot grant privileges on table <%s>"), Fi->table);

    db_begin_transaction(driver);

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

    G_message(_("Tracing paths from 'from' features ..."));
    from_nr = 0;
    for (i = 1; i <= nlines; i++) {
	if (varrayf->c[i]) {
	    int type = Vect_read_line(&In, Points, Cats, i);
	    int node, tcat, cat;
	    double cost;
	    dglInt32_t *vertex, vertex_id;

	    if (!Vect_cat_get(Cats, flayer, &cat))
		continue;
		
	    if (type & GV_POINTS) {
		node = Vect_find_node(&In, Points->x[0], Points->y[0], Points->z[0], 0, 0);
	    }
	    else {
		Vect_get_line_nodes(&In, i, &node, NULL);
	    }
	    if (node < 1)
		continue;
	    if (dst[node] < 0) {
		/* unreachable */
		from_nr++;
 		continue;
	    }
	    cost = dst[node] / (double)In.dgraph.cost_multip;
	    vertex = dglGetNode(graph, node);
	    vertex_id = node;
	    slist->n_values = 0;
	    while (nxt[vertex_id] != NULL) {
		int edge_id;

		edge_id = (int) dglEdgeGet_Id(graph, nxt[vertex_id]);
		if (segments) {
		    Vect_cat_set(on_path[abs(edge_id)], 1, cat);
		    if (edge_id < 0) {
			segdir[abs(edge_id)] = 1;
		    }
		}
		else
		    G_ilist_add(slist, edge_id);

		vertex = dglEdgeGet_Tail(graph, nxt[vertex_id]);
		vertex_id = dglNodeGet_Id(graph, vertex);
	    }
	    G_debug(3, "read line %d, vertex id %d", nodes_to_features[vertex_id], (int)vertex_id);
	    Vect_read_line(&In, NULL, TCats, nodes_to_features[vertex_id]);
	    if (!Vect_cat_get(TCats, tlayer, &tcat))
		continue;

	    Vect_write_line(&Out, type, Points, Cats);
	    sprintf(buf, "insert into %s values (%d, %d, %f)", Fi->table, cat,
		    tcat, cost);
	    db_set_string(&sql, buf);
	    G_debug(3, "%s", db_get_string(&sql));
	    if (db_execute_immediate(driver, &sql) != DB_OK) {
		G_fatal_error(_("Cannot insert new record: %s"),
			      db_get_string(&sql));
	    };

	    if (!segments) {
		Vect_reset_line(PPoints);
		for (j = 0; j < slist->n_values; j++) {
		    Vect_read_line(&In, Points, NULL, abs(slist->value[j]));
		    if (slist->value[j] > 0)
			Vect_append_points(PPoints, Points,
					   GV_FORWARD);
		    else
			Vect_append_points(PPoints, Points,
					   GV_BACKWARD);
		    PPoints->n_points--;
		}
		PPoints->n_points++;
		Vect_reset_cats(Cats);
		Vect_cat_set(Cats, 1, cat);
		Vect_write_line(&Out, GV_LINE, PPoints, Cats);
	    }

	}
    }

    if (segments) {
	for (i = 1; i <= nlines; i++) {
	    if (on_path[i]->n_cats > 0) {
		int type; 
		
		if (segdir[i]) {
		    type = Vect_read_line(&In, PPoints, NULL, i);
		    Vect_reset_line(Points);
		    Vect_append_points(Points, PPoints, GV_BACKWARD);
		}
		else
		    type = Vect_read_line(&In, Points, NULL, i);

		Vect_write_line(&Out, type, Points, on_path[i]);
	    }
	}
    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

    Vect_build(&Out);

    Vect_close(&In);
    Vect_close(&Out);

    for (i = 1; i <= nlines; i++)
	Vect_destroy_cats_struct(on_path[i]);
    G_free(on_path);
    G_free(nodes_to_features);
    G_free(dst);
    G_free(nxt);
    G_free(segdir);

    if (from_nr)
	G_warning(n_("%d 'from' feature was not reachable",
                     "%d 'from' features were not reachable",
                     from_nr), from_nr);

    exit(EXIT_SUCCESS);
}
Esempio n. 23
0
/*----------------------------------------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* Declarations */
    int dim_vect, nparameters, BW, npoints;
    int nsply, nsplx, nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row;
    int subregion = 0, nsubregions = 0;
    const char *dvr, *db, *mapset;
    char table_name[GNAME_MAX];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
    double lambda, mean, stepN, stepE, HighThresh,
	LowThresh;
    double N_extension, E_extension, edgeE, edgeN;

    int i, nterrain, count_terrain;

    int last_row, last_column, flag_auxiliar = FALSE;

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

    struct Map_info In, Out, Terrain;
    struct Option *in_opt, *out_opt, *out_terrain_opt, *stepE_opt,
	*stepN_opt, *lambda_f_opt, *Thresh_A_opt, *Thresh_B_opt;
    struct Flag *spline_step_flag;
    struct GModule *module;

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

    struct Point *observ;
    struct lidar_cat *lcat;

    dbDriver *driver;

/*----------------------------------------------------------------------------------------------------------*/
    /* Options' declaration */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("LIDAR"));
    module->description =
	_("Corrects the v.lidar.growing output. It is the last of the three algorithms for LIDAR filtering.");

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

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_opt->description =
	_("Input observation vector map name (v.lidar.growing output)");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    out_opt->description = _("Output classified vector map name");

    out_terrain_opt = G_define_option();
    out_terrain_opt->key = "terrain";
    out_terrain_opt->type = TYPE_STRING;
    out_terrain_opt->key_desc = "name";
    out_terrain_opt->required = YES;
    out_terrain_opt->gisprompt = "new,vector,vector";
    out_terrain_opt->description =
	_("Only 'terrain' points output vector map");

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

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

    lambda_f_opt = G_define_option();
    lambda_f_opt->key = "lambda_c";
    lambda_f_opt->type = TYPE_DOUBLE;
    lambda_f_opt->required = NO;
    lambda_f_opt->description =
	_("Regularization weight in reclassification evaluation");
    lambda_f_opt->answer = "1";

    Thresh_A_opt = G_define_option();
    Thresh_A_opt->key = "tch";
    Thresh_A_opt->type = TYPE_DOUBLE;
    Thresh_A_opt->required = NO;
    Thresh_A_opt->description =
	_("High threshold for object to terrain reclassification");
    Thresh_A_opt->answer = "2";

    Thresh_B_opt = G_define_option();
    Thresh_B_opt->key = "tcl";
    Thresh_B_opt->type = TYPE_DOUBLE;
    Thresh_B_opt->required = NO;
    Thresh_B_opt->description =
	_("Low threshold for terrain to object reclassification");
    Thresh_B_opt->answer = "1";

    /* Parsing */
    G_gisinit(argv[0]);

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

    stepN = atof(stepN_opt->answer);
    stepE = atof(stepE_opt->answer);
    lambda = atof(lambda_f_opt->answer);
    HighThresh = atof(Thresh_A_opt->answer);
    LowThresh = atof(Thresh_B_opt->answer);

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

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

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

    /* Something went wrong in a previous v.lidar.correction execution */
    if (db_table_exists(dvr, db, table_name)) {
	/* Start driver and open db */
	driver = db_start_driver_open_database(dvr, db);
	if (driver == NULL)
	    G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
			  dvr);
        db_set_error_handler_driver(driver);
        
	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_fatal_error(_("Old auxiliar table could not be dropped"));
	db_close_database_shutdown_driver(driver);
    }

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

    /* Open input vector */
    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL)
	G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);

    Vect_set_open_level(1);	/* without topology */
    if (1 > Vect_open_old(&In, in_opt->answer, mapset))
	G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);

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

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

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

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

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

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

    /* Create auxiliar table */
    if ((flag_auxiliar =
	 P_Create_Aux2_Table(driver, table_name)) == FALSE) {
	Vect_close(&In);
	Vect_close(&Out);
	Vect_close(&Terrain);
	exit(EXIT_FAILURE);
    }

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

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

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

    /* Fixing parameters of the elaboration region */
    P_zero_dim(&dims);

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

    G_verbose_message(n_("adjusted EW spline %d",
                         "adjusted EW splines %d",
                         nsplx_adj), nsplx_adj);
    G_verbose_message(n_("adjusted NS spline %d",
                         "adjusted NS splines %d",
                         nsply_adj), nsply_adj);

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

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

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

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

    nsubregions = nsubregion_row * nsubregion_col;

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

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

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

	if (elaboration_reg.north > original_reg.north) {	/* First row */
	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  FIRST_ROW);
	}

	if (elaboration_reg.south <= original_reg.south) {	/* Last row */
	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  LAST_ROW);
	    last_row = TRUE;
	}

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

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

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

	    subregion++;
	    if (nsubregions > 1)
		G_message(_("subregion %d of %d"), subregion, nsubregions);

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

	    if (elaboration_reg.west < original_reg.west) {	/* First column */
		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, FIRST_COLUMN);
	    }

	    if (elaboration_reg.east >= original_reg.east) {	/* Last column */
		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, LAST_COLUMN);
		last_column = TRUE;
	    }

	    nsplx =
		ceil((elaboration_reg.east - elaboration_reg.west) / stepE) +
		0.5;
	    /*
	    if (nsplx > NSPLX_MAX) {
		nsplx = NSPLX_MAX;
	    }
	    */
	    G_debug(1, _("nsplx = %d"), nsplx);

	    dim_vect = nsplx * nsply;
	    G_debug(1, _("read vector region map"));
	    observ =
		P_Read_Vector_Correction(&In, &elaboration_reg, &npoints,
					 &nterrain, dim_vect, &lcat);

	    G_debug(5, _("npoints = %d, nterrain = %d"), npoints, nterrain);
	    if (npoints > 0) {	/* If there is any point falling into elaboration_reg. */
		count_terrain = 0;
		nparameters = nsplx * nsply;

		/* Mean calculation */
		G_debug(3, _("Mean calculation"));
		mean = P_Mean_Calc(&elaboration_reg, observ, npoints);

		/*Least Squares system */
		BW = P_get_BandWidth(P_BILINEAR, nsply);	/* Bilinear interpolation */
		N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
		TN = G_alloc_vector(nparameters);	/* vector */
		parVect = G_alloc_vector(nparameters);	/* Bilinear parameters vector */
		obsVect = G_alloc_matrix(nterrain + 1, 3);	/* Observation vector with terrain points */
		obsVect_all = G_alloc_matrix(npoints + 1, 3);	/* Observation vector with all points */
		Q = G_alloc_vector(nterrain + 1);	/* "a priori" var-cov matrix */
		lineVect = G_alloc_ivector(npoints + 1);

		/* Setting obsVect vector & Q matrix */
		G_debug(3, _("Only TERRAIN points"));
		for (i = 0; i < npoints; i++) {
		    if (observ[i].cat == TERRAIN_SINGLE) {
			obsVect[count_terrain][0] = observ[i].coordX;
			obsVect[count_terrain][1] = observ[i].coordY;
			obsVect[count_terrain][2] = observ[i].coordZ - mean;
			Q[count_terrain] = 1;	/* Q=I */
			count_terrain++;
		    }
		    lineVect[i] = observ[i].lineID;
		    obsVect_all[i][0] = observ[i].coordX;
		    obsVect_all[i][1] = observ[i].coordY;
		    obsVect_all[i][2] = observ[i].coordZ - mean;
		}

		G_free(observ);

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

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

		G_verbose_message( _("Correction and creation of terrain vector"));
		P_Sparse_Correction(&In, &Out, &Terrain, &elaboration_reg,
				    general_box, overlap_box, obsVect_all, lcat,
				    parVect, lineVect, stepN, stepE,
				    dims.overlap, HighThresh, LowThresh,
				    nsplx, nsply, npoints, driver, mean, table_name);

		G_free_vector(parVect);
		G_free_matrix(obsVect_all);
		G_free_ivector(lineVect);
	    }
	    else {
		G_free(observ);
		G_warning(_("No data within this subregion. "
			    "Consider changing the spline step."));
	    }
	    G_free(lcat);
	}			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

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

    db_close_database_shutdown_driver(driver);

    Vect_close(&In);
    Vect_close(&Out);
    Vect_close(&Terrain);

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*! END MAIN */
Esempio n. 24
0
File: main.c Progetto: caomw/grass
int main(int argc, char **argv)
{
    int field, type, vertex_type;
    double dmax;
    char buf[DB_SQL_MAX];

    struct {
        struct Option *input, *output, *type, *dmax, *lfield, *use;
    } opt;
    struct {
        struct Flag *table, *inter;
    } flag;
    struct GModule *module;
    struct Map_info In, Out;
    struct line_cats *LCats;
    struct line_pnts *LPoints;

    dbDriver *driver;
    struct field_info *Fi;

    dbString stmt;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    G_add_keyword("3D");
    G_add_keyword(_("node"));
    G_add_keyword(_("vertex"));
    module->description =
	_("Creates points along input lines in new vector map with 2 layers.");

    opt.input = G_define_standard_option(G_OPT_V_INPUT);

    opt.lfield = G_define_standard_option(G_OPT_V_FIELD);
    opt.lfield->key = "llayer";
    opt.lfield->answer = "1";
    opt.lfield->label = "Line layer number or name";
    opt.lfield->guisection = _("Selection");

    opt.type = G_define_standard_option(G_OPT_V3_TYPE);
    opt.type->answer = "point,line,boundary,centroid,face";
    opt.type->guisection = _("Selection");

    opt.output = G_define_standard_option(G_OPT_V_OUTPUT);

    opt.use = G_define_option();
    opt.use->key = "use";
    opt.use->type = TYPE_STRING;
    opt.use->required = NO;
    opt.use->description = _("Use line nodes or vertices only");
    opt.use->options = "node,vertex";

    opt.dmax = G_define_option();
    opt.dmax->key = "dmax";
    opt.dmax->type = TYPE_DOUBLE;
    opt.dmax->required = NO;
    opt.dmax->answer = "100";
    opt.dmax->description = _("Maximum distance between points in map units");

    flag.inter = G_define_flag();
    flag.inter->key = 'i';
    flag.inter->description = _("Interpolate points between line vertices (only for use=vertex)");
    

    flag.table = G_define_standard_flag(G_FLG_V_TABLE);

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

    LCats = Vect_new_cats_struct();
    LPoints = Vect_new_line_struct();
    db_init_string(&stmt);

    type = Vect_option_to_types(opt.type);
    dmax = atof(opt.dmax->answer);

    vertex_type = 0;
    if (opt.use->answer) {
        if (opt.use->answer[0] == 'n')
            vertex_type = GV_NODE;
        else
            vertex_type = GV_VERTEX;
    }
    
    Vect_check_input_output_name(opt.input->answer, opt.output->answer,
				 G_FATAL_EXIT);

    /* Open input lines */
    Vect_set_open_level(2);

    if (Vect_open_old2(&In, opt.input->answer, "", opt.lfield->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), opt.input->answer);

    Vect_set_error_handler_io(&In, &Out);
    
    field = Vect_get_field_number(&In, opt.lfield->answer);
    
    /* Open output segments */
    if (Vect_open_new(&Out, opt.output->answer, Vect_is_3d(&In)) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"),
			opt.output->answer);

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

    /* Table */
    Fi = NULL;
    if (!flag.table->answer) {
	struct field_info *Fin;

	/* copy input table */
	Fin = Vect_get_field(&In, field);
	if (Fin) {		/* table defined */
	    int ret;

	    Fi = Vect_default_field_info(&Out, 1, NULL, GV_MTABLE);
	    Vect_map_add_dblink(&Out, 1, NULL, Fi->table, Fin->key,
				Fi->database, Fi->driver);

	    ret = db_copy_table(Fin->driver, Fin->database, Fin->table,
				Fi->driver, Vect_subst_var(Fi->database,
							   &Out), Fi->table);

	    if (ret == DB_FAILED) {
		G_fatal_error(_("Unable to copy table <%s>"),
			      Fin->table);
	    }
	}

	Fi = Vect_default_field_info(&Out, 2, NULL, GV_MTABLE);
	Vect_map_add_dblink(&Out, 2, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			    Fi->driver);

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

	if (field == -1) 
            sprintf(buf,
                "create table %s ( cat int, along double precision )",
                Fi->table);
         else
            sprintf(buf,
		"create table %s ( cat int, lcat int, along double precision )",
		Fi->table);
	db_append_string(&stmt, buf);

	if (db_execute_immediate(driver, &stmt) != DB_OK) {
	    G_fatal_error(_("Unable to create table: '%s'"),
			  db_get_string(&stmt));
	}

	if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK)
	    G_warning(_("Unable to create index for table <%s>, key <%s>"),
		      Fi->table, GV_KEY_COLUMN);

	if (db_grant_on_table (driver, Fi->table, DB_PRIV_SELECT,
                               DB_GROUP | DB_PUBLIC) != DB_OK)
	    G_fatal_error(_("Unable to grant privileges on table <%s>"),
			  Fi->table);

	db_begin_transaction(driver);
    }

    if (type & (GV_POINTS | GV_LINES | GV_FACE)) {
        int line, nlines, nskipped;

        nskipped = 0;
	nlines = Vect_get_num_lines(&In);
	for (line = 1; line <= nlines; line++) {
	    int ltype, cat;

	    G_debug(3, "line = %d", line);
	    G_percent(line, nlines, 2);
            
	    ltype = Vect_read_line(&In, LPoints, LCats, line);
	    if (!(ltype & type))
		continue;
            if (!Vect_cat_get(LCats, field, &cat) && field != -1) {
                nskipped++;
		continue;
            }

            /* Assign CAT for layer 0 objects (i.e. boundaries) */
            if (field == -1)
                cat = -1;

	    if (LPoints->n_points <= 1) {
		write_point(&Out, LPoints->x[0], LPoints->y[0], LPoints->z[0],
			    cat, 0.0, driver, Fi);
	    }
	    else {		/* lines */
		write_line(&Out, LPoints, cat, vertex_type,
			   flag.inter->answer, dmax, driver, Fi);
	    }
	}

        if (nskipped > 0)
            G_warning(_("%d features without category in layer <%d> skipped. "
                        "Note that features without category (usually boundaries) are not "
                        "skipped when '%s=-1' is given."),
                      nskipped, field, opt.lfield->key);
    }

    if (type == GV_AREA) {
	int area, nareas, centroid, cat;

	nareas = Vect_get_num_areas(&In);
	for (area = 1; area <= nareas; area++) {
	    int i, isle, nisles;

	    G_percent(area, nareas, 2);
            
	    centroid = Vect_get_area_centroid(&In, area);
	    cat = -1;
	    if (centroid > 0) {
		Vect_read_line(&In, NULL, LCats, centroid);
		if (!Vect_cat_get(LCats, field, &cat))
		  continue;
	    }

	    Vect_get_area_points(&In, area, LPoints);

	    write_line(&Out, LPoints, cat, vertex_type, flag.inter->answer,
		       dmax, driver, Fi);

	    nisles = Vect_get_area_num_isles(&In, area);

	    for (i = 0; i < nisles; i++) {
		isle = Vect_get_area_isle(&In, area, i);
		Vect_get_isle_points(&In, isle, LPoints);

		write_line(&Out, LPoints, cat, vertex_type,
			   flag.inter->answer, dmax, driver, Fi);
	    }
	}
    }

    if (!flag.table->answer) {
	db_commit_transaction(driver);
	db_close_database_shutdown_driver(driver);
    }

    Vect_build(&Out);

    /* Free, close ... */
    Vect_close(&In);

    G_done_msg(_("%d points written to output vector map."),
               Vect_get_num_primitives(&Out, GV_POINT));

    Vect_close(&Out);
    
    exit(EXIT_SUCCESS);
}
Esempio n. 25
0
int execute_random(struct rr_state *theState)
{
    long nt;
    long nc;
    struct Cell_head window;
    int nrows, ncols, row, col;
    int infd, cinfd, outfd;
    struct Map_info Out;
    struct field_info *fi;
    dbTable *table;
    dbColumn *column;
    dbString sql;
    dbDriver *driver;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int cat;
    RASTER_MAP_TYPE type;
    int do_check;

    G_get_window(&window);

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

    /* open the data files, input raster should be set-up already */
    if ((infd = theState->fd_old) < 0)
	G_fatal_error(_("Unable to open raster map <%s>"),
		      theState->inraster);
    if (theState->docover == TRUE) {
	if ((cinfd = theState->fd_cold) < 0)
	    G_fatal_error(_("Unable to open raster map <%s>"),
			  theState->inrcover);
    }

    if (theState->outraster != NULL) {
	if (theState->docover == TRUE)
	    type = theState->cover.type;
	else
	    type = theState->buf.type;
	outfd = Rast_open_new(theState->outraster, type);
	theState->fd_new = outfd;

    }

    if (theState->outvector) {
	if (Vect_open_new(&Out, theState->outvector, theState->z_geometry) < 0)
	    G_fatal_error(_("Unable to create vector map <%s>"),
			    theState->outvector);
	Vect_hist_command(&Out);

	fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);

	driver =
	    db_start_driver_open_database(fi->driver,
					  Vect_subst_var(fi->database, &Out));
	if (!driver)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Vect_subst_var(fi->database, &Out), fi->driver);
        db_set_error_handler_driver(driver);
        
	Vect_map_add_dblink(&Out, 1, NULL, fi->table, GV_KEY_COLUMN, fi->database,
			    fi->driver);

	if (theState->docover == TRUE)
	    table = db_alloc_table(3);
	else
	    table = db_alloc_table(2);
	db_set_table_name(table, fi->table);

	column = db_get_table_column(table, 0);
	db_set_column_name(column, GV_KEY_COLUMN);
	db_set_column_sqltype(column, DB_SQL_TYPE_INTEGER);

	column = db_get_table_column(table, 1);
	db_set_column_name(column, "value");
	db_set_column_sqltype(column, DB_SQL_TYPE_DOUBLE_PRECISION);

	if (theState->docover == TRUE) {
	    column = db_get_table_column(table, 2);
	    db_set_column_name(column, "covervalue");
	    db_set_column_sqltype(column, DB_SQL_TYPE_DOUBLE_PRECISION);
	}
	if (db_create_table(driver, table) != DB_OK)
	    G_warning(_("Cannot create new table"));

	db_begin_transaction(driver);

	Points = Vect_new_line_struct();
	Cats = Vect_new_cats_struct();
	db_init_string(&sql);
    }

    if (theState->outvector && theState->outraster)
	G_message(_("Writing raster map <%s> and vector map <%s> ..."),
		  theState->outraster, theState->outvector);
    else if (theState->outraster)
	G_message(_("Writing raster map <%s> ..."), theState->outraster);
    else if (theState->outvector)
	G_message(_("Writing vector map <%s> ..."), theState->outvector);

    G_percent(0, theState->nRand, 2);

    init_rand();
    nc = (theState->use_nulls) ? theState->nCells :
	theState->nCells - theState->nNulls;
    nt = theState->nRand;	/* Number of points to generate */
    cat = 1;

    /* Execute for loop for every row if nt>1 */
    for (row = 0; row < nrows && nt; row++) {
	Rast_get_row(infd, theState->buf.data.v, row, theState->buf.type);
	if (theState->docover == TRUE) {
	    Rast_get_row(cinfd, theState->cover.data.v, row,
			 theState->cover.type);
	}

	for (col = 0; col < ncols && nt; col++) {
	    do_check = 0;

	    if (theState->use_nulls || !is_null_value(theState->buf, col))
		do_check = 1;
	    if (do_check && theState->docover == TRUE) {	/* skip no data cover points */
		if (!theState->use_nulls &&
		    is_null_value(theState->cover, col))
		    do_check = 0;
	    }

	    if (do_check && make_rand() % nc < nt) {
		nt--;
		if (is_null_value(theState->buf, col))
		    cpvalue(&theState->nulls, 0, &theState->buf, col);
		if (theState->docover == TRUE) {
		    if (is_null_value(theState->cover, col))
			cpvalue(&theState->cnulls, 0, &theState->cover, col);
		}

		if (theState->outvector) {
		    double x, y, val, coverval;
		    char buf[500];

		    Vect_reset_line(Points);
		    Vect_reset_cats(Cats);

		    x = window.west + (col + .5) * window.ew_res;
		    y = window.north - (row + .5) * window.ns_res;

		    val = cell_as_dbl(&theState->buf, col);
		    if (theState->docover == 1)
			coverval = cell_as_dbl(&theState->cover, col);

		    if (theState->z_geometry)
			Vect_append_point(Points, x, y, val);
		    else
			Vect_append_point(Points, x, y, 0.0);
		    Vect_cat_set(Cats, 1, cat);

		    Vect_write_line(&Out, GV_POINT, Points, Cats);

		    if (theState->docover == 1)
			if (is_null_value(theState->cover, col))
			    sprintf(buf,
				    "insert into %s values ( %d, %f, NULL )",
				    fi->table, cat, val);
			else
			    sprintf(buf,
				    "insert into %s values ( %d, %f, %f )",
				    fi->table, cat, val, coverval);
		    else
			sprintf(buf, "insert into %s values ( %d, %f )",
				fi->table, cat, val);
		    db_set_string(&sql, buf);

		    if (db_execute_immediate(driver, &sql) != DB_OK)
			G_fatal_error(_("Cannot insert new record: %s"),
				      db_get_string(&sql));

		    cat++;
		}
		G_percent((theState->nRand - nt), theState->nRand, 2);
	    }
	    else {
		set_to_null(&theState->buf, col);
		if (theState->docover == 1)
		    set_to_null(&theState->cover, col);
	    }

	    if (do_check)
		nc--;
	}

	while (col < ncols) {
	    set_to_null(&theState->buf, col);
	    if (theState->docover == 1)
		set_to_null(&theState->cover, col);
	    col++;
	}

	if (theState->outraster) {
	    if (theState->docover == 1)
		Rast_put_row(outfd, theState->cover.data.v,
				 theState->cover.type);
	    else
		Rast_put_row(outfd, theState->buf.data.v,
				 theState->buf.type);
	}
    }

    /* Catch any remaining rows in the window */
    if (theState->outraster && row < nrows) {
	for (col = 0; col < ncols; col++) {
	    if (theState->docover == 1)
		set_to_null(&theState->cover, col);
	    else
		set_to_null(&theState->buf, col);
	}
	for (; row < nrows; row++) {
	    if (theState->docover == 1)
		Rast_put_row(outfd, theState->cover.data.v,
				 theState->cover.type);
	    else
		Rast_put_row(outfd, theState->buf.data.v,
				 theState->buf.type);
	}
    }

    if (nt > 0)
	G_warning(_("Only [%ld] random points created"),
		  theState->nRand - nt);

    /* close files */
    Rast_close(infd);
    if (theState->docover == TRUE)
	Rast_close(cinfd);
    if (theState->outvector) {
	db_commit_transaction(driver);
	if (db_create_index2(driver, fi->table, GV_KEY_COLUMN) != DB_OK)
	    G_warning(_("Unable to create index"));
	if (db_grant_on_table
	    (driver, fi->table, DB_PRIV_SELECT,
	     DB_GROUP | DB_PUBLIC) != DB_OK) {
	    G_fatal_error(_("Unable to grant privileges on table <%s>"),
			  fi->table);
	}
	db_close_database_shutdown_driver(driver);
	if (theState->notopol != 1)
	    Vect_build(&Out);
	Vect_close(&Out);
    }
    if (theState->outraster)
	Rast_close(outfd);

    return 0;
}				/* execute_random() */
Esempio n. 26
0
File: main.c Progetto: caomw/grass
int main(int argc, char *argv[])
{

    /* loop */
    int i, j;

    /* store filename and path  */
    char *dig_file;
    
    char buf[2000];

    /* Other local variables */
    int attCount, nbreaks;

    struct grid_description grid_info;
    struct Cell_head window;
    struct Map_info Map;
    struct Option *vectname, *grid, *coord, *box, *angle, *position_opt, *breaks;
    struct GModule *module;
    struct Flag *points_fl, *line_fl;
    int points_p, line_p, output_type;
    char *desc;

    struct line_pnts *Points;
    struct line_cats *Cats;

    /* Attributes */
    struct field_info *Fi;
    dbDriver *Driver;
    dbString sql;

    G_gisinit(argv[0]);

    /* Set description */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    module->description = _("Creates a vector map of a user-defined grid.");

    vectname = G_define_standard_option(G_OPT_V_OUTPUT);
    vectname->key = "map";

    grid = G_define_option();
    grid->key = "grid";
    grid->key_desc = _("rows,columns");
    grid->type = TYPE_INTEGER;
    grid->required = YES;
    grid->multiple = NO;
    grid->description = _("Number of rows and columns in grid");

    position_opt = G_define_option();
    position_opt->key = "position";
    position_opt->type = TYPE_STRING;
    position_opt->required = NO;
    position_opt->multiple = NO;
    position_opt->options = "region,coor";
    position_opt->answer = "region";
    position_opt->description = _("Where to place the grid");
    desc = NULL;
    G_asprintf(&desc,
            "region;%s;coor;%s",
            _("current region"),
            _("use 'coor' and 'box' options"));
    position_opt->descriptions = desc;

    coord = G_define_option();
    coord->key = "coor";
    coord->key_desc = "x,y";
    coord->type = TYPE_DOUBLE;
    coord->required = NO;
    coord->multiple = NO;
    coord->description =
	_("Lower left easting and northing coordinates of map");

    box = G_define_option();
    box->key = "box";
    box->key_desc = _("width,height");
    box->type = TYPE_DOUBLE;
    box->required = NO;
    box->multiple = NO;
    box->description = _("Width and height of boxes in grid");

    angle = G_define_option();
    angle->key = "angle";
    angle->type = TYPE_DOUBLE;
    angle->required = NO;
    angle->description =
	_("Angle of rotation (in degrees counter-clockwise)");
    angle->answer = "0";

    breaks = G_define_option();
    breaks->key = "breaks";
    breaks->type = TYPE_INTEGER;
    breaks->required = NO;
    breaks->description =
	_("Number of vertex points per grid cell");
    breaks->options = "0-60";
    breaks->answer = "3";

    points_fl = G_define_flag();
    points_fl->key = 'p';
    points_fl->description =
	_("Create grid of points instead of areas and centroids");

    line_fl = G_define_flag();
    line_fl->key = 'l';
    line_fl->description =
	_("Create grid as lines, instead of areas");

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

    line_p = line_fl->answer;
    if (line_p) {
	output_type = GV_LINE;
    } else {
	output_type = GV_BOUNDARY;
    }

    points_p = points_fl->answer;

    /* get the current window  */
    G_get_window(&window);

    /*
     * information we need to collect from user: origin point x and y (lower
     * left), shift in x, shift in y,  number of rows, number of cols
     */
    dig_file = G_store(vectname->answer);

    /* Number of row and cols */
    grid_info.num_rows = atoi(grid->answers[0]);
    grid_info.num_cols = atoi(grid->answers[1]);

    grid_info.angle = M_PI / 180 * atof(angle->answer);

    nbreaks = atoi(breaks->answer);

    /* Position */
    if (position_opt->answer[0] == 'r') {	/* region */
	if (coord->answer)
	    G_fatal_error(_("'coor' and 'position=region' are exclusive options"));

	if (box->answer)
	    G_fatal_error(_("'box' and 'position=region' are exclusive options"));

	if (grid_info.angle != 0.0)
	    G_fatal_error(_("'angle' and 'position=region' are exclusive options"));

	grid_info.origin_x = window.west;
	grid_info.origin_y = window.south;

	grid_info.length = (window.east - window.west) / grid_info.num_cols;
	grid_info.width = (window.north - window.south) / grid_info.num_rows;

	G_debug(2, "x = %e y = %e l = %e w = %e", grid_info.origin_x,
		grid_info.origin_y, grid_info.length, grid_info.width);
    }
    else {
	if (!coord->answer)
	    G_fatal_error(_("'coor' option missing"));

	if (!box->answer)
	    G_fatal_error(_("'box' option missing"));

	if (!G_scan_easting
	    (coord->answers[0], &(grid_info.origin_x), window.proj))
	    G_fatal_error(_("Invalid easting"));;
	if (!G_scan_northing
	    (coord->answers[1], &(grid_info.origin_y), window.proj))
	    G_fatal_error(_("Invalid northing"));;

	if (!G_scan_resolution
	    (box->answers[0], &(grid_info.length), window.proj))
	    G_fatal_error(_("Invalid distance"));;
	if (!G_scan_resolution
	    (box->answers[1], &(grid_info.width), window.proj))
	    G_fatal_error(_("Invalid distance"));;

    }

    /*
     * vector rows are the actual number of rows of vectors to make up the
     * entire grid.   ditto for cols.
     */
    grid_info.num_vect_rows = grid_info.num_rows + 1;
    grid_info.num_vect_cols = grid_info.num_cols + 1;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    db_init_string(&sql);

    /* Open output map */
    if (0 > Vect_open_new(&Map, dig_file, 0)) {
	G_fatal_error(_("Unable to create vector map <%s>"), dig_file);
    }

    Vect_hist_command(&Map);

    /* Open database, create table */
    Fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);
    Vect_map_add_dblink(&Map, Fi->number, Fi->name, Fi->table, Fi->key,
			Fi->database, Fi->driver);

    Driver =
	db_start_driver_open_database(Fi->driver,
				      Vect_subst_var(Fi->database, &Map));
    if (Driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);
    db_set_error_handler_driver(Driver);

    if (grid_info.num_rows < 27 && grid_info.num_cols < 27) {
	sprintf(buf,
		"create table %s ( cat integer, row integer, col integer, "
		"rown varchar(1), coln varchar(1))", Fi->table);
    }
    else {
	sprintf(buf,
		"create table %s ( cat integer, row integer, col integer)",
		Fi->table);
    }
    db_set_string(&sql, buf);

    G_debug(1, "SQL: %s", db_get_string(&sql));

    if (db_execute_immediate(Driver, &sql) != DB_OK) {
	G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql));
    }

    if (db_create_index2(Driver, Fi->table, Fi->key) != DB_OK)
	G_warning(_("Unable to create index"));

    if (db_grant_on_table
	(Driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
	G_fatal_error(_("Unable to grant privileges on table <%s>"),
		      Fi->table);

    if (!points_p) {
	/* create areas */
	write_grid(&grid_info, &Map, nbreaks, output_type);
    }

    /* Create a grid of label points at the centres of the grid cells */
    G_verbose_message(_("Creating centroids..."));

    /* Write out centroids and attributes */
    /* If the output id is lines it skips to add centroids and attributes
       TODO decide what to write in the attribute table
     */
    if (!line_p) {
      db_begin_transaction(Driver);
      attCount = 0;
      for (i = 0; i < grid_info.num_rows; ++i) {
	  for (j = 0; j < grid_info.num_cols; ++j) {
	      double x, y;
	      const int point_type = points_p ? GV_POINT : GV_CENTROID;

	      x = grid_info.origin_x + (0.5 + j) * grid_info.length;
	      y = grid_info.origin_y + (0.5 + i) * grid_info.width;

	      rotate(&x, &y, grid_info.origin_x, grid_info.origin_y,
		    grid_info.angle);

	      Vect_reset_line(Points);
	      Vect_reset_cats(Cats);

	      Vect_append_point(Points, x, y, 0.0);
	      Vect_cat_set(Cats, 1, attCount + 1);
	      Vect_write_line(&Map, point_type, Points, Cats);

	      sprintf(buf, "insert into %s values ", Fi->table);
	      if (db_set_string(&sql, buf) != DB_OK)
		  G_fatal_error(_("Unable to fill attribute table"));

	      if (grid_info.num_rows < 27 && grid_info.num_cols < 27) {
		  sprintf(buf,
			  "( %d, %d, %d, '%c', '%c' )",
			  attCount + 1, grid_info.num_rows - i,
			  j + 1, 'A' + grid_info.num_rows - i - 1, 'A' + j);
	      }
	      else {
		  sprintf(buf, "( %d, %d, %d )",
			  attCount + 1, i + 1, j + 1);
	      }
	      if (db_append_string(&sql, buf) != DB_OK)
		      G_fatal_error(_("Unable to fill attribute table"));

	      G_debug(3, "SQL: %s", db_get_string(&sql));

	      if (db_execute_immediate(Driver, &sql) != DB_OK) {
		  G_fatal_error(_("Unable to insert new record: %s"),
			      db_get_string(&sql));
	      }
	      attCount++;
	  }
      }
    }
    db_commit_transaction(Driver);

    db_close_database_shutdown_driver(Driver);

    Vect_build(&Map);
    Vect_close(&Map);

    exit(EXIT_SUCCESS);
}
Esempio n. 27
0
/* Returns 0 - ok , 1 - error */
int
plot(int ctype, struct Map_info *Map, int type, int field,
     char *columns, int ncols, char *sizecol, int size, double scale,
     COLOR * ocolor, COLOR * colors, int y_center, double *max_reference,
     int do3d)
{
    int ltype, nlines, line, col, more, coltype, nselcols;
    double x, y, csize, len;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int cat;
    double *val;
    char buf[2000];
    struct field_info *Fi;
    dbDriver *driver;
    dbValue *value;
    dbString sql;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    db_init_string(&sql);

    Fi = Vect_get_field(Map, field);
    if (Fi == NULL)
	G_fatal_error(_("Database connection not defined for layer %d"),
		      field);

    /* Open driver */
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL) {
	G_warning(_("Unable to open database <%s> by driver <%s>"),
		  Fi->database,
		  Fi->driver);
	return 1;
    }
    db_set_error_handler_driver(driver);

    val = (double *)G_malloc((ncols + 1) * sizeof(double));	/* + 1 for sizecol */

    Vect_rewind(Map);

    nlines = Vect_get_num_lines(Map);

    /* loop through each vector feature */
    for (line = 1; line <= nlines; line++) {
	G_debug(3, "line = %d", line);
	ltype = Vect_read_line(Map, Points, Cats, line);

	if (!(ltype & type))
	    continue;

	Vect_cat_get(Cats, field, &cat);
	if (cat < 0)
	    continue;

	/* Select values from DB */
	if (ctype == CTYPE_PIE && sizecol != NULL) {
	    sprintf(buf, "select %s, %s from %s where %s = %d", columns,
		    sizecol, Fi->table, Fi->key, cat);
	    nselcols = ncols + 1;
	}
	else {
	    sprintf(buf, "select %s from %s where %s = %d", columns,
		    Fi->table, Fi->key, cat);
	    nselcols = ncols;
	}

	db_set_string(&sql, buf);
	G_debug(3, "SQL: %s", buf);

	if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) !=
	    DB_OK) {
	    G_warning(_("Unable to open select cursor: '%s'"),
		      buf);
	    return 1;
	}

	table = db_get_cursor_table(&cursor);
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK || !more)
	    continue;

	for (col = 0; col < nselcols; col++) {
	    column = db_get_table_column(table, col);
	    value = db_get_column_value(column);
	    coltype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	    switch (coltype) {
	    case DB_C_TYPE_INT:
		val[col] = (double)db_get_value_int(value);
		break;
	    case DB_C_TYPE_DOUBLE:
		val[col] = db_get_value_double(value);
		break;
	    default:
		G_warning("Column type not supported (must be INT or FLOAT)");
		return 1;
	    }
	    G_debug(4, "  val[%d]: %f", col, val[col]);
	}

	db_close_cursor(&cursor);

	/* Center of chart */
	if (ltype & GV_LINES) {	/* find center */
	    len = Vect_line_length(Points) / 2;
	    Vect_point_on_line(Points, len, &x, &y, NULL, NULL, NULL);
	}
	else {
	    x = Points->x[0];
	    y = Points->y[0];
	}

	if (ctype == CTYPE_PIE) {
	    if (sizecol != NULL) {
		csize = val[ncols];
		size = scale * csize;
	    }
	    pie(x, y, size, val, ncols, ocolor, colors, do3d);
	}
	else {
	    bar(x, y, size, scale, val, ncols, ocolor, colors, y_center,
		max_reference, do3d);
	}
    }

    db_close_database_shutdown_driver(driver);
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return 0;
}
Esempio n. 28
0
File: main.c Progetto: caomw/grass
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *in_opt, *out_opt, *feature_opt, *column_name;
    struct Flag *smooth_flg, *value_flg, *z_flg, *no_topol, *notab_flg;
    int feature, notab_flag;


    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("conversion"));
    G_add_keyword(_("geometry"));
    G_add_keyword(_("vectorization"));
    module->description = _("Converts a raster map into a vector map.");

    in_opt = G_define_standard_option(G_OPT_R_INPUT);

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    
    feature_opt = G_define_standard_option(G_OPT_V_TYPE);
    feature_opt->required = YES;
    feature_opt->multiple = NO;
    feature_opt->options = "point,line,area";
    feature_opt->answer = NULL;

    column_name = G_define_standard_option(G_OPT_DB_COLUMN);
    column_name->label = _("Name of attribute column to store value");
    column_name->description = _("Name must be SQL compliant");
    column_name->answer = "value";

    smooth_flg = G_define_flag();
    smooth_flg->key = 's';
    smooth_flg->description = _("Smooth corners of area features");

    value_flg = G_define_flag();
    value_flg->key = 'v';
    value_flg->description =
	_("Use raster values as categories instead of unique sequence (CELL only)");
    value_flg->guisection = _("Attributes");

    z_flg = G_define_flag();
    z_flg->key = 'z';
    z_flg->label = _("Write raster values as z coordinate");
    z_flg->description = _("Table is not created. "
			   "Currently supported only for points.");
    z_flg->guisection = _("Attributes");

    no_topol = G_define_flag();
    no_topol->key = 'b';
    no_topol->label = _("Do not build vector topology");
    no_topol->description = _("Recommended for massive point conversion");

    notab_flg = G_define_standard_flag(G_FLG_V_TABLE);

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

    feature = Vect_option_to_types(feature_opt);
    smooth_flag = (smooth_flg->answer) ? SMOOTH : NO_SMOOTH;
    value_flag = value_flg->answer;
    notab_flag = notab_flg->answer;

    if (z_flg->answer && (feature != GV_POINT))
	G_fatal_error(_("z flag is supported only for points"));

    /* Open files */
    input_fd = Rast_open_old(in_opt->answer, "");

    data_type = Rast_get_map_type(input_fd);
    data_size = Rast_cell_size(data_type);
    G_get_window(&cell_head);

    if (value_flag && data_type != CELL_TYPE) {
	if (!notab_flag)
	    G_warning(_("Raster is not CELL, '-v' flag ignored, raster values will be written to the table."));
	else if (z_flg->answer)
	    G_warning(_("Raster is not CELL, '-v' flag ignored, raster values will be z coordinate."));
	else
	    G_warning(_("Raster is not CELL, '-v' flag ignored, raster values will be lost."));
	value_flag = 0;
    }

    if (!value_flag && notab_flag) {
	G_warning(_("Categories will be unique sequence, raster values will be lost."));
    }

    if (Vect_open_new(&Map, out_opt->answer, z_flg->answer) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);

    Vect_hist_command(&Map);

    Cats = Vect_new_cats_struct();

    /* Open category labels */
    if (data_type == CELL_TYPE) {
	if (0 == Rast_read_cats(in_opt->answer, "", &RastCats))
	    has_cats = 1;
    }
    else
	has_cats = 0;

    db_init_string(&sql);
    db_init_string(&label);

    /* Create table */
    if ((feature & (GV_AREA | GV_POINT | GV_LINE)) &&
	(!value_flag || (value_flag && has_cats)) && !(z_flg->answer)
	&& !notab_flag) {
	char buf[1000];

	Fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);
	Vect_map_add_dblink(&Map, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			    Fi->driver);

	driver =
	    db_start_driver_open_database(Fi->driver,
					  Vect_subst_var(Fi->database, &Map));
	if (driver == NULL)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Fi->database, Fi->driver);
        db_set_error_handler_driver(driver);

	/* Create new table */
	db_zero_string(&sql);
	sprintf(buf, "create table %s ( cat integer", Fi->table);
	db_append_string(&sql, buf);

	if (!value_flag) {	/* add value to the table */
	    if (data_type == CELL_TYPE) {
		db_append_string(&sql, ", ");
		db_append_string(&sql, column_name->answer);
		db_append_string(&sql, " integer");
	    } else {
		db_append_string(&sql, ",");
		db_append_string(&sql, column_name->answer);
		db_append_string(&sql, " double precision");
	    }
	}

	if (has_cats) {
	    int i, len;
	    int clen = 0;

	    /* Get maximum column length */
	    for (i = 0; i < RastCats.ncats; i++) {
		len = strlen(RastCats.labels[i]);
		if (len > clen)
		    clen = len;
	    }
	    clen += 10;

	    sprintf(buf, ", label varchar(%d)", clen);
	    db_append_string(&sql, buf);
	}

	db_append_string(&sql, ")");

	G_debug(3, db_get_string(&sql));

	if (db_execute_immediate(driver, &sql) != DB_OK)
	    G_fatal_error(_("Unable to create table: %s"),
			  db_get_string(&sql));

	if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK)
	    G_warning(_("Unable to create index"));

	if (db_grant_on_table
	    (driver, Fi->table, DB_PRIV_SELECT,
	     DB_GROUP | DB_PUBLIC) != DB_OK)
	    G_fatal_error(_("Unable to grant privileges on table <%s>"),
			  Fi->table);

	db_begin_transaction(driver);

    }
    else {
	driver = NULL;
    }

    /* init variables for lines and areas */
    first_read = 1;
    last_read = 0;
    direction = FORWARD;
    row_length = cell_head.cols;
    n_rows = cell_head.rows;
    row_count = 0;

    if (feature == GV_LINE) {
	alloc_lines_bufs(row_length + 2);
	extract_lines();
    }
    else if (feature == GV_AREA) {
	alloc_areas_bufs(row_length + 2);
	extract_areas();
    }
    else {			/* GV_POINT */

	extract_points(z_flg->answer);
    }

    Rast_close(input_fd);

    if (!no_topol->answer)
	Vect_build(&Map);


    /* insert cats and optionally labels if raster cats were used */
    if (driver && value_flag) {
	char buf[1000];
	int c, i, cat, fidx, ncats, lastcat, tp, id;

	fidx = Vect_cidx_get_field_index(&Map, 1);
	if (fidx >= 0) {
	    ncats = Vect_cidx_get_num_cats_by_index(&Map, fidx);
	    lastcat = -1;
            
            G_important_message(_("Updating attributes..."));
	    for (c = 0; c < ncats; c++) {
		Vect_cidx_get_cat_by_index(&Map, fidx, c, &cat, &tp, &id);

		if (lastcat == cat)
		    continue;

		/* find label, slow -> TODO faster */
		db_set_string(&label, "");
		for (i = 0; i < RastCats.ncats; i++) {
		    if (cat == (int)RastCats.q.table[i].dLow) {	/* cats are in dLow/High not in cLow/High !!! */
			db_set_string(&label, RastCats.labels[i]);
			db_double_quote_string(&label);
			break;
		    }
		}
		G_debug(3, "cat = %d label = %s", cat, db_get_string(&label));

		sprintf(buf, "insert into %s values ( %d, '%s')", Fi->table,
			cat, db_get_string(&label));
		db_set_string(&sql, buf);
		G_debug(3, db_get_string(&sql));

		if (db_execute_immediate(driver, &sql) != DB_OK)
		    G_fatal_error(_("Unable to insert into table: %s"),
				  db_get_string(&sql));

		lastcat = cat;
	    }
	}
    }

    if (has_cats)
	Rast_free_cats(&RastCats);

    if (driver != NULL) {
	db_commit_transaction(driver);
	db_close_database_shutdown_driver(driver);
    }

    Vect_close(&Map);
    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}
Esempio n. 29
0
File: main.c Progetto: caomw/grass
int main(int argc, char *argv[])
{
    int i, cat, with_z, more, ctype, nrows;
    char buf[DB_SQL_MAX];
    int count;
    double coor[3];
    int ncoor;
    struct Option *driver_opt, *database_opt, *table_opt;
    struct Option *xcol_opt, *ycol_opt, *zcol_opt, *keycol_opt, *where_opt,
	*outvect;
    struct Flag *same_table_flag;
    struct GModule *module;
    struct Map_info Map;
    struct line_pnts *Points;
    struct line_cats *Cats;
    dbString sql;
    dbDriver *driver;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;
    dbValue *value;
    struct field_info *fi;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("import"));
    G_add_keyword(_("database"));
    G_add_keyword(_("points"));
    module->description =
	_("Creates new vector (points) map from database table containing coordinates.");

    table_opt = G_define_standard_option(G_OPT_DB_TABLE);
    table_opt->required = YES;
    table_opt->description = _("Input table name");

    driver_opt = G_define_standard_option(G_OPT_DB_DRIVER);
    driver_opt->options = db_list_drivers();
    driver_opt->answer = (char *)db_get_default_driver_name();
    driver_opt->guisection = _("Input DB");

    database_opt = G_define_standard_option(G_OPT_DB_DATABASE);
    database_opt->answer = (char *)db_get_default_database_name();
    database_opt->guisection = _("Input DB");

    xcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    xcol_opt->key = "x";
    xcol_opt->required = YES;
    xcol_opt->description = _("Name of column containing x coordinate");

    ycol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    ycol_opt->key = "y";
    ycol_opt->required = YES;
    ycol_opt->description = _("Name of column containing y coordinate");

    zcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    zcol_opt->key = "z";
    zcol_opt->description = _("Name of column containing z coordinate");
    zcol_opt->guisection = _("3D output");

    keycol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    keycol_opt->key = "key";
    keycol_opt->required = NO;
    keycol_opt->label = _("Name of column containing category number");
    keycol_opt->description = _("Must refer to an integer column");

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);
    where_opt->guisection = _("Selection");

    outvect = G_define_standard_option(G_OPT_V_OUTPUT);

    same_table_flag = G_define_flag();
    same_table_flag->key = 't';
    same_table_flag->description =
	_("Use imported table as attribute table for new map");

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

    if (zcol_opt->answer) {
	with_z = WITH_Z;
	ncoor = 3;
    }
    else {
	with_z = WITHOUT_Z;
	ncoor = 2;
    }

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    db_init_string(&sql);

    if (G_get_overwrite()) {
	/* We don't want to delete the input table when overwriting the output
	 * vector. */
	char name[GNAME_MAX], mapset[GMAPSET_MAX];

	if (!G_name_is_fully_qualified(outvect->answer, name, mapset)) {
	    strcpy(name, outvect->answer);
	    strcpy(mapset, G_mapset());
	}

	Vect_set_open_level(1); /* no topo needed */

	if (strcmp(mapset, G_mapset()) == 0 && G_find_vector2(name, mapset) &&
	    Vect_open_old(&Map, name, mapset) >= 0) {
	    int num_dblinks;

	    num_dblinks = Vect_get_num_dblinks(&Map);
	    for (i = 0; i < num_dblinks; i++) {
		if ((fi = Vect_get_dblink(&Map, i)) != NULL &&
		    strcmp(fi->driver, driver_opt->answer) == 0 &&
		    strcmp(fi->database, database_opt->answer) == 0 &&
		    strcmp(fi->table, table_opt->answer) == 0)
		    G_fatal_error(_("Vector map <%s> cannot be overwritten "
				    "because input table <%s> is linked to "
				    "this map."),
				    outvect->answer, table_opt->answer);
	    }
	    Vect_close(&Map);
	}
    }

    if (Vect_open_new(&Map, outvect->answer, with_z) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"),
			outvect->answer);

    Vect_set_error_handler_io(NULL, &Map);
    
    Vect_hist_command(&Map);

    fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);

    /* Open driver */
    driver = db_start_driver_open_database(driver_opt->answer,
					   database_opt->answer);
    if (driver == NULL) {
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database, fi->driver);
    }
    db_set_error_handler_driver(driver);
    
    /* check if target table already exists */
    G_debug(3, "Output vector table <%s>, driver: <%s>, database: <%s>",
	    outvect->answer, db_get_default_driver_name(),
	    db_get_default_database_name());

    if (!same_table_flag->answer &&
	db_table_exists(db_get_default_driver_name(),
			db_get_default_database_name(), outvect->answer) == 1)
	G_fatal_error(_("Output vector map, table <%s> (driver: <%s>, database: <%s>) "
		       "already exists"), outvect->answer,
		      db_get_default_driver_name(),
		      db_get_default_database_name());

    if (keycol_opt->answer) {
        int coltype;
        coltype = db_column_Ctype(driver, table_opt->answer, keycol_opt->answer);

        if (coltype == -1)
            G_fatal_error(_("Column <%s> not found in table <%s>"),
                          keycol_opt->answer, table_opt->answer);
        if (coltype != DB_C_TYPE_INT)
            G_fatal_error(_("Data type of key column must be integer"));
    }
    else {
        if (same_table_flag->answer) {
            G_fatal_error(_("Option <%s> must be specified when -%c flag is given"),
                          keycol_opt->key, same_table_flag->key);
        }

        if (strcmp(db_get_default_driver_name(), "sqlite") != 0)
            G_fatal_error(_("Unable to define key column. This operation is not supported "
                            "by <%s> driver. You need to define <%s> option."),
                          fi->driver, keycol_opt->key);
    }

    /* Open select cursor */
    sprintf(buf, "SELECT %s, %s", xcol_opt->answer, ycol_opt->answer);
    db_set_string(&sql, buf);
    if (with_z) {
	sprintf(buf, ", %s", zcol_opt->answer);
	db_append_string(&sql, buf);
    }
    if (keycol_opt->answer) {
	sprintf(buf, ", %s", keycol_opt->answer);
	db_append_string(&sql, buf);
    }
    sprintf(buf, " FROM %s", table_opt->answer);
    db_append_string(&sql, buf);
    
    if (where_opt->answer) {
	sprintf(buf, " WHERE %s", where_opt->answer);
	db_append_string(&sql, buf);
    }
    G_debug(2, "SQL: %s", db_get_string(&sql));

    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
	G_fatal_error(_("Unable to open select cursor: '%s'"),
		      db_get_string(&sql));
    }

    table = db_get_cursor_table(&cursor);
    nrows = db_get_num_rows(&cursor);

    G_debug(2, "%d points selected", nrows);

    count = cat = 0;
    G_message(_("Writing features..."));
    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
	G_percent(count, nrows, 2);
	/* key column */
        if (keycol_opt->answer) {
            column = db_get_table_column(table, with_z ? 3 : 2);
            ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
            if (ctype != DB_C_TYPE_INT)
                G_fatal_error(_("Key column must be integer"));
            value = db_get_column_value(column);
            cat = db_get_value_int(value);
        }
        else {
            cat++;
        }

        /* coordinates */
	for (i = 0; i < ncoor; i++) {
	    column = db_get_table_column(table, i);
	    ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
		G_fatal_error(_("x/y/z column must be integer or double"));
	    value = db_get_column_value(column);
	    if (ctype == DB_C_TYPE_INT)
		coor[i] = (double)db_get_value_int(value);
	    else
		coor[i] = db_get_value_double(value);
	}

	Vect_reset_line(Points);
	Vect_reset_cats(Cats);

	Vect_append_point(Points, coor[0], coor[1], coor[2]);

	Vect_cat_set(Cats, 1, cat);

	Vect_write_line(&Map, GV_POINT, Points, Cats);

	count++;
    }
    G_percent(1, 1, 1);

    /* close connection to input DB before copying attributes */
    db_close_database_shutdown_driver(driver);

    /* Copy table */
    if (!same_table_flag->answer) {
        G_message(_("Copying attributes..."));
        
        if (DB_FAILED == db_copy_table_where(driver_opt->answer, database_opt->answer,
                                             table_opt->answer,
                                             fi->driver, fi->database, fi->table,
                                             where_opt->answer)) { /* where can be NULL */
            G_warning(_("Unable to copy table"));
	}
	else {
	    Vect_map_add_dblink(&Map, 1, NULL, fi->table,
                                keycol_opt->answer ? keycol_opt->answer : GV_KEY_COLUMN,
				fi->database, fi->driver);
	}

        if (!keycol_opt->answer) {
            /* TODO: implement for all DB drivers in generic way if
             * possible */
            
            driver = db_start_driver_open_database(fi->driver, fi->database);
            if (driver == NULL) {
                G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
                              fi->database, fi->driver);
            }
            db_set_error_handler_driver(driver);

            /* add key column */
            sprintf(buf, "ALTER TABLE %s ADD COLUMN %s INTEGER",
                    fi->table, GV_KEY_COLUMN);
            db_set_string(&sql, buf);
            
            if (db_execute_immediate(driver, &sql) != DB_OK) {
                G_fatal_error(_("Unable to add key column <%s>: "
                                "SERIAL type is not supported by <%s>"), 
                              GV_KEY_COLUMN, fi->driver);
            }

            /* update key column */
            sprintf(buf, "UPDATE %s SET %s = _ROWID_",
                    fi->table, GV_KEY_COLUMN);
            db_set_string(&sql, buf);
            
            if (db_execute_immediate(driver, &sql) != DB_OK) {
                G_fatal_error(_("Failed to update key column <%s>"),
                              GV_KEY_COLUMN);
            }

        }
    }
    else {
        /* do not copy attributes, link original table */
	Vect_map_add_dblink(&Map, 1, NULL, table_opt->answer,
                            keycol_opt->answer ? keycol_opt->answer : GV_KEY_COLUMN,
                            database_opt->answer, driver_opt->answer);
    }

    Vect_build(&Map);
    Vect_close(&Map);

    G_done_msg(_n("%d point written to vector map.",
                  "%d points written to vector map.",
                  count), count);

    return (EXIT_SUCCESS);
}
Esempio n. 30
0
File: main.c Progetto: caomw/grass
int main(int argc, char *argv[])
{
    /* Variables' declarations */
    int nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row, subregion = 0, nsubregions = 0;
    double N_extension, E_extension, edgeE, edgeN;
    int dim_vect, nparameters, BW, npoints;
    double lambda_B, lambda_F, grad_H, grad_L, alpha, mean;
    const char *dvr, *db, *mapset;
    char table_interpolation[GNAME_MAX], table_name[GNAME_MAX];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    int last_row, last_column, flag_auxiliar = FALSE;

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

    /* Structs' declarations */
    struct Map_info In, Out;
    struct Option *in_opt, *out_opt, *stepE_opt, *stepN_opt,
	*lambdaF_opt, *lambdaB_opt, *gradH_opt, *gradL_opt, *alfa_opt;
    struct Flag *spline_step_flag;
    struct GModule *module;

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

    struct Point *observ;

    dbDriver *driver;

/*------------------------------------------------------------------------------------------*/
    /* Options' declaration */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("LIDAR"));
    G_add_keyword(_("edges"));
    module->description =
	_("Detects the object's edges from a LIDAR data set.");

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

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);

    stepE_opt = G_define_option();
    stepE_opt->key = "see";
    stepE_opt->type = TYPE_DOUBLE;
    stepE_opt->required = NO;
    stepE_opt->answer = "4";
    stepE_opt->description =
	_("Interpolation spline step value in east direction");
    stepE_opt->guisection = _("Settings");

    stepN_opt = G_define_option();
    stepN_opt->key = "sen";
    stepN_opt->type = TYPE_DOUBLE;
    stepN_opt->required = NO;
    stepN_opt->answer = "4";
    stepN_opt->description =
	_("Interpolation spline step value in north direction");
    stepN_opt->guisection = _("Settings");

    lambdaB_opt = G_define_option();
    lambdaB_opt->key = "lambda_g";
    lambdaB_opt->type = TYPE_DOUBLE;
    lambdaB_opt->required = NO;
    lambdaB_opt->description =
	_("Regularization weight in gradient evaluation");
    lambdaB_opt->answer = "0.01";
    lambdaB_opt->guisection = _("Settings");

    gradH_opt = G_define_option();
    gradH_opt->key = "tgh";
    gradH_opt->type = TYPE_DOUBLE;
    gradH_opt->required = NO;
    gradH_opt->description =
	_("High gradient threshold for edge classification");
    gradH_opt->answer = "6";
    gradH_opt->guisection = _("Settings");

    gradL_opt = G_define_option();
    gradL_opt->key = "tgl";
    gradL_opt->type = TYPE_DOUBLE;
    gradL_opt->required = NO;
    gradL_opt->description =
	_("Low gradient threshold for edge classification");
    gradL_opt->answer = "3";
    gradL_opt->guisection = _("Settings");

    alfa_opt = G_define_option();
    alfa_opt->key = "theta_g";
    alfa_opt->type = TYPE_DOUBLE;
    alfa_opt->required = NO;
    alfa_opt->description = _("Angle range for same direction detection");
    alfa_opt->answer = "0.26";
    alfa_opt->guisection = _("Settings");

    lambdaF_opt = G_define_option();
    lambdaF_opt->key = "lambda_r";
    lambdaF_opt->type = TYPE_DOUBLE;
    lambdaF_opt->required = NO;
    lambdaF_opt->description =
	_("Regularization weight in residual evaluation");
    lambdaF_opt->answer = "2";
    lambdaF_opt->guisection = _("Settings");

    /* Parsing */
    G_gisinit(argv[0]);

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

    line_out_counter = 1;
    stepN = atof(stepN_opt->answer);
    stepE = atof(stepE_opt->answer);
    lambda_F = atof(lambdaF_opt->answer);
    lambda_B = atof(lambdaB_opt->answer);
    grad_H = atof(gradH_opt->answer);
    grad_L = atof(gradL_opt->answer);
    alpha = atof(alfa_opt->answer);

    grad_L = grad_L * grad_L;
    grad_H = grad_H * grad_H;

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

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

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

    /* Something went wrong in a previous v.lidar.edgedetection execution */
    if (db_table_exists(dvr, db, table_name)) {
	/* Start driver and open db */
	driver = db_start_driver_open_database(dvr, db);
	if (driver == NULL)
	    G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
			  dvr);
	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_fatal_error(_("Old auxiliar table could not be dropped"));
	db_close_database_shutdown_driver(driver);
    }

    /* Something went wrong in a previous v.lidar.edgedetection execution */
    if (db_table_exists(dvr, db, table_interpolation)) {
	/* Start driver and open db */
	driver = db_start_driver_open_database(dvr, db);
	if (driver == NULL)
	    G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
			  dvr);
	if (P_Drop_Aux_Table(driver, table_interpolation) != DB_OK)
	    G_fatal_error(_("Old auxiliar table could not be dropped"));
	db_close_database_shutdown_driver(driver);
    }

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

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

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

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

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

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

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

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

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

    if (P_Create_Aux2_Table(driver, table_interpolation) == FALSE)
	G_fatal_error(_("It was impossible to create <%s> interpolation table in database."),
		      out_opt->answer);

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

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

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

    /* Fixing parameters of the elaboration region */
    P_zero_dim(&dims);

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

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

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

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

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

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

    nsubregions = nsubregion_row * nsubregion_col;

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

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

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

	if (elaboration_reg.north > original_reg.north) {	/* First row */
	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  FIRST_ROW);
	}

	if (elaboration_reg.south <= original_reg.south) {	/* Last row */
	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  LAST_ROW);
	    last_row = TRUE;
	}

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

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

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

	    subregion++;
	    if (nsubregions > 1)
		G_message(_("subregion %d of %d"), subregion, nsubregions);

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

	    if (elaboration_reg.west < original_reg.west) {	/* First column */
		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, FIRST_COLUMN);
	    }

	    if (elaboration_reg.east >= original_reg.east) {	/* Last column */
		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, LAST_COLUMN);
		last_column = TRUE;
	    }

	    nsplx =
		ceil((elaboration_reg.east - elaboration_reg.west) / stepE) +
		0.5;
	    /*
	    if (nsplx > NSPLX_MAX) {
		nsplx = NSPLX_MAX;
	    }
	    */
	    G_debug(1, "nsplx = %d", nsplx);

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

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

		nparameters = nsplx * nsply;

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

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

		lineVect = G_alloc_ivector(npoints + 1);

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

		G_free(observ);

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

		G_free_matrix(N);
		for (tn = 0; tn < nparameters; tn++)
		    TN[tn] = 0;

		G_debug(1, _("Allocating memory for bicubic interpolation"));
		BW = P_get_BandWidth(P_BICUBIC, nsply);
		N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
		parVect_bicub = G_alloc_vector(nparameters);	/* Bicubic parameters vector */

		G_verbose_message(_("Bicubic interpolation"));
		normalDefBicubic(N, TN, Q, obsVect, stepE, stepN, nsplx,
				 nsply, elaboration_reg.west,
				 elaboration_reg.south, npoints, nparameters,
				 BW);
		nCorrectLapl(N, lambda_F, nsplx, nsply, stepE, stepN);
		G_math_solver_cholesky_sband(N, parVect_bicub, TN, nparameters, BW);

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

		G_verbose_message(_("Point classification"));
		classification(&Out, elaboration_reg, general_box,
			       overlap_box, obsVect, parVect_bilin,
			       parVect_bicub, mean, alpha, grad_H, grad_L,
			       dims.overlap, lineVect, npoints, driver,
			       table_interpolation, table_name);

		G_free_vector(parVect_bilin);
		G_free_vector(parVect_bicub);
		G_free_matrix(obsVect);
		G_free_ivector(lineVect);
	    }			/* IF */
	    else {
		G_free(observ);
		G_warning(_("No data within this subregion. "
			    "Consider changing the spline step."));
	    }
	}			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    /* Dropping auxiliar table */
    if (npoints > 0) {
	G_debug(1, _("Dropping <%s>"), table_name);
	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_warning(_("Auxiliar table could not be dropped"));
    }

    db_close_database_shutdown_driver(driver);

    Vect_close(&In);

    Vect_map_add_dblink(&Out, F_INTERPOLATION, NULL, table_interpolation,
			"id", db, dvr);

    Vect_close(&Out);

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*!END MAIN */