Example #1
0
/*!
  \brief Writes feature on level 2

  \param Map pointer to Map_info structure
  \param type feature type
  \param points pointer to line_pnts structure (feature geometry)
  \param cats pointer to line_cats structure (feature categories)

  \return feature offset into file
  \return -1 on error
*/
off_t V2_write_line_ogr(struct Map_info *Map, int type,
                        const struct line_pnts *points, const struct line_cats *cats)
{
    int line;
    off_t offset;
    struct Plus_head *plus;
    struct bound_box box;

    line = 0;

    G_debug(3, "V2_write_line_ogr()");

    offset = V1_write_line_ogr(Map, type, points, cats);
    if (offset < 0)
        return -1;

    /* Update topology */
    plus = &(Map->plus);
    /* Add line */
    if (plus->built >= GV_BUILD_BASE) {
        dig_line_box(points, &box);
        line = dig_add_line(plus, type, points, &box, offset);
        G_debug(3, "  line added to topo with id = %d", line);
        if (line == 1)
            Vect_box_copy(&(plus->box), &box);
        else
            Vect_box_extend(&(plus->box), &box);

        V2__add_line_to_topo_ogr(Map, line, points, cats);
    }


    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
            plus->n_upnodes);

    /* returns int line, but is defined as off_t for compatibility with
     * Write_line_array in write.c */

    return line;

}
Example #2
0
/* code taken from Vect_build_nat() */
int level_one_info(struct Map_info *Map)
{
    struct Plus_head *plus;
    int i, type, first = 1;
    off_t offset;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct bound_box box;

    int n_primitives, n_points, n_lines, n_boundaries, n_centroids;
    int n_faces, n_kernels;

    G_debug(1, "Count vector objects for level 1");

    plus = &(Map->plus);

    n_primitives = n_points = n_lines = n_boundaries = n_centroids = 0;
    n_faces = n_kernels = 0;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    
    Vect_rewind(Map);
    /* G_message(_("Registering primitives...")); */
    i = 1;
    while (1) {
	/* register line */
	type = Vect_read_next_line(Map, Points, Cats);

	/* Note: check for dead lines is not needed, because they are skipped by V1_read_next_line_nat() */
	if (type == -1) {
	    G_warning(_("Unable to read vector map"));
	    return 0;
	}
	else if (type == -2) {
	    break;
	}

	/* count features */
	n_primitives++;
	
	if (type & GV_POINT)  /* probably most common */
	    n_points++;
	else if (type & GV_LINE)
	    n_lines++;
	else if (type & GV_BOUNDARY)
	    n_boundaries++;
	else if (type & GV_CENTROID)
	    n_centroids++;
	else if (type & GV_KERNEL)
	    n_kernels++;
	else if (type & GV_FACE)
	    n_faces++;

	offset = Map->head.last_offset;

	G_debug(3, "Register line: offset = %lu", (unsigned long)offset);
	dig_line_box(Points, &box);
	if (first == 1) {
	    Vect_box_copy(&(plus->box), &box);
	    first = 0;
	}
	else
	    Vect_box_extend(&(plus->box), &box);

	/* can't print progress, unfortunately */
/*
	if (G_verbose() > G_verbose_min() && i % 1000 == 0) {
	    if (format == G_INFO_FORMAT_PLAIN)
		fprintf(stderr, "%d..", i);
	    else
		fprintf(stderr, "%11d\b\b\b\b\b\b\b\b\b\b\b", i);
	}
	i++;
*/
    }

    /* save result in plus */
    plus->n_lines = n_primitives;
    plus->n_plines = n_points;
    plus->n_llines = n_lines;
    plus->n_blines = n_boundaries;
    plus->n_clines = n_centroids;
    plus->n_klines = n_kernels;
    plus->n_flines = n_faces;

    return 1;
}
Example #3
0
/*!
   \brief Build area on given side of line (GV_LEFT or GV_RIGHT)

   \param Map pointer to Map_info structure
   \param iline line id
   \param side side (GV_LEFT or GV_RIGHT)

   \return > 0 area id
   \return < 0 isle id
   \return 0 not created (may also already exist)
 */
int Vect_build_line_area(struct Map_info *Map, int iline, int side)
{
    int area, isle, n_lines;

    struct Plus_head *plus;
    struct bound_box box;
    static struct line_pnts *APoints = NULL;
    plus_t *lines;
    double area_size;

    plus = &(Map->plus);

    G_debug(3, "Vect_build_line_area() line = %d, side = %d", iline, side);

    if (!APoints)
	APoints = Vect_new_line_struct();
    
    /* get area */
    area = dig_line_get_area(plus, iline, side);
    if (area != 0) {
        /* -> there is already an area on this side of the line, skip */
        G_debug(3, "  area/isle = %d -> skip", area);
        return 0;
    }
    
    /* build an area with this line */
    n_lines = dig_build_area_with_line(plus, iline, side, &lines);
    G_debug(3, "  n_lines = %d", n_lines);
    if (n_lines < 1) {
	return 0;
    }				/* area was not built */

    /* get line points which forms a boundary of an area */
    Vect__get_area_points(Map, lines, n_lines, APoints);
    dig_line_box(APoints, &box);

    Vect_line_prune(APoints);
    if (APoints->n_points < 4) {
	G_warning(_("Area of size = 0.0 (less than 4 vertices) ignored"));
	return 0;
    }

    /* Area or island ? */
    dig_find_area_poly(APoints, &area_size);

    /* area_size = dig_find_poly_orientation(APoints); */
    /* area_size is not real area size, we are only interested in the sign */

    G_debug(3, "  area/isle size = %f", area_size);

    if (area_size > 0) {	/* CW: area */
	/* add area structure to plus */
	area = dig_add_area(plus, n_lines, lines, &box);
	if (area == -1) {	/* error */
	    G_fatal_error(_("Unable to add area (map closed, topo saved)"));
	}
	G_debug(3, "  -> area %d", area);
	return area;
    }
    else if (area_size < 0) {	/* CCW: island */
	isle = dig_add_isle(plus, n_lines, lines, &box);
	if (isle == -1) {	/* error */
	    G_fatal_error(_("Unable to add isle (map closed, topo saved)"));
	}
	G_debug(3, "  -> isle %d", isle);
	return -isle;
    }
    else {
	/* TODO: What to do with such areas? Should be areas/isles of size 0 stored,
	 *        so that may be found and cleaned by some utility
	 *  Note: it would be useful for vertical closed polygons, but such would be added twice
	 *        as area */
	G_warning(_("Area of size = 0.0 ignored"));
    }
    return 0;
}
Example #4
0
/*!
   \brief Build topology 

   \param Map vector map
   \param build build level

   \return 1 on success
   \return 0 on error
 */
int Vect_build_nat(struct Map_info *Map, int build)
{
    struct Plus_head *plus;
    int i, s, type, line;
    off_t offset;
    int side, area;
    struct line_cats *Cats;
    struct P_line *Line;
    struct P_area *Area;
    struct bound_box box;
    
    G_debug(3, "Vect_build_nat() build = %d", build);

    plus = &(Map->plus);

    if (build == plus->built)
	return 1;		/* Do nothing */

    /* Check if upgrade or downgrade */
    if (build < plus->built) {
        /* -> downgrade */
	Vect__build_downgrade(Map, build);
        return 1;
    }

    /* -> upgrade */
    if (!Points)
        Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    
    if (plus->built < GV_BUILD_BASE) {
        int npoints, c;
        
	/* 
	 *  We shall go through all primitives in coor file and add
	 *  new node for each end point to nodes structure if the node
	 *  with the same coordinates doesn't exist yet.
	 */

	/* register lines, create nodes */
	Vect_rewind(Map);
	G_message(_("Registering primitives..."));
	i = 0;
	npoints = 0;
	while (TRUE) {
	    /* register line */
	    type = Vect_read_next_line(Map, Points, Cats);

	    /* Note: check for dead lines is not needed, because they
               are skipped by V1_read_next_line() */
	    if (type == -1) {
		G_warning(_("Unable to read vector map"));
		return 0;
	    }
	    else if (type == -2) {
		break;
	    }

	    G_progress(++i, 1e4);
	    
	    npoints += Points->n_points;

	    offset = Map->head.last_offset;

	    G_debug(3, "Register line: offset = %lu", (unsigned long)offset);
	    dig_line_box(Points, &box);
	    line = dig_add_line(plus, type, Points, &box, offset);
	    if (line == 1)
		Vect_box_copy(&(plus->box), &box);
	    else
		Vect_box_extend(&(plus->box), &box);

	    /* Add all categories to category index */
	    if (build == GV_BUILD_ALL) {
		for (c = 0; c < Cats->n_cats; c++) {
		    dig_cidx_add_cat(plus, Cats->field[c], Cats->cat[c],
				     line, type);
		}
		if (Cats->n_cats == 0)	/* add field 0, cat 0 */
		    dig_cidx_add_cat(plus, 0, 0, line, type);
	    }
	}
	G_progress(1, 1);

	G_message(_n("One primitive registered", "%d primitives registered", plus->n_lines), plus->n_lines);
	G_message(_n("One vertex registered", "%d vertices registered", npoints), npoints);

	plus->built = GV_BUILD_BASE;
    }

    if (build < GV_BUILD_AREAS)
	return 1;

    if (plus->built < GV_BUILD_AREAS) {
	/* Build areas */
	/* Go through all bundaries and try to build area for both sides */
	G_important_message(_("Building areas..."));
	for (line = 1; line <= plus->n_lines; line++) {
	    G_percent(line, plus->n_lines, 1);

	    /* build */
	    if (plus->Line[line] == NULL) {
		continue;
	    }			/* dead line */
	    Line = plus->Line[line];
	    if (Line->type != GV_BOUNDARY) {
		continue;
	    }

	    for (s = 0; s < 2; s++) {
		if (s == 0)
		    side = GV_LEFT;
		else
		    side = GV_RIGHT;

		G_debug(3, "Build area for line = %d, side = %d", line, side);
		Vect_build_line_area(Map, line, side);
	    }
	}
	G_message(_n("One area built", "%d areas built", plus->n_areas), plus->n_areas);
	G_message(_n("One isle built", "%d isles built", plus->n_isles), plus->n_isles);
	plus->built = GV_BUILD_AREAS;
    }

    if (build < GV_BUILD_ATTACH_ISLES)
	return 1;

    /* Attach isles to areas */
    if (plus->built < GV_BUILD_ATTACH_ISLES) {
	G_important_message(_("Attaching islands..."));
	for (i = 1; i <= plus->n_isles; i++) {
	    G_percent(i, plus->n_isles, 1);
	    Vect_attach_isle(Map, i);
	}
	plus->built = GV_BUILD_ATTACH_ISLES;
    }

    if (build < GV_BUILD_CENTROIDS)
	return 1;

    /* Attach centroids to areas */
    if (plus->built < GV_BUILD_CENTROIDS) {
	int nlines;
	struct P_topo_c *topo;

	G_important_message(_("Attaching centroids..."));

	nlines = Vect_get_num_lines(Map);
	for (line = 1; line <= nlines; line++) {
	    G_percent(line, nlines, 1);

	    Line = plus->Line[line];
	    if (!Line)
		continue;	/* Dead */

	    if (Line->type != GV_CENTROID)
		continue;

	    Vect_read_line(Map, Points, NULL, line);
	    area = Vect_find_area(Map, Points->x[0], Points->y[0]);

	    if (area > 0) {
		G_debug(3, "Centroid (line=%d) in area %d", line, area);

		Area = plus->Area[area];
		topo = (struct P_topo_c *)Line->topo;

		if (Area->centroid == 0) {	/* first */
		    Area->centroid = line;
		    topo->area = area;
		}
		else {		/* duplicate */
		    topo->area = -area;
		}
	    }
	}
	plus->built = GV_BUILD_CENTROIDS;
    }

    /* Add areas to category index */
    for (i = 1; i <= plus->n_areas; i++) {
	int c;

	if (plus->Area[i] == NULL)
	    continue;

	if (plus->Area[i]->centroid > 0) {
	    Vect_read_line(Map, NULL, Cats, plus->Area[i]->centroid);

	    for (c = 0; c < Cats->n_cats; c++) {
		dig_cidx_add_cat(plus, Cats->field[c], Cats->cat[c], i,
				 GV_AREA);
	    }
	}

	if (plus->Area[i]->centroid == 0 || Cats->n_cats == 0)	/* no centroid or no cats */
	    dig_cidx_add_cat(plus, 0, 0, i, GV_AREA);
    }

    Vect_destroy_cats_struct(Cats);
    
    return 1;
}
Example #5
0
File: line.c Project: caomw/grass
/*!
  \brief Get bounding box of line
  
  \param Points pointer to line_pnts structure
  \param[out] Box bounding box
*/
void Vect_line_box(const struct line_pnts *Points, struct bound_box *Box)
{
    dig_line_box(Points, Box);
}