PostGIS  2.1.10dev-r@@SVN_REVISION@@
int point_in_ring_rtree ( RTREE_NODE root,
POINT2D point 
)

Definition at line 921 of file lwgeom_functions_analytic.c.

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

Referenced by point_in_multipolygon_rtree(), and point_in_polygon_rtree().

922 {
923  int wn = 0;
924  int i;
925  double side;
926  POINT2D seg1;
927  POINT2D seg2;
928  LWMLINE *lines;
929 
930  POSTGIS_DEBUG(2, "point_in_ring called.");
931 
932  lines = RTreeFindLineSegments(root, point->y);
933  if (!lines)
934  return -1;
935 
936  for (i=0; i<lines->ngeoms; i++)
937  {
938  getPoint2d_p(lines->geoms[i]->points, 0, &seg1);
939  getPoint2d_p(lines->geoms[i]->points, 1, &seg2);
940 
941 
942  side = determineSide(&seg1, &seg2, point);
943 
944  POSTGIS_DEBUGF(3, "segment: (%.8f, %.8f),(%.8f, %.8f)", seg1.x, seg1.y, seg2.x, seg2.y);
945  POSTGIS_DEBUGF(3, "side result: %.8f", side);
946  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));
947 
948  /* zero length segments are ignored. */
949  if (((seg2.x-seg1.x)*(seg2.x-seg1.x)+(seg2.y-seg1.y)*(seg2.y-seg1.y)) < 1e-12*1e-12)
950  {
951  POSTGIS_DEBUG(3, "segment is zero length... ignoring.");
952 
953  continue;
954  }
955 
956  /* a point on the boundary of a ring is not contained. */
957  /* WAS: if (fabs(side) < 1e-12), see #852 */
958  if (side == 0.0)
959  {
960  if (isOnSegment(&seg1, &seg2, point) == 1)
961  {
962  POSTGIS_DEBUGF(3, "point on ring boundary between points %d, %d", i, i+1);
963 
964  return 0;
965  }
966  }
967 
968  /*
969  * If the point is to the left of the line, and it's rising,
970  * then the line is to the right of the point and
971  * circling counter-clockwise, so incremement.
972  */
973  if (FP_CONTAINS_BOTTOM(seg1.y,point->y,seg2.y) && side>0)
974  {
975  POSTGIS_DEBUG(3, "incrementing winding number.");
976 
977  ++wn;
978  }
979  /*
980  * If the point is to the right of the line, and it's falling,
981  * then the line is to the right of the point and circling
982  * clockwise, so decrement.
983  */
984  else if (FP_CONTAINS_BOTTOM(seg2.y,point->y,seg1.y) && side<0)
985  {
986  POSTGIS_DEBUG(3, "decrementing winding number.");
987 
988  --wn;
989  }
990  }
991 
992  POSTGIS_DEBUGF(3, "winding number %d", wn);
993 
994  if (wn == 0)
995  return -1;
996  return 1;
997 }
LWMLINE * RTreeFindLineSegments(RTREE_NODE *root, double value)
Retrieves a collection of line segments given the root and crossing value.
Definition: lwgeom_rtree.c:436
int ngeoms
Definition: liblwgeom.h:437
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
LWLINE ** geoms
Definition: liblwgeom.h:439
#define FP_CONTAINS_BOTTOM(A, X, B)
double determineSide(POINT2D *seg1, POINT2D *seg2, POINT2D *point)
POINTARRAY * points
Definition: liblwgeom.h:378

Here is the call graph for this function:

Here is the caller graph for this function: