PostGIS  2.5.0dev-r@@SVN_REVISION@@
void lwgeom_remove_repeated_points_in_place ( LWGEOM in,
double  tolerance 
)

Definition at line 1596 of file lwgeom.c.

References CIRCSTRINGTYPE, COLLECTIONTYPE, COMPOUNDTYPE, CURVEPOLYTYPE, distance2d_sqr_pt_pt(), LWMPOINT::geoms, LWCOLLECTION::geoms, getPoint2d_cp(), LINETYPE, lwalloc(), lwerror(), lwfree(), lwgeom_free(), lwgeom_is_empty(), lwpoint_free(), lwtype_name(), POINTARRAY::maxpoints, MULTICURVETYPE, MULTILINETYPE, MULTIPOINTTYPE, MULTIPOLYGONTYPE, MULTISURFACETYPE, LWMPOINT::ngeoms, LWCOLLECTION::ngeoms, POINTARRAY::npoints, LWPOLY::nrings, circ_node::p1, circ_node::p2, LWPOINT::point, LWLINE::points, POINTTYPE, POLYGONTYPE, ptarray_copy_point(), ptarray_free(), ptarray_remove_repeated_points_in_place(), LWPOLY::rings, and LWGEOM::type.

Referenced by lwgeom_remove_repeated_points(), mvt_geom(), and test_lwgeom_remove_repeated_points().

1597 {
1598  switch (geom->type)
1599  {
1600  /* No-op! Cannot remote points */
1601  case POINTTYPE:
1602  return;
1603  case LINETYPE:
1604  {
1605  LWLINE *g = (LWLINE*)(geom);
1606  POINTARRAY *pa = g->points;
1607  ptarray_remove_repeated_points_in_place(pa, tolerance, 2);
1608  /* Invalid output */
1609  if (pa->npoints == 1 && pa->maxpoints > 1)
1610  {
1611  /* Use first point as last point */
1612  pa->npoints = 2;
1613  ptarray_copy_point(pa, 0, 1);
1614  }
1615  break;
1616  }
1617  case POLYGONTYPE:
1618  {
1619  uint32_t i, j = 0;
1620  LWPOLY *g = (LWPOLY*)(geom);
1621  for (i = 0; i < g->nrings; i++)
1622  {
1623  POINTARRAY *pa = g->rings[i];
1624  int minpoints = 4;
1625  /* Skip zero'ed out rings */
1626  if(!pa)
1627  continue;
1628  ptarray_remove_repeated_points_in_place(pa, tolerance, minpoints);
1629  /* Drop collapsed rings */
1630  if(pa->npoints < 4)
1631  {
1632  ptarray_free(pa);
1633  continue;
1634  }
1635  g->rings[j++] = pa;
1636  }
1637  /* Update ring count */
1638  g->nrings = j;
1639  break;
1640  }
1641  case MULTIPOINTTYPE:
1642  {
1643  static uint32_t out_stack_size = 32;
1644  double tolsq = tolerance*tolerance;
1645  uint32_t i, j, n = 0;
1646  LWMPOINT *mpt = (LWMPOINT *)(geom);
1647  LWPOINT **out;
1648  LWPOINT *out_stack[out_stack_size];
1649  int use_heap = (mpt->ngeoms > out_stack_size);
1650 
1651  /* No-op on empty */
1652  if (mpt->ngeoms == 0) return;
1653 
1654  /* We cannot write directly back to the multipoint */
1655  /* geoms array because we're reading out of it still */
1656  /* so we use a side array */
1657  if (use_heap)
1658  out = lwalloc(sizeof(LWMPOINT *) * mpt->ngeoms);
1659  else
1660  out = out_stack;
1661 
1662  /* Inefficient O(n^2) implementation */
1663  for (i = 0; i < mpt->ngeoms; i++)
1664  {
1665  int seen = 0;
1666  LWPOINT *p1 = mpt->geoms[i];
1667  const POINT2D *pt1 = getPoint2d_cp(p1->point, 0);
1668  for (j = 0; j < n; j++)
1669  {
1670  LWPOINT *p2 = out[j];
1671  const POINT2D *pt2 = getPoint2d_cp(p2->point, 0);
1672  if (distance2d_sqr_pt_pt(pt1, pt2) <= tolsq)
1673  {
1674  seen = 1;
1675  break;
1676  }
1677  }
1678  if (seen)
1679  {
1680  lwpoint_free(p1);
1681  continue;
1682  }
1683  out[n++] = p1;
1684  }
1685 
1686  /* Copy remaining points back into the input */
1687  /* array */
1688  memcpy(mpt->geoms, out, sizeof(LWPOINT *) * n);
1689  mpt->ngeoms = n;
1690  if (use_heap) lwfree(out);
1691  return;
1692  }
1693 
1694  case CIRCSTRINGTYPE:
1695  /* Dunno how to handle these, will return untouched */
1696  return;
1697 
1698  /* Can process most multi* types as generic collection */
1699  case MULTILINETYPE:
1700  case MULTIPOLYGONTYPE:
1701  case COLLECTIONTYPE:
1702  /* Curve types we mostly ignore, but allow the linear */
1703  /* portions to be processed by recursing into them */
1704  case MULTICURVETYPE:
1705  case CURVEPOLYTYPE:
1706  case MULTISURFACETYPE:
1707  case COMPOUNDTYPE:
1708  {
1709  uint32_t i, j = 0;
1710  LWCOLLECTION *col = (LWCOLLECTION*)(geom);
1711  for (i = 0; i < col->ngeoms; i++)
1712  {
1713  LWGEOM *g = col->geoms[i];
1714  if (!g) continue;
1716  /* Drop zero'ed out geometries */
1717  if(lwgeom_is_empty(g))
1718  {
1719  lwgeom_free(g);
1720  continue;
1721  }
1722  col->geoms[j++] = g;
1723  }
1724  /* Update geometry count */
1725  col->ngeoms = j;
1726  break;
1727  }
1728  default:
1729  {
1730  lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(geom->type));
1731  break;
1732  }
1733  }
1734  return;
1735 }
#define LINETYPE
Definition: liblwgeom.h:85
#define MULTICURVETYPE
Definition: liblwgeom.h:94
uint32_t ngeoms
Definition: liblwgeom.h:467
void lwfree(void *mem)
Definition: lwutil.c:244
#define POLYGONTYPE
Definition: liblwgeom.h:86
#define CURVEPOLYTYPE
Definition: liblwgeom.h:93
void ptarray_copy_point(POINTARRAY *pa, uint32_t from, uint32_t to)
Definition: lwgeom_api.c:450
void lwpoint_free(LWPOINT *pt)
Definition: lwpoint.c:213
void ptarray_free(POINTARRAY *pa)
Definition: ptarray.c:328
#define COMPOUNDTYPE
Definition: liblwgeom.h:92
#define MULTIPOINTTYPE
Definition: liblwgeom.h:87
uint32_t maxpoints
Definition: liblwgeom.h:371
uint32_t ngeoms
Definition: liblwgeom.h:506
POINTARRAY * point
Definition: liblwgeom.h:410
uint32_t nrings
Definition: liblwgeom.h:454
unsigned int uint32_t
Definition: uthash.h:78
void lwgeom_remove_repeated_points_in_place(LWGEOM *geom, double tolerance)
Definition: lwgeom.c:1596
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:218
LWGEOM ** geoms
Definition: liblwgeom.h:508
POINTARRAY ** rings
Definition: liblwgeom.h:456
LWPOINT ** geoms
Definition: liblwgeom.h:469
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
Definition: lwgeom.c:1386
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:89
#define MULTISURFACETYPE
Definition: liblwgeom.h:95
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:84
void ptarray_remove_repeated_points_in_place(POINTARRAY *pa, double tolerance, uint32_t min_points)
Definition: ptarray.c:1446
double distance2d_sqr_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition: measures.c:2322
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:91
void * lwalloc(size_t size)
Definition: lwutil.c:229
void lwgeom_free(LWGEOM *lwgeom)
Definition: lwgeom.c:1137
#define MULTILINETYPE
Definition: liblwgeom.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
#define COLLECTIONTYPE
Definition: liblwgeom.h:90
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from...
Definition: lwgeom_api.c:364
POINTARRAY * points
Definition: liblwgeom.h:421
uint32_t npoints
Definition: liblwgeom.h:370

Here is the call graph for this function:

Here is the caller graph for this function: