PostGIS  2.2.7dev-r@@SVN_REVISION@@
static void test_ptarray_contains_point_sphere ( void  )
static

Definition at line 927 of file cu_geodetic.c.

References LW_FALSE, LW_PARSER_CHECK_NONE, LW_TRUE, lwgeom_free(), lwgeom_from_hexwkb(), lwgeom_from_wkt(), ptarray_contains_point_sphere(), LWPOLY::rings, POINT2D::x, and POINT2D::y.

Referenced by geodetic_suite_setup().

928 {
929  LWGEOM *lwg;
930  LWPOLY *poly;
931  POINT2D pt_to_test;
932  POINT2D pt_outside;
933  int result;
934 
935  /* Small polygon and huge distance between outside point and close-but-not-quite-inside point. Should return LW_FALSE. Pretty degenerate case. */
936  lwg = lwgeom_from_hexwkb("0103000020E61000000100000025000000ACAD6F91DDB65EC03F84A86D57264540CCABC279DDB65EC0FCE6926B57264540B6DEAA62DDB65EC0A79F6B63572645402E0BE84CDDB65EC065677155572645405D0B1D39DDB65EC0316310425726454082B5DB27DDB65EC060A4E12957264540798BB619DDB65EC0C393A10D57264540D4BC160FDDB65EC0BD0320EE56264540D7AC4E08DDB65EC096C862CC56264540AFD29205DDB65EC02A1F68A956264540363AFA06DDB65EC0722E418656264540B63A780CDDB65EC06E9B0064562645409614E215DDB65EC0E09DA84356264540FF71EF22DDB65EC0B48145265626454036033F33DDB65EC081B8A60C5626454066FB4546DDB65EC08A47A6F7552645409061785BDDB65EC0F05AE0E755264540D4B63772DDB65EC05C86CEDD55264540D2E4C689DDB65EC09B6EBFD95526454082E573A1DDB65EC0C90BD5DB552645401ABE85B8DDB65EC06692FCE35526454039844ECEDDB65EC04D8AF6F155264540928319E2DDB65EC0AD8D570556264540D31055F3DDB65EC02D618F1D56264540343B7A01DEB65EC0EB70CF3956264540920A1A0CDEB65EC03B00515956264540911BE212DEB65EC0E43A0E7B56264540E3F69D15DEB65EC017E4089E562645408D903614DEB65EC0F0D42FC1562645402191B80EDEB65EC0586870E35626454012B84E05DEB65EC09166C80357264540215B41F8DDB65EC08F832B21572645408392F7E7DDB65EC01138C13A57264540F999F0D4DDB65EC0E4A9C14F57264540AC3FB8BFDDB65EC0EED6875F57264540D3DCFEA8DDB65EC04F6C996957264540ACAD6F91DDB65EC03F84A86D57264540", LW_PARSER_CHECK_NONE);
937  poly = (LWPOLY*)lwg;
938  pt_to_test.x = -122.819436560680316;
939  pt_to_test.y = 42.2702301207017328;
940  pt_outside.x = 120.695136159150778;
941  pt_outside.y = 40.6920926049588516;
942  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
943  CU_ASSERT_EQUAL(result, LW_FALSE);
944  lwgeom_free(lwg);
945 
946  /* Point on ring between vertexes case */
947  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
948  poly = (LWPOLY*)lwg;
949  pt_to_test.x = 1.1;
950  pt_to_test.y = 1.05;
951  pt_outside.x = 1.2;
952  pt_outside.y = 1.05;
953  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
954  CU_ASSERT_EQUAL(result, LW_TRUE);
955  lwgeom_free(lwg);
956 
957  /* Simple containment case */
958  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
959  poly = (LWPOLY*)lwg;
960  pt_to_test.x = 1.05;
961  pt_to_test.y = 1.05;
962  pt_outside.x = 1.2;
963  pt_outside.y = 1.15;
964  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
965  CU_ASSERT_EQUAL(result, LW_TRUE);
966  lwgeom_free(lwg);
967 
968  /* Less Simple containment case. */
969  /* Interior point quite close to boundary and stab line going through bottom edge vertex */
970  /* This breaks the "extend-it" trick of handling vertex crossings */
971  /* It should also break the "lowest end" trick. */
972  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.0, 1.05 0.95, 1.0 1.0))", LW_PARSER_CHECK_NONE);
973  poly = (LWPOLY*)lwg;
974  pt_to_test.x = 1.05;
975  pt_to_test.y = 1.00;
976  pt_outside.x = 1.05;
977  pt_outside.y = 0.5;
978  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
979  CU_ASSERT_EQUAL(result, LW_TRUE);
980  lwgeom_free(lwg);
981 
982  /* Simple noncontainment case */
983  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
984  poly = (LWPOLY*)lwg;
985  pt_to_test.x = 1.05;
986  pt_to_test.y = 1.15;
987  pt_outside.x = 1.2;
988  pt_outside.y = 1.2;
989  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
990  CU_ASSERT_EQUAL(result, LW_FALSE);
991  lwgeom_free(lwg);
992 
993  /* Harder noncontainment case */
994  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
995  poly = (LWPOLY*)lwg;
996  pt_to_test.x = 1.05;
997  pt_to_test.y = 0.9;
998  pt_outside.x = 1.2;
999  pt_outside.y = 1.05;
1000  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1001  CU_ASSERT_EQUAL(result, LW_FALSE);
1002  lwgeom_free(lwg);
1003 
1004  /* Harder containment case */
1005  lwg = lwgeom_from_wkt("POLYGON((0 0, 0 2, 1 2, 0 3, 2 3, 0 4, 3 5, 0 6, 6 10, 6 1, 0 0))", LW_PARSER_CHECK_NONE);
1006  poly = (LWPOLY*)lwg;
1007  pt_to_test.x = 1.0;
1008  pt_to_test.y = 1.0;
1009  pt_outside.x = 1.0;
1010  pt_outside.y = 10.0;
1011  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1012  CU_ASSERT_EQUAL(result, LW_TRUE);
1013  lwgeom_free(lwg);
1014 
1015  /* Point on ring at first vertex case */
1016  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
1017  poly = (LWPOLY*)lwg;
1018  pt_to_test.x = 1.0;
1019  pt_to_test.y = 1.0;
1020  pt_outside.x = 1.2;
1021  pt_outside.y = 1.05;
1022  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1023  CU_ASSERT_EQUAL(result, LW_TRUE);
1024  lwgeom_free(lwg);
1025 
1026  /* Point on ring at vertex case */
1027  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
1028  poly = (LWPOLY*)lwg;
1029  pt_to_test.x = 1.0;
1030  pt_to_test.y = 1.1;
1031  pt_outside.x = 1.2;
1032  pt_outside.y = 1.05;
1033  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1034  CU_ASSERT_EQUAL(result, LW_TRUE);
1035  lwgeom_free(lwg);
1036 
1037  /* Co-linear crossing case for point-in-polygon test, should return LW_TRUE */
1038  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.2, 1.2 1.2, 1.2 1.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
1039  poly = (LWPOLY*)lwg;
1040  pt_to_test.x = 1.1;
1041  pt_to_test.y = 1.05;
1042  pt_outside.x = 1.1;
1043  pt_outside.y = 1.3;
1044  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1045  CU_ASSERT_EQUAL(result, LW_TRUE);
1046  lwgeom_free(lwg);
1047 
1048  /* Co-linear grazing case for point-in-polygon test, should return LW_FALSE */
1049  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.2, 1.2 1.2, 1.2 1.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
1050  poly = (LWPOLY*)lwg;
1051  pt_to_test.x = 1.0;
1052  pt_to_test.y = 0.0;
1053  pt_outside.x = 1.0;
1054  pt_outside.y = 2.0;
1055  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1056  CU_ASSERT_EQUAL(result, LW_FALSE);
1057  lwgeom_free(lwg);
1058 
1059  /* Grazing case for point-in-polygon test, should return LW_FALSE */
1060  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 2.0, 1.5 1.5, 1.0 1.0))", LW_PARSER_CHECK_NONE);
1061  poly = (LWPOLY*)lwg;
1062  pt_to_test.x = 1.5;
1063  pt_to_test.y = 1.0;
1064  pt_outside.x = 1.5;
1065  pt_outside.y = 2.0;
1066  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1067  CU_ASSERT_EQUAL(result, LW_FALSE);
1068  lwgeom_free(lwg);
1069 
1070  /* Grazing case at first point for point-in-polygon test, should return LW_FALSE */
1071  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 2.0 3.0, 2.0 0.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
1072  poly = (LWPOLY*)lwg;
1073  pt_to_test.x = 1.0;
1074  pt_to_test.y = 0.0;
1075  pt_outside.x = 1.0;
1076  pt_outside.y = 2.0;
1077  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1078  CU_ASSERT_EQUAL(result, LW_FALSE);
1079  lwgeom_free(lwg);
1080 
1081  /* Outside multi-crossing case for point-in-polygon test, should return LW_FALSE */
1082  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.2, 1.2 1.2, 1.2 1.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
1083  poly = (LWPOLY*)lwg;
1084  pt_to_test.x = 0.99;
1085  pt_to_test.y = 0.99;
1086  pt_outside.x = 1.21;
1087  pt_outside.y = 1.21;
1088  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1089  CU_ASSERT_EQUAL(result, LW_FALSE);
1090  lwgeom_free(lwg);
1091 
1092  /* Inside multi-crossing case for point-in-polygon test, should return LW_TRUE */
1093  lwg = lwgeom_from_wkt("POLYGON((1.0 1.0, 1.0 1.1, 1.1 1.1, 1.1 1.2, 1.2 1.2, 1.2 1.0, 1.0 1.0))", LW_PARSER_CHECK_NONE);
1094  poly = (LWPOLY*)lwg;
1095  pt_to_test.x = 1.11;
1096  pt_to_test.y = 1.11;
1097  pt_outside.x = 1.21;
1098  pt_outside.y = 1.21;
1099  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1100  CU_ASSERT_EQUAL(result, LW_TRUE);
1101  lwgeom_free(lwg);
1102 
1103  /* Point on vertex of ring */
1104  lwg = lwgeom_from_wkt("POLYGON((-9 50,51 -11,-10 50,-9 50))", LW_PARSER_CHECK_NONE);
1105  poly = (LWPOLY*)lwg;
1106  pt_to_test.x = -10.0;
1107  pt_to_test.y = 50.0;
1108  pt_outside.x = -10.2727799838316134;
1109  pt_outside.y = -16.9370033133329976;
1110  result = ptarray_contains_point_sphere(poly->rings[0], &pt_outside, &pt_to_test);
1111  CU_ASSERT_EQUAL(result, LW_TRUE);
1112  lwgeom_free(lwg);
1113 
1114 }
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1050
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition: lwin_wkt.c:890
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:1869
double x
Definition: liblwgeom.h:312
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...
Definition: lwgeodetic.c:3204
#define LW_FALSE
Definition: liblwgeom.h:62
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:61
POINTARRAY ** rings
Definition: liblwgeom.h:441
double y
Definition: liblwgeom.h:312
LWGEOM * lwgeom_from_hexwkb(const char *hexwkb, const char check)
Definition: lwin_wkb.c:779

Here is the call graph for this function:

Here is the caller graph for this function: