QgsGrassFeatureIterator::QgsGrassFeatureIterator( QgsGrassProvider* p, const QgsFeatureRequest& request )
    : QgsAbstractFeatureIterator( request ), P( p )
{
  // make sure that only one iterator is active
  if ( P->mActiveIterator )
  {
    QgsMessageLog::logMessage( QObject::tr( "Already active iterator on this provider was closed." ), QObject::tr( "GRASS" ) );
    P->mActiveIterator->close();
  }
  P->mActiveIterator = this;

  // check if outdated and update if necessary
  P->ensureUpdated();

  // Init structures
  mPoints = Vect_new_line_struct();
  mCats = Vect_new_cats_struct();
  mList = Vect_new_list();

  // Create selection array
  allocateSelection( P->mMap );
  resetSelection( 1 );

  if ( request.filterType() == QgsFeatureRequest::FilterRect )
  {
    setSelectionRect( request.filterRect(), request.flags() & QgsFeatureRequest::ExactIntersect );
  }
  else
  {
    // TODO: implement fast lookup by feature id

    //no filter - use all features
    resetSelection( 1 );
  }
}
Ejemplo n.º 2
0
QgsGrassFeatureIterator::QgsGrassFeatureIterator( QgsGrassFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )
    : QgsAbstractFeatureIteratorFromSource<QgsGrassFeatureSource>( source, ownSource, request )
{
  sMutex.lock();

  // Init structures
  mPoints = Vect_new_line_struct();
  mCats = Vect_new_cats_struct();
  mList = Vect_new_list();

  // Create selection array
  allocateSelection( mSource->mMap );
  resetSelection( 1 );

  if ( request.filterType() == QgsFeatureRequest::FilterRect )
  {
    setSelectionRect( request.filterRect(), request.flags() & QgsFeatureRequest::ExactIntersect );
  }
  else
  {
    // TODO: implement fast lookup by feature id

    //no filter - use all features
    resetSelection( 1 );
  }
}
Ejemplo n.º 3
0
/* Writes a site to file open on fptr. */
int G_site_put(struct Map_info *Map, const Site * s)
{
    static struct line_pnts *Points = NULL;
    static struct line_cats *Cats = NULL;

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

    Vect_reset_line(Points);
    Vect_reset_cats(Cats);

    /* no 3D support so far: s->dim[0] */
    Vect_append_point(Points, s->east, s->north, 0.0);

    G_debug(4, "cattype = %d", s->cattype);

    if (s->cattype == FCELL_TYPE || s->cattype == DCELL_TYPE)
	G_fatal_error(_("Category must be integer"));

    if (s->cattype == CELL_TYPE)
	Vect_cat_set(Cats, 1, s->ccat);

    Vect_write_line(Map, GV_POINT, Points, Cats);

    return 0;
}
Ejemplo n.º 4
0
/** Get the lines and boundaries from the map and load them in an array
*/
void load_lines(struct Map_info *map, struct Point **points, int *num_points,
		struct Line **lines, int *num_lines)
{
    int index_line = 0;
    int index_point = 0;
    struct line_pnts *sites;
    struct line_cats *cats;
    int cat = 0;
    int type;

    sites = Vect_new_line_struct();
    cats = Vect_new_cats_struct();

    while ((type = Vect_read_next_line(map, sites, cats)) > -1) {

	if (type != GV_LINE && type != GV_BOUNDARY && type != GV_POINT)
	    continue;

	if (type == GV_LINE)
	    process_line(sites, points, &index_point, lines, &index_line, -1);
	else if (type == GV_BOUNDARY)
	    process_boundary(sites, points, &index_point, lines, &index_line,
			     cat++);
	else if (type == GV_POINT)
	    process_point(sites, points, &index_point, -1);

    }

    *num_points = index_point;
    *num_lines = index_line;

    Vect_destroy_line_struct(sites);
    Vect_destroy_cats_struct(cats);
}
Ejemplo n.º 5
0
/* Check if point is inside area with category of given field. All cats are set in 
 * Cats with original field.
 * returns number of cats.
 */
int point_area(struct Map_info *Map, int field, double x, double y,
	       struct line_cats *Cats)
{
    int i, area, centr;
    static struct line_cats *CCats = NULL;

    Vect_reset_cats(Cats);
    area = Vect_find_area(Map, x, y);
    G_debug(4, "  area = %d", area);

    if (!area)
	return 0;

    centr = Vect_get_area_centroid(Map, area);

    if (centr <= 0)
	return 0;

    if (!CCats)
	CCats = Vect_new_cats_struct();
    Vect_read_line(Map, NULL, CCats, centr);

    for (i = 0; i < CCats->n_cats; i++) {
	if (CCats->field[i] == field) {
	    Vect_cat_set(Cats, field, CCats->cat[i]);
	}
    }

    return Cats->n_cats;
}
Ejemplo n.º 6
0
int sort_areas(struct Map_info *Map, struct line_pnts *Points,
               int field, struct cat_list *cat_list)
{
    int i, centroid, nareas_selected;
    struct line_cats *Cats;
    CELL cat;

    G_begin_polygon_area_calculations();
    Cats = Vect_new_cats_struct();

    /* first count valid areas */
    nareas = Vect_get_num_areas(Map);
    if (nareas == 0)
	return 0;

    /* allocate list to hold valid area info */
    list =
	(struct list *)G_calloc(nareas * sizeof(char), sizeof(struct list));

    /* store area size,cat,index in list */
    nareas_selected = 0;
    for (i = 0; i < nareas; i++) {

	centroid = Vect_get_area_centroid(Map, i + 1);
	SETNULL(&cat);
	if (centroid <= 0) {
	    G_debug(2,_("Area without centroid (OK for island)"));
	}
	else {
	    Vect_read_line(Map, NULL, Cats, centroid);
	    if (field > 0) {
		if (Vect_cats_in_constraint(Cats, field, cat_list)) {
		    Vect_cat_get(Cats, field, &cat);
		    nareas_selected++;
		}
		else {
		    G_debug(2, _("Area centroid without category"));
		}
	    }
	    else {
		/* field < 1, process all areas with centroid */
		cat = 0;
		nareas_selected++;
	    }
	}

	list[i].index = i + 1;
	Vect_get_area_points(Map, i + 1, Points);
	list[i].size =
	    G_area_of_polygon(Points->x, Points->y, Points->n_points);

	list[i].cat = cat;
    }
    if (nareas_selected > 0) {
	/* sort the list by size */
	qsort(list, nareas * sizeof(char), sizeof(struct list), compare);
    }

    return nareas_selected;
}
Ejemplo n.º 7
0
double P_estimate_splinestep(struct Map_info *Map, double *dens, double *dist)
{
    int type, npoints = 0;
    double xmin = 0, xmax = 0, ymin = 0, ymax = 0;
    double x, y, z;
    struct line_pnts *points;
    struct line_cats *categories;
    struct bound_box region_box;
    struct Cell_head orig;

    G_get_set_window(&orig);
    Vect_region_box(&orig, &region_box);

    points = Vect_new_line_struct();
    categories = Vect_new_cats_struct();

    Vect_rewind(Map);
    while ((type = Vect_read_next_line(Map, points, categories)) > 0) {
	if (!(type & GV_POINT))
	    continue;

	x = points->x[0];
	y = points->y[0];
	if (points->z != NULL)
	    z = points->z[0];
	else
	    z = 0.0;

	/* only use points in current region */
	if (Vect_point_in_box(x, y, z, &region_box)) {
	    npoints++;

	    if (npoints > 1) {
		if (xmin > x)
		    xmin = x;
		else if (xmax < x)
		    xmax = x;
		if (ymin > y)
		    ymin = y;
		else if (ymax < y)
		    ymax = y;
	    }
	    else {
		xmin = xmax = x;
		ymin = ymax = y;
	    }
	}
    }
    if (npoints > 0) {
	/* estimated average distance between points in map units */
	*dist = sqrt(((xmax - xmin) * (ymax - ymin)) / npoints);
	/* estimated point density as number of points per square map unit */
	*dens = npoints / ((xmax - xmin) * (ymax - ymin));
	return 0;
    }
    else {
	return -1;
    }
}
Ejemplo n.º 8
0
/*-
 * Reads ptr and returns 0 on success,
 *                      -1 on EOF,
 *                      -2 on other fatal error or insufficient data,
 *                       1 on format mismatch (extra data)
 */
int G_site_get(struct Map_info *Map, Site * s)
{
    int i, type, cat;
    static struct line_pnts *Points = NULL;
    static struct line_cats *Cats = NULL;
    SITE_ATT *sa;

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

    while (1) {
	type = Vect_read_next_line(Map, Points, Cats);

	if (type == -1)
	    return -2;		/* Error */
	if (type == -2)
	    return -1;		/* EOF */
	if (type != GV_POINT)
	    continue;		/* Is not point */

	Vect_cat_get(Cats, 1, &cat);

	G_debug(4, "Site: %f|%f|%f|#%d", Points->x[0], Points->y[0],
		Points->z[0], cat);

	s->east = Points->x[0];
	s->north = Points->y[0];
	if (Vect_is_3d(Map))
	    s->dim[0] = Points->z[0];

	s->ccat = cat;

	/* find att */

	if (Map->n_site_att > 0) {
	    sa = (SITE_ATT *) bsearch((void *)&cat, (void *)Map->site_att,
				      Map->n_site_att, sizeof(SITE_ATT),
				      site_att_cmp);

	    if (sa == NULL) {
		G_warning(_("Attributes for category %d not found"), cat);
		for (i = 0; i < Map->n_site_dbl; i++)
		    s->dbl_att[i] = 0;
		for (i = 0; i < Map->n_site_str; i++)
		    G_strncpy(s->str_att[i], "", MAX_SITE_STRING);
	    }
	    else {
		for (i = 0; i < Map->n_site_dbl; i++)
		    s->dbl_att[i] = sa->dbl[i];
		for (i = 0; i < Map->n_site_str; i++)
		    G_strncpy(s->str_att[i], sa->str[i], MAX_SITE_STRING);
	    }
	}

	return 0;
    }
}
Ejemplo n.º 9
0
int loadSiteCoordinates(struct Map_info *Map, struct Point **points, int region,
			struct Cell_head *window, int field, struct cat_list *cat_list)
{
    int i, pointIdx;
    struct line_pnts *sites;
    struct line_cats *cats;
    struct bound_box box;
    int type;

    sites = Vect_new_line_struct();
    cats = Vect_new_cats_struct();

    *points = NULL;
    pointIdx = 0;
    
    /* copy window to box */
    Vect_region_box(window, &box);

    while ((type = Vect_read_next_line(Map, sites, cats)) > -1) {

	if (type != GV_POINT && !(type & GV_LINES))
	    continue;

	if (field > 0 && !Vect_cats_in_constraint(cats, field, cat_list))
	    continue;
	
	for (i = 0; i < sites->n_points; i++) {
	    G_debug(4, "Point: %f|%f|%f", sites->x[i], sites->y[i],
		    sites->z[i]);
	    
	    if (region && !Vect_point_in_box(sites->x[i], sites->y[i], sites->z[i], &box))
		continue;
	    
	    G_debug(4, "Point in the box");

	    if ((pointIdx % ALLOC_CHUNK) == 0)
		*points = (struct Point *) G_realloc(*points,
						     (pointIdx + ALLOC_CHUNK) * sizeof(struct Point));
	    
	    (*points)[pointIdx].x = sites->x[i];
	    (*points)[pointIdx].y = sites->y[i];
	    (*points)[pointIdx].z = sites->z[i];
	    pointIdx++;
	}
    }

    if (pointIdx > 0)
	*points = (struct Point *)G_realloc(*points,
					    (pointIdx + 1) * sizeof(struct Point));
    
    return pointIdx;
}
Ejemplo n.º 10
0
/**
 * \brief Create network arcs (edge) based on given point vector map (nodes)
 *
 * \param file input file defining arcs
 * \param Points input vector point map
 * \param Out output vector map
 * \param afield arcs layer 
 * \param nfield nodes layer 
 *
 * \return number of new arcs
 */
int create_arcs(FILE * file, struct Map_info *Pnts,
		struct Map_info *Out, int afield, int nfield)
{
    char buff[1024];
    int lcat, fcat, tcat;
    int node1, node2;
    int narcs;

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

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

    narcs = 0;

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

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

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

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

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

	narcs++;
    }

    Vect_destroy_line_struct(points);
    Vect_destroy_cats_struct(cats);

    return narcs;
}
Ejemplo n.º 11
0
/*!
   \brief Get node cost

   For each node in the map, finds the category of the point on it (if
   there is any) and stores the value associated with this category in
   the array node_costs. If there is no point with a category,
   node_costs=0.

   node_costs are multiplied by 1000000 and truncated to integers (as
   is done in Vect_net_build_graph)

   \param In pointer to Map_info structure
   \param layer layer number
   \param column name of column
   \param[out] node_costs list of node costs

   \returns 1 on success
   \return 0 on failure
 */
int NetA_get_node_costs(struct Map_info *In, int layer, char *column,
			int *node_costs)
{
    int i, nlines, nnodes;
    dbCatValArray vals;
    struct line_cats *Cats;
    struct line_pnts *Points;

    dbDriver *driver;
    struct field_info *Fi;

    Fi = Vect_get_field(In, layer);
    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);

    nlines = Vect_get_num_lines(In);
    nnodes = Vect_get_num_nodes(In);
    Cats = Vect_new_cats_struct();
    Points = Vect_new_line_struct();
    for (i = 1; i <= nnodes; i++)
	node_costs[i] = 0;

    db_CatValArray_init(&vals);

    if (db_select_CatValArray(driver, Fi->table, Fi->key, column, NULL, &vals)
	== -1)
	return 0;
    for (i = 1; i <= nlines; i++) {
	int type = Vect_read_line(In, Points, Cats, i);

	if (type == GV_POINT) {
	    int node, cat;
	    double value;

	    if (!Vect_cat_get(Cats, layer, &cat))
		continue;
	    Vect_get_line_nodes(In, i, &node, NULL);
	    if (db_CatValArray_get_value_double(&vals, cat, &value) == DB_OK)
		node_costs[node] = value * 1000000.0;
	}
    }

    Vect_destroy_cats_struct(Cats);
    db_CatValArray_free(&vals);
    db_close_database_shutdown_driver(driver);
    return 1;
}
Ejemplo n.º 12
0
void scan_cats(const struct Map_info *Map, int field,
	       const char *style, const char *rules,
	       const struct FPRange *range, struct Colors *colors)
{
    int ltype, lmin, lmax, cmin, cmax;
    struct line_cats *Cats;

    cmin = cmax = -1;
    Cats = Vect_new_cats_struct();

    G_message(_("Reading features..."));
    while(TRUE) {
	ltype = Vect_read_next_line(Map, NULL, Cats);
	if (ltype == -1)
	    G_fatal_error(_("Unable to read vector map"));
	if (ltype == -2)
	    break; /* EOF */

	scan_layer(field, Cats, &lmin, &lmax);

	if (cmin == -1 || lmin <= cmin)
	    cmin = lmin;
	if (cmax == -1 || lmax >= cmax)
	    cmax = lmax;
    }

    if (range) {
	if (range->min >= cmin && range->min <= cmax)
	    cmin = range->min;
	else
	    G_warning(_("Min value (%d) is out of range %d,%d"),
		      (int) range->min, cmin, cmax);
	
	if (range->max <= cmax && range->max >= cmin)
	    cmax = range->max;
	else
	    G_warning(_("Max value (%d) is out of range %d,%d"),
		      (int) range->max, cmin, cmax);
    }

    if (style)
	make_colors(colors, style, (DCELL) cmin, (DCELL) cmax, FALSE);
    else if (rules) {
	load_colors(colors, rules, (DCELL) cmin, (DCELL) cmax, FALSE);
    }

    Vect_destroy_cats_struct(Cats);
}
Ejemplo n.º 13
0
Archivo: line.c Proyecto: caomw/grass
/*!
  \brief Fetches FIRST category number for given vector line and field
  
  \param Map pointer to Map_info structure
  \param line line id
  \param field layer number

  \return -1 no category
  \return category number (>=0)
 */
int Vect_get_line_cat(const struct Map_info *Map, int line, int field)
{

    static struct line_cats *cats = NULL;
    int cat, ltype;

    if (cats == NULL)
	cats = Vect_new_cats_struct();

    ltype = Vect_read_line(Map, NULL, cats, line);
    Vect_cat_get(cats, field, &cat);
    G_debug(3, "Vect_get_line_cat: display line %d, ltype %d, cat %d", line,
	    ltype, cat);

    return cat;
}
Ejemplo n.º 14
0
int rmdac(struct Map_info *Out, struct Map_info *Err)
{
    int i, type, area, ndupl, nlines;

    struct line_pnts *Points;
    struct line_cats *Cats;

    nlines = Vect_get_num_lines(Out);

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

    G_debug(1, "nlines =  %d", nlines);

    ndupl = 0;

    for (i = 1; i <= nlines; i++) {
	G_percent(i, nlines, 2);
	if (!Vect_line_alive(Out, i))
	    continue;

	type = Vect_read_line(Out, Points, Cats, i);
	if (!(type & GV_CENTROID))
	    continue;

	area = Vect_get_centroid_area(Out, i);
	G_debug(3, "  area = %d", area);

	if (area < 0) {
	    Vect_delete_line(Out, i);
	    ndupl++;

	    if (Err) {
		Vect_write_line(Err, type, Points, Cats);
	    }
	}
    }

    G_verbose_message(_("Duplicate area centroids: %d"), ndupl);

    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return ndupl;
}
Ejemplo n.º 15
0
int write_vect(double x1, double y1, double x2, double y2,
	       struct Map_info *Map, struct line_pnts *Points, int out_type)
{
    static struct line_cats *Cats = NULL;

    if (!Cats) {
	Cats = Vect_new_cats_struct();
    }

    xarray[0] = x1;
    xarray[1] = x2;
    yarray[0] = y1;
    yarray[1] = y2;

    if (0 > Vect_copy_xyz_to_pnts(Points, xarray, yarray, NULL, NUM_POINTS))
	G_fatal_error(_("Out of memory"));
    Vect_write_line(Map, out_type, Points, Cats);

