PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ test_ptarray_contains_point_sphere()

static void test_ptarray_contains_point_sphere ( void  )
static

Definition at line 933 of file cu_geodetic.c.

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

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

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