PostGIS  2.5.1dev-r@@SVN_REVISION@@

◆ lwgeom_remove_repeated_points_in_place()

void lwgeom_remove_repeated_points_in_place ( LWGEOM geom,
double  tolerance 
)

Definition at line 1603 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().

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