PostGIS  3.1.6dev-r@@SVN_REVISION@@

◆ lwgeom_simplify_in_place()

int lwgeom_simplify_in_place ( LWGEOM igeom,
double  dist,
int  preserve_collapsed 
)

Definition at line 1714 of file lwgeom.c.

1715 {
1716  int modified = LW_FALSE;
1717  switch (geom->type)
1718  {
1719  /* No-op! Cannot simplify points or triangles */
1720  case POINTTYPE:
1721  return modified;
1722  case TRIANGLETYPE:
1723  {
1724  if (preserve_collapsed)
1725  return modified;
1726  LWTRIANGLE *t = lwgeom_as_lwtriangle(geom);
1727  POINTARRAY *pa = t->points;
1728  ptarray_simplify_in_place(pa, epsilon, 0);
1729  if (pa->npoints < 3)
1730  {
1731  pa->npoints = 0;
1732  modified = LW_TRUE;
1733  }
1734  break;
1735  }
1736  case LINETYPE:
1737  {
1738  LWLINE *g = (LWLINE*)(geom);
1739  POINTARRAY *pa = g->points;
1740  uint32_t in_npoints = pa->npoints;
1741  ptarray_simplify_in_place(pa, epsilon, 2);
1742  modified = in_npoints != pa->npoints;
1743  /* Invalid output */
1744  if (pa->npoints == 1 && pa->maxpoints > 1)
1745  {
1746  /* Use first point as last point */
1747  if (preserve_collapsed)
1748  {
1749  pa->npoints = 2;
1750  ptarray_copy_point(pa, 0, 1);
1751  }
1752  /* Finish the collapse process */
1753  else
1754  {
1755  pa->npoints = 0;
1756  }
1757  }
1758  /* Duped output, force collapse */
1759  if (pa->npoints == 2 && !preserve_collapsed)
1760  {
1761  if (p2d_same(getPoint2d_cp(pa, 0), getPoint2d_cp(pa, 1)))
1762  pa->npoints = 0;
1763  }
1764  break;
1765  }
1766  case POLYGONTYPE:
1767  {
1768  uint32_t i, j = 0;
1769  LWPOLY *g = (LWPOLY*)(geom);
1770  for (i = 0; i < g->nrings; i++)
1771  {
1772  POINTARRAY *pa = g->rings[i];
1773  /* Only stop collapse on first ring */
1774  int minpoints = (preserve_collapsed && i == 0) ? 4 : 0;
1775  /* Skip zero'ed out rings */
1776  if(!pa)
1777  continue;
1778  uint32_t in_npoints = pa->npoints;
1779  ptarray_simplify_in_place(pa, epsilon, minpoints);
1780  modified |= in_npoints != pa->npoints;
1781  /* Drop collapsed rings */
1782  if(pa->npoints < 4)
1783  {
1784  if (i == 0)
1785  {
1786  /* If the outter ring is dropped, all can be dropped */
1787  for (i = 0; i < g->nrings; i++)
1788  {
1789  pa = g->rings[i];
1790  ptarray_free(pa);
1791  }
1792  break;
1793  }
1794  else
1795  {
1796  /* Drop this inner ring only */
1797  ptarray_free(pa);
1798  continue;
1799  }
1800  }
1801  g->rings[j++] = pa;
1802  }
1803  /* Update ring count */
1804  g->nrings = j;
1805  break;
1806  }
1807  /* Can process all multi* types as generic collection */
1808  case MULTIPOINTTYPE:
1809  case MULTILINETYPE:
1810  case MULTIPOLYGONTYPE:
1811  case TINTYPE:
1812  case COLLECTIONTYPE:
1813  {
1814  uint32_t i, j = 0;
1815  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1816  for (i = 0; i < col->ngeoms; i++)
1817  {
1818  LWGEOM *g = col->geoms[i];
1819  if (!g) continue;
1820  modified |= lwgeom_simplify_in_place(g, epsilon, preserve_collapsed);
1821  /* Drop zero'ed out geometries */
1822  if(lwgeom_is_empty(g))
1823  {
1824  lwgeom_free(g);
1825  continue;
1826  }
1827  col->geoms[j++] = g;
1828  }
1829  /* Update geometry count */
1830  col->ngeoms = j;
1831  break;
1832  }
1833  default:
1834  {
1835  lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(geom->type));
1836  break;
1837  }
1838  }
1839 
1840  if (modified)
1841  {
1842  lwgeom_drop_bbox(geom);
1843  }
1844  return modified;
1845 }
#define LW_FALSE
Definition: liblwgeom.h:108
#define COLLECTIONTYPE
Definition: liblwgeom.h:122
#define MULTILINETYPE
Definition: liblwgeom.h:120
#define LINETYPE
Definition: liblwgeom.h:117
#define MULTIPOINTTYPE
Definition: liblwgeom.h:119
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:116
#define TINTYPE
Definition: liblwgeom.h:130
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:121
#define POLYGONTYPE
Definition: liblwgeom.h:118
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
void ptarray_free(POINTARRAY *pa)
Definition: ptarray.c:327
#define TRIANGLETYPE
Definition: liblwgeom.h:129
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:107
void ptarray_simplify_in_place(POINTARRAY *pa, double tolerance, uint32_t minpts)
Definition: ptarray.c:1638
void ptarray_copy_point(POINTARRAY *pa, uint32_t from, uint32_t to)
Definition: lwgeom_api.c:395
int p2d_same(const POINT2D *p1, const POINT2D *p2)
Definition: lwalgorithm.c:50
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition: lwgeom.c:665
LWTRIANGLE * lwgeom_as_lwtriangle(const LWGEOM *lwgeom)
Definition: lwgeom.c:207
void lwgeom_free(LWGEOM *lwgeom)
Definition: lwgeom.c:1138
int lwgeom_simplify_in_place(LWGEOM *geom, double epsilon, int preserve_collapsed)
Definition: lwgeom.c:1714
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwinline.h:101
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition: lwinline.h:203
uint32_t ngeoms
Definition: liblwgeom.h:594
LWGEOM ** geoms
Definition: liblwgeom.h:589
POINTARRAY * points
Definition: liblwgeom.h:497
POINTARRAY ** rings
Definition: liblwgeom.h:533
uint32_t nrings
Definition: liblwgeom.h:538
POINTARRAY * points
Definition: liblwgeom.h:509
uint32_t maxpoints
Definition: liblwgeom.h:442
uint32_t npoints
Definition: liblwgeom.h:441

References COLLECTIONTYPE, LWCOLLECTION::geoms, getPoint2d_cp(), LINETYPE, LW_FALSE, LW_TRUE, lwerror(), lwgeom_as_lwtriangle(), lwgeom_drop_bbox(), lwgeom_free(), lwgeom_is_empty(), lwgeom_simplify_in_place(), lwtype_name(), POINTARRAY::maxpoints, MULTILINETYPE, MULTIPOINTTYPE, MULTIPOLYGONTYPE, LWCOLLECTION::ngeoms, POINTARRAY::npoints, LWPOLY::nrings, p2d_same(), LWLINE::points, LWTRIANGLE::points, POINTTYPE, POLYGONTYPE, ptarray_copy_point(), ptarray_free(), ptarray_simplify_in_place(), LWPOLY::rings, TINTYPE, TRIANGLETYPE, and LWGEOM::type.

Referenced by lwgeom_simplify(), LWGEOM_simplify2d(), lwgeom_simplify_in_place(), lwgeom_subdivide_recursive(), and mvt_geom().

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