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

Definition at line 989 of file cu_measures.c.

References ASSERT_DOUBLE_EQUAL, ASSERT_STRING_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().

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