Find the time of closest point of approach.
1139{
1141 int i;
1143 double tmin, tmax;
1144 double *mvals;
1145 int nmvals = 0;
1146 double mintime;
1147 double mindist2 = FLT_MAX;
1148
1150 {
1151 lwerror(
"Both input geometries must have a measure dimension");
1152 return -1;
1153 }
1154
1157
1158 if (!l1 || !l2)
1159 {
1160 lwerror(
"Both input geometries must be linestrings");
1161 return -1;
1162 }
1163
1165 {
1166 lwerror(
"Both input lines must have at least 2 points");
1167 return -1;
1168 }
1169
1170
1171
1172
1175
1176
1177
1178
1179
1180
1183
1184 if (tmax < tmin)
1185 {
1186 LWDEBUG(1,
"Inputs never exist at the same time");
1187 return -2;
1188 }
1189
1190
1191
1192
1193
1194
1195
1197
1198
1201
1202
1204
1205
1206 nmvals =
uniq(mvals, nmvals);
1207
1208 if (nmvals < 2)
1209 {
1210 {
1211
1212 double t0 = mvals[0];
1214 LWDEBUGF(1,
"Inputs only exist both at a single time (%g)", t0);
1215 if (mindist)
1216 {
1218 {
1220 lwerror(
"Could not find point with M=%g on first geom", t0);
1221 return -1;
1222 }
1224 {
1226 lwerror(
"Could not find point with M=%g on second geom", t0);
1227 return -1;
1228 }
1230 }
1232 return t0;
1233 }
1234 }
1235
1236
1237
1238
1239
1240 mintime = tmin;
1241 for (i = 1; i < nmvals; ++i)
1242 {
1243 double t0 = mvals[i - 1];
1244 double t1 = mvals[i];
1245 double t;
1247 int seg;
1248 double dist2;
1249
1250
1251
1253 if (-1 == seg)
1254 continue;
1255
1256
1258 if (-1 == seg)
1259 continue;
1260
1261
1263 if (-1 == seg)
1264 continue;
1265
1266
1268 if (-1 == seg)
1269 continue;
1270
1271
1273
1274
1275
1276
1277
1278
1279
1280 dist2 = (q0.
x - p0.
x) * (q0.
x - p0.
x) + (q0.
y - p0.
y) * (q0.
y - p0.
y) + (q0.
z - p0.
z) * (q0.
z - p0.
z);
1281 if (dist2 < mindist2)
1282 {
1283 mindist2 = dist2;
1284 mintime = t;
1285
1286 }
1287 }
1288
1289
1290
1291
1292
1294
1295 if (mindist)
1296 {
1297 *mindist = sqrt(mindist2);
1298 }
1299
1300
1301 return mintime;
1302}
void * lwalloc(size_t size)
double distance3d_pt_pt(const POINT3D *p1, const POINT3D *p2)
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate bounding box of a geometry, automatically taking into account whether it is cartesian or ge...
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
static int ptarray_collect_mvals(const POINTARRAY *pa, double tmin, double tmax, double *mvals)
static int compare_double(const void *pa, const void *pb)
static double segments_tcpa(POINT4D *p0, const POINT4D *p1, POINT4D *q0, const POINT4D *q1, double t0, double t1)
static int ptarray_locate_along_linear(const POINTARRAY *pa, double m, POINT4D *p, uint32_t from)
static int uniq(double *vals, int nvals)