From: Paul Ramsey Date: Sat, 7 Nov 2009 00:12:56 +0000 (+0000) Subject: Fix for point-on-vertex case of st_covers (#271) X-Git-Tag: 1.5.0b1~278 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=64b981e012bb7893c2d7e827c15b840dd64671f8;p=postgis Fix for point-on-vertex case of st_covers (#271) git-svn-id: http://svn.osgeo.org/postgis/trunk@4761 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/cunit/cu_geodetic.c b/liblwgeom/cunit/cu_geodetic.c index b61e4a6ba..6cecdff1c 100644 --- a/liblwgeom/cunit/cu_geodetic.c +++ b/liblwgeom/cunit/cu_geodetic.c @@ -36,7 +36,8 @@ CU_pSuite register_geodetic_suite(void) (NULL == CU_add_test(pSuite, "test_edge_distance_to_point()", test_edge_distance_to_point)) || (NULL == CU_add_test(pSuite, "test_edge_distance_to_edge()", test_edge_distance_to_edge)) || (NULL == CU_add_test(pSuite, "test_lwgeom_distance_sphere()", test_lwgeom_distance_sphere)) || - (NULL == CU_add_test(pSuite, "test_ptarray_point_in_ring()", test_ptarray_point_in_ring)) || + (NULL == CU_add_test(pSuite, "test_ptarray_point_in_ring()", test_ptarray_point_in_ring)) || + (NULL == CU_add_test(pSuite, "test_lwpoly_covers_point2d()", test_lwpoly_covers_point2d)) || (NULL == CU_add_test(pSuite, "test_spheroid_distance()", test_spheroid_distance)) || (NULL == CU_add_test(pSuite, "test_spheroid_area()", test_spheroid_area)) ) @@ -266,6 +267,12 @@ void test_edge_intersection(void) GEOGRAPHIC_POINT g; int rv; + /* Covers case, end-to-end intersection */ + edge_set(50, -10.999999999999998224, -10.0, 50.0, &e1); + edge_set(-10.0, 50.0, -10.272779983831613393, -16.937003313332997578, &e2); + rv = edge_intersection(e1, e2, &g); + CU_ASSERT_EQUAL(rv, LW_TRUE); + /* Medford case, very short segment vs very long one */ e1.start.lat = 0.74123572595649878103; e1.start.lon = -2.1496353191142714145; @@ -488,6 +495,26 @@ void test_ptarray_point_in_ring(void) } +void test_lwpoly_covers_point2d(void) +{ + LWPOLY *poly; + LWGEOM *lwg; + POINT2D pt_to_test; + GBOX gbox; + int result; + + gbox.flags = gflags(0, 0, 1); + + lwg = lwgeom_from_ewkt("POLYGON((-9 50,51 -11,-10 50,-9 50))", PARSER_CHECK_NONE); + lwgeom_calculate_gbox_geodetic(lwg, &gbox); + poly = (LWPOLY*)lwg; + pt_to_test.x = -10.0; + pt_to_test.y = 50.0; + result = lwpoly_covers_point2d(poly, gbox, pt_to_test); + CU_ASSERT_EQUAL(result, LW_TRUE); + lwgeom_free(lwg); + +} void test_lwgeom_distance_sphere(void) diff --git a/liblwgeom/cunit/cu_geodetic.h b/liblwgeom/cunit/cu_geodetic.h index 594fda1c1..25f6983f8 100644 --- a/liblwgeom/cunit/cu_geodetic.h +++ b/liblwgeom/cunit/cu_geodetic.h @@ -37,3 +37,4 @@ void test_lwgeom_distance_sphere(void); void test_ptarray_point_in_ring(void); void test_spheroid_distance(void); void test_spheroid_area(void); +void test_lwpoly_covers_point2d(void); diff --git a/liblwgeom/lwgeodetic.c b/liblwgeom/lwgeodetic.c index eee0d8c1d..cafb3a1b6 100644 --- a/liblwgeom/lwgeodetic.c +++ b/liblwgeom/lwgeodetic.c @@ -752,6 +752,27 @@ int edge_intersection(GEOGRAPHIC_EDGE e1, GEOGRAPHIC_EDGE e2, GEOGRAPHIC_POINT * LWDEBUGF(4, "e1 start(%.20g %.20g) end(%.20g %.20g)", rad2deg(e1.start.lon), rad2deg(e1.start.lat), rad2deg(e1.end.lon), rad2deg(e1.end.lat)); LWDEBUGF(4, "e2 start(%.20g %.20g) end(%.20g %.20g)", rad2deg(e2.start.lon), rad2deg(e2.start.lat), rad2deg(e2.end.lon), rad2deg(e2.end.lat)); + if( geographic_point_equals(e1.start, e2.start) ) + { + *g = e1.start; + return LW_TRUE; + } + if( geographic_point_equals(e1.end, e2.end) ) + { + *g = e1.end; + return LW_TRUE; + } + if( geographic_point_equals(e1.end, e2.start) ) + { + *g = e1.end; + return LW_TRUE; + } + if( geographic_point_equals(e1.start, e2.end) ) + { + *g = e1.start; + return LW_TRUE; + } + robust_cross_product(e1.start, e1.end, &ea); normalize(&ea); robust_cross_product(e2.start, e2.end, &eb);