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

Definition at line 775 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().

776 {
777  int wn = 0;
778  int i;
779  double side;
780  POINT2D seg1;
781  POINT2D seg2;
782 
783  POSTGIS_DEBUG(2, "point_in_ring called.");
784 
785 
786  for (i=0; i<pts->npoints-1; i++)
787  {
788  getPoint2d_p(pts, i, &seg1);
789  getPoint2d_p(pts, i+1, &seg2);
790 
791 
792  side = determineSide(&seg1, &seg2, point);
793 
794  POSTGIS_DEBUGF(3, "segment: (%.8f, %.8f),(%.8f, %.8f)", seg1.x, seg1.y, seg2.x, seg2.y);
795  POSTGIS_DEBUGF(3, "side result: %.8f", side);
796  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));
797 
798  /* zero length segments are ignored. */
799  if (((seg2.x-seg1.x)*(seg2.x-seg1.x)+(seg2.y-seg1.y)*(seg2.y-seg1.y)) < 1e-12*1e-12)
800  {
801  POSTGIS_DEBUG(3, "segment is zero length... ignoring.");
802 
803  continue;
804  }
805 
806  /* a point on the boundary of a ring is not contained. */
807  /* WAS: if (fabs(side) < 1e-12), see #852 */
808  if (side == 0.0)
809  {
810  if (isOnSegment(&seg1, &seg2, point) == 1)
811  {
812  POSTGIS_DEBUGF(3, "point on ring boundary between points %d, %d", i, i+1);
813 
814  return 0;
815  }
816  }
817 
818  /*
819  * If the point is to the left of the line, and it's rising,
820  * then the line is to the right of the point and
821  * circling counter-clockwise, so incremement.
822  */
823  if (FP_CONTAINS_BOTTOM(seg1.y,point->y,seg2.y) && side>0)
824  {
825  POSTGIS_DEBUG(3, "incrementing winding number.");
826 
827  ++wn;
828  }
829  /*
830  * If the point is to the right of the line, and it's falling,
831  * then the line is to the right of the point and circling
832  * clockwise, so decrement.
833  */
834  else if (FP_CONTAINS_BOTTOM(seg2.y,point->y,seg1.y) && side<0)
835  {
836  POSTGIS_DEBUG(3, "decrementing winding number.");
837 
838  --wn;
839  }
840  }
841 
842  POSTGIS_DEBUGF(3, "winding number %d", wn);
843 
844  if (wn == 0)
845  return -1;
846  return 1;
847 }
int npoints
Definition: liblwgeom.h:355
double x
Definition: liblwgeom.h:312
int isOnSegment(POINT2D *seg1, POINT2D *seg2, POINT2D *point)
double y
Definition: liblwgeom.h:312
int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
Definition: lwgeom_api.c:448
#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: