PostGIS  2.5.0beta1dev-r@@SVN_REVISION@@

◆ test_lwgeom_tcpa()

static void test_lwgeom_tcpa ( void  )
static

Definition at line 1096 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().

1097 {
1098  LWGEOM *g1, *g2;
1099  double m, dist;
1100 
1101  /* Invalid input, lack of dimensions */
1102 
1103  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1104  g2 = lwgeom_from_wkt("LINESTRING (0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1105  m = lwgeom_tcpa(g1, g2, NULL);
1106  lwgeom_free(g1);
1107  lwgeom_free(g2);
1108  ASSERT_DOUBLE_EQUAL(m, -1.0);
1110  cu_error_msg,
1111  "Both input geometries must have a measure dimension");
1112 
1113  /* Invalid input, not linestrings */
1114 
1115  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1116  g2 = lwgeom_from_wkt("POINT M (0 0 2)", LW_PARSER_CHECK_NONE);
1117  m = lwgeom_tcpa(g1, g2, NULL);
1118  lwgeom_free(g1);
1119  lwgeom_free(g2);
1120  ASSERT_DOUBLE_EQUAL(m, -1.0);
1122  "Both input geometries must be linestrings");
1123 
1124  /* Invalid input, too short linestring */
1125 
1126  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1127  g2 = lwgeom_from_wkt("LINESTRING M(2 0 1)", LW_PARSER_CHECK_NONE);
1128  dist = -77;
1129  m = lwgeom_tcpa(g1, g2, &dist);
1130  lwgeom_free(g1);
1131  lwgeom_free(g2);
1132  ASSERT_DOUBLE_EQUAL(dist, -77.0); /* not touched */
1133  ASSERT_DOUBLE_EQUAL(m, -1.0);
1135  cu_error_msg,
1136  "Both input lines must have at least 2 points" /* should be accepted
1137  ? */
1138 
1139  );
1140 
1141  /* Invalid input, empty linestring */
1142 
1143  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1144  g2 = lwgeom_from_wkt("LINESTRING M EMPTY", LW_PARSER_CHECK_NONE);
1145  m = lwgeom_tcpa(g1, g2, NULL);
1146  lwgeom_free(g1);
1147  lwgeom_free(g2);
1148  ASSERT_DOUBLE_EQUAL(m, -1.0);
1150  "Both input lines must have at least 2 points"
1151 
1152  );
1153 
1154  /* Timeranges do not overlap */
1155 
1156  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1157  g2 = lwgeom_from_wkt("LINESTRING M(0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1158  m = lwgeom_tcpa(g1, g2, NULL);
1159  lwgeom_free(g1);
1160  lwgeom_free(g2);
1161  ASSERT_DOUBLE_EQUAL(m, -2.0); /* means timeranges do not overlap */
1162 
1163  /* One of the tracks is still, the other passes to that point */
1164 
1165  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1166  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1167  dist = -1;
1168  m = lwgeom_tcpa(g1, g2, &dist);
1169  ASSERT_DOUBLE_EQUAL(m, 1.0);
1170  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1171  CU_ASSERT( lwgeom_cpa_within(g1, g2, 0.0) == LW_TRUE );
1172  lwgeom_free(g1);
1173  lwgeom_free(g2);
1174 
1175  /* One of the tracks is still, the other passes at 10 meters from point */
1176 
1177  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1178  g2 = lwgeom_from_wkt("LINESTRING M(-10 10 1, 10 10 5)", LW_PARSER_CHECK_NONE);
1179  dist = -1;
1180  m = lwgeom_tcpa(g1, g2, &dist);
1181  ASSERT_DOUBLE_EQUAL(m, 3.0);
1182  ASSERT_DOUBLE_EQUAL(dist, 10.0);
1183  CU_ASSERT( lwgeom_cpa_within(g1, g2, 11.0) == LW_TRUE );
1184  CU_ASSERT( lwgeom_cpa_within(g1, g2, 10.0) == LW_TRUE );
1185  CU_ASSERT( lwgeom_cpa_within(g1, g2, 9.0) == LW_FALSE );
1186  lwgeom_free(g1);
1187  lwgeom_free(g2);
1188 
1189  /* Equal tracks, 2d */
1190 
1191  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1192  g2 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1193  dist = -1;
1194  m = lwgeom_tcpa(g1, g2, &dist);
1195  lwgeom_free(g1);
1196  lwgeom_free(g2);
1197  ASSERT_DOUBLE_EQUAL(m, 10.0);
1198  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1199 
1200  /* Reversed tracks, 2d */
1201 
1202  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1203  g2 = lwgeom_from_wkt("LINESTRING M(10 0 10, 0 0 20)", LW_PARSER_CHECK_NONE);
1204  dist = -1;
1205  m = lwgeom_tcpa(g1, g2, &dist);
1206  lwgeom_free(g1);
1207  lwgeom_free(g2);
1208  ASSERT_DOUBLE_EQUAL(m, 15.0);
1209  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1210 
1211  /* Parallel tracks, same speed, 2d */
1212 
1213  g1 = lwgeom_from_wkt("LINESTRING M(2 0 10, 12 0 20)", LW_PARSER_CHECK_NONE);
1214  g2 = lwgeom_from_wkt("LINESTRING M(13 0 10, 23 0 20)", LW_PARSER_CHECK_NONE);
1215  dist = -1;
1216  m = lwgeom_tcpa(g1, g2, &dist);
1217  lwgeom_free(g1);
1218  lwgeom_free(g2);
1219  ASSERT_DOUBLE_EQUAL(m, 10.0);
1220  ASSERT_DOUBLE_EQUAL(dist, 11.0);
1221 
1222  /* Parallel tracks, different speed (g2 gets closer as time passes), 2d */
1223 
1224  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1225  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 9 0 20)", LW_PARSER_CHECK_NONE);
1226  dist = -1;
1227  m = lwgeom_tcpa(g1, g2, &dist);
1228  lwgeom_free(g1);
1229  lwgeom_free(g2);
1230  ASSERT_DOUBLE_EQUAL(m, 20.0);
1231  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1232 
1233  /* Parallel tracks, different speed (g2 left behind as time passes), 2d */
1234 
1235  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1236  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 6 0 20)", LW_PARSER_CHECK_NONE);
1237  dist = -1;
1238  m = lwgeom_tcpa(g1, g2, &dist);
1239  lwgeom_free(g1);
1240  lwgeom_free(g2);
1241  ASSERT_DOUBLE_EQUAL(m, 10.0);
1242  ASSERT_DOUBLE_EQUAL(dist, 2.0);
1243 
1244  /* Tracks, colliding, 2d */
1245 
1246  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1247  g2 = lwgeom_from_wkt("LINESTRING M(5 -8 0, 5 8 10)", LW_PARSER_CHECK_NONE);
1248  dist = -1;
1249  m = lwgeom_tcpa(g1, g2, &dist);
1250  lwgeom_free(g1);
1251  lwgeom_free(g2);
1252  ASSERT_DOUBLE_EQUAL(m, 5.0);
1253  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1254 
1255  /* Tracks crossing, NOT colliding, 2d */
1256 
1257  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1258  g2 = lwgeom_from_wkt("LINESTRING M(8 -5 0, 8 5 10)", LW_PARSER_CHECK_NONE);
1259  dist = -1;
1260  m = lwgeom_tcpa(g1, g2, &dist);
1261  lwgeom_free(g1);
1262  lwgeom_free(g2);
1263  ASSERT_DOUBLE_EQUAL(m, 6.5);
1264  ASSERT_DOUBLE_EQUAL(rint(dist*100), 212.0);
1265 
1266  /* Same origin, different direction, 2d */
1267 
1268  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1269  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, -100 0 10)", LW_PARSER_CHECK_NONE);
1270  dist = -1;
1271  m = lwgeom_tcpa(g1, g2, &dist);
1272  lwgeom_free(g1);
1273  lwgeom_free(g2);
1274  ASSERT_DOUBLE_EQUAL(m, 1.0);
1275  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1276 
1277  /* Same ending, different direction, 2d */
1278 
1279  g1 = lwgeom_from_wkt("LINESTRING M(10 0 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1280  g2 = lwgeom_from_wkt("LINESTRING M(0 -100 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1281  dist = -1;
1282  m = lwgeom_tcpa(g1, g2, &dist);
1283  lwgeom_free(g1);
1284  lwgeom_free(g2);
1285  ASSERT_DOUBLE_EQUAL(m, 10.0);
1286  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1287 
1288  /* Converging tracks, 3d */
1289 
1290  g1 = lwgeom_from_wkt("LINESTRING ZM(0 0 0 10, 10 0 0 20)", LW_PARSER_CHECK_NONE);
1291  g2 = lwgeom_from_wkt("LINESTRING ZM(0 0 8 10, 10 0 5 20)", LW_PARSER_CHECK_NONE);
1292  dist = -1;
1293  m = lwgeom_tcpa(g1, g2, &dist);
1294  lwgeom_free(g1);
1295  lwgeom_free(g2);
1296  ASSERT_DOUBLE_EQUAL(m, 20.0);
1297  ASSERT_DOUBLE_EQUAL(dist, 5.0);
1298 
1299  /* G1 stops at t=1 until t=4 to let G2 pass by, then continues */
1300  /* G2 passes at 1 meter from G1 t=3 */
1301 
1302  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 0 1 1, 0 1 4, 0 10 13)", LW_PARSER_CHECK_NONE);
1303  g2 = lwgeom_from_wkt("LINESTRING M(-10 2 0, 0 2 3, 12 2 13)", LW_PARSER_CHECK_NONE);
1304  dist = -1;
1305  m = lwgeom_tcpa(g1, g2, &dist);
1306  lwgeom_free(g1);
1307  lwgeom_free(g2);
1308  ASSERT_DOUBLE_EQUAL(m, 3.0);
1309  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1310 
1311  /* Test for https://trac.osgeo.org/postgis/ticket/3136 */
1312 
1313  g1 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,2 0 1432291536) ", LW_PARSER_CHECK_NONE);
1314  g2 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,1 0 1432291466.25,2 0 1432291500)", LW_PARSER_CHECK_NONE);
1315  dist = -1;
1316  m = lwgeom_tcpa(g1, g2, &dist);
1317  lwgeom_free(g1);
1318  lwgeom_free(g2);
1319  ASSERT_DOUBLE_EQUAL(m, 1432291464.0);
1320  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1321 
1322  /* Tracks share a single point in time */
1323 
1324  g1 = lwgeom_from_wkt("LINESTRINGM(0 0 0, 1 0 2)", LW_PARSER_CHECK_NONE);
1325  g2 = lwgeom_from_wkt("LINESTRINGM(0 0 2, 1 0 3)", LW_PARSER_CHECK_NONE);
1326  dist = -1;
1327  m = lwgeom_tcpa(g1, g2, &dist);
1328  lwgeom_free(g1);
1329  lwgeom_free(g2);
1330  ASSERT_DOUBLE_EQUAL(m, 2.0);
1331  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1332 
1333 }
#define ASSERT_STRING_EQUAL(o, e)
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1144
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:2004
#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: