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

◆ test_lwgeom_tcpa()

static void test_lwgeom_tcpa ( void  )
static

Definition at line 1251 of file cu_measures.c.

1252{
1253 LWGEOM *g1, *g2;
1254 double m, dist;
1255
1256 /* Invalid input, lack of dimensions */
1257
1258 g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1259 g2 = lwgeom_from_wkt("LINESTRING (0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1260 m = lwgeom_tcpa(g1, g2, NULL);
1261 lwgeom_free(g1);
1262 lwgeom_free(g2);
1263 ASSERT_DOUBLE_EQUAL(m, -1.0);
1266 "Both input geometries must have a measure dimension");
1267
1268 /* Invalid input, not linestrings */
1269
1270 g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1271 g2 = lwgeom_from_wkt("POINT M (0 0 2)", LW_PARSER_CHECK_NONE);
1272 m = lwgeom_tcpa(g1, g2, NULL);
1273 lwgeom_free(g1);
1274 lwgeom_free(g2);
1275 ASSERT_DOUBLE_EQUAL(m, -1.0);
1277 "Both input geometries must be linestrings");
1278
1279 /* Invalid input, too short linestring */
1280
1281 g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1282 g2 = lwgeom_from_wkt("LINESTRING M(2 0 1)", LW_PARSER_CHECK_NONE);
1283 dist = -77;
1284 m = lwgeom_tcpa(g1, g2, &dist);
1285 lwgeom_free(g1);
1286 lwgeom_free(g2);
1287 ASSERT_DOUBLE_EQUAL(dist, -77.0); /* not touched */
1288 ASSERT_DOUBLE_EQUAL(m, -1.0);
1291 "Both input lines must have at least 2 points" /* should be accepted
1292 ? */
1293
1294 );
1295
1296 /* Invalid input, empty linestring */
1297
1298 g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1299 g2 = lwgeom_from_wkt("LINESTRING M EMPTY", LW_PARSER_CHECK_NONE);
1300 m = lwgeom_tcpa(g1, g2, NULL);
1301 lwgeom_free(g1);
1302 lwgeom_free(g2);
1303 ASSERT_DOUBLE_EQUAL(m, -1.0);
1305 "Both input lines must have at least 2 points"
1306
1307 );
1308
1309 /* Timeranges do not overlap */
1310
1311 g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1312 g2 = lwgeom_from_wkt("LINESTRING M(0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1313 m = lwgeom_tcpa(g1, g2, NULL);
1314 lwgeom_free(g1);
1315 lwgeom_free(g2);
1316 ASSERT_DOUBLE_EQUAL(m, -2.0); /* means timeranges do not overlap */
1317
1318 /* One of the tracks is still, the other passes to that point */
1319
1320 g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1321 g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1322 dist = -1;
1323 m = lwgeom_tcpa(g1, g2, &dist);
1324 ASSERT_DOUBLE_EQUAL(m, 1.0);
1325 ASSERT_DOUBLE_EQUAL(dist, 0.0);
1326 CU_ASSERT( lwgeom_cpa_within(g1, g2, 0.0) == LW_TRUE );
1327 lwgeom_free(g1);
1328 lwgeom_free(g2);
1329
1330 /* One of the tracks is still, the other passes at 10 meters from point */
1331
1332 g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1333 g2 = lwgeom_from_wkt("LINESTRING M(-10 10 1, 10 10 5)", LW_PARSER_CHECK_NONE);
1334 dist = -1;
1335 m = lwgeom_tcpa(g1, g2, &dist);
1336 ASSERT_DOUBLE_EQUAL(m, 3.0);
1337 ASSERT_DOUBLE_EQUAL(dist, 10.0);
1338 CU_ASSERT( lwgeom_cpa_within(g1, g2, 11.0) == LW_TRUE );
1339 CU_ASSERT( lwgeom_cpa_within(g1, g2, 10.0) == LW_TRUE );
1340 CU_ASSERT( lwgeom_cpa_within(g1, g2, 9.0) == LW_FALSE );
1341 lwgeom_free(g1);
1342 lwgeom_free(g2);
1343
1344 /* Equal tracks, 2d */
1345
1346 g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1347 g2 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1348 dist = -1;
1349 m = lwgeom_tcpa(g1, g2, &dist);
1350 lwgeom_free(g1);
1351 lwgeom_free(g2);
1352 ASSERT_DOUBLE_EQUAL(m, 10.0);
1353 ASSERT_DOUBLE_EQUAL(dist, 0.0);
1354
1355 /* Reversed tracks, 2d */
1356
1357 g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1358 g2 = lwgeom_from_wkt("LINESTRING M(10 0 10, 0 0 20)", LW_PARSER_CHECK_NONE);
1359 dist = -1;
1360 m = lwgeom_tcpa(g1, g2, &dist);
1361 lwgeom_free(g1);
1362 lwgeom_free(g2);
1363 ASSERT_DOUBLE_EQUAL(m, 15.0);
1364 ASSERT_DOUBLE_EQUAL(dist, 0.0);
1365
1366 /* Parallel tracks, same speed, 2d */
1367
1368 g1 = lwgeom_from_wkt("LINESTRING M(2 0 10, 12 0 20)", LW_PARSER_CHECK_NONE);
1369 g2 = lwgeom_from_wkt("LINESTRING M(13 0 10, 23 0 20)", LW_PARSER_CHECK_NONE);
1370 dist = -1;
1371 m = lwgeom_tcpa(g1, g2, &dist);
1372 lwgeom_free(g1);
1373 lwgeom_free(g2);
1374 ASSERT_DOUBLE_EQUAL(m, 10.0);
1375 ASSERT_DOUBLE_EQUAL(dist, 11.0);
1376
1377 /* Parallel tracks, different speed (g2 gets closer as time passes), 2d */
1378
1379 g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1380 g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 9 0 20)", LW_PARSER_CHECK_NONE);
1381 dist = -1;
1382 m = lwgeom_tcpa(g1, g2, &dist);
1383 lwgeom_free(g1);
1384 lwgeom_free(g2);
1385 ASSERT_DOUBLE_EQUAL(m, 20.0);
1386 ASSERT_DOUBLE_EQUAL(dist, 1.0);
1387
1388 /* Parallel tracks, different speed (g2 left behind as time passes), 2d */
1389
1390 g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1391 g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 6 0 20)", LW_PARSER_CHECK_NONE);
1392 dist = -1;
1393 m = lwgeom_tcpa(g1, g2, &dist);
1394 lwgeom_free(g1);
1395 lwgeom_free(g2);
1396 ASSERT_DOUBLE_EQUAL(m, 10.0);
1397 ASSERT_DOUBLE_EQUAL(dist, 2.0);
1398
1399 /* Tracks, colliding, 2d */
1400
1401 g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1402 g2 = lwgeom_from_wkt("LINESTRING M(5 -8 0, 5 8 10)", LW_PARSER_CHECK_NONE);
1403 dist = -1;
1404 m = lwgeom_tcpa(g1, g2, &dist);
1405 lwgeom_free(g1);
1406 lwgeom_free(g2);
1407 ASSERT_DOUBLE_EQUAL(m, 5.0);
1408 ASSERT_DOUBLE_EQUAL(dist, 0.0);
1409
1410 /* Tracks crossing, NOT colliding, 2d */
1411
1412 g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1413 g2 = lwgeom_from_wkt("LINESTRING M(8 -5 0, 8 5 10)", LW_PARSER_CHECK_NONE);
1414 dist = -1;
1415 m = lwgeom_tcpa(g1, g2, &dist);
1416 lwgeom_free(g1);
1417 lwgeom_free(g2);
1418 ASSERT_DOUBLE_EQUAL(m, 6.5);
1419 ASSERT_DOUBLE_EQUAL(rint(dist*100), 212.0);
1420
1421 /* Same origin, different direction, 2d */
1422
1423 g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1424 g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, -100 0 10)", LW_PARSER_CHECK_NONE);
1425 dist = -1;
1426 m = lwgeom_tcpa(g1, g2, &dist);
1427 lwgeom_free(g1);
1428 lwgeom_free(g2);
1429 ASSERT_DOUBLE_EQUAL(m, 1.0);
1430 ASSERT_DOUBLE_EQUAL(dist, 0.0);
1431
1432 /* Same ending, different direction, 2d */
1433
1434 g1 = lwgeom_from_wkt("LINESTRING M(10 0 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1435 g2 = lwgeom_from_wkt("LINESTRING M(0 -100 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1436 dist = -1;
1437 m = lwgeom_tcpa(g1, g2, &dist);
1438 lwgeom_free(g1);
1439 lwgeom_free(g2);
1440 ASSERT_DOUBLE_EQUAL(m, 10.0);
1441 ASSERT_DOUBLE_EQUAL(dist, 0.0);
1442
1443 /* Converging tracks, 3d */
1444
1445 g1 = lwgeom_from_wkt("LINESTRING ZM(0 0 0 10, 10 0 0 20)", LW_PARSER_CHECK_NONE);
1446 g2 = lwgeom_from_wkt("LINESTRING ZM(0 0 8 10, 10 0 5 20)", LW_PARSER_CHECK_NONE);
1447 dist = -1;
1448 m = lwgeom_tcpa(g1, g2, &dist);
1449 lwgeom_free(g1);
1450 lwgeom_free(g2);
1451 ASSERT_DOUBLE_EQUAL(m, 20.0);
1452 ASSERT_DOUBLE_EQUAL(dist, 5.0);
1453
1454 /* G1 stops at t=1 until t=4 to let G2 pass by, then continues */
1455 /* G2 passes at 1 meter from G1 t=3 */
1456
1457 g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 0 1 1, 0 1 4, 0 10 13)", LW_PARSER_CHECK_NONE);
1458 g2 = lwgeom_from_wkt("LINESTRING M(-10 2 0, 0 2 3, 12 2 13)", LW_PARSER_CHECK_NONE);
1459 dist = -1;
1460 m = lwgeom_tcpa(g1, g2, &dist);
1461 lwgeom_free(g1);
1462 lwgeom_free(g2);
1463 ASSERT_DOUBLE_EQUAL(m, 3.0);
1464 ASSERT_DOUBLE_EQUAL(dist, 1.0);
1465
1466 /* Test for https://trac.osgeo.org/postgis/ticket/3136 */
1467
1468 g1 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,2 0 1432291536) ", LW_PARSER_CHECK_NONE);
1469 g2 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,1 0 1432291466.25,2 0 1432291500)", LW_PARSER_CHECK_NONE);
1470 dist = -1;
1471 m = lwgeom_tcpa(g1, g2, &dist);
1472 lwgeom_free(g1);
1473 lwgeom_free(g2);
1474 ASSERT_DOUBLE_EQUAL(m, 1432291464.0);
1475 ASSERT_DOUBLE_EQUAL(dist, 0.0);
1476
1477 /* Tracks share a single point in time */
1478
1479 g1 = lwgeom_from_wkt("LINESTRINGM(0 0 0, 1 0 2)", LW_PARSER_CHECK_NONE);
1480 g2 = lwgeom_from_wkt("LINESTRINGM(0 0 2, 1 0 3)", LW_PARSER_CHECK_NONE);
1481 dist = -1;
1482 m = lwgeom_tcpa(g1, g2, &dist);
1483 lwgeom_free(g1);
1484 lwgeom_free(g2);
1485 ASSERT_DOUBLE_EQUAL(m, 2.0);
1486 ASSERT_DOUBLE_EQUAL(dist, 1.0);
1487
1488}
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:108
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1138
#define LW_PARSER_CHECK_NONE
Definition liblwgeom.h:2060
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:107
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition lwin_wkt.c:905
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: