PostGIS  3.6.1dev-r@@SVN_REVISION@@

◆ test_lwgeom_tcpa()

static void test_lwgeom_tcpa ( void  )
static

Definition at line 1300 of file cu_measures.c.

1301 {
1302  LWGEOM *g1, *g2;
1303  double m, dist;
1304 
1305  /* Invalid input, lack of dimensions */
1306 
1307  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1308  g2 = lwgeom_from_wkt("LINESTRING (0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1309  m = lwgeom_tcpa(g1, g2, NULL);
1310  lwgeom_free(g1);
1311  lwgeom_free(g2);
1312  ASSERT_DOUBLE_EQUAL(m, -1.0);
1314  cu_error_msg,
1315  "Both input geometries must have a measure dimension");
1316 
1317  /* Invalid input, not linestrings */
1318 
1319  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1320  g2 = lwgeom_from_wkt("POINT M (0 0 2)", LW_PARSER_CHECK_NONE);
1321  m = lwgeom_tcpa(g1, g2, NULL);
1322  lwgeom_free(g1);
1323  lwgeom_free(g2);
1324  ASSERT_DOUBLE_EQUAL(m, -1.0);
1326  "Both input geometries must be linestrings");
1327 
1328  /* Invalid input, too short linestring */
1329 
1330  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1331  g2 = lwgeom_from_wkt("LINESTRING M(2 0 1)", LW_PARSER_CHECK_NONE);
1332  dist = -77;
1333  m = lwgeom_tcpa(g1, g2, &dist);
1334  lwgeom_free(g1);
1335  lwgeom_free(g2);
1336  ASSERT_DOUBLE_EQUAL(dist, -77.0); /* not touched */
1337  ASSERT_DOUBLE_EQUAL(m, -1.0);
1339  cu_error_msg,
1340  "Both input lines must have at least 2 points" /* should be accepted
1341  ? */
1342 
1343  );
1344 
1345  /* Invalid input, empty linestring */
1346 
1347  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1348  g2 = lwgeom_from_wkt("LINESTRING M EMPTY", LW_PARSER_CHECK_NONE);
1349  m = lwgeom_tcpa(g1, g2, NULL);
1350  lwgeom_free(g1);
1351  lwgeom_free(g2);
1352  ASSERT_DOUBLE_EQUAL(m, -1.0);
1354  "Both input lines must have at least 2 points"
1355 
1356  );
1357 
1358  /* Timeranges do not overlap */
1359 
1360  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1361  g2 = lwgeom_from_wkt("LINESTRING M(0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1362  m = lwgeom_tcpa(g1, g2, NULL);
1363  lwgeom_free(g1);
1364  lwgeom_free(g2);
1365  ASSERT_DOUBLE_EQUAL(m, -2.0); /* means timeranges do not overlap */
1366 
1367  /* One of the tracks is still, the other passes to that point */
1368 
1369  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1370  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1371  dist = -1;
1372  m = lwgeom_tcpa(g1, g2, &dist);
1373  ASSERT_DOUBLE_EQUAL(m, 1.0);
1374  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1375  CU_ASSERT( lwgeom_cpa_within(g1, g2, 0.0) == LW_TRUE );
1376  lwgeom_free(g1);
1377  lwgeom_free(g2);
1378 
1379  /* One of the tracks is still, the other passes at 10 meters from point */
1380 
1381  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1382  g2 = lwgeom_from_wkt("LINESTRING M(-10 10 1, 10 10 5)", LW_PARSER_CHECK_NONE);
1383  dist = -1;
1384  m = lwgeom_tcpa(g1, g2, &dist);
1385  ASSERT_DOUBLE_EQUAL(m, 3.0);
1386  ASSERT_DOUBLE_EQUAL(dist, 10.0);
1387  CU_ASSERT( lwgeom_cpa_within(g1, g2, 11.0) == LW_TRUE );
1388  CU_ASSERT( lwgeom_cpa_within(g1, g2, 10.0) == LW_TRUE );
1389  CU_ASSERT( lwgeom_cpa_within(g1, g2, 9.0) == LW_FALSE );
1390  lwgeom_free(g1);
1391  lwgeom_free(g2);
1392 
1393  /* Equal tracks, 2d */
1394 
1395  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1396  g2 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1397  dist = -1;
1398  m = lwgeom_tcpa(g1, g2, &dist);
1399  lwgeom_free(g1);
1400  lwgeom_free(g2);
1401  ASSERT_DOUBLE_EQUAL(m, 10.0);
1402  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1403 
1404  /* Reversed tracks, 2d */
1405 
1406  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1407  g2 = lwgeom_from_wkt("LINESTRING M(10 0 10, 0 0 20)", LW_PARSER_CHECK_NONE);
1408  dist = -1;
1409  m = lwgeom_tcpa(g1, g2, &dist);
1410  lwgeom_free(g1);
1411  lwgeom_free(g2);
1412  ASSERT_DOUBLE_EQUAL(m, 15.0);
1413  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1414 
1415  /* Parallel tracks, same speed, 2d */
1416 
1417  g1 = lwgeom_from_wkt("LINESTRING M(2 0 10, 12 0 20)", LW_PARSER_CHECK_NONE);
1418  g2 = lwgeom_from_wkt("LINESTRING M(13 0 10, 23 0 20)", LW_PARSER_CHECK_NONE);
1419  dist = -1;
1420  m = lwgeom_tcpa(g1, g2, &dist);
1421  lwgeom_free(g1);
1422  lwgeom_free(g2);
1423  ASSERT_DOUBLE_EQUAL(m, 10.0);
1424  ASSERT_DOUBLE_EQUAL(dist, 11.0);
1425 
1426  /* Parallel tracks, different speed (g2 gets closer as time passes), 2d */
1427 
1428  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1429  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 9 0 20)", LW_PARSER_CHECK_NONE);
1430  dist = -1;
1431  m = lwgeom_tcpa(g1, g2, &dist);
1432  lwgeom_free(g1);
1433  lwgeom_free(g2);
1434  ASSERT_DOUBLE_EQUAL(m, 20.0);
1435  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1436 
1437  /* Parallel tracks, different speed (g2 left behind as time passes), 2d */
1438 
1439  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1440  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 6 0 20)", LW_PARSER_CHECK_NONE);
1441  dist = -1;
1442  m = lwgeom_tcpa(g1, g2, &dist);
1443  lwgeom_free(g1);
1444  lwgeom_free(g2);
1445  ASSERT_DOUBLE_EQUAL(m, 10.0);
1446  ASSERT_DOUBLE_EQUAL(dist, 2.0);
1447 
1448  /* Tracks, colliding, 2d */
1449 
1450  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1451  g2 = lwgeom_from_wkt("LINESTRING M(5 -8 0, 5 8 10)", LW_PARSER_CHECK_NONE);
1452  dist = -1;
1453  m = lwgeom_tcpa(g1, g2, &dist);
1454  lwgeom_free(g1);
1455  lwgeom_free(g2);
1456  ASSERT_DOUBLE_EQUAL(m, 5.0);
1457  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1458 
1459  /* Tracks crossing, NOT colliding, 2d */
1460 
1461  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1462  g2 = lwgeom_from_wkt("LINESTRING M(8 -5 0, 8 5 10)", LW_PARSER_CHECK_NONE);
1463  dist = -1;
1464  m = lwgeom_tcpa(g1, g2, &dist);
1465  lwgeom_free(g1);
1466  lwgeom_free(g2);
1467  ASSERT_DOUBLE_EQUAL(m, 6.5);
1468  ASSERT_DOUBLE_EQUAL(rint(dist*100), 212.0);
1469 
1470  /* Same origin, different direction, 2d */
1471 
1472  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1473  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, -100 0 10)", LW_PARSER_CHECK_NONE);
1474  dist = -1;
1475  m = lwgeom_tcpa(g1, g2, &dist);
1476  lwgeom_free(g1);
1477  lwgeom_free(g2);
1478  ASSERT_DOUBLE_EQUAL(m, 1.0);
1479  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1480 
1481  /* Same ending, different direction, 2d */
1482 
1483  g1 = lwgeom_from_wkt("LINESTRING M(10 0 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1484  g2 = lwgeom_from_wkt("LINESTRING M(0 -100 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1485  dist = -1;
1486  m = lwgeom_tcpa(g1, g2, &dist);
1487  lwgeom_free(g1);
1488  lwgeom_free(g2);
1489  ASSERT_DOUBLE_EQUAL(m, 10.0);
1490  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1491 
1492  /* Converging tracks, 3d */
1493 
1494  g1 = lwgeom_from_wkt("LINESTRING ZM(0 0 0 10, 10 0 0 20)", LW_PARSER_CHECK_NONE);
1495  g2 = lwgeom_from_wkt("LINESTRING ZM(0 0 8 10, 10 0 5 20)", LW_PARSER_CHECK_NONE);
1496  dist = -1;
1497  m = lwgeom_tcpa(g1, g2, &dist);
1498  lwgeom_free(g1);
1499  lwgeom_free(g2);
1500  ASSERT_DOUBLE_EQUAL(m, 20.0);
1501  ASSERT_DOUBLE_EQUAL(dist, 5.0);
1502 
1503  /* G1 stops at t=1 until t=4 to let G2 pass by, then continues */
1504  /* G2 passes at 1 meter from G1 t=3 */
1505 
1506  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 0 1 1, 0 1 4, 0 10 13)", LW_PARSER_CHECK_NONE);
1507  g2 = lwgeom_from_wkt("LINESTRING M(-10 2 0, 0 2 3, 12 2 13)", LW_PARSER_CHECK_NONE);
1508  dist = -1;
1509  m = lwgeom_tcpa(g1, g2, &dist);
1510  lwgeom_free(g1);
1511  lwgeom_free(g2);
1512  ASSERT_DOUBLE_EQUAL(m, 3.0);
1513  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1514 
1515  /* Test for https://trac.osgeo.org/postgis/ticket/3136 */
1516 
1517  g1 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,2 0 1432291536) ", LW_PARSER_CHECK_NONE);
1518  g2 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,1 0 1432291466.25,2 0 1432291500)", LW_PARSER_CHECK_NONE);
1519  dist = -1;
1520  m = lwgeom_tcpa(g1, g2, &dist);
1521  lwgeom_free(g1);
1522  lwgeom_free(g2);
1523  ASSERT_DOUBLE_EQUAL(m, 1432291464.0);
1524  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1525 
1526  /* Tracks share a single point in time */
1527 
1528  g1 = lwgeom_from_wkt("LINESTRINGM(0 0 0, 1 0 2)", LW_PARSER_CHECK_NONE);
1529  g2 = lwgeom_from_wkt("LINESTRINGM(0 0 2, 1 0 3)", LW_PARSER_CHECK_NONE);
1530  dist = -1;
1531  m = lwgeom_tcpa(g1, g2, &dist);
1532  lwgeom_free(g1);
1533  lwgeom_free(g2);
1534  ASSERT_DOUBLE_EQUAL(m, 2.0);
1535  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1536 
1537 }
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:94
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1218
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2146
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:940
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:93
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: