PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ lwgeom_remove_repeated_points_in_place()

void lwgeom_remove_repeated_points_in_place ( LWGEOM in,
double  tolerance 
)

Definition at line 1603 of file lwgeom.c.

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

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

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

Here is the call graph for this function:
Here is the caller graph for this function: