/*! \brief Returns polygon array of points (outer ring) of given area \param Map pointer to Map_info structure \param area area id \param[out] BPoints points array \return number of points \return -1 on error */ int Vect_get_area_points(const struct Map_info *Map, int area, struct line_pnts *BPoints) { const struct Plus_head *Plus; struct P_area *Area; G_debug(3, "Vect_get_area_points(): area = %d", area); Vect_reset_line(BPoints); Plus = &(Map->plus); Area = Plus->Area[area]; if (Area == NULL) { /* dead area */ G_warning(_("Attempt to read points of nonexistent area")); return -1; /* error, because we should not read dead areas */ } G_debug(3, " n_lines = %d", Area->n_lines); return Vect__get_area_points(Map, Area->lines, Area->n_lines, BPoints); }
/*! \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; }