    return 0;
}
Ejemplo n.º 16
0
int print_tree(struct multtree *tree,
	       double x_orig, double y_orig, struct Map_info *Map)
{
    double xarray[5], yarray[5], zarray[5];
    struct line_pnts *Points;
    struct line_cats *Cats;
    int j;
    int type = GV_LINE;

    if (tree == NULL)
	return 0;
    if (tree->data == NULL)
	return 0;
    if (tree->leafs != NULL) {
	for (j = 0; j < 4; j++) {
	    print_tree(tree->leafs[j], x_orig, y_orig, Map);
	}
    }
    else {
	Points = Vect_new_line_struct();
	Cats = Vect_new_cats_struct();
	xarray[0] = ((struct quaddata *)(tree->data))->x_orig + x_orig;
	yarray[0] = ((struct quaddata *)(tree->data))->y_orig + y_orig;
	xarray[1] = xarray[0];
	yarray[3] = yarray[0];
	xarray[3] = ((struct quaddata *)(tree->data))->xmax + x_orig;
	yarray[1] = ((struct quaddata *)(tree->data))->ymax + y_orig;
	yarray[2] = yarray[1];
	xarray[2] = xarray[3];
	yarray[4] = yarray[0];
	xarray[4] = xarray[0];
	if (Vect_copy_xyz_to_pnts(Points, xarray, yarray, zarray, 5) < 0) {
	    clean();
	    G_fatal_error(_("Out of memory"));
	}
	Vect_write_line(Map, (unsigned int)type, Points, Cats);

	G_free(Points);
    }
    return 1;
}
Ejemplo n.º 17
0
int move_line_begin(void *closure)
{
    struct move_line *ml = closure;

    G_debug(2, "move_line()");

    ml->Points = Vect_new_line_struct();
    ml->Cats = Vect_new_cats_struct();

    i_prompt(_("Move point, line, boundary, or centroid:"));
    i_prompt_buttons(_("Select"), "", _("Quit tool"));

    ml->thresh = get_thresh();
    G_debug(2, "thresh = %f", ml->thresh);

    ml->last_line = 0;

    set_mode(MOUSE_POINT);

    return 0;
}
Ejemplo n.º 18
0
/*
    Write a vector geometry to the output GRASS vector map.
    Write attributes to table linked to that map. Link vector object to attribute
    table record.
*/
void write_vect( int cat, int skelID, int boneID, int unitID,
		 double *xpnts, double *ypnts, double *zpnts, 
		 int arr_size, int type )
{
    struct line_cats *Cats;
    struct line_pnts *Points;
    char buf[MAXSTR];
    char rgbbuf[12];
    char rgbbuf2[12];
    

    /* copy xyzpnts to Points */
    Points = Vect_new_line_struct();
    Vect_copy_xyz_to_pnts(Points, xpnts, ypnts, zpnts, arr_size);

    /* write database attributes */
    Cats = Vect_new_cats_struct();
    sprintf ( rgbbuf, "%i:%i:%i", RGB[RGBNUM][0], RGB[RGBNUM][1], RGB[RGBNUM][2] );
    sprintf ( rgbbuf2, "%i:%i:%i", RGB[RGB_MAPPER_COLOUR[boneID-1]][0],RGB[RGB_MAPPER_COLOUR[boneID-1]][1], RGB[RGB_MAPPER_COLOUR[boneID-1]][2] );
    sprintf(buf, "insert into %s (cat, skel_id, bone_id, unit_id, GRASSRGB, BONERGB) values(%i,%i,%i,%i,'%s','%s');",
            Fi->table, cat, skelID, boneID, unitID, rgbbuf, rgbbuf2);

    if ( DEBUG ) {
        fprintf ( stderr, "Writing attribute: %s\n", buf );
    }

    db_set_string(&sql, buf);
    if (db_execute_immediate(driver, &sql) != DB_OK) {
	G_fatal_error(_("Unable to insert new record: %s"), db_get_string(&sql));
    }
    db_free_string(&sql);
 
    Vect_cat_set(Cats, 1, cat);

    /* write */
    Vect_write_line(Map, type, Points, Cats);

    Vect_destroy_cats_struct(Cats);
    Vect_destroy_line_struct(Points);
}
Ejemplo n.º 19
0
int new_line_begin(void *closure)
{
    struct new_line *nl = closure;
    char buf[1000];

    G_debug(2, "new_line(): type = %d", nl->type);

    nl->Points = Vect_new_line_struct();
    nl->Cats = Vect_new_cats_struct();

    sprintf(buf, _("Digitize new %s:"), get_line_type_name(nl->type));
    i_prompt(buf);
    i_prompt_buttons(_("New point"), "", _("Quit tool"));

    i_new_line_options(1);

    nl->first = 1;

    set_mode(MOUSE_POINT);

    return 0;
}
Ejemplo n.º 20
0
/** counts the number of individual segments ( boundaries and lines ) and vertices
*/
void count(struct Map_info *map, int *num_points, int *num_lines)
{
    int index_line = 0;
    int index_point = 0;
    struct line_pnts *sites;
    struct line_cats *cats;
    int type, i;

    sites = Vect_new_line_struct();
    cats = Vect_new_cats_struct();

    for (i = 1; i <= map->plus.n_lines; i++) {

	type = Vect_read_line(map, sites, cats, i);

	if (type != GV_LINE && type != GV_BOUNDARY && type != GV_POINT)
	    continue;

	if (type == GV_LINE) {
	    index_point += sites->n_points;
	    index_line += sites->n_points - 1;
	}
	else if (type == GV_BOUNDARY) {
	    index_point += sites->n_points - 1;
	    index_line += sites->n_points - 1;
	}
	else if (type == GV_POINT) {
	    index_point++;
	}


    }

    *num_points = index_point;
    *num_lines = index_line;

    Vect_destroy_line_struct(sites);
    Vect_destroy_cats_struct(cats);
}
Ejemplo n.º 21
0
Archivo: area.c Proyecto: caomw/grass
/*!
   \brief Find FIRST category of given field and area

   \param Map pointer to Map_info structure
   \param area area id
   \param field layer number

   \return first found category of given field
   \return -1 no centroid or no category found
 */
int Vect_get_area_cat(const struct Map_info *Map, int area, int field)
{
    int i;
    static struct line_cats *Cats = NULL;

    if (!Cats)
	Cats = Vect_new_cats_struct();
    else
	Vect_reset_cats(Cats);

    if (Vect_get_area_cats(Map, area, Cats) == 1 || Cats->n_cats == 0) {
	return -1;
    }

    for (i = 0; i < Cats->n_cats; i++) {
	if (Cats->field[i] == field) {
	    return Cats->cat[i];
	}
    }

    return -1;
}
Ejemplo n.º 22
0
int delete_line_begin(void *closure)
{
    struct delete_line *dl = closure;

    G_debug(2, "delete_line()");

    dl->Points = Vect_new_line_struct();
    dl->Cats = Vect_new_cats_struct();

    i_prompt(_("Delete point, line, boundary, or centroid:"));
    i_prompt_buttons(_("Select"), _("Unselect"), _("Quit tool"));

    dl->thresh = get_thresh();
    G_debug(2, "thresh = %f", dl->thresh);

    dl->line = 0;
    dl->first = 1;
    dl->last_line = 0;

    set_mode(MOUSE_POINT);

    return 0;
}
Ejemplo n.º 23
0
/** add the edge pq to the map out 
*/
void report(struct Point *p, struct Point *q, struct Map_info *out)
{
    struct line_pnts *sites;
    struct line_cats *cats;
    double *tmpx = G_malloc(2 * sizeof(double));
    double *tmpy = G_malloc(2 * sizeof(double));

    sites = Vect_new_line_struct();
    cats = Vect_new_cats_struct();

    tmpx[0] = p->x;
    tmpx[1] = q->x;
    tmpy[0] = p->y;
    tmpy[1] = q->y;

    Vect_copy_xyz_to_pnts(sites, tmpx, tmpy, 0, 2);
    Vect_write_line(out, GV_LINE, sites, cats);

    Vect_destroy_line_struct(sites);
    Vect_destroy_cats_struct(cats);
    G_free(tmpx);
    G_free(tmpy);
}
Ejemplo n.º 24
0
void edit_line_phase2(struct edit_line *el, double x, double y)
{
    int node1, node2;
    double nodex, nodey, nodez, dist;

    el->phase = 2;

    el->Points = Vect_new_line_struct();
    el->Cats = Vect_new_cats_struct();
    el->line_type = Vect_read_line(&Map, el->Points, el->Cats, el->line);

    el->reversed = 0;

    /* Find out the node nearest to the line */
    Vect_get_line_nodes(&Map, el->line, &node1, &node2);

    Vect_get_node_coor(&Map, node2, &nodex, &nodey, &nodez);
    dist = (x - nodex) * (x - nodex) + (y - nodey) * (y - nodey);

    Vect_get_node_coor(&Map, node1, &nodex, &nodey, &nodez);
    if ((x - nodex) * (x - nodex) + (y - nodey) * (y - nodey) < dist) {
	/* The first node is the nearest => reverse the line and remember
	 * doing so. */
	Vect_line_reverse(el->Points);
	el->reversed = 1;
    }

    display_node(node1, SYMB_BACKGROUND, 1);
    display_node(node2, SYMB_BACKGROUND, 1);
    i_prompt_buttons(_("New Point"), _("Undo Last Point"), _("Close line"));

    set_location(D_u_to_d_col(el->Points->x[el->Points->n_points - 1]),
		 D_u_to_d_row(el->Points->y[el->Points->n_points - 1])
	);
    set_mode(MOUSE_LINE);
}
Ejemplo n.º 25
0
int out_ep(struct Edge *e)
{
    static struct line_pnts *Points = NULL;
    static struct line_cats *Cats = NULL;

    if (!Points) {
	Points = Vect_new_line_struct();
	Cats = Vect_new_cats_struct();
    }

    if (!triangulate & plot)
	clip_line(e);
    if (!triangulate & !plot) {
	/*
	   fprintf (stdout,"e %d", e->edgenbr);
	   fprintf (stdout," %d ", e->ep[le] != (struct Site *)NULL ? e->ep[le]->sitenbr : -1);
	   fprintf (stdout,"%d\n", e->ep[re] != (struct Site *)NULL ? e->ep[re]->sitenbr : -1);
	 */

	write_ep(e);
    }

    return 0;
}
Ejemplo n.º 26
0
/* plot areas */
int PS_vareas_plot(struct Map_info *P_map, int vec)
{
    int na, area, ret;
    double e, w, n, s, aw, shift;
    double llx, lly, urx, ury, sc;
    char pat[50];
    struct line_cats *Cats;
    struct bound_box box;
    struct varray *Varray = NULL;
    PSCOLOR color;
    int centroid;

    /* rgbcol */
    dbCatValArray cvarr_rgb;

    fprintf(PS.fp, "1 setlinejoin\n");	/* set line join to round */

    Cats = Vect_new_cats_struct();

    /* Create vector array if required */
    if (vector.layer[vec].cats != NULL || vector.layer[vec].where != NULL) {
	Varray = Vect_new_varray(Vect_get_num_areas(P_map));
	if (vector.layer[vec].cats != NULL) {
	    ret =
		Vect_set_varray_from_cat_string(P_map,
						vector.layer[vec].field,
						vector.layer[vec].cats,
						GV_AREA, 1, Varray);
	}
	else {
	    ret = Vect_set_varray_from_db(P_map, vector.layer[vec].field,
					  vector.layer[vec].where, GV_AREA, 1,
					  Varray);
	}
	G_debug(3, "%d items selected for vector %d", ret, vec);
	if (ret == -1)
	    G_fatal_error(_("Cannot load data from table"));
    }

    /* load attributes if rgbcol used */
    if (vector.layer[vec].rgbcol != NULL) {
	load_catval_array_rgb(P_map, vec, &cvarr_rgb);
    }

    shift = 0;
    /* read and plot areas */
    na = Vect_get_num_areas(P_map);
    for (area = 1; area <= na; area++) {
	G_debug(4, "area = %d", area);

	if (Varray != NULL && Varray->c[area] == 0)
	    continue;		/* is not in array */

	if (!Vect_area_alive(P_map, area))
	    continue;

	centroid = Vect_get_area_centroid(P_map, area);
	G_debug(4, "centroid = %d", centroid);
	if (centroid < 1)  /* area is an island */
	    continue;

	Vect_get_area_box(P_map, area, &box);
	n = box.N;
	s = box.S;
	e = box.E;
	w = box.W;
	if (PS.w.proj == PROJECTION_LL) {
	    aw = G_adjust_easting(w, &PS.w);
	    if (aw > PS.w.east)
		aw -= 360.0;
	    shift = aw - w;
	    e += shift;
	    w += shift;
	}
	/* check if in window */
	if (n < PS.w.south || s > PS.w.north || e < PS.w.west ||
	    w > PS.w.east)
	    continue;

	fprintf(PS.fp, "NP\n");
	if (PS.w.proj == PROJECTION_LL) {
	    /* plot area while in window */
	    while (e > PS.w.west) {
		ret = plot_area(P_map, area, shift);
		if (ret != 1)
		    return 0;
		shift -= 360.0;
		e -= 360.0;
	    }
	}
	else {
	    ret = plot_area(P_map, area, shift);
	    if (ret != 1)
		return 0;
	}

	if (vector.layer[vec].pat != NULL ||
	    (!color_none(&vector.layer[vec].fcolor) ||
	     vector.layer[vec].rgbcol != NULL)) {

	    if (vector.layer[vec].rgbcol != NULL) {
		/* load fill color from rgbcol */
		/* if data column is empty or cat is missing don't fill */
		if (get_ps_color_rgbcol_varea(P_map, vec, area, &cvarr_rgb, &color) != 1)
		    return 0;
	    }
	    else {
		color = vector.layer[vec].fcolor;
	    }

	    if (vector.layer[vec].pat != NULL) {	/* use pattern */
		sc = vector.layer[vec].scale;
		/* DEBUG */
		/*
		   printf("\n eps pattern = %s\n", vector.layer[vec].eps);
		   printf("       scale = %f\n", vector.layer[vec].scale);
		 */
		/* load pattern */
		eps_bbox(vector.layer[vec].pat, &llx, &lly, &urx, &ury);
		sprintf(pat, "APATTEPS%d", vec);
		pat_save(PS.fp, vector.layer[vec].pat, pat);
		fprintf(PS.fp,
			"<<  /PatternType 1\n    /PaintType 1\n    /TilingType 1\n");
		fprintf(PS.fp, "    /BBox [%f %f %f %f]\n", llx * sc,
			lly * sc, urx * sc, ury * sc);
		fprintf(PS.fp, "    /XStep %f\n    /YStep %f\n",
			(urx - llx) * sc, (ury - lly) * sc);
		fprintf(PS.fp, "    /PaintProc\n      { begin\n");
		fprintf(PS.fp, "        %f %f scale\n", sc, sc);

		set_ps_color(&color);

		fprintf(PS.fp, "        %.8f W\n", vector.layer[vec].pwidth);
		fprintf(PS.fp, "        %s\n", pat);
		fprintf(PS.fp, "        end\n");
		fprintf(PS.fp, "      } bind\n>>\n");
		sprintf(pat, "APATT%d", vec);
		fprintf(PS.fp, " matrix\n makepattern /%s exch def\n", pat);
		fprintf(PS.fp, "/Pattern setcolorspace\n %s setcolor\n", pat);
	    }
	    else {
		set_ps_color(&color);
	    }

	    fprintf(PS.fp, "F\n");
	}
	if (vector.layer[vec].width > 0 &&
	    !(color_none(&vector.layer[vec].color))) {
	    fprintf(PS.fp, "%.8f W\n", vector.layer[vec].width);
	    set_ps_color(&(vector.layer[vec].color));
	    fprintf(PS.fp, "stroke\n");
	}
    }
    fprintf(PS.fp, "\n");
    fprintf(PS.fp, "0 setlinejoin\n");	/* reset line join to miter */
    return 1;
}
Ejemplo n.º 27
0
/* merge a given line with all other lines of the same type and 
 * with the same categories */
static int merge_line(struct Map_info *Map, int line,
		      struct line_pnts *MPoints, struct line_cats *MCats)
{
    int nlines, i, first, last, next_line, curr_line;
    int merged = 0, newl = 0;
    int next_node, direction, node_n_lines, type, ltype, lines_type;
    static struct ilist *List = NULL;
    static struct line_pnts *Points = NULL;
    static struct line_cats *Cats = NULL;
    type = GV_LINE;

    nlines = Vect_get_num_lines(Map);

    if (!Points)
	Points = Vect_new_line_struct();
    if (!Cats)
	Cats = Vect_new_cats_struct();
    if (!List)
	List = Vect_new_list();

    Vect_reset_line(Points);
    Vect_reset_cats(Cats);
    Vect_reset_cats(MCats);
    Vect_reset_list(List);

    if (!Vect_line_alive(Map, line))
	return 0;

    ltype = Vect_get_line_type(Map, line);

    if (!(ltype & type))
	return 0;
	
    Vect_read_line(Map, MPoints, MCats, line);

    /* special cases:
     *  - loop back to start boundary via several other boundaries
     *  - one boundary forming closed loop
     *  - node with 3 entries but only 2 boundaries, one of them connecting twice,
     *    the other one must then be topologically incorrect in case of boundary */

    /* go backward as long as there is only one other line/boundary at the current node */
    G_debug(3, "go backward");
    Vect_get_line_nodes(Map, line, &next_node, NULL);

    first = -line;
    while (1) {
	node_n_lines = Vect_get_node_n_lines(Map, next_node);
	/* count lines/boundaries at this node */
	lines_type = 0;
	next_line = first;
	for (i = 0; i < node_n_lines; i++) {
	    curr_line = Vect_get_node_line(Map, next_node, i);
	    if ((Vect_get_line_type(Map, abs(curr_line)) & GV_LINES))
		lines_type++;
	    if ((Vect_get_line_type(Map, abs(curr_line)) == ltype)) {
		if (abs(curr_line) != abs(first)) {
		    Vect_read_line(Map, NULL, Cats, abs(curr_line));
		    
		    /* catgories must be identical */
		    if (compare_cats(MCats, Cats) == 0)
			next_line = curr_line;
		}
	    }
	}
	if (lines_type == 2 && abs(next_line) != abs(first) &&
	    abs(next_line) != line) {
	    first = next_line;

	    if (first < 0) {
		Vect_get_line_nodes(Map, -first, &next_node, NULL);
	    }
	    else {
		Vect_get_line_nodes(Map, first, NULL, &next_node);
	    }
	}
	else
	    break;
    }

    /* go forward as long as there is only one other line/boundary at the current node */
    G_debug(3, "go forward");

    /* reverse direction */
    last = -first;

    if (last < 0) {
	Vect_get_line_nodes(Map, -last, &next_node, NULL);
    }
    else {
	Vect_get_line_nodes(Map, last, NULL, &next_node);
    }

    Vect_reset_list(List);
    while (1) {
	G_ilist_add(List, last);
	node_n_lines = Vect_get_node_n_lines(Map, next_node);
	lines_type = 0;
	next_line = last;
	for (i = 0; i < node_n_lines; i++) {
	    curr_line = Vect_get_node_line(Map, next_node, i);
	    if ((Vect_get_line_type(Map, abs(curr_line)) & GV_LINES))
		lines_type++;
	    if ((Vect_get_line_type(Map, abs(curr_line)) == ltype)) {
		if (abs(curr_line) != abs(last)) {
		    Vect_read_line(Map, NULL, Cats, abs(curr_line));
		    
		    if (compare_cats(MCats, Cats) == 0)
			next_line = curr_line;
		}
	    }
	}

	if (lines_type == 2 && abs(next_line) != abs(last) &&
	    abs(next_line) != abs(first)) {
	    last = next_line;

	    if (last < 0) {
		Vect_get_line_nodes(Map, -last, &next_node, NULL);
	    }
	    else {
		Vect_get_line_nodes(Map, last, NULL, &next_node);
	    }
	}
	else
	    break;
    }

    /* merge lines */
    G_debug(3, "merge %d lines", List->n_values);
    Vect_reset_line(MPoints);

    for (i = 0; i < List->n_values; i++) {
	Vect_reset_line(Points);
	Vect_read_line(Map, Points, Cats, abs(List->value[i]));
	direction = (List->value[i] < 0 ? GV_BACKWARD : GV_FORWARD);
	Vect_append_points(MPoints, Points, direction);
	MPoints->n_points--;
	Vect_delete_line(Map, abs(List->value[i]));
    }
    MPoints->n_points++;
    merged += List->n_values;
    newl++;

    return merged;
}
Ejemplo n.º 28
0
int line_area(struct Map_info *In, int *field, struct Map_info *Tmp,
	      struct Map_info *Out, struct field_info *Fi,
	      dbDriver * driver, int operator, int *ofield,
	      ATTRIBUTES * attr, struct ilist *BList)
{
    int line, nlines, ncat;
    struct line_pnts *Points;
    struct line_cats *Cats, *ACats, *OCats;

    char buf[1000];
    dbString stmt;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    ACats = Vect_new_cats_struct();
    OCats = Vect_new_cats_struct();
    db_init_string(&stmt);

    G_message(_("Breaking lines..."));
    Vect_break_lines_list(Tmp, NULL, BList, GV_LINE | GV_BOUNDARY, NULL);

    /*
    G_message(_("Merging lines..."));
    Vect_merge_lines(Tmp, GV_LINE, NULL, NULL);
    */

    nlines = Vect_get_num_lines(Tmp);

    /* Warning!: cleaning process (break) creates new vertices which are usually slightly 
     * moved (RE), to compare such new vertex with original input is a problem?
     * 
     * TODO?: would it be better to copy centroids also and query output map? 
     */

    /* Check if the line is inside or outside binput area */
    G_message(_("Selecting lines..."));
    ncat = 1;
    for (line = 1; line <= nlines; line++) {
	int ltype;

	G_percent(line, nlines, 1);	/* must be before any continue */

	if (!Vect_line_alive(Tmp, line))
	    continue;

	ltype = Vect_get_line_type(Tmp, line);

	if (ltype == GV_BOUNDARY) {	/* No more needed */
	    continue;
	}

	/* Now the type should be only GV_LINE */

	/* Decide if the line is inside or outside the area. In theory:
	 * 1) All vertices outside
	 *      - easy, first vertex must be outside
	 * 2) All vertices inside 
	 * 3) All vertices on the boundary, we take it as inside (attention, 
	 *    result of Vect_point_in_area() for points on segments between vertices may be both
	 *    inside or outside, because of representation of numbers)
	 * 4) One or two end vertices on the boundary, all others outside
	 * 5) One or two end vertices on the boundary, all others inside 
	 *
	 */

	/* Note/TODO: the test done is quite simple, check the point in the middle of segment.
	 * If the line overlaps the boundary, the result may be both outside and inside
	 * this should be solved (check angles?)
	 * This should not happen if Vect_break_lines_list() works correctly
	 */

	/* merge here */
	merge_line(Tmp, line, Points, Cats);

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

	point_area(&(In[1]), field[1], (Points->x[0] + Points->x[1]) / 2,
		   (Points->y[0] + Points->y[1]) / 2, ACats);

	if ((ACats->n_cats > 0 && operator == OP_AND) ||
	    (ACats->n_cats == 0 && operator == OP_NOT)) {
	    int i;

	    /* Point is inside */
	    G_debug(3, "OK, write line, line ncats = %d area ncats = %d",
		    Cats->n_cats, ACats->n_cats);

	    Vect_reset_cats(OCats);

	    if (ofield[0]  > 0) {
		/* rewrite with all combinations of acat - bcat (-1 in cycle for null) */
		for (i = -1; i < Cats->n_cats; i++) {	/* line cats */
		    int j;

		    if (i == -1 && Cats->n_cats > 0)
			continue;	/* no need to make null */

		    for (j = -1; j < ACats->n_cats; j++) {
			if (j == -1 && ACats->n_cats > 0)
			    continue;	/* no need to make null */

			if (ofield[0] > 0)
			    Vect_cat_set(OCats, ofield[0], ncat);

			/* Attributes */
			if (driver) {
			    ATTR *at;

			    sprintf(buf, "insert into %s values ( %d", Fi->table,
				    ncat);
			    db_set_string(&stmt, buf);

			    /* cata */
			    if (i >= 0) {
				if (attr[0].columns) {
				    at = find_attr(&(attr[0]), Cats->cat[i]);
				    if (!at)
					G_fatal_error(_("Attribute not found"));

				    if (at->values)
					db_append_string(&stmt, at->values);
				    else
					db_append_string(&stmt,
							 attr[0].null_values);
				}
				else {
				    sprintf(buf, ", %d", Cats->cat[i]);
				    db_append_string(&stmt, buf);
				}
			    }
			    else {
				if (attr[0].columns) {
				    db_append_string(&stmt, attr[0].null_values);
				}
				else {
				    sprintf(buf, ", null");
				    db_append_string(&stmt, buf);
				}
			    }

			    /* catb */
			    if (j >= 0) {
				if (attr[1].columns) {
				    at = find_attr(&(attr[1]), ACats->cat[j]);
				    if (!at)
					G_fatal_error(_("Attribute not found"));

				    if (at->values)
					db_append_string(&stmt, at->values);
				    else
					db_append_string(&stmt,
							 attr[1].null_values);
				}
				else {
				    sprintf(buf, ", %d", ACats->cat[j]);
				    db_append_string(&stmt, buf);
				}
			    }
			    else {
				if (attr[1].columns) {
				    db_append_string(&stmt, attr[1].null_values);
				}
				else {
				    sprintf(buf, ", null");
				    db_append_string(&stmt, buf);
				}
			    }

			    db_append_string(&stmt, " )");

			    G_debug(3, "%s", db_get_string(&stmt));

			    if (db_execute_immediate(driver, &stmt) != DB_OK)
				G_warning(_("Unable to insert new record: '%s'"),
					  db_get_string(&stmt));
			}

			ncat++;
		    }
		}
	    }

	    /* Add cats from input vectors */
	    if (ofield[1] > 0 && field[0] > 0) {
		for (i = 0; i < Cats->n_cats; i++) {
		    if (Cats->field[i] == field[0])
			Vect_cat_set(OCats, ofield[1], Cats->cat[i]);
		}
	    }

	    if (ofield[2] > 0 && field[1] > 0 && ofield[1] != ofield[2]) {
		for (i = 0; i < ACats->n_cats; i++) {
		    if (ACats->field[i] == field[1])
			Vect_cat_set(OCats, ofield[2], ACats->cat[i]);
		}
	    }

	    Vect_write_line(Out, ltype, Points, OCats);
	}
    }

    return 0;
}
Ejemplo n.º 29
0
Archivo: main.c Proyecto: 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);
}
Ejemplo n.º 30
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *map_opt, *type_opt, *field_opt, *col_opt, *where_opt,
	*percentile;
    struct Flag *shell_flag, *extended;
    struct Map_info Map;
    struct field_info *Fi;
    dbDriver *Driver;
    dbCatValArray Cvarr;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int otype, ofield;
    int compatible = 1;		/* types are compatible: point+centroid or line+boundary or area */
    int nrec, ctype, nlines, line, nareas, area;
    int nmissing = 0;		/* number of missing atttributes */
    int nnull = 0;		/* number of null values */
    int first = 1;

    /* Statistics */
    int count = 0;		/* number of features with non-null attribute */
    double sum = 0.0;
    double sumsq = 0.0;
    double sumcb = 0.0;
    double sumqt = 0.0;
    double sum_abs = 0.0;
    double min = 0.0 / 0.0;	/* init as nan */
    double max = 0.0 / 0.0;
    double mean, mean_abs, pop_variance, sample_variance, pop_stdev,
	sample_stdev, pop_coeff_variation, kurtosis, skewness;
    double total_size = 0.0;	/* total size: length/area */

    /* Extended statistics */
    int perc;

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("statistics"));
    module->label =
	_("Calculates univariate statistics for attribute.");
    module->description = _("Variance and standard "
			    "deviation is calculated only for points if specified.");

    map_opt = G_define_standard_option(G_OPT_V_MAP);

    field_opt = G_define_standard_option(G_OPT_V_FIELD);

    type_opt = G_define_standard_option(G_OPT_V_TYPE);
    type_opt->options = "point,line,boundary,centroid,area";

    col_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    col_opt->required = YES;

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);

    percentile = G_define_option();
    percentile->key = "percentile";
    percentile->type = TYPE_INTEGER;
    percentile->required = NO;
    percentile->options = "0-100";
    percentile->answer = "90";
    percentile->description =
	_("Percentile to calculate (requires extended statistics flag)");

    shell_flag = G_define_flag();
    shell_flag->key = 'g';
    shell_flag->description = _("Print the stats in shell script style");

    extended = G_define_flag();
    extended->key = 'e';
    extended->description = _("Calculate extended statistics");

    G_gisinit(argv[0]);

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

    otype = Vect_option_to_types(type_opt);
    perc = atoi(percentile->answer);

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

    /* open input vector */
    Vect_set_open_level(2);
    Vect_open_old2(&Map, map_opt->answer, "", field_opt->answer);
    ofield = Vect_get_field_number(&Map, field_opt->answer);

    /* Check if types are compatible */
    if ((otype & GV_POINTS) && ((otype & GV_LINES) || (otype & GV_AREA)))
	compatible = 0;
    if ((otype & GV_LINES) && (otype & GV_AREA))
	compatible = 0;

    if (!compatible) {
	G_warning(_("Incompatible vector type(s) specified, only number of features, minimum, maximum and range "
		   "can be calculated"));
    }

    if (extended->answer && !(otype & GV_POINTS)) {
	G_warning(_("Extended statistics is currently supported only for points/centroids"));
    }

    /* Read attributes */
    db_CatValArray_init(&Cvarr);
    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);

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

    nrec =
	db_select_CatValArray(Driver, Fi->table, Fi->key, col_opt->answer,
			      where_opt->answer, &Cvarr);
    G_debug(2, "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"));

    db_close_database_shutdown_driver(Driver);

    /* Lines */
    nlines = Vect_get_num_lines(&Map);

    for (line = 1; line <= nlines; line++) {
	int i, type;

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

	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;
		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 {	/* GV_LINES */
			double l;

			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;
		    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;

			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);

    if (compatible) {
	if ((otype & GV_LINES) || (otype & GV_AREA)) {
	    mean = sum / total_size;
	    mean_abs = sum_abs / total_size;
	    /* Roger Bivand says it is wrong see GRASS devel list 7/2004 */
	    /*
	       pop_variance = (sumsq - sum*sum/total_size)/total_size;
	       pop_stdev = sqrt(pop_variance);
	     */
	}
	else {
	    double n = count;

	    mean = sum / count;
	    mean_abs = sum_abs / count;
	    pop_variance = (sumsq - sum * sum / count) / count;
	    pop_stdev = sqrt(pop_variance);
	    pop_coeff_variation = pop_stdev / (sqrt(sum * sum) / count);
	    sample_variance = (sumsq - sum * sum / count) / (count - 1);
	    sample_stdev = sqrt(sample_variance);
	    kurtosis =
		(sumqt / count - 4 * sum * sumcb / (n * n) +
		 6 * sum * sum * sumsq / (n * n * n) -
		 3 * sum * sum * sum * sum / (n * n * n * n))
		/ (sample_stdev * sample_stdev * sample_stdev *
		   sample_stdev) - 3;
	    skewness =
		(sumcb / n - 3 * sum * sumsq / (n * n) +
		 2 * sum * sum * sum / (n * n * n))
		/ (sample_stdev * sample_stdev * sample_stdev);
	}
    }

    G_debug(3, "otype %d:", otype);

    if (shell_flag->answer) {
	fprintf(stdout, "n=%d\n", count);
	fprintf(stdout, "nmissing=%d\n", nmissing);
	fprintf(stdout, "nnull=%d\n", nnull);
	if (count > 0) {
	    fprintf(stdout, "min=%g\n", min);
	    fprintf(stdout, "max=%g\n", max);
	    fprintf(stdout, "range=%g\n", max - min);
	    if (compatible && (otype & GV_POINTS)) {
		fprintf(stdout, "mean=%g\n", mean);
		fprintf(stdout, "mean_abs=%g\n", mean_abs);
		fprintf(stdout, "population_stddev=%g\n", pop_stdev);
		fprintf(stdout, "population_variance=%g\n", pop_variance);
		fprintf(stdout, "population_coeff_variation=%g\n",
			pop_coeff_variation);
		if (otype & GV_POINTS) {
		    fprintf(stdout, "sample_stddev=%g\n", sample_stdev);
		    fprintf(stdout, "sample_variance=%g\n", sample_variance);
		    fprintf(stdout, "kurtosis=%g\n", kurtosis);
		    fprintf(stdout, "skewness=%g\n", skewness);
		}
	    }
	}
    }
    else {
	fprintf(stdout, "number of features with non NULL attribute: %d\n",
		count);
	fprintf(stdout, "number of missing attributes: %d\n", nmissing);
	fprintf(stdout, "number of NULL attributes: %d\n", nnull);
	if (count > 0) {
	    fprintf(stdout, "minimum: %g\n", min);
	    fprintf(stdout, "maximum: %g\n", max);
	    fprintf(stdout, "range: %g\n", max - min);
	    if (compatible && (otype & GV_POINTS)) {
		fprintf(stdout, "mean: %g\n", mean);
		fprintf(stdout, "mean of absolute values: %g\n", mean_abs);
		fprintf(stdout, "population standard deviation: %g\n",
			pop_stdev);
		fprintf(stdout, "population variance: %g\n", pop_variance);
		fprintf(stdout, "population coefficient of variation: %g\n",
			pop_coeff_variation);
		if (otype & GV_POINTS) {
		    fprintf(stdout, "sample standard deviation: %g\n",
			    sample_stdev);
		    fprintf(stdout, "sample variance: %g\n", sample_variance);
		    fprintf(stdout, "kurtosis: %g\n", kurtosis);
		    fprintf(stdout, "skewness: %g\n", skewness);
		}
	    }
	}
    }

    /* TODO: mode, skewness, kurtosis */
    if (extended->answer && compatible && (otype & GV_POINTS) && count > 0) {
	double quartile_25 = 0.0, quartile_75 = 0.0, quartile_perc = 0.0;
	double median = 0.0;
	int qpos_25, qpos_75, qpos_perc;

	qpos_25 = (int)(count * 0.25 - 0.5);
	qpos_75 = (int)(count * 0.75 - 0.5);
	qpos_perc = (int)(count * perc / 100. - 0.5);

	if (db_CatValArray_sort_by_value(&Cvarr) != DB_OK)
	    G_fatal_error(_("Cannot sort the key/value array"));

	if (Cvarr.ctype == DB_C_TYPE_INT) {
	    quartile_25 = (Cvarr.value[qpos_25]).val.i;
	    if (count % 2)	/* odd */
		median = (Cvarr.value[(int)(count / 2)]).val.i;
	    else		/* even */
		median =
		    ((Cvarr.value[count / 2 - 1]).val.i +
		     (Cvarr.value[count / 2]).val.i) / 2.0;
	    quartile_75 = (Cvarr.value[qpos_75]).val.i;
	    quartile_perc = (Cvarr.value[qpos_perc]).val.i;
	}
	else {			/* must be DB_C_TYPE_DOUBLE */
	    quartile_25 = (Cvarr.value[qpos_25]).val.d;
	    if (count % 2)	/* odd */
		median = (Cvarr.value[(int)(count / 2)]).val.d;
	    else		/* even */
		median =
		    ((Cvarr.value[count / 2 - 1]).val.d +
		     (Cvarr.value[count / 2]).val.d) / 2.0;
	    quartile_75 = (Cvarr.value[qpos_75]).val.d;
	    quartile_perc = (Cvarr.value[qpos_perc]).val.d;
	}

	if (shell_flag->answer) {
	    fprintf(stdout, "first_quartile=%g\n", quartile_25);
	    fprintf(stdout, "median=%g\n", median);
	    fprintf(stdout, "third_quartile=%g\n", quartile_75);
	    fprintf(stdout, "percentile_%d=%g\n", perc, quartile_perc);
	}
	else {
	    fprintf(stdout, "1st quartile: %g\n", quartile_25);
	    if (count % 2)
		fprintf(stdout, "median (odd number of cells): %g\n", median);
	    else
		fprintf(stdout, "median (even number of cells): %g\n",
			median);
	    fprintf(stdout, "3rd quartile: %g\n", quartile_75);

	    if (perc % 10 == 1 && perc != 11)
		fprintf(stdout, "%dst percentile: %g\n", perc, quartile_perc);
	    else if (perc % 10 == 2 && perc != 12)
		fprintf(stdout, "%dnd percentile: %g\n", perc, quartile_perc);
	    else if (perc % 10 == 3 && perc != 13)
		fprintf(stdout, "%drd percentile: %g\n", perc, quartile_perc);
	    else
		fprintf(stdout, "%dth percentile: %g\n", perc, quartile_perc);
	}
    }

    Vect_close(&Map);

    exit(EXIT_SUCCESS);
}