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

Definition at line 987 of file cu_measures.c.

References ASSERT_DOUBLE_EQUAL, cu_error_msg, LW_FALSE, LW_PARSER_CHECK_NONE, LW_TRUE, lwgeom_cpa_within(), lwgeom_free(), lwgeom_from_wkt(), and lwgeom_tcpa().

Referenced by measures_suite_setup().

988 {
989  LWGEOM *g1, *g2;
990  double m, dist;
991 
992  /* Invalid input, lack of dimensions */
993 
994  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
995  g2 = lwgeom_from_wkt("LINESTRING (0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
996  m = lwgeom_tcpa(g1, g2, NULL);
997  lwgeom_free(g1);
998  lwgeom_free(g2);
999  ASSERT_DOUBLE_EQUAL(m, -1.0);
1000  CU_ASSERT_STRING_EQUAL(
1001  "Both input geometries must have a measure dimension",
1002  cu_error_msg
1003  );
1004 
1005  /* Invalid input, not linestrings */
1006 
1007  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1008  g2 = lwgeom_from_wkt("POINT M (0 0 2)", LW_PARSER_CHECK_NONE);
1009  m = lwgeom_tcpa(g1, g2, NULL);
1010  lwgeom_free(g1);
1011  lwgeom_free(g2);
1012  ASSERT_DOUBLE_EQUAL(m, -1.0);
1013  CU_ASSERT_STRING_EQUAL(
1014  "Both input geometries must be linestrings",
1015  cu_error_msg
1016  );
1017 
1018  /* Invalid input, too short linestring */
1019 
1020  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1021  g2 = lwgeom_from_wkt("LINESTRING M(2 0 1)", LW_PARSER_CHECK_NONE);
1022  dist = -77;
1023  m = lwgeom_tcpa(g1, g2, &dist);
1024  lwgeom_free(g1);
1025  lwgeom_free(g2);
1026  ASSERT_DOUBLE_EQUAL(dist, -77.0); /* not touched */
1027  ASSERT_DOUBLE_EQUAL(m, -1.0);
1028  CU_ASSERT_STRING_EQUAL(
1029  "Both input lines must have at least 2 points", /* should be accepted ? */
1030  cu_error_msg
1031  );
1032 
1033  /* Invalid input, empty linestring */
1034 
1035  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1036  g2 = lwgeom_from_wkt("LINESTRING M EMPTY", LW_PARSER_CHECK_NONE);
1037  m = lwgeom_tcpa(g1, g2, NULL);
1038  lwgeom_free(g1);
1039  lwgeom_free(g2);
1040  ASSERT_DOUBLE_EQUAL(m, -1.0);
1041  CU_ASSERT_STRING_EQUAL(
1042  "Both input lines must have at least 2 points",
1043  cu_error_msg
1044  );
1045 
1046  /* Timeranges do not overlap */
1047 
1048  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1049  g2 = lwgeom_from_wkt("LINESTRING M(0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1050  m = lwgeom_tcpa(g1, g2, NULL);
1051  lwgeom_free(g1);
1052  lwgeom_free(g2);
1053  ASSERT_DOUBLE_EQUAL(m, -2.0); /* means timeranges do not overlap */
1054 
1055  /* One of the tracks is still, the other passes to that point */
1056 
1057  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1058  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1059  dist = -1;
1060  m = lwgeom_tcpa(g1, g2, &dist);
1061  ASSERT_DOUBLE_EQUAL(m, 1.0);
1062  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1063  CU_ASSERT( lwgeom_cpa_within(g1, g2, 0.0) == LW_TRUE );
1064  lwgeom_free(g1);
1065  lwgeom_free(g2);
1066 
1067  /* One of the tracks is still, the other passes at 10 meters from point */
1068 
1069  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1070  g2 = lwgeom_from_wkt("LINESTRING M(-10 10 1, 10 10 5)", LW_PARSER_CHECK_NONE);
1071  dist = -1;
1072  m = lwgeom_tcpa(g1, g2, &dist);
1073  ASSERT_DOUBLE_EQUAL(m, 3.0);
1074  ASSERT_DOUBLE_EQUAL(dist, 10.0);
1075  CU_ASSERT( lwgeom_cpa_within(g1, g2, 11.0) == LW_TRUE );
1076  CU_ASSERT( lwgeom_cpa_within(g1, g2, 10.0) == LW_TRUE );
1077  CU_ASSERT( lwgeom_cpa_within(g1, g2, 9.0) == LW_FALSE );
1078  lwgeom_free(g1);
1079  lwgeom_free(g2);
1080 
1081  /* Equal tracks, 2d */
1082 
1083  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1084  g2 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1085  dist = -1;
1086  m = lwgeom_tcpa(g1, g2, &dist);
1087  lwgeom_free(g1);
1088  lwgeom_free(g2);
1089  ASSERT_DOUBLE_EQUAL(m, 10.0);
1090  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1091 
1092  /* Reversed tracks, 2d */
1093 
1094  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1095  g2 = lwgeom_from_wkt("LINESTRING M(10 0 10, 0 0 20)", LW_PARSER_CHECK_NONE);
1096  dist = -1;
1097  m = lwgeom_tcpa(g1, g2, &dist);
1098  lwgeom_free(g1);
1099  lwgeom_free(g2);
1100  ASSERT_DOUBLE_EQUAL(m, 15.0);
1101  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1102 
1103  /* Parallel tracks, same speed, 2d */
1104 
1105  g1 = lwgeom_from_wkt("LINESTRING M(2 0 10, 12 0 20)", LW_PARSER_CHECK_NONE);
1106  g2 = lwgeom_from_wkt("LINESTRING M(13 0 10, 23 0 20)", LW_PARSER_CHECK_NONE);
1107  dist = -1;
1108  m = lwgeom_tcpa(g1, g2, &dist);
1109  lwgeom_free(g1);
1110  lwgeom_free(g2);
1111  ASSERT_DOUBLE_EQUAL(m, 10.0);
1112  ASSERT_DOUBLE_EQUAL(dist, 11.0);
1113 
1114  /* Parallel tracks, different speed (g2 gets closer as time passes), 2d */
1115 
1116  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1117  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 9 0 20)", LW_PARSER_CHECK_NONE);
1118  dist = -1;
1119  m = lwgeom_tcpa(g1, g2, &dist);
1120  lwgeom_free(g1);
1121  lwgeom_free(g2);
1122  ASSERT_DOUBLE_EQUAL(m, 20.0);
1123  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1124 
1125  /* Parallel tracks, different speed (g2 left behind as time passes), 2d */
1126 
1127  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1128  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 6 0 20)", LW_PARSER_CHECK_NONE);
1129  dist = -1;
1130  m = lwgeom_tcpa(g1, g2, &dist);
1131  lwgeom_free(g1);
1132  lwgeom_free(g2);
1133  ASSERT_DOUBLE_EQUAL(m, 10.0);
1134  ASSERT_DOUBLE_EQUAL(dist, 2.0);
1135 
1136  /* Tracks, colliding, 2d */
1137 
1138  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1139  g2 = lwgeom_from_wkt("LINESTRING M(5 -8 0, 5 8 10)", LW_PARSER_CHECK_NONE);
1140  dist = -1;
1141  m = lwgeom_tcpa(g1, g2, &dist);
1142  lwgeom_free(g1);
1143  lwgeom_free(g2);
1144  ASSERT_DOUBLE_EQUAL(m, 5.0);
1145  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1146 
1147  /* Tracks crossing, NOT colliding, 2d */
1148 
1149  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1150  g2 = lwgeom_from_wkt("LINESTRING M(8 -5 0, 8 5 10)", LW_PARSER_CHECK_NONE);
1151  dist = -1;
1152  m = lwgeom_tcpa(g1, g2, &dist);
1153  lwgeom_free(g1);
1154  lwgeom_free(g2);
1155  ASSERT_DOUBLE_EQUAL(m, 6.5);
1156  ASSERT_DOUBLE_EQUAL(rint(dist*100), 212.0);
1157 
1158  /* Same origin, different direction, 2d */
1159 
1160  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1161  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, -100 0 10)", LW_PARSER_CHECK_NONE);
1162  dist = -1;
1163  m = lwgeom_tcpa(g1, g2, &dist);
1164  lwgeom_free(g1);
1165  lwgeom_free(g2);
1166  ASSERT_DOUBLE_EQUAL(m, 1.0);
1167  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1168 
1169  /* Same ending, different direction, 2d */
1170 
1171  g1 = lwgeom_from_wkt("LINESTRING M(10 0 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1172  g2 = lwgeom_from_wkt("LINESTRING M(0 -100 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1173  dist = -1;
1174  m = lwgeom_tcpa(g1, g2, &dist);
1175  lwgeom_free(g1);
1176  lwgeom_free(g2);
1177  ASSERT_DOUBLE_EQUAL(m, 10.0);
1178  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1179 
1180  /* Converging tracks, 3d */
1181 
1182  g1 = lwgeom_from_wkt("LINESTRING ZM(0 0 0 10, 10 0 0 20)", LW_PARSER_CHECK_NONE);
1183  g2 = lwgeom_from_wkt("LINESTRING ZM(0 0 8 10, 10 0 5 20)", LW_PARSER_CHECK_NONE);
1184  dist = -1;
1185  m = lwgeom_tcpa(g1, g2, &dist);
1186  lwgeom_free(g1);
1187  lwgeom_free(g2);
1188  ASSERT_DOUBLE_EQUAL(m, 20.0);
1189  ASSERT_DOUBLE_EQUAL(dist, 5.0);
1190 
1191  /* G1 stops at t=1 until t=4 to let G2 pass by, then continues */
1192  /* G2 passes at 1 meter from G1 t=3 */
1193 
1194  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 0 1 1, 0 1 4, 0 10 13)", LW_PARSER_CHECK_NONE);
1195  g2 = lwgeom_from_wkt("LINESTRING M(-10 2 0, 0 2 3, 12 2 13)", LW_PARSER_CHECK_NONE);
1196  dist = -1;
1197  m = lwgeom_tcpa(g1, g2, &dist);
1198  lwgeom_free(g1);
1199  lwgeom_free(g2);
1200  ASSERT_DOUBLE_EQUAL(m, 3.0);
1201  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1202 
1203  /* Test for https://trac.osgeo.org/postgis/ticket/3136 */
1204 
1205  g1 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,2 0 1432291536) ", LW_PARSER_CHECK_NONE);
1206  g2 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,1 0 1432291466.25,2 0 1432291500)", LW_PARSER_CHECK_NONE);
1207  dist = -1;
1208  m = lwgeom_tcpa(g1, g2, &dist);
1209  lwgeom_free(g1);
1210  lwgeom_free(g2);
1211  ASSERT_DOUBLE_EQUAL(m, 1432291464.0);
1212  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1213 
1214  /* Tracks share a single point in time */
1215 
1216  g1 = lwgeom_from_wkt("LINESTRINGM(0 0 0, 1 0 2)", LW_PARSER_CHECK_NONE);
1217  g2 = lwgeom_from_wkt("LINESTRINGM(0 0 2, 1 0 3)", LW_PARSER_CHECK_NONE);
1218  dist = -1;
1219  m = lwgeom_tcpa(g1, g2, &dist);
1220  lwgeom_free(g1);
1221  lwgeom_free(g2);
1222  ASSERT_DOUBLE_EQUAL(m, 2.0);
1223  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1224 
1225 }
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1050
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition: lwin_wkt.c:890
int lwgeom_cpa_within(const LWGEOM *g1, const LWGEOM *g2, double maxdist)
Is the closest point of approach within a distance ?
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:1869
#define LW_FALSE
Definition: liblwgeom.h:62
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:61
double lwgeom_tcpa(const LWGEOM *g1, const LWGEOM *g2, double *mindist)
Find the time of closest point of approach.
#define ASSERT_DOUBLE_EQUAL(o, e)
char cu_error_msg[MAX_CUNIT_ERROR_LENGTH+1]

Here is the call graph for this function:

Here is the caller graph for this function: