PostGIS  3.0.0dev-r@@SVN_REVISION@@

◆ test_lwgeom_tcpa()

static void test_lwgeom_tcpa ( void  )
static

Definition at line 1113 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().

1114 {
1115  LWGEOM *g1, *g2;
1116  double m, dist;
1117 
1118  /* Invalid input, lack of dimensions */
1119 
1120  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1121  g2 = lwgeom_from_wkt("LINESTRING (0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1122  m = lwgeom_tcpa(g1, g2, NULL);
1123  lwgeom_free(g1);
1124  lwgeom_free(g2);
1125  ASSERT_DOUBLE_EQUAL(m, -1.0);
1127  cu_error_msg,
1128  "Both input geometries must have a measure dimension");
1129 
1130  /* Invalid input, not linestrings */
1131 
1132  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1133  g2 = lwgeom_from_wkt("POINT M (0 0 2)", LW_PARSER_CHECK_NONE);
1134  m = lwgeom_tcpa(g1, g2, NULL);
1135  lwgeom_free(g1);
1136  lwgeom_free(g2);
1137  ASSERT_DOUBLE_EQUAL(m, -1.0);
1139  "Both input geometries must be linestrings");
1140 
1141  /* Invalid input, too short linestring */
1142 
1143  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1144  g2 = lwgeom_from_wkt("LINESTRING M(2 0 1)", LW_PARSER_CHECK_NONE);
1145  dist = -77;
1146  m = lwgeom_tcpa(g1, g2, &dist);
1147  lwgeom_free(g1);
1148  lwgeom_free(g2);
1149  ASSERT_DOUBLE_EQUAL(dist, -77.0); /* not touched */
1150  ASSERT_DOUBLE_EQUAL(m, -1.0);
1152  cu_error_msg,
1153  "Both input lines must have at least 2 points" /* should be accepted
1154  ? */
1155 
1156  );
1157 
1158  /* Invalid input, empty linestring */
1159 
1160  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1161  g2 = lwgeom_from_wkt("LINESTRING M EMPTY", 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 lines must have at least 2 points"
1168 
1169  );
1170 
1171  /* Timeranges do not overlap */
1172 
1173  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1174  g2 = lwgeom_from_wkt("LINESTRING M(0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1175  m = lwgeom_tcpa(g1, g2, NULL);
1176  lwgeom_free(g1);
1177  lwgeom_free(g2);
1178  ASSERT_DOUBLE_EQUAL(m, -2.0); /* means timeranges do not overlap */
1179 
1180  /* One of the tracks is still, the other passes to that point */
1181 
1182  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1183  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1184  dist = -1;
1185  m = lwgeom_tcpa(g1, g2, &dist);
1186  ASSERT_DOUBLE_EQUAL(m, 1.0);
1187  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1188  CU_ASSERT( lwgeom_cpa_within(g1, g2, 0.0) == LW_TRUE );
1189  lwgeom_free(g1);
1190  lwgeom_free(g2);
1191 
1192  /* One of the tracks is still, the other passes at 10 meters from point */
1193 
1194  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1195  g2 = lwgeom_from_wkt("LINESTRING M(-10 10 1, 10 10 5)", LW_PARSER_CHECK_NONE);
1196  dist = -1;
1197  m = lwgeom_tcpa(g1, g2, &dist);
1198  ASSERT_DOUBLE_EQUAL(m, 3.0);
1199  ASSERT_DOUBLE_EQUAL(dist, 10.0);
1200  CU_ASSERT( lwgeom_cpa_within(g1, g2, 11.0) == LW_TRUE );
1201  CU_ASSERT( lwgeom_cpa_within(g1, g2, 10.0) == LW_TRUE );
1202  CU_ASSERT( lwgeom_cpa_within(g1, g2, 9.0) == LW_FALSE );
1203  lwgeom_free(g1);
1204  lwgeom_free(g2);
1205 
1206  /* Equal tracks, 2d */
1207 
1208  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1209  g2 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1210  dist = -1;
1211  m = lwgeom_tcpa(g1, g2, &dist);
1212  lwgeom_free(g1);
1213  lwgeom_free(g2);
1214  ASSERT_DOUBLE_EQUAL(m, 10.0);
1215  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1216 
1217  /* Reversed tracks, 2d */
1218 
1219  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1220  g2 = lwgeom_from_wkt("LINESTRING M(10 0 10, 0 0 20)", LW_PARSER_CHECK_NONE);
1221  dist = -1;
1222  m = lwgeom_tcpa(g1, g2, &dist);
1223  lwgeom_free(g1);
1224  lwgeom_free(g2);
1225  ASSERT_DOUBLE_EQUAL(m, 15.0);
1226  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1227 
1228  /* Parallel tracks, same speed, 2d */
1229 
1230  g1 = lwgeom_from_wkt("LINESTRING M(2 0 10, 12 0 20)", LW_PARSER_CHECK_NONE);
1231  g2 = lwgeom_from_wkt("LINESTRING M(13 0 10, 23 0 20)", LW_PARSER_CHECK_NONE);
1232  dist = -1;
1233  m = lwgeom_tcpa(g1, g2, &dist);
1234  lwgeom_free(g1);
1235  lwgeom_free(g2);
1236  ASSERT_DOUBLE_EQUAL(m, 10.0);
1237  ASSERT_DOUBLE_EQUAL(dist, 11.0);
1238 
1239  /* Parallel tracks, different speed (g2 gets closer as time passes), 2d */
1240 
1241  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1242  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 9 0 20)", LW_PARSER_CHECK_NONE);
1243  dist = -1;
1244  m = lwgeom_tcpa(g1, g2, &dist);
1245  lwgeom_free(g1);
1246  lwgeom_free(g2);
1247  ASSERT_DOUBLE_EQUAL(m, 20.0);
1248  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1249 
1250  /* Parallel tracks, different speed (g2 left behind as time passes), 2d */
1251 
1252  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1253  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 6 0 20)", LW_PARSER_CHECK_NONE);
1254  dist = -1;
1255  m = lwgeom_tcpa(g1, g2, &dist);
1256  lwgeom_free(g1);
1257  lwgeom_free(g2);
1258  ASSERT_DOUBLE_EQUAL(m, 10.0);
1259  ASSERT_DOUBLE_EQUAL(dist, 2.0);
1260 
1261  /* Tracks, colliding, 2d */
1262 
1263  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1264  g2 = lwgeom_from_wkt("LINESTRING M(5 -8 0, 5 8 10)", LW_PARSER_CHECK_NONE);
1265  dist = -1;
1266  m = lwgeom_tcpa(g1, g2, &dist);
1267  lwgeom_free(g1);
1268  lwgeom_free(g2);
1269  ASSERT_DOUBLE_EQUAL(m, 5.0);
1270  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1271 
1272  /* Tracks crossing, NOT colliding, 2d */
1273 
1274  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1275  g2 = lwgeom_from_wkt("LINESTRING M(8 -5 0, 8 5 10)", LW_PARSER_CHECK_NONE);
1276  dist = -1;
1277  m = lwgeom_tcpa(g1, g2, &dist);
1278  lwgeom_free(g1);
1279  lwgeom_free(g2);
1280  ASSERT_DOUBLE_EQUAL(m, 6.5);
1281  ASSERT_DOUBLE_EQUAL(rint(dist*100), 212.0);
1282 
1283  /* Same origin, different direction, 2d */
1284 
1285  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1286  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, -100 0 10)", LW_PARSER_CHECK_NONE);
1287  dist = -1;
1288  m = lwgeom_tcpa(g1, g2, &dist);
1289  lwgeom_free(g1);
1290  lwgeom_free(g2);
1291  ASSERT_DOUBLE_EQUAL(m, 1.0);
1292  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1293 
1294  /* Same ending, different direction, 2d */
1295 
1296  g1 = lwgeom_from_wkt("LINESTRING M(10 0 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1297  g2 = lwgeom_from_wkt("LINESTRING M(0 -100 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1298  dist = -1;
1299  m = lwgeom_tcpa(g1, g2, &dist);
1300  lwgeom_free(g1);
1301  lwgeom_free(g2);
1302  ASSERT_DOUBLE_EQUAL(m, 10.0);
1303  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1304 
1305  /* Converging tracks, 3d */
1306 
1307  g1 = lwgeom_from_wkt("LINESTRING ZM(0 0 0 10, 10 0 0 20)", LW_PARSER_CHECK_NONE);
1308  g2 = lwgeom_from_wkt("LINESTRING ZM(0 0 8 10, 10 0 5 20)", LW_PARSER_CHECK_NONE);
1309  dist = -1;
1310  m = lwgeom_tcpa(g1, g2, &dist);
1311  lwgeom_free(g1);
1312  lwgeom_free(g2);
1313  ASSERT_DOUBLE_EQUAL(m, 20.0);
1314  ASSERT_DOUBLE_EQUAL(dist, 5.0);
1315 
1316  /* G1 stops at t=1 until t=4 to let G2 pass by, then continues */
1317  /* G2 passes at 1 meter from G1 t=3 */
1318 
1319  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 0 1 1, 0 1 4, 0 10 13)", LW_PARSER_CHECK_NONE);
1320  g2 = lwgeom_from_wkt("LINESTRING M(-10 2 0, 0 2 3, 12 2 13)", LW_PARSER_CHECK_NONE);
1321  dist = -1;
1322  m = lwgeom_tcpa(g1, g2, &dist);
1323  lwgeom_free(g1);
1324  lwgeom_free(g2);
1325  ASSERT_DOUBLE_EQUAL(m, 3.0);
1326  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1327 
1328  /* Test for https://trac.osgeo.org/postgis/ticket/3136 */
1329 
1330  g1 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,2 0 1432291536) ", LW_PARSER_CHECK_NONE);
1331  g2 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,1 0 1432291466.25,2 0 1432291500)", LW_PARSER_CHECK_NONE);
1332  dist = -1;
1333  m = lwgeom_tcpa(g1, g2, &dist);
1334  lwgeom_free(g1);
1335  lwgeom_free(g2);
1336  ASSERT_DOUBLE_EQUAL(m, 1432291464.0);
1337  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1338 
1339  /* Tracks share a single point in time */
1340 
1341  g1 = lwgeom_from_wkt("LINESTRINGM(0 0 0, 1 0 2)", LW_PARSER_CHECK_NONE);
1342  g2 = lwgeom_from_wkt("LINESTRINGM(0 0 2, 1 0 3)", LW_PARSER_CHECK_NONE);
1343  dist = -1;
1344  m = lwgeom_tcpa(g1, g2, &dist);
1345  lwgeom_free(g1);
1346  lwgeom_free(g2);
1347  ASSERT_DOUBLE_EQUAL(m, 2.0);
1348  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1349 
1350 }
#define ASSERT_STRING_EQUAL(o, e)
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1128
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:1966
#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: