PostGIS  2.1.10dev-r@@SVN_REVISION@@
double ptarray_locate_point ( const POINTARRAY pa,
const POINT4D pt,
double *  dist,
POINT4D p_located 
)

Definition at line 1267 of file ptarray.c.

References closest_point_on_segment(), distance2d_pt_pt(), distance2d_pt_seg(), getPoint2d_cp(), getPoint4d_p(), LWDEBUG, LWDEBUGF, POINTARRAY::npoints, p2d_same(), ptarray_length_2d(), POINT2D::x, POINT4D::x, POINT2D::y, and POINT4D::y.

Referenced by lwgeom_interpolate_point(), LWGEOM_line_locate_point(), lwline_split_by_point_to(), and test_ptarray_locate_point().

1268 {
1269  double mindist=-1;
1270  double tlen, plen;
1271  int t, seg=-1;
1272  POINT4D start4d, end4d, projtmp;
1273  POINT2D proj, p;
1274  const POINT2D *start = NULL, *end = NULL;
1275 
1276  /* Initialize our 2D copy of the input parameter */
1277  p.x = p4d->x;
1278  p.y = p4d->y;
1279 
1280  if ( ! proj4d ) proj4d = &projtmp;
1281 
1282  start = getPoint2d_cp(pa, 0);
1283 
1284  /* If the pointarray has only one point, the nearest point is */
1285  /* just that point */
1286  if ( pa->npoints == 1 )
1287  {
1288  getPoint4d_p(pa, 0, proj4d);
1289  if ( mindistout )
1290  *mindistout = distance2d_pt_pt(&p, start);
1291  return 0.0;
1292  }
1293 
1294  /* Loop through pointarray looking for nearest segment */
1295  for (t=1; t<pa->npoints; t++)
1296  {
1297  double dist;
1298  end = getPoint2d_cp(pa, t);
1299  dist = distance2d_pt_seg(&p, start, end);
1300 
1301  if (t==1 || dist < mindist )
1302  {
1303  mindist = dist;
1304  seg=t-1;
1305  }
1306 
1307  if ( mindist == 0 )
1308  {
1309  LWDEBUG(3, "Breaking on mindist=0");
1310  break;
1311  }
1312 
1313  start = end;
1314  }
1315 
1316  if ( mindistout ) *mindistout = mindist;
1317 
1318  LWDEBUGF(3, "Closest segment: %d", seg);
1319  LWDEBUGF(3, "mindist: %g", mindist);
1320 
1321  /*
1322  * We need to project the
1323  * point on the closest segment.
1324  */
1325  getPoint4d_p(pa, seg, &start4d);
1326  getPoint4d_p(pa, seg+1, &end4d);
1327  closest_point_on_segment(p4d, &start4d, &end4d, proj4d);
1328 
1329  /* Copy 4D values into 2D holder */
1330  proj.x = proj4d->x;
1331  proj.y = proj4d->y;
1332 
1333  LWDEBUGF(3, "Closest segment:%d, npoints:%d", seg, pa->npoints);
1334 
1335  /* For robustness, force 1 when closest point == endpoint */
1336  if ( (seg >= (pa->npoints-2)) && p2d_same(&proj, end) )
1337  {
1338  return 1.0;
1339  }
1340 
1341  LWDEBUGF(3, "Closest point on segment: %g,%g", proj.x, proj.y);
1342 
1343  tlen = ptarray_length_2d(pa);
1344 
1345  LWDEBUGF(3, "tlen %g", tlen);
1346 
1347  /* Location of any point on a zero-length line is 0 */
1348  /* See http://trac.osgeo.org/postgis/ticket/1772#comment:2 */
1349  if ( tlen == 0 ) return 0;
1350 
1351  plen=0;
1352  start = getPoint2d_cp(pa, 0);
1353  for (t=0; t<seg; t++, start=end)
1354  {
1355  end = getPoint2d_cp(pa, t+1);
1356  plen += distance2d_pt_pt(start, end);
1357 
1358  LWDEBUGF(4, "Segment %d made plen %g", t, plen);
1359  }
1360 
1361  plen+=distance2d_pt_pt(&proj, start);
1362 
1363  LWDEBUGF(3, "plen %g, tlen %g", plen, tlen);
1364 
1365  return plen/tlen;
1366 }
int npoints
Definition: liblwgeom.h:327
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:50
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
The old function nessecary for ptarray_segmentize2d in ptarray.c.
Definition: measures.c:2123
double distance2d_pt_seg(const POINT2D *p, const POINT2D *A, const POINT2D *B)
The old function nessecary for ptarray_segmentize2d in ptarray.c.
Definition: measures.c:2148
double x
Definition: liblwgeom.h:284
int p2d_same(const POINT2D *p1, const POINT2D *p2)
Definition: lwalgorithm.c:47
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, int n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from...
Definition: lwgeom_api.c:458
void closest_point_on_segment(const POINT4D *p, const POINT4D *A, const POINT4D *B, POINT4D *ret)
Definition: ptarray.c:1219
double y
Definition: liblwgeom.h:284
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it's 3d)
Definition: ptarray.c:1586
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:217

Here is the call graph for this function:

Here is the caller graph for this function: