PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ lwgeom_simplify_in_place()

int lwgeom_simplify_in_place ( LWGEOM geom,
double  epsilon,
int  preserve_collapsed 
)

Definition at line 1715 of file lwgeom.c.

1716 {
1717  int modified = LW_FALSE;
1718  switch (geom->type)
1719  {
1720  /* No-op! Cannot simplify points or triangles */
1721  case POINTTYPE:
1722  return modified;
1723  case TRIANGLETYPE:
1724  {
1725  if (preserve_collapsed)
1726  return modified;
1727  LWTRIANGLE *t = lwgeom_as_lwtriangle(geom);
1728  POINTARRAY *pa = t->points;
1729  ptarray_simplify_in_place(pa, epsilon, 0);
1730  if (pa->npoints < 3)
1731  {
1732  pa->npoints = 0;
1733  modified = LW_TRUE;
1734  }
1735  break;
1736  }
1737  case LINETYPE:
1738  {
1739  LWLINE *g = (LWLINE*)(geom);
1740  POINTARRAY *pa = g->points;
1741  uint32_t in_npoints = pa->npoints;
1742  ptarray_simplify_in_place(pa, epsilon, 2);
1743  modified = in_npoints != pa->npoints;
1744  /* Invalid output */
1745  if (pa->npoints == 1 && pa->maxpoints > 1)
1746  {
1747  /* Use first point as last point */
1748  if (preserve_collapsed)
1749  {
1750  pa->npoints = 2;
1751  ptarray_copy_point(pa, 0, 1);
1752  }
1753  /* Finish the collapse process */
1754  else
1755  {
1756  pa->npoints = 0;
1757  }
1758  }
1759  /* Duped output, force collapse */
1760  if (pa->npoints == 2 && !preserve_collapsed)
1761  {
1762  if (p2d_same(getPoint2d_cp(pa, 0), getPoint2d_cp(pa, 1)))
1763  pa->npoints = 0;
1764  }
1765  break;
1766  }
1767  case POLYGONTYPE:
1768  {
1769  uint32_t i, j = 0;
1770  LWPOLY *g = (LWPOLY*)(geom);
1771  for (i = 0; i < g->nrings; i++)
1772  {
1773  POINTARRAY *pa = g->rings[i];
1774  /* Only stop collapse on first ring */
1775  int minpoints = (preserve_collapsed && i == 0) ? 4 : 0;
1776  /* Skip zero'ed out rings */
1777  if(!pa)
1778  continue;
1779  uint32_t in_npoints = pa->npoints;
1780  ptarray_simplify_in_place(pa, epsilon, minpoints);
1781  modified |= in_npoints != pa->npoints;
1782  /* Drop collapsed rings */
1783  if(pa->npoints < 4)
1784  {
1785  if (i == 0)
1786  {
1787  /* If the outter ring is dropped, all can be dropped */
1788  for (i = 0; i < g->nrings; i++)
1789  {
1790  pa = g->rings[i];
1791  ptarray_free(pa);
1792  }
1793  break;
1794  }
1795  else
1796  {
1797  /* Drop this inner ring only */
1798  ptarray_free(pa);
1799  continue;
1800  }
1801  }
1802  g->rings[j++] = pa;
1803  }
1804  /* Update ring count */
1805  g->nrings = j;
1806  break;
1807  }
1808  /* Can process all multi* types as generic collection */
1809  case MULTIPOINTTYPE:
1810  case MULTILINETYPE:
1811  case MULTIPOLYGONTYPE:
1812  case TINTYPE:
1813  case COLLECTIONTYPE:
1814  {
1815  uint32_t i, j = 0;
1816  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1817  for (i = 0; i < col->ngeoms; i++)
1818  {
1819  LWGEOM *g = col->geoms[i];
1820  if (!g) continue;
1821  modified |= lwgeom_simplify_in_place(g, epsilon, preserve_collapsed);
1822  /* Drop zero'ed out geometries */
1823  if(lwgeom_is_empty(g))
1824  {
1825  lwgeom_free(g);
1826  continue;
1827  }
1828  col->geoms[j++] = g;
1829  }
1830  /* Update geometry count */
1831  col->ngeoms = j;
1832  break;
1833  }
1834  default:
1835  {
1836  lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(geom->type));
1837  break;
1838  }
1839  }
1840 
1841  if (modified)
1842  {
1843  lwgeom_drop_bbox(geom);
1844  }
1845  return modified;
1846 }
#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:319
#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:1587
void ptarray_copy_point(POINTARRAY *pa, uint32_t from, uint32_t to)
Definition: lwgeom_api.c:401
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:664
LWTRIANGLE * lwgeom_as_lwtriangle(const LWGEOM *lwgeom)
Definition: lwgeom.c:206
void lwgeom_free(LWGEOM *lwgeom)
Definition: lwgeom.c:1138
int lwgeom_simplify_in_place(LWGEOM *geom, double epsilon, int preserve_collapsed)
Definition: lwgeom.c:1715
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:91
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:193
uint32_t ngeoms
Definition: liblwgeom.h:566
LWGEOM ** geoms
Definition: liblwgeom.h:561
uint8_t type
Definition: liblwgeom.h:448
POINTARRAY * points
Definition: liblwgeom.h:469
POINTARRAY ** rings
Definition: liblwgeom.h:505
uint32_t nrings
Definition: liblwgeom.h:510
POINTARRAY * points
Definition: liblwgeom.h:481
uint32_t maxpoints
Definition: liblwgeom.h:414
uint32_t npoints
Definition: liblwgeom.h:413

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: