PostGIS  2.2.8dev-r@@SVN_REVISION@@

◆ ptarray_remove_repeated_points_minpoints()

POINTARRAY* ptarray_remove_repeated_points_minpoints ( POINTARRAY in,
double  tolerance,
int  minpoints 
)

Definition at line 1437 of file ptarray.c.

References distance2d_sqr_pt_pt(), POINTARRAY::flags, FLAGS_GET_M, FLAGS_GET_Z, getPoint2d_cp(), getPoint_internal(), LWDEBUGF, POINTARRAY::npoints, ptarray_clone_deep(), ptarray_construct(), and ptarray_point_size().

Referenced by lwline_remove_repeated_points(), lwpoly_remove_repeated_points(), and ptarray_remove_repeated_points().

1438 {
1439  POINTARRAY* out;
1440  size_t ptsize;
1441  size_t ipn, opn;
1442  const POINT2D *last_point, *this_point;
1443  double tolsq = tolerance * tolerance;
1444 
1445  if ( minpoints < 1 ) minpoints = 1;
1446 
1447  LWDEBUGF(3, "%s called", __func__);
1448 
1449  /* Single or zero point arrays can't have duplicates */
1450  if ( in->npoints < 3 ) return ptarray_clone_deep(in);
1451 
1452  ptsize = ptarray_point_size(in);
1453 
1454  LWDEBUGF(3, " ptsize: %d", ptsize);
1455 
1456  /* Allocate enough space for all points */
1457  out = ptarray_construct(FLAGS_GET_Z(in->flags),
1458  FLAGS_GET_M(in->flags), in->npoints);
1459 
1460  /* Now fill up the actual points (NOTE: could be optimized) */
1461 
1462  opn=1;
1463  /* Keep the first point */
1464  memcpy(getPoint_internal(out, 0), getPoint_internal(in, 0), ptsize);
1465  last_point = getPoint2d_cp(in, 0);
1466  LWDEBUGF(3, " first point copied, out points: %d", opn);
1467  for ( ipn = 1; ipn < in->npoints; ++ipn)
1468  {
1469  this_point = getPoint2d_cp(in, ipn);
1470  if ( ipn < in->npoints-minpoints+1 || opn >= minpoints ) /* need extra points to hit minponts */
1471  {
1472  if (
1473  (tolerance == 0 && memcmp(getPoint_internal(in, ipn-1), getPoint_internal(in, ipn), ptsize) == 0) || /* exact dupe */
1474  (tolerance > 0.0 && distance2d_sqr_pt_pt(last_point, this_point) <= tolsq) /* within the removal tolerance */
1475  ) continue;
1476  }
1477 
1478  /*
1479  * The point is different (see above) from the previous,
1480  * so we add it to output
1481  */
1482  memcpy(getPoint_internal(out, opn++), getPoint_internal(in, ipn), ptsize);
1483  last_point = this_point;
1484  LWDEBUGF(3, " Point %d differs from point %d. Out points: %d", ipn, ipn-1, opn);
1485  }
1486  /* Keep the last point */
1487  if ( memcmp(last_point, getPoint_internal(in, ipn-1), ptsize) != 0 )
1488  {
1489  memcpy(getPoint_internal(out, opn-1), getPoint_internal(in, ipn-1), ptsize);
1490  }
1491 
1492  LWDEBUGF(3, " in:%d out:%d", out->npoints, opn);
1493  out->npoints = opn;
1494 
1495  return out;
1496 }
int ptarray_point_size(const POINTARRAY *pa)
Definition: ptarray.c:54
int npoints
Definition: liblwgeom.h:355
POINTARRAY * ptarray_clone_deep(const POINTARRAY *in)
Deep clone a pointarray (also clones serialized pointlist)
Definition: ptarray.c:634
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:472
uint8_t flags
Definition: liblwgeom.h:353
POINTARRAY * ptarray_construct(char hasz, char hasm, uint32_t npoints)
Construct an empty pointarray, allocating storage and setting the npoints, but not filling in any inf...
Definition: ptarray.c:62
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:124
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:125
double distance2d_sqr_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition: measures.c:2312
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
uint8_t * getPoint_internal(const POINTARRAY *pa, int n)
Definition: ptarray.c:1706
Here is the call graph for this function:
Here is the caller graph for this function: