PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ lwgeom_simplify_in_place()

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

Definition at line 1737 of file lwgeom.c.

1738 {
1739  int modified = LW_FALSE;
1740  switch (geom->type)
1741  {
1742  /* No-op! Cannot simplify points or triangles */
1743  case POINTTYPE:
1744  return modified;
1745  case TRIANGLETYPE:
1746  {
1747  if (preserve_collapsed)
1748  return modified;
1749  LWTRIANGLE *t = lwgeom_as_lwtriangle(geom);
1750  POINTARRAY *pa = t->points;
1751  ptarray_simplify_in_place(pa, epsilon, 0);
1752  if (pa->npoints < 3)
1753  {
1754  pa->npoints = 0;
1755  modified = LW_TRUE;
1756  }
1757  break;
1758  }
1759  case LINETYPE:
1760  {
1761  LWLINE *g = (LWLINE*)(geom);
1762  POINTARRAY *pa = g->points;
1763  uint32_t in_npoints = pa->npoints;
1764  ptarray_simplify_in_place(pa, epsilon, 2);
1765  modified = in_npoints != pa->npoints;
1766  /* Invalid output */
1767  if (pa->npoints == 1 && pa->maxpoints > 1)
1768  {
1769  /* Use first point as last point */
1770  if (preserve_collapsed)
1771  {
1772  pa->npoints = 2;
1773  ptarray_copy_point(pa, 0, 1);
1774  }
1775  /* Finish the collapse process */
1776  else
1777  {
1778  pa->npoints = 0;
1779  }
1780  }
1781  /* Duped output, force collapse */
1782  if (pa->npoints == 2 && !preserve_collapsed)
1783  {
1784  if (p2d_same(getPoint2d_cp(pa, 0), getPoint2d_cp(pa, 1)))
1785  pa->npoints = 0;
1786  }
1787  break;
1788  }
1789  case POLYGONTYPE:
1790  {
1791  uint32_t i, j = 0;
1792  LWPOLY *g = (LWPOLY*)(geom);
1793  for (i = 0; i < g->nrings; i++)
1794  {
1795  POINTARRAY *pa = g->rings[i];
1796  /* Only stop collapse on first ring */
1797  int minpoints = (preserve_collapsed && i == 0) ? 4 : 0;
1798  /* Skip zero'ed out rings */
1799  if(!pa)
1800  continue;
1801  uint32_t in_npoints = pa->npoints;
1802  ptarray_simplify_in_place(pa, epsilon, minpoints);
1803  modified |= in_npoints != pa->npoints;
1804  /* Drop collapsed rings */
1805  if(pa->npoints < 4)
1806  {
1807  if (i == 0)
1808  {
1809  /* If the outter ring is dropped, all can be dropped */
1810  for (i = 0; i < g->nrings; i++)
1811  {
1812  pa = g->rings[i];
1813  ptarray_free(pa);
1814  }
1815  break;
1816  }
1817  else
1818  {
1819  /* Drop this inner ring only */
1820  ptarray_free(pa);
1821  continue;
1822  }
1823  }
1824  g->rings[j++] = pa;
1825  }
1826  /* Update ring count */
1827  g->nrings = j;
1828  break;
1829  }
1830  /* Can process all multi* types as generic collection */
1831  case MULTIPOINTTYPE:
1832  case MULTILINETYPE:
1833  case MULTIPOLYGONTYPE:
1834  case TINTYPE:
1835  case COLLECTIONTYPE:
1836  {
1837  uint32_t i, j = 0;
1838  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1839  for (i = 0; i < col->ngeoms; i++)
1840  {
1841  LWGEOM *g = col->geoms[i];
1842  if (!g) continue;
1843  modified |= lwgeom_simplify_in_place(g, epsilon, preserve_collapsed);
1844  /* Drop zero'ed out geometries */
1845  if(lwgeom_is_empty(g))
1846  {
1847  lwgeom_free(g);
1848  continue;
1849  }
1850  col->geoms[j++] = g;
1851  }
1852  /* Update geometry count */
1853  col->ngeoms = j;
1854  break;
1855  }
1856  default:
1857  {
1858  lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(geom->type));
1859  break;
1860  }
1861  }
1862 
1863  if (modified)
1864  {
1865  lwgeom_drop_bbox(geom);
1866  }
1867  return modified;
1868 }
#define LW_FALSE
Definition: liblwgeom.h:94
#define COLLECTIONTYPE
Definition: liblwgeom.h:108
#define MULTILINETYPE
Definition: liblwgeom.h:106
#define LINETYPE
Definition: liblwgeom.h:103
#define MULTIPOINTTYPE
Definition: liblwgeom.h:105
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:102
#define TINTYPE
Definition: liblwgeom.h:116
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:107
#define POLYGONTYPE
Definition: liblwgeom.h:104
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:115
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:93
void ptarray_simplify_in_place(POINTARRAY *pa, double tolerance, uint32_t minpts)
Definition: ptarray.c:1713
void ptarray_copy_point(POINTARRAY *pa, uint32_t from, uint32_t to)
Definition: lwgeom_api.c:394
int p2d_same(const POINT2D *p1, const POINT2D *p2)
Definition: lwalgorithm.c:49
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition: lwgeom.c:682
LWTRIANGLE * lwgeom_as_lwtriangle(const LWGEOM *lwgeom)
Definition: lwgeom.c:224
void lwgeom_free(LWGEOM *lwgeom)
Definition: lwgeom.c:1155
int lwgeom_simplify_in_place(LWGEOM *geom, double epsilon, int preserve_collapsed)
Definition: lwgeom.c:1737
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:580
LWGEOM ** geoms
Definition: liblwgeom.h:575
uint8_t type
Definition: liblwgeom.h:462
POINTARRAY * points
Definition: liblwgeom.h:483
POINTARRAY ** rings
Definition: liblwgeom.h:519
uint32_t nrings
Definition: liblwgeom.h:524
POINTARRAY * points
Definition: liblwgeom.h:495
uint32_t maxpoints
Definition: liblwgeom.h:428
uint32_t npoints
Definition: liblwgeom.h:427

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: