PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ 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);
1265  cu_error_msg,
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);
1290  cu_error_msg,
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.
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:107
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: