PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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);
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);
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:1246
#define LW_PARSER_CHECK_NONE
Definition liblwgeom.h:2149
double lwgeom_tcpa(const LWGEOM *g1, const LWGEOM *g2, double *mindist)
Find the time of closest point of approach.
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition lwin_wkt.c:940
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: