PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ test_lwgeom_tcpa()

static void test_lwgeom_tcpa ( void  )
static

Definition at line 1044 of file cu_measures.c.

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

1045 {
1046  LWGEOM *g1, *g2;
1047  double m, dist;
1048 
1049  /* Invalid input, lack of dimensions */
1050 
1051  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1052  g2 = lwgeom_from_wkt("LINESTRING (0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1053  m = lwgeom_tcpa(g1, g2, NULL);
1054  lwgeom_free(g1);
1055  lwgeom_free(g2);
1056  ASSERT_DOUBLE_EQUAL(m, -1.0);
1057  CU_ASSERT_STRING_EQUAL(
1058  "Both input geometries must have a measure dimension",
1059  cu_error_msg
1060  );
1061 
1062  /* Invalid input, not linestrings */
1063 
1064  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1065  g2 = lwgeom_from_wkt("POINT M (0 0 2)", LW_PARSER_CHECK_NONE);
1066  m = lwgeom_tcpa(g1, g2, NULL);
1067  lwgeom_free(g1);
1068  lwgeom_free(g2);
1069  ASSERT_DOUBLE_EQUAL(m, -1.0);
1070  CU_ASSERT_STRING_EQUAL(
1071  "Both input geometries must be linestrings",
1072  cu_error_msg
1073  );
1074 
1075  /* Invalid input, too short linestring */
1076 
1077  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1078  g2 = lwgeom_from_wkt("LINESTRING M(2 0 1)", LW_PARSER_CHECK_NONE);
1079  dist = -77;
1080  m = lwgeom_tcpa(g1, g2, &dist);
1081  lwgeom_free(g1);
1082  lwgeom_free(g2);
1083  ASSERT_DOUBLE_EQUAL(dist, -77.0); /* not touched */
1084  ASSERT_DOUBLE_EQUAL(m, -1.0);
1085  CU_ASSERT_STRING_EQUAL(
1086  "Both input lines must have at least 2 points", /* should be accepted ? */
1087  cu_error_msg
1088  );
1089 
1090  /* Invalid input, empty linestring */
1091 
1092  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1093  g2 = lwgeom_from_wkt("LINESTRING M EMPTY", LW_PARSER_CHECK_NONE);
1094  m = lwgeom_tcpa(g1, g2, NULL);
1095  lwgeom_free(g1);
1096  lwgeom_free(g2);
1097  ASSERT_DOUBLE_EQUAL(m, -1.0);
1098  CU_ASSERT_STRING_EQUAL(
1099  "Both input lines must have at least 2 points",
1100  cu_error_msg
1101  );
1102 
1103  /* Timeranges do not overlap */
1104 
1105  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1106  g2 = lwgeom_from_wkt("LINESTRING M(0 0 2, 0 0 5)", LW_PARSER_CHECK_NONE);
1107  m = lwgeom_tcpa(g1, g2, NULL);
1108  lwgeom_free(g1);
1109  lwgeom_free(g2);
1110  ASSERT_DOUBLE_EQUAL(m, -2.0); /* means timeranges do not overlap */
1111 
1112  /* One of the tracks is still, the other passes to that point */
1113 
1114  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 1)", LW_PARSER_CHECK_NONE);
1115  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1116  dist = -1;
1117  m = lwgeom_tcpa(g1, g2, &dist);
1118  ASSERT_DOUBLE_EQUAL(m, 1.0);
1119  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1120  CU_ASSERT( lwgeom_cpa_within(g1, g2, 0.0) == LW_TRUE );
1121  lwgeom_free(g1);
1122  lwgeom_free(g2);
1123 
1124  /* One of the tracks is still, the other passes at 10 meters from point */
1125 
1126  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 0 0 5)", LW_PARSER_CHECK_NONE);
1127  g2 = lwgeom_from_wkt("LINESTRING M(-10 10 1, 10 10 5)", LW_PARSER_CHECK_NONE);
1128  dist = -1;
1129  m = lwgeom_tcpa(g1, g2, &dist);
1130  ASSERT_DOUBLE_EQUAL(m, 3.0);
1131  ASSERT_DOUBLE_EQUAL(dist, 10.0);
1132  CU_ASSERT( lwgeom_cpa_within(g1, g2, 11.0) == LW_TRUE );
1133  CU_ASSERT( lwgeom_cpa_within(g1, g2, 10.0) == LW_TRUE );
1134  CU_ASSERT( lwgeom_cpa_within(g1, g2, 9.0) == LW_FALSE );
1135  lwgeom_free(g1);
1136  lwgeom_free(g2);
1137 
1138  /* Equal tracks, 2d */
1139 
1140  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1141  g2 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1142  dist = -1;
1143  m = lwgeom_tcpa(g1, g2, &dist);
1144  lwgeom_free(g1);
1145  lwgeom_free(g2);
1146  ASSERT_DOUBLE_EQUAL(m, 10.0);
1147  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1148 
1149  /* Reversed tracks, 2d */
1150 
1151  g1 = lwgeom_from_wkt("LINESTRING M(0 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1152  g2 = lwgeom_from_wkt("LINESTRING M(10 0 10, 0 0 20)", LW_PARSER_CHECK_NONE);
1153  dist = -1;
1154  m = lwgeom_tcpa(g1, g2, &dist);
1155  lwgeom_free(g1);
1156  lwgeom_free(g2);
1157  ASSERT_DOUBLE_EQUAL(m, 15.0);
1158  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1159 
1160  /* Parallel tracks, same speed, 2d */
1161 
1162  g1 = lwgeom_from_wkt("LINESTRING M(2 0 10, 12 0 20)", LW_PARSER_CHECK_NONE);
1163  g2 = lwgeom_from_wkt("LINESTRING M(13 0 10, 23 0 20)", LW_PARSER_CHECK_NONE);
1164  dist = -1;
1165  m = lwgeom_tcpa(g1, g2, &dist);
1166  lwgeom_free(g1);
1167  lwgeom_free(g2);
1168  ASSERT_DOUBLE_EQUAL(m, 10.0);
1169  ASSERT_DOUBLE_EQUAL(dist, 11.0);
1170 
1171  /* Parallel tracks, different speed (g2 gets closer as time passes), 2d */
1172 
1173  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1174  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 9 0 20)", LW_PARSER_CHECK_NONE);
1175  dist = -1;
1176  m = lwgeom_tcpa(g1, g2, &dist);
1177  lwgeom_free(g1);
1178  lwgeom_free(g2);
1179  ASSERT_DOUBLE_EQUAL(m, 20.0);
1180  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1181 
1182  /* Parallel tracks, different speed (g2 left behind as time passes), 2d */
1183 
1184  g1 = lwgeom_from_wkt("LINESTRING M(4 0 10, 10 0 20)", LW_PARSER_CHECK_NONE);
1185  g2 = lwgeom_from_wkt("LINESTRING M(2 0 10, 6 0 20)", LW_PARSER_CHECK_NONE);
1186  dist = -1;
1187  m = lwgeom_tcpa(g1, g2, &dist);
1188  lwgeom_free(g1);
1189  lwgeom_free(g2);
1190  ASSERT_DOUBLE_EQUAL(m, 10.0);
1191  ASSERT_DOUBLE_EQUAL(dist, 2.0);
1192 
1193  /* Tracks, colliding, 2d */
1194 
1195  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1196  g2 = lwgeom_from_wkt("LINESTRING M(5 -8 0, 5 8 10)", LW_PARSER_CHECK_NONE);
1197  dist = -1;
1198  m = lwgeom_tcpa(g1, g2, &dist);
1199  lwgeom_free(g1);
1200  lwgeom_free(g2);
1201  ASSERT_DOUBLE_EQUAL(m, 5.0);
1202  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1203 
1204  /* Tracks crossing, NOT colliding, 2d */
1205 
1206  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 10 0 10)", LW_PARSER_CHECK_NONE);
1207  g2 = lwgeom_from_wkt("LINESTRING M(8 -5 0, 8 5 10)", LW_PARSER_CHECK_NONE);
1208  dist = -1;
1209  m = lwgeom_tcpa(g1, g2, &dist);
1210  lwgeom_free(g1);
1211  lwgeom_free(g2);
1212  ASSERT_DOUBLE_EQUAL(m, 6.5);
1213  ASSERT_DOUBLE_EQUAL(rint(dist*100), 212.0);
1214 
1215  /* Same origin, different direction, 2d */
1216 
1217  g1 = lwgeom_from_wkt("LINESTRING M(0 0 1, 10 0 10)", LW_PARSER_CHECK_NONE);
1218  g2 = lwgeom_from_wkt("LINESTRING M(0 0 1, -100 0 10)", LW_PARSER_CHECK_NONE);
1219  dist = -1;
1220  m = lwgeom_tcpa(g1, g2, &dist);
1221  lwgeom_free(g1);
1222  lwgeom_free(g2);
1223  ASSERT_DOUBLE_EQUAL(m, 1.0);
1224  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1225 
1226  /* Same ending, different direction, 2d */
1227 
1228  g1 = lwgeom_from_wkt("LINESTRING M(10 0 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1229  g2 = lwgeom_from_wkt("LINESTRING M(0 -100 1, 0 0 10)", LW_PARSER_CHECK_NONE);
1230  dist = -1;
1231  m = lwgeom_tcpa(g1, g2, &dist);
1232  lwgeom_free(g1);
1233  lwgeom_free(g2);
1234  ASSERT_DOUBLE_EQUAL(m, 10.0);
1235  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1236 
1237  /* Converging tracks, 3d */
1238 
1239  g1 = lwgeom_from_wkt("LINESTRING ZM(0 0 0 10, 10 0 0 20)", LW_PARSER_CHECK_NONE);
1240  g2 = lwgeom_from_wkt("LINESTRING ZM(0 0 8 10, 10 0 5 20)", LW_PARSER_CHECK_NONE);
1241  dist = -1;
1242  m = lwgeom_tcpa(g1, g2, &dist);
1243  lwgeom_free(g1);
1244  lwgeom_free(g2);
1245  ASSERT_DOUBLE_EQUAL(m, 20.0);
1246  ASSERT_DOUBLE_EQUAL(dist, 5.0);
1247 
1248  /* G1 stops at t=1 until t=4 to let G2 pass by, then continues */
1249  /* G2 passes at 1 meter from G1 t=3 */
1250 
1251  g1 = lwgeom_from_wkt("LINESTRING M(0 0 0, 0 1 1, 0 1 4, 0 10 13)", LW_PARSER_CHECK_NONE);
1252  g2 = lwgeom_from_wkt("LINESTRING M(-10 2 0, 0 2 3, 12 2 13)", LW_PARSER_CHECK_NONE);
1253  dist = -1;
1254  m = lwgeom_tcpa(g1, g2, &dist);
1255  lwgeom_free(g1);
1256  lwgeom_free(g2);
1257  ASSERT_DOUBLE_EQUAL(m, 3.0);
1258  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1259 
1260  /* Test for https://trac.osgeo.org/postgis/ticket/3136 */
1261 
1262  g1 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,2 0 1432291536) ", LW_PARSER_CHECK_NONE);
1263  g2 = lwgeom_from_wkt("LINESTRING M (0 0 1432291464,1 0 1432291466.25,2 0 1432291500)", LW_PARSER_CHECK_NONE);
1264  dist = -1;
1265  m = lwgeom_tcpa(g1, g2, &dist);
1266  lwgeom_free(g1);
1267  lwgeom_free(g2);
1268  ASSERT_DOUBLE_EQUAL(m, 1432291464.0);
1269  ASSERT_DOUBLE_EQUAL(dist, 0.0);
1270 
1271  /* Tracks share a single point in time */
1272 
1273  g1 = lwgeom_from_wkt("LINESTRINGM(0 0 0, 1 0 2)", LW_PARSER_CHECK_NONE);
1274  g2 = lwgeom_from_wkt("LINESTRINGM(0 0 2, 1 0 3)", LW_PARSER_CHECK_NONE);
1275  dist = -1;
1276  m = lwgeom_tcpa(g1, g2, &dist);
1277  lwgeom_free(g1);
1278  lwgeom_free(g2);
1279  ASSERT_DOUBLE_EQUAL(m, 2.0);
1280  ASSERT_DOUBLE_EQUAL(dist, 1.0);
1281 
1282 }
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1099
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:2013
#define LW_FALSE
Definition: liblwgeom.h:77
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:76
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: