PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ test_lwgeom_tcpa()

static void test_lwgeom_tcpa ( void  )
static

Definition at line 1159 of file cu_measures.c.

1160 {
1161  LWGEOM *g1, *g2;
1162  double m, dist;
1163 
1164  /* Invalid input, lack of dimensions */
1165 
1166  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1167  g2 = lwgeom_from_wkt("LINESTRING (0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1168  m = lwgeom_tcpa(g1, g2, NULL);
1169  lwgeom_free(g1);
1170  lwgeom_free(g2);
1171  ASSERT_DOUBLE_EQUAL(m, -1.0);
1173  cu_error_msg,
1174  "Both input geometries must have a measure dimension");
1175 
1176  /* Invalid input, not linestrings */
1177 
1178  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1179  g2 = lwgeom_from_wkt("POINT M (0 0 2)", LW_PARSER_CHECK_NONE);
1180  m = lwgeom_tcpa(g1, g2, NULL);
1181  lwgeom_free(g1);
1182  lwgeom_free(g2);
1183  ASSERT_DOUBLE_EQUAL(m, -1.0);
1185  "Both input geometries must be linestrings");
1186 
1187  /* Invalid input, too short linestring */
1188 
1189  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1190  g2 = lwgeom_from_wkt("LINESTRING M(2 0 1)", LW_PARSER_CHECK_NONE);
1191  dist = -77;
1192  m = lwgeom_tcpa(g1, g2, &dist);
1193  lwgeom_free(g1);
1194  lwgeom_free(g2);
1195  ASSERT_DOUBLE_EQUAL(dist, -77.0); /* not touched */
1196  ASSERT_DOUBLE_EQUAL(m, -1.0);
1198  cu_error_msg,
1199  "Both input lines must have at least 2 points" /* should be accepted
1200  ? */
1201 
1202  );
1203 
1204  /* Invalid input, empty linestring */
1205 
1206  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1207  g2 = lwgeom_from_wkt("LINESTRING M EMPTY", LW_PARSER_CHECK_NONE);
1208  m = lwgeom_tcpa(g1, g2, NULL);
1209  lwgeom_free(g1);
1210  lwgeom_free(g2);
1211  ASSERT_DOUBLE_EQUAL(m, -1.0);
1213  "Both input lines must have at least 2 points"
1214 
1215  );
1216 
1217  /* Timeranges do not overlap */
1218 
1219  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1220  g2 = lwgeom_from_wkt("LINESTRING M(0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1221  m = lwgeom_tcpa(g1, g2, NULL);
1222  lwgeom_free(g1);
1223  lwgeom_free(g2);
1224  ASSERT_DOUBLE_EQUAL(m, -2.0); /* means timeranges do not overlap */
1225 
1226  /* One of the tracks is still, the other passes to that point */
1227 
1228  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1229  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1230  dist = -1;
1231  m = lwgeom_tcpa(g1, g2, &dist);
1232  ASSERT_DOUBLE_EQUAL(m, 1.0);
1233  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1234  CU_ASSERT( lwgeom_cpa_within(g1, g2, 0.0) == LW_TRUE );
1235  lwgeom_free(g1);
1236  lwgeom_free(g2);
1237 
1238  /* One of the tracks is still, the other passes at 10 meters from point */
1239 
1240  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1241  g2 = lwgeom_from_wkt("LINESTRING M(-10 10 1, 10 10 5)", LW_PARSER_CHECK_NONE);
1242  dist = -1;
1243  m = lwgeom_tcpa(g1, g2, &dist);
1244  ASSERT_DOUBLE_EQUAL(m, 3.0);
1245  ASSERT_DOUBLE_EQUAL(dist, 10.0);
1246  CU_ASSERT( lwgeom_cpa_within(g1, g2, 11.0) == LW_TRUE );
1247  CU_ASSERT( lwgeom_cpa_within(g1, g2, 10.0) == LW_TRUE );
1248  CU_ASSERT( lwgeom_cpa_within(g1, g2, 9.0) == LW_FALSE );
1249  lwgeom_free(g1);
1250  lwgeom_free(g2);
1251 
1252  /* Equal tracks, 2d */
1253 
1254  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1255  g2 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1256  dist = -1;
1257  m = lwgeom_tcpa(g1, g2, &dist);
1258  lwgeom_free(g1);
1259  lwgeom_free(g2);
1260  ASSERT_DOUBLE_EQUAL(m, 10.0);
1261  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1262 
1263  /* Reversed tracks, 2d */
1264 
1265  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1266  g2 = lwgeom_from_wkt("LINESTRING M(10 0 10, 0 0 20)", LW_PARSER_CHECK_NONE);
1267  dist = -1;
1268  m = lwgeom_tcpa(g1, g2, &dist);
1269  lwgeom_free(g1);
1270  lwgeom_free(g2);
1271  ASSERT_DOUBLE_EQUAL(m, 15.0);
1272  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1273 
1274  /* Parallel tracks, same speed, 2d */
1275 
1276  g1 = lwgeom_from_wkt("LINESTRING M(2 0 10, 12 0 20)", LW_PARSER_CHECK_NONE);
1277  g2 = lwgeom_from_wkt("LINESTRING M(13 0 10, 23 0 20)", LW_PARSER_CHECK_NONE);
1278  dist = -1;
1279  m = lwgeom_tcpa(g1, g2, &dist);
1280  lwgeom_free(g1);
1281  lwgeom_free(g2);
1282  ASSERT_DOUBLE_EQUAL(m, 10.0);
1283  ASSERT_DOUBLE_EQUAL(dist, 11.0);
1284 
1285  /* Parallel tracks, different speed (g2 gets closer as time passes), 2d */
1286 
1287  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1288  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 9 0 20)", LW_PARSER_CHECK_NONE);
1289  dist = -1;
1290  m = lwgeom_tcpa(g1, g2, &dist);
1291  lwgeom_free(g1);
1292  lwgeom_free(g2);
1293  ASSERT_DOUBLE_EQUAL(m, 20.0);
1294  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1295 
1296  /* Parallel tracks, different speed (g2 left behind as time passes), 2d */
1297 
1298  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1299  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 6 0 20)", LW_PARSER_CHECK_NONE);
1300  dist = -1;
1301  m = lwgeom_tcpa(g1, g2, &dist);
1302  lwgeom_free(g1);
1303  lwgeom_free(g2);
1304  ASSERT_DOUBLE_EQUAL(m, 10.0);
1305  ASSERT_DOUBLE_EQUAL(dist, 2.0);
1306 
1307  /* Tracks, colliding, 2d */
1308 
1309  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1310  g2 = lwgeom_from_wkt("LINESTRING M(5 -8 0, 5 8 10)", LW_PARSER_CHECK_NONE);
1311  dist = -1;
1312  m = lwgeom_tcpa(g1, g2, &dist);
1313  lwgeom_free(g1);
1314  lwgeom_free(g2);
1315  ASSERT_DOUBLE_EQUAL(m, 5.0);
1316  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1317 
1318  /* Tracks crossing, NOT colliding, 2d */
1319 
1320  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1321  g2 = lwgeom_from_wkt("LINESTRING M(8 -5 0, 8 5 10)", LW_PARSER_CHECK_NONE);
1322  dist = -1;
1323  m = lwgeom_tcpa(g1, g2, &dist);
1324  lwgeom_free(g1);
1325  lwgeom_free(g2);
1326  ASSERT_DOUBLE_EQUAL(m, 6.5);
1327  ASSERT_DOUBLE_EQUAL(rint(dist*100), 212.0);
1328 
1329  /* Same origin, different direction, 2d */
1330 
1331  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1332  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, -100 0 10)", LW_PARSER_CHECK_NONE);
1333  dist = -1;
1334  m = lwgeom_tcpa(g1, g2, &dist);
1335  lwgeom_free(g1);
1336  lwgeom_free(g2);
1337  ASSERT_DOUBLE_EQUAL(m, 1.0);
1338  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1339 
1340  /* Same ending, different direction, 2d */
1341 
1342  g1 = lwgeom_from_wkt("LINESTRING M(10 0 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1343  g2 = lwgeom_from_wkt("LINESTRING M(0 -100 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1344  dist = -1;
1345  m = lwgeom_tcpa(g1, g2, &dist);
1346  lwgeom_free(g1);
1347  lwgeom_free(g2);
1348  ASSERT_DOUBLE_EQUAL(m, 10.0);
1349  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1350 
1351  /* Converging tracks, 3d */
1352 
1353  g1 = lwgeom_from_wkt("LINESTRING ZM(0 0 0 10, 10 0 0 20)", LW_PARSER_CHECK_NONE);
1354  g2 = lwgeom_from_wkt("LINESTRING ZM(0 0 8 10, 10 0 5 20)", LW_PARSER_CHECK_NONE);
1355  dist = -1;
1356  m = lwgeom_tcpa(g1, g2, &dist);
1357  lwgeom_free(g1);
1358  lwgeom_free(g2);
1359  ASSERT_DOUBLE_EQUAL(m, 20.0);
1360  ASSERT_DOUBLE_EQUAL(dist, 5.0);
1361 
1362  /* G1 stops at t=1 until t=4 to let G2 pass by, then continues */
1363  /* G2 passes at 1 meter from G1 t=3 */
1364 
1365  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 0 1 1, 0 1 4, 0 10 13)", LW_PARSER_CHECK_NONE);
1366  g2 = lwgeom_from_wkt("LINESTRING M(-10 2 0, 0 2 3, 12 2 13)", LW_PARSER_CHECK_NONE);
1367  dist = -1;
1368  m = lwgeom_tcpa(g1, g2, &dist);
1369  lwgeom_free(g1);
1370  lwgeom_free(g2);
1371  ASSERT_DOUBLE_EQUAL(m, 3.0);
1372  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1373 
1374  /* Test for https://trac.osgeo.org/postgis/ticket/3136 */
1375 
1376  g1 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,2 0 1432291536) ", LW_PARSER_CHECK_NONE);
1377  g2 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,1 0 1432291466.25,2 0 1432291500)", LW_PARSER_CHECK_NONE);
1378  dist = -1;
1379  m = lwgeom_tcpa(g1, g2, &dist);
1380  lwgeom_free(g1);
1381  lwgeom_free(g2);
1382  ASSERT_DOUBLE_EQUAL(m, 1432291464.0);
1383  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1384 
1385  /* Tracks share a single point in time */
1386 
1387  g1 = lwgeom_from_wkt("LINESTRINGM(0 0 0, 1 0 2)", LW_PARSER_CHECK_NONE);
1388  g2 = lwgeom_from_wkt("LINESTRINGM(0 0 2, 1 0 3)", LW_PARSER_CHECK_NONE);
1389  dist = -1;
1390  m = lwgeom_tcpa(g1, g2, &dist);
1391  lwgeom_free(g1);
1392  lwgeom_free(g2);
1393  ASSERT_DOUBLE_EQUAL(m, 2.0);
1394  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1395 
1396 }
char cu_error_msg[MAX_CUNIT_ERROR_LENGTH+1]
#define ASSERT_DOUBLE_EQUAL(o, e)
#define ASSERT_STRING_EQUAL(o, e)
#define LW_FALSE
Definition: liblwgeom.h:77
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1144
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2005
double lwgeom_tcpa(const LWGEOM *g1, const LWGEOM *g2, double *mindist)
Find the time of closest point of approach.
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 lwgeom_cpa_within(const LWGEOM *g1, const LWGEOM *g2, double maxdist)
Is the closest point of approach within a distance ?

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

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