PostGIS  2.1.10dev-r@@SVN_REVISION@@
int point_in_ring ( POINTARRAY pts,
POINT2D point 
)

Definition at line 1005 of file lwgeom_functions_analytic.c.

References determineSide(), FP_CONTAINS_BOTTOM, getPoint2d_p(), isOnSegment(), POINTARRAY::npoints, POINT2D::x, and POINT2D::y.

Referenced by point_in_multipolygon(), and point_in_polygon().

1006 {
1007  int wn = 0;
1008  int i;
1009  double side;
1010  POINT2D seg1;
1011  POINT2D seg2;
1012 
1013  POSTGIS_DEBUG(2, "point_in_ring called.");
1014 
1015 
1016  for (i=0; i<pts->npoints-1; i++)
1017  {
1018  getPoint2d_p(pts, i, &seg1);
1019  getPoint2d_p(pts, i+1, &seg2);
1020 
1021 
1022  side = determineSide(&seg1, &seg2, point);
1023 
1024  POSTGIS_DEBUGF(3, "segment: (%.8f, %.8f),(%.8f, %.8f)", seg1.x, seg1.y, seg2.x, seg2.y);
1025  POSTGIS_DEBUGF(3, "side result: %.8f", side);
1026  POSTGIS_DEBUGF(3, "counterclockwise wrap %d, clockwise wrap %d", FP_CONTAINS_BOTTOM(seg1.y,point->y,seg2.y), FP_CONTAINS_BOTTOM(seg2.y,point->y,seg1.y));
1027 
1028  /* zero length segments are ignored. */
1029  if (((seg2.x-seg1.x)*(seg2.x-seg1.x)+(seg2.y-seg1.y)*(seg2.y-seg1.y)) < 1e-12*1e-12)
1030  {
1031  POSTGIS_DEBUG(3, "segment is zero length... ignoring.");
1032 
1033  continue;
1034  }
1035 
1036  /* a point on the boundary of a ring is not contained. */
1037  /* WAS: if (fabs(side) < 1e-12), see #852 */
1038  if (side == 0.0)
1039  {
1040  if (isOnSegment(&seg1, &seg2, point) == 1)
1041  {
1042  POSTGIS_DEBUGF(3, "point on ring boundary between points %d, %d", i, i+1);
1043 
1044  return 0;
1045  }
1046  }
1047 
1048  /*
1049  * If the point is to the left of the line, and it's rising,
1050  * then the line is to the right of the point and
1051  * circling counter-clockwise, so incremement.
1052  */
1053  if (FP_CONTAINS_BOTTOM(seg1.y,point->y,seg2.y) && side>0)
1054  {
1055  POSTGIS_DEBUG(3, "incrementing winding number.");
1056 
1057  ++wn;
1058  }
1059  /*
1060  * If the point is to the right of the line, and it's falling,
1061  * then the line is to the right of the point and circling
1062  * clockwise, so decrement.
1063  */
1064  else if (FP_CONTAINS_BOTTOM(seg2.y,point->y,seg1.y) && side<0)
1065  {
1066  POSTGIS_DEBUG(3, "decrementing winding number.");
1067 
1068  --wn;
1069  }
1070  }
1071 
1072  POSTGIS_DEBUGF(3, "winding number %d", wn);
1073 
1074  if (wn == 0)
1075  return -1;
1076  return 1;
1077 }
int npoints
Definition: liblwgeom.h:327
double x
Definition: liblwgeom.h:284
int isOnSegment(POINT2D *seg1, POINT2D *seg2, POINT2D *point)
double y
Definition: liblwgeom.h:284
int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
Definition: lwgeom_api.c:434
#define FP_CONTAINS_BOTTOM(A, X, B)
double determineSide(POINT2D *seg1, POINT2D *seg2, POINT2D *point)

Here is the call graph for this function:

Here is the caller graph for this function: