PostGIS  2.5.2dev-r@@SVN_REVISION@@

◆ test_lwgeom_tcpa()

static void test_lwgeom_tcpa ( void  )
static

Definition at line 1141 of file cu_measures.c.

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().

1142 {
1143  LWGEOM *g1, *g2;
1144  double m, dist;
1145 
1146  /* Invalid input, lack of dimensions */
1147 
1148  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1149  g2 = lwgeom_from_wkt("LINESTRING (0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1150  m = lwgeom_tcpa(g1, g2, NULL);
1151  lwgeom_free(g1);
1152  lwgeom_free(g2);
1153  ASSERT_DOUBLE_EQUAL(m, -1.0);
1155  cu_error_msg,
1156  "Both input geometries must have a measure dimension");
1157 
1158  /* Invalid input, not linestrings */
1159 
1160  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1161  g2 = lwgeom_from_wkt("POINT M (0 0 2)", LW_PARSER_CHECK_NONE);
1162  m = lwgeom_tcpa(g1, g2, NULL);
1163  lwgeom_free(g1);
1164  lwgeom_free(g2);
1165  ASSERT_DOUBLE_EQUAL(m, -1.0);
1167  "Both input geometries must be linestrings");
1168 
1169  /* Invalid input, too short linestring */
1170 
1171  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1172  g2 = lwgeom_from_wkt("LINESTRING M(2 0 1)", LW_PARSER_CHECK_NONE);
1173  dist = -77;
1174  m = lwgeom_tcpa(g1, g2, &dist);
1175  lwgeom_free(g1);
1176  lwgeom_free(g2);
1177  ASSERT_DOUBLE_EQUAL(dist, -77.0); /* not touched */
1178  ASSERT_DOUBLE_EQUAL(m, -1.0);
1180  cu_error_msg,
1181  "Both input lines must have at least 2 points" /* should be accepted
1182  ? */
1183 
1184  );
1185 
1186  /* Invalid input, empty linestring */
1187 
1188  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1189  g2 = lwgeom_from_wkt("LINESTRING M EMPTY", LW_PARSER_CHECK_NONE);
1190  m = lwgeom_tcpa(g1, g2, NULL);
1191  lwgeom_free(g1);
1192  lwgeom_free(g2);
1193  ASSERT_DOUBLE_EQUAL(m, -1.0);
1195  "Both input lines must have at least 2 points"
1196 
1197  );
1198 
1199  /* Timeranges do not overlap */
1200 
1201  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1202  g2 = lwgeom_from_wkt("LINESTRING M(0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1203  m = lwgeom_tcpa(g1, g2, NULL);
1204  lwgeom_free(g1);
1205  lwgeom_free(g2);
1206  ASSERT_DOUBLE_EQUAL(m, -2.0); /* means timeranges do not overlap */
1207 
1208  /* One of the tracks is still, the other passes to that point */
1209 
1210  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1211  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1212  dist = -1;
1213  m = lwgeom_tcpa(g1, g2, &dist);
1214  ASSERT_DOUBLE_EQUAL(m, 1.0);
1215  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1216  CU_ASSERT( lwgeom_cpa_within(g1, g2, 0.0) == LW_TRUE );
1217  lwgeom_free(g1);
1218  lwgeom_free(g2);
1219 
1220  /* One of the tracks is still, the other passes at 10 meters from point */
1221 
1222  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1223  g2 = lwgeom_from_wkt("LINESTRING M(-10 10 1, 10 10 5)", LW_PARSER_CHECK_NONE);
1224  dist = -1;
1225  m = lwgeom_tcpa(g1, g2, &dist);
1226  ASSERT_DOUBLE_EQUAL(m, 3.0);
1227  ASSERT_DOUBLE_EQUAL(dist, 10.0);
1228  CU_ASSERT( lwgeom_cpa_within(g1, g2, 11.0) == LW_TRUE );
1229  CU_ASSERT( lwgeom_cpa_within(g1, g2, 10.0) == LW_TRUE );
1230  CU_ASSERT( lwgeom_cpa_within(g1, g2, 9.0) == LW_FALSE );
1231  lwgeom_free(g1);
1232  lwgeom_free(g2);
1233 
1234  /* Equal tracks, 2d */
1235 
1236  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1237  g2 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1238  dist = -1;
1239  m = lwgeom_tcpa(g1, g2, &dist);
1240  lwgeom_free(g1);
1241  lwgeom_free(g2);
1242  ASSERT_DOUBLE_EQUAL(m, 10.0);
1243  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1244 
1245  /* Reversed tracks, 2d */
1246 
1247  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1248  g2 = lwgeom_from_wkt("LINESTRING M(10 0 10, 0 0 20)", LW_PARSER_CHECK_NONE);
1249  dist = -1;
1250  m = lwgeom_tcpa(g1, g2, &dist);
1251  lwgeom_free(g1);
1252  lwgeom_free(g2);
1253  ASSERT_DOUBLE_EQUAL(m, 15.0);
1254  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1255 
1256  /* Parallel tracks, same speed, 2d */
1257 
1258  g1 = lwgeom_from_wkt("LINESTRING M(2 0 10, 12 0 20)", LW_PARSER_CHECK_NONE);
1259  g2 = lwgeom_from_wkt("LINESTRING M(13 0 10, 23 0 20)", LW_PARSER_CHECK_NONE);
1260  dist = -1;
1261  m = lwgeom_tcpa(g1, g2, &dist);
1262  lwgeom_free(g1);
1263  lwgeom_free(g2);
1264  ASSERT_DOUBLE_EQUAL(m, 10.0);
1265  ASSERT_DOUBLE_EQUAL(dist, 11.0);
1266 
1267  /* Parallel tracks, different speed (g2 gets closer as time passes), 2d */
1268 
1269  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1270  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 9 0 20)", LW_PARSER_CHECK_NONE);
1271  dist = -1;
1272  m = lwgeom_tcpa(g1, g2, &dist);
1273  lwgeom_free(g1);
1274  lwgeom_free(g2);
1275  ASSERT_DOUBLE_EQUAL(m, 20.0);
1276  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1277 
1278  /* Parallel tracks, different speed (g2 left behind as time passes), 2d */
1279 
1280  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1281  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 6 0 20)", LW_PARSER_CHECK_NONE);
1282  dist = -1;
1283  m = lwgeom_tcpa(g1, g2, &dist);
1284  lwgeom_free(g1);
1285  lwgeom_free(g2);
1286  ASSERT_DOUBLE_EQUAL(m, 10.0);
1287  ASSERT_DOUBLE_EQUAL(dist, 2.0);
1288 
1289  /* Tracks, colliding, 2d */
1290 
1291  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1292  g2 = lwgeom_from_wkt("LINESTRING M(5 -8 0, 5 8 10)", LW_PARSER_CHECK_NONE);
1293  dist = -1;
1294  m = lwgeom_tcpa(g1, g2, &dist);
1295  lwgeom_free(g1);
1296  lwgeom_free(g2);
1297  ASSERT_DOUBLE_EQUAL(m, 5.0);
1298  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1299 
1300  /* Tracks crossing, NOT colliding, 2d */
1301 
1302  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1303  g2 = lwgeom_from_wkt("LINESTRING M(8 -5 0, 8 5 10)", LW_PARSER_CHECK_NONE);
1304  dist = -1;
1305  m = lwgeom_tcpa(g1, g2, &dist);
1306  lwgeom_free(g1);
1307  lwgeom_free(g2);
1308  ASSERT_DOUBLE_EQUAL(m, 6.5);
1309  ASSERT_DOUBLE_EQUAL(rint(dist*100), 212.0);
1310 
1311  /* Same origin, different direction, 2d */
1312 
1313  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1314  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, -100 0 10)", LW_PARSER_CHECK_NONE);
1315  dist = -1;
1316  m = lwgeom_tcpa(g1, g2, &dist);
1317  lwgeom_free(g1);
1318  lwgeom_free(g2);
1319  ASSERT_DOUBLE_EQUAL(m, 1.0);
1320  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1321 
1322  /* Same ending, different direction, 2d */
1323 
1324  g1 = lwgeom_from_wkt("LINESTRING M(10 0 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1325  g2 = lwgeom_from_wkt("LINESTRING M(0 -100 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1326  dist = -1;
1327  m = lwgeom_tcpa(g1, g2, &dist);
1328  lwgeom_free(g1);
1329  lwgeom_free(g2);
1330  ASSERT_DOUBLE_EQUAL(m, 10.0);
1331  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1332 
1333  /* Converging tracks, 3d */
1334 
1335  g1 = lwgeom_from_wkt("LINESTRING ZM(0 0 0 10, 10 0 0 20)", LW_PARSER_CHECK_NONE);
1336  g2 = lwgeom_from_wkt("LINESTRING ZM(0 0 8 10, 10 0 5 20)", LW_PARSER_CHECK_NONE);
1337  dist = -1;
1338  m = lwgeom_tcpa(g1, g2, &dist);
1339  lwgeom_free(g1);
1340  lwgeom_free(g2);
1341  ASSERT_DOUBLE_EQUAL(m, 20.0);
1342  ASSERT_DOUBLE_EQUAL(dist, 5.0);
1343 
1344  /* G1 stops at t=1 until t=4 to let G2 pass by, then continues */
1345  /* G2 passes at 1 meter from G1 t=3 */
1346 
1347  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 0 1 1, 0 1 4, 0 10 13)", LW_PARSER_CHECK_NONE);
1348  g2 = lwgeom_from_wkt("LINESTRING M(-10 2 0, 0 2 3, 12 2 13)", LW_PARSER_CHECK_NONE);
1349  dist = -1;
1350  m = lwgeom_tcpa(g1, g2, &dist);
1351  lwgeom_free(g1);
1352  lwgeom_free(g2);
1353  ASSERT_DOUBLE_EQUAL(m, 3.0);
1354  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1355 
1356  /* Test for https://trac.osgeo.org/postgis/ticket/3136 */
1357 
1358  g1 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,2 0 1432291536) ", LW_PARSER_CHECK_NONE);
1359  g2 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,1 0 1432291466.25,2 0 1432291500)", LW_PARSER_CHECK_NONE);
1360  dist = -1;
1361  m = lwgeom_tcpa(g1, g2, &dist);
1362  lwgeom_free(g1);
1363  lwgeom_free(g2);
1364  ASSERT_DOUBLE_EQUAL(m, 1432291464.0);
1365  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1366 
1367  /* Tracks share a single point in time */
1368 
1369  g1 = lwgeom_from_wkt("LINESTRINGM(0 0 0, 1 0 2)", LW_PARSER_CHECK_NONE);
1370  g2 = lwgeom_from_wkt("LINESTRINGM(0 0 2, 1 0 3)", LW_PARSER_CHECK_NONE);
1371  dist = -1;
1372  m = lwgeom_tcpa(g1, g2, &dist);
1373  lwgeom_free(g1);
1374  lwgeom_free(g2);
1375  ASSERT_DOUBLE_EQUAL(m, 2.0);
1376  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1377 
1378 }
#define ASSERT_STRING_EQUAL(o, e)
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1144
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition: lwin_wkt.c:904
int lwgeom_cpa_within(const LWGEOM *g1, const LWGEOM *g2, double maxdist)
Is the closest point of approach within a distance ?
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2004
#define LW_FALSE
Definition: liblwgeom.h:76
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
double lwgeom_tcpa(const LWGEOM *g1, const LWGEOM *g2, double *mindist)
Find the time of closest point of approach.
#define ASSERT_DOUBLE_EQUAL(o, e)
char cu_error_msg[MAX_CUNIT_ERROR_LENGTH+1]
Here is the call graph for this function:
Here is the caller graph for this function: