PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ test_lwgeom_tcpa()

static void test_lwgeom_tcpa ( void  )
static

Definition at line 1259 of file cu_measures.c.

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