PostGIS  3.2.2dev-r@@SVN_REVISION@@

◆ lwgeom_simplify_in_place()

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

Definition at line 1743 of file lwgeom.c.

1744 {
1745  int modified = LW_FALSE;
1746  switch (geom->type)
1747  {
1748  /* No-op! Cannot simplify points or triangles */
1749  case POINTTYPE:
1750  return modified;
1751  case TRIANGLETYPE:
1752  {
1753  if (preserve_collapsed)
1754  return modified;
1755  LWTRIANGLE *t = lwgeom_as_lwtriangle(geom);
1756  POINTARRAY *pa = t->points;
1757  ptarray_simplify_in_place(pa, epsilon, 0);
1758  if (pa->npoints < 3)
1759  {
1760  pa->npoints = 0;
1761  modified = LW_TRUE;
1762  }
1763  break;
1764  }
1765  case LINETYPE:
1766  {
1767  LWLINE *g = (LWLINE*)(geom);
1768  POINTARRAY *pa = g->points;
1769  uint32_t in_npoints = pa->npoints;
1770  ptarray_simplify_in_place(pa, epsilon, 2);
1771  modified = in_npoints != pa->npoints;
1772  /* Invalid output */
1773  if (pa->npoints == 1 && pa->maxpoints > 1)
1774  {
1775  /* Use first point as last point */
1776  if (preserve_collapsed)
1777  {
1778  pa->npoints = 2;
1779  ptarray_copy_point(pa, 0, 1);
1780  }
1781  /* Finish the collapse process */
1782  else
1783  {
1784  pa->npoints = 0;
1785  }
1786  }
1787  /* Duped output, force collapse */
1788  if (pa->npoints == 2 && !preserve_collapsed)
1789  {
1790  if (p2d_same(getPoint2d_cp(pa, 0), getPoint2d_cp(pa, 1)))
1791  pa->npoints = 0;
1792  }
1793  break;
1794  }
1795  case POLYGONTYPE:
1796  {
1797  uint32_t i, j = 0;
1798  LWPOLY *g = (LWPOLY*)(geom);
1799  for (i = 0; i < g->nrings; i++)
1800  {
1801  POINTARRAY *pa = g->rings[i];
1802  /* Only stop collapse on first ring */
1803  int minpoints = (preserve_collapsed && i == 0) ? 4 : 0;
1804  /* Skip zero'ed out rings */
1805  if(!pa)
1806  continue;
1807  uint32_t in_npoints = pa->npoints;
1808  ptarray_simplify_in_place(pa, epsilon, minpoints);
1809  modified |= in_npoints != pa->npoints;
1810  /* Drop collapsed rings */
1811  if(pa->npoints < 4)
1812  {
1813  if (i == 0)
1814  {
1815  /* If the outter ring is dropped, all can be dropped */
1816  for (i = 0; i < g->nrings; i++)
1817  {
1818  pa = g->rings[i];
1819  ptarray_free(pa);
1820  }
1821  break;
1822  }
1823  else
1824  {
1825  /* Drop this inner ring only */
1826  ptarray_free(pa);
1827  continue;
1828  }
1829  }
1830  g->rings[j++] = pa;
1831  }
1832  /* Update ring count */
1833  g->nrings = j;
1834  break;
1835  }
1836  /* Can process all multi* types as generic collection */
1837  case MULTIPOINTTYPE:
1838  case MULTILINETYPE:
1839  case MULTIPOLYGONTYPE:
1840  case TINTYPE:
1841  case COLLECTIONTYPE:
1842  {
1843  uint32_t i, j = 0;
1844  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1845  for (i = 0; i < col->ngeoms; i++)
1846  {
1847  LWGEOM *g = col->geoms[i];
1848  if (!g) continue;
1849  modified |= lwgeom_simplify_in_place(g, epsilon, preserve_collapsed);
1850  /* Drop zero'ed out geometries */
1851  if(lwgeom_is_empty(g))
1852  {
1853  lwgeom_free(g);
1854  continue;
1855  }
1856  col->geoms[j++] = g;
1857  }
1858  /* Update geometry count */
1859  col->ngeoms = j;
1860  break;
1861  }
1862  default:
1863  {
1864  lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(geom->type));
1865  break;
1866  }
1867  }
1868 
1869  if (modified)
1870  {
1871  lwgeom_drop_bbox(geom);
1872  }
1873  return modified;
1874 }
#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:1700
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:1743
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
uint8_t type
Definition: liblwgeom.h:476
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: