PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ point_in_ring_rtree()

static int point_in_ring_rtree ( RTREE_NODE root,
const POINT2D point 
)
static

Definition at line 735 of file lwgeom_functions_analytic.c.

736{
737 int wn = 0;
738 uint32_t i;
739 double side;
740 const POINT2D *seg1;
741 const POINT2D *seg2;
742 LWMLINE *lines;
743
744 POSTGIS_DEBUG(2, "point_in_ring called.");
745
746 lines = RTreeFindLineSegments(root, point->y);
747 if (!lines)
748 return -1;
749
750 for (i=0; i<lines->ngeoms; i++)
751 {
752 seg1 = getPoint2d_cp(lines->geoms[i]->points, 0);
753 seg2 = getPoint2d_cp(lines->geoms[i]->points, 1);
754
755 side = determineSide(seg1, seg2, point);
756
757 POSTGIS_DEBUGF(3, "segment: (%.8f, %.8f),(%.8f, %.8f)", seg1->x, seg1->y, seg2->x, seg2->y);
758 POSTGIS_DEBUGF(3, "side result: %.8f", side);
759 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));
760
761 /* zero length segments are ignored. */
762 if (((seg2->x - seg1->x)*(seg2->x - seg1->x) + (seg2->y - seg1->y)*(seg2->y - seg1->y)) < 1e-12*1e-12)
763 {
764 POSTGIS_DEBUG(3, "segment is zero length... ignoring.");
765
766 continue;
767 }
768
769 /* a point on the boundary of a ring is not contained. */
770 /* WAS: if (fabs(side) < 1e-12), see #852 */
771 if (side == 0.0)
772 {
773 if (isOnSegment(seg1, seg2, point) == 1)
774 {
775 POSTGIS_DEBUGF(3, "point on ring boundary between points %d, %d", i, i+1);
776
777 return 0;
778 }
779 }
780
781 /*
782 * If the point is to the left of the line, and it's rising,
783 * then the line is to the right of the point and
784 * circling counter-clockwise, so increment.
785 */
786 if ((seg1->y <= point->y) && (point->y < seg2->y) && (side > 0))
787 {
788 POSTGIS_DEBUG(3, "incrementing winding number.");
789
790 ++wn;
791 }
792 /*
793 * If the point is to the right of the line, and it's falling,
794 * then the line is to the right of the point and circling
795 * clockwise, so decrement.
796 */
797 else if ((seg2->y <= point->y) && (point->y < seg1->y) && (side < 0))
798 {
799 POSTGIS_DEBUG(3, "decrementing winding number.");
800
801 --wn;
802 }
803 }
804
805 POSTGIS_DEBUGF(3, "winding number %d", wn);
806
807 if (wn == 0)
808 return -1;
809 return 1;
810}
#define FP_CONTAINS_BOTTOM(A, X, B)
static int isOnSegment(const POINT2D *seg1, const POINT2D *seg2, const POINT2D *point)
static double determineSide(const POINT2D *seg1, const POINT2D *seg2, const POINT2D *point)
LWMLINE * RTreeFindLineSegments(RTREE_NODE *root, double value)
Retrieves a collection of line segments given the root and crossing value.
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition lwinline.h:91
POINTARRAY * points
Definition liblwgeom.h:469
LWLINE ** geoms
Definition liblwgeom.h:533
uint32_t ngeoms
Definition liblwgeom.h:538
double y
Definition liblwgeom.h:376
double x
Definition liblwgeom.h:376

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().

Here is the call graph for this function:
Here is the caller graph for this function: