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

◆ lwpoly_covers_point2d()

int lwpoly_covers_point2d ( const LWPOLY poly,
const POINT2D pt_to_test 
)

Given a polygon (lon/lat decimal degrees) and point (lon/lat decimal degrees) and a guaranteed outside point (lon/lat decimal degrees) (calculate with gbox_pt_outside()) return LW_TRUE if point is inside or on edge of polygon.

Definition at line 2518 of file lwgeodetic.c.

2519{
2520 uint32_t i;
2521 int in_hole_count = 0;
2522 POINT3D p;
2523 GEOGRAPHIC_POINT gpt_to_test;
2524 POINT2D pt_outside;
2525 GBOX gbox;
2526#if POSTGIS_DEBUG_LEVEL >= 4
2527 char *geom_ewkt;
2528#endif
2529 gbox.flags = 0;
2530
2531 /* Nulls and empties don't contain anything! */
2532 if ( ! poly || lwgeom_is_empty((LWGEOM*)poly) )
2533 {
2534 LWDEBUG(4,"returning false, geometry is empty or null");
2535 return LW_FALSE;
2536 }
2537
2538 /* Make sure we have boxes */
2539 if ( poly->bbox )
2540 gbox = *(poly->bbox);
2541 else
2543
2544 /* Point not in box? Done! */
2545 geographic_point_init(pt_to_test->x, pt_to_test->y, &gpt_to_test);
2546 geog2cart(&gpt_to_test, &p);
2547 if ( ! gbox_contains_point3d(&gbox, &p) )
2548 {
2549 LWDEBUG(4, "the point is not in the box!");
2550 return LW_FALSE;
2551 }
2552
2553 /* Calculate our outside point from the gbox */
2554 lwpoly_pt_outside(poly, &pt_outside);
2555
2556 LWDEBUGF(4, "pt_outside POINT(%.18g %.18g)", pt_outside.x, pt_outside.y);
2557 LWDEBUGF(4, "pt_to_test POINT(%.18g %.18g)", pt_to_test->x, pt_to_test->y);
2558#if POSTGIS_DEBUG_LEVEL >= 4
2559 geom_ewkt = lwgeom_to_ewkt((LWGEOM*)poly);
2560 LWDEBUGF(4, "polygon %s", geom_ewkt);
2561 lwfree(geom_ewkt);
2562 geom_ewkt = gbox_to_string(&gbox);
2563 LWDEBUGF(4, "gbox %s", geom_ewkt);
2564 lwfree(geom_ewkt);
2565#endif
2566
2567 /* Not in outer ring? We're done! */
2568 if ( ! ptarray_contains_point_sphere(poly->rings[0], &pt_outside, pt_to_test) )
2569 {
2570 LWDEBUG(4,"returning false, point is outside ring");
2571 return LW_FALSE;
2572 }
2573
2574 LWDEBUGF(4, "testing %d rings", poly->nrings);
2575
2576 /* But maybe point is in a hole... */
2577 for ( i = 1; i < poly->nrings; i++ )
2578 {
2579 LWDEBUGF(4, "ring test loop %d", i);
2580 /* Count up hole containment. Odd => outside boundary. */
2581 if ( ptarray_contains_point_sphere(poly->rings[i], &pt_outside, pt_to_test) )
2582 in_hole_count++;
2583 }
2584
2585 LWDEBUGF(4, "in_hole_count == %d", in_hole_count);
2586
2587 if ( in_hole_count % 2 )
2588 {
2589 LWDEBUG(4,"returning false, inner ring containment count is odd");
2590 return LW_FALSE;
2591 }
2592
2593 LWDEBUG(4,"returning true, inner ring containment count is even");
2594 return LW_TRUE;
2595}
int gbox_contains_point3d(const GBOX *gbox, const POINT3D *pt)
Return true if the point is inside the gbox.
Definition gbox.c:247
char * gbox_to_string(const GBOX *gbox)
Allocate a string representation of the GBOX, based on dimensionality of flags.
Definition gbox.c:392
#define LW_FALSE
Definition liblwgeom.h:108
char * lwgeom_to_ewkt(const LWGEOM *lwgeom)
Return an alloced string.
Definition lwgeom.c:547
void lwfree(void *mem)
Definition lwutil.c:242
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:107
int ptarray_contains_point_sphere(const POINTARRAY *pa, const POINT2D *pt_outside, const POINT2D *pt_to_test)
This routine returns LW_TRUE if the stabline joining the pt_outside and pt_to_test crosses the ring a...
int lwgeom_calculate_gbox_geodetic(const LWGEOM *geom, GBOX *gbox)
Calculate the geodetic bounding box for an LWGEOM.
int lwpoly_pt_outside(const LWPOLY *poly, POINT2D *pt_outside)
void geographic_point_init(double lon, double lat, GEOGRAPHIC_POINT *g)
Initialize a geographic point.
Definition lwgeodetic.c:180
void geog2cart(const GEOGRAPHIC_POINT *g, POINT3D *p)
Convert spherical coordinates to cartesian coordinates on unit sphere.
Definition lwgeodetic.c:404
#define LWDEBUG(level, msg)
Definition lwgeom_log.h:83
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:88
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition lwinline.h:193
lwflags_t flags
Definition liblwgeom.h:339
Point in spherical coordinates on the world.
Definition lwgeodetic.h:54
GBOX * bbox
Definition liblwgeom.h:444
double y
Definition liblwgeom.h:376
double x
Definition liblwgeom.h:376

References LWPOLY::bbox, GBOX::flags, gbox_contains_point3d(), gbox_to_string(), geog2cart(), geographic_point_init(), LW_FALSE, LW_TRUE, LWDEBUG, LWDEBUGF, lwfree(), lwgeom_calculate_gbox_geodetic(), lwgeom_is_empty(), lwgeom_to_ewkt(), lwpoly_pt_outside(), LWPOLY::nrings, ptarray_contains_point_sphere(), LWPOLY::rings, POINT2D::x, and POINT2D::y.

Referenced by lwgeom_covers_lwgeom_sphere(), lwgeom_distance_spheroid(), lwpoly_covers_pointarray(), test_lwpoly_covers_point2d(), and test_tree_circ_pip2().

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