PostGIS  2.5.0dev-r@@SVN_REVISION@@
static int point_in_ring_rtree ( RTREE_NODE root,
const POINT2D point 
)
static

Definition at line 650 of file lwgeom_functions_analytic.c.

References determineSide(), FP_CONTAINS_BOTTOM, LWMLINE::geoms, getPoint2d_cp(), isOnSegment(), LWMLINE::ngeoms, LWLINE::points, RTreeFindLineSegments(), POINT2D::x, and POINT2D::y.

Referenced by point_in_multipolygon_rtree(), and point_in_polygon_rtree().

651 {
652  int wn = 0;
653  uint32_t i;
654  double side;
655  const POINT2D *seg1;
656  const POINT2D *seg2;
657  LWMLINE *lines;
658 
659  POSTGIS_DEBUG(2, "point_in_ring called.");
660 
661  lines = RTreeFindLineSegments(root, point->y);
662  if (!lines)
663  return -1;
664 
665  for (i=0; i<lines->ngeoms; i++)
666  {
667  seg1 = getPoint2d_cp(lines->geoms[i]->points, 0);
668  seg2 = getPoint2d_cp(lines->geoms[i]->points, 1);
669 
670  side = determineSide(seg1, seg2, point);
671 
672  POSTGIS_DEBUGF(3, "segment: (%.8f, %.8f),(%.8f, %.8f)", seg1->x, seg1->y, seg2->x, seg2->y);
673  POSTGIS_DEBUGF(3, "side result: %.8f", side);
674  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));
675 
676  /* zero length segments are ignored. */
677  if (((seg2->x - seg1->x)*(seg2->x - seg1->x) + (seg2->y - seg1->y)*(seg2->y - seg1->y)) < 1e-12*1e-12)
678  {
679  POSTGIS_DEBUG(3, "segment is zero length... ignoring.");
680 
681  continue;
682  }
683 
684  /* a point on the boundary of a ring is not contained. */
685  /* WAS: if (fabs(side) < 1e-12), see #852 */
686  if (side == 0.0)
687  {
688  if (isOnSegment(seg1, seg2, point) == 1)
689  {
690  POSTGIS_DEBUGF(3, "point on ring boundary between points %d, %d", i, i+1);
691 
692  return 0;
693  }
694  }
695 
696  /*
697  * If the point is to the left of the line, and it's rising,
698  * then the line is to the right of the point and
699  * circling counter-clockwise, so incremement.
700  */
701  if (FP_CONTAINS_BOTTOM(seg1->y, point->y, seg2->y) && side>0)
702  {
703  POSTGIS_DEBUG(3, "incrementing winding number.");
704 
705  ++wn;
706  }
707  /*
708  * If the point is to the right of the line, and it's falling,
709  * then the line is to the right of the point and circling
710  * clockwise, so decrement.
711  */
712  else if (FP_CONTAINS_BOTTOM(seg2->y, point->y, seg1->y) && side<0)
713  {
714  POSTGIS_DEBUG(3, "decrementing winding number.");
715 
716  --wn;
717  }
718  }
719 
720  POSTGIS_DEBUGF(3, "winding number %d", wn);
721 
722  if (wn == 0)
723  return -1;
724  return 1;
725 }
LWMLINE * RTreeFindLineSegments(RTREE_NODE *root, double value)
Retrieves a collection of line segments given the root and crossing value.
Definition: lwgeom_rtree.c:450
unsigned int uint32_t
Definition: uthash.h:78
double x
Definition: liblwgeom.h:327
double y
Definition: liblwgeom.h:327
uint32_t ngeoms
Definition: liblwgeom.h:480
LWLINE ** geoms
Definition: liblwgeom.h:482
static int isOnSegment(const POINT2D *seg1, const POINT2D *seg2, const POINT2D *point)
static double determineSide(const POINT2D *seg1, const POINT2D *seg2, const POINT2D *point)
#define FP_CONTAINS_BOTTOM(A, X, B)
POINTARRAY * points
Definition: liblwgeom.h:421
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from...
Definition: lwgeom_api.c:364

Here is the call graph for this function:

Here is the caller graph for this function: