[GRASS-SVN] r70803 - grass/branches/releasebranch_7_2/vector/v.overlay
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Mar 27 12:03:52 PDT 2017
Author: mmetz
Date: 2017-03-27 12:03:52 -0700 (Mon, 27 Mar 2017)
New Revision: 70803
Modified:
grass/branches/releasebranch_7_2/vector/v.overlay/line_area.c
Log:
v.overlay: fix test if line is inside an area (#3319, backport trunk r70800)
Modified: grass/branches/releasebranch_7_2/vector/v.overlay/line_area.c
===================================================================
--- grass/branches/releasebranch_7_2/vector/v.overlay/line_area.c 2017-03-27 19:02:14 UTC (rev 70802)
+++ grass/branches/releasebranch_7_2/vector/v.overlay/line_area.c 2017-03-27 19:03:52 UTC (rev 70803)
@@ -239,9 +239,10 @@
dbDriver * driver, int operator, int *ofield,
ATTRIBUTES * attr, struct ilist *BList)
{
- int line, nlines, ncat;
+ int i, line, nlines, ncat;
struct line_pnts *Points;
struct line_cats *Cats, *ACats, *OCats;
+ double x, y;
char buf[1000];
dbString stmt;
@@ -303,6 +304,8 @@
* 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
+ * The problem is the middle of the segment. Use line vertices
+ * if possible, avoid calculating middle of the segment
*/
/* merge here */
@@ -310,12 +313,42 @@
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 (Points->n_points < 2)
+ continue;
+ if (Points->n_points == 2) {
+ /* only 2 vertices, must use mid-segment point */
+ x = (Points->x[0] + Points->x[1]) / 2;
+ y = (Points->y[0] + Points->y[1]) / 2;
+ point_area(&(In[1]), field[1], x, y, ACats);
+ }
+ else {
+ /* more than 2 vertices
+ * find a point that is really outside any area
+ * this skips points that are on the boundary
+ * do not calculate mid-segment points because of RE
+ */
+
+ int ret;
+
+ i = (Points->n_points - 1) / 2;
+ x = Points->x[i];
+ y = Points->y[i];
+ ret = point_area(&(In[1]), field[1], x, y, ACats);
+ if (ret && Points->n_points > 3) {
+
+ i++;
+ x = Points->x[i];
+ y = Points->y[i];
+ ret = point_area(&(In[1]), field[1], x, y, ACats);
+ if (!ret)
+ G_warning(_("Ambiguous line %d: not all vertices are really outside any area"),
+ line);
+ }
+ }
+
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",
More information about the grass-commit
mailing list