int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt) { int i; LWLINE *lwline; LWCIRCSTRING *lwcirc; int wn = 0; int winding_number = 0; int result; for ( i = 0; i < comp->ngeoms; i++ ) { LWGEOM *lwgeom = comp->geoms[i]; if ( lwgeom->type == LINETYPE ) { lwline = lwgeom_as_lwline(lwgeom); if ( comp->ngeoms == 1 ) { return ptarray_contains_point(lwline->points, pt); } else { /* Don't check closure while doing p-i-p test */ result = ptarray_contains_point_partial(lwline->points, pt, LW_FALSE, &winding_number); } } else { lwcirc = lwgeom_as_lwcircstring(lwgeom); if ( ! lwcirc ) { lwerror("Unexpected component of type %s in compound curve", lwtype_name(lwgeom->type)); return 0; } if ( comp->ngeoms == 1 ) { return ptarrayarc_contains_point(lwcirc->points, pt); } else { /* Don't check closure while doing p-i-p test */ result = ptarrayarc_contains_point_partial(lwcirc->points, pt, LW_FALSE, &winding_number); } } /* Propogate boundary condition */ if ( result == LW_BOUNDARY ) return LW_BOUNDARY; wn += winding_number; } /* Outside */ if (wn == 0) return LW_OUTSIDE; /* Inside */ return LW_INSIDE; }
int lwpoly_contains_point(const LWPOLY *poly, const POINT2D *pt) { int i; if ( lwpoly_is_empty(poly) ) return LW_FALSE; if ( ptarray_contains_point(poly->rings[0], pt) == LW_OUTSIDE ) return LW_FALSE; for ( i = 1; i < poly->nrings; i++ ) { if ( ptarray_contains_point(poly->rings[i], pt) == LW_INSIDE ) return LW_FALSE; } return LW_TRUE; }
int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt) { switch( geom->type ) { case LINETYPE: return ptarray_contains_point(((LWLINE*)geom)->points, pt); case CIRCSTRINGTYPE: return ptarrayarc_contains_point(((LWCIRCSTRING*)geom)->points, pt); case COMPOUNDTYPE: return lwcompound_contains_point((LWCOMPOUND*)geom, pt); } lwerror("lwgeom_contains_point failed"); return LW_FAILURE; }
static void test_ptarray_contains_point() { /* int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt, int *winding_number) */ LWLINE *lwline; POINTARRAY *pa; POINT2D pt; int rv; lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0, 0 1, 1 1, 1 0, 0 0)")); pa = lwline->points; /* Point in middle of square */ pt.x = 0.5; pt.y = 0.5; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_INSIDE); /* Point on left edge of square */ pt.x = 0; pt.y = 0.5; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /* Point on top edge of square */ pt.x = 0.5; pt.y = 1; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /* Point on bottom left corner of square */ pt.x = 0; pt.y = 0; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /* Point on top left corner of square */ pt.x = 0; pt.y = 1; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /* Point outside top left corner of square */ pt.x = -0.1; pt.y = 1; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_OUTSIDE); /* Point outside top left corner of square */ pt.x = 0; pt.y = 1.1; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_OUTSIDE); /* Point outside left side of square */ pt.x = -0.2; pt.y = 0.5; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_OUTSIDE); lwline_free(lwline); lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0, 1 1, 2 0, 0 0)")); pa = lwline->points; /* Point outside grazing top of triangle */ pt.x = 0; pt.y = 1; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_OUTSIDE); lwline_free(lwline); lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(0 0, 0 4, 1 4, 2 2, 3 4, 4 4, 4 0, 0 0)")); pa = lwline->points; /* Point outside grazing top of triangle */ pt.x = 1; pt.y = 2; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_INSIDE); /* Point outside grazing top of triangle */ pt.x = 3; pt.y = 2; rv = ptarray_contains_point(pa, &pt); CU_ASSERT_EQUAL(rv, LW_INSIDE); lwline_free(lwline); }