PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ lwgeom_simplify_in_place()

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

Definition at line 1760 of file lwgeom.c.

1761 {
1762  int modified = LW_FALSE;
1763  switch (geom->type)
1764  {
1765  /* No-op! Cannot simplify points or triangles */
1766  case POINTTYPE:
1767  return modified;
1768  case TRIANGLETYPE:
1769  {
1770  if (preserve_collapsed)
1771  return modified;
1772  LWTRIANGLE *t = lwgeom_as_lwtriangle(geom);
1773  POINTARRAY *pa = t->points;
1774  ptarray_simplify_in_place(pa, epsilon, 0);
1775  if (pa->npoints < 3)
1776  {
1777  pa->npoints = 0;
1778  modified = LW_TRUE;
1779  }
1780  break;
1781  }
1782  case LINETYPE:
1783  {
1784  LWLINE *g = (LWLINE*)(geom);
1785  POINTARRAY *pa = g->points;
1786  uint32_t in_npoints = pa->npoints;
1787  ptarray_simplify_in_place(pa, epsilon, 2);
1788  modified = in_npoints != pa->npoints;
1789  /* Invalid output */
1790  if (pa->npoints == 1 && pa->maxpoints > 1)
1791  {
1792  /* Use first point as last point */
1793  if (preserve_collapsed)
1794  {
1795  pa->npoints = 2;
1796  ptarray_copy_point(pa, 0, 1);
1797  }
1798  /* Finish the collapse process */
1799  else
1800  {
1801  pa->npoints = 0;
1802  }
1803  }
1804  /* Duped output, force collapse */
1805  if (pa->npoints == 2 && !preserve_collapsed)
1806  {
1807  if (p2d_same(getPoint2d_cp(pa, 0), getPoint2d_cp(pa, 1)))
1808  pa->npoints = 0;
1809  }
1810  break;
1811  }
1812  case POLYGONTYPE:
1813  {
1814  uint32_t i, j = 0;
1815  LWPOLY *g = (LWPOLY*)(geom);
1816  for (i = 0; i < g->nrings; i++)
1817  {
1818  POINTARRAY *pa = g->rings[i];
1819  /* Only stop collapse on first ring */
1820  int minpoints = (preserve_collapsed && i == 0) ? 4 : 0;
1821  /* Skip zero'ed out rings */
1822  if(!pa)
1823  continue;
1824  uint32_t in_npoints = pa->npoints;
1825  ptarray_simplify_in_place(pa, epsilon, minpoints);
1826  modified |= in_npoints != pa->npoints;
1827  /* Drop collapsed rings */
1828  if(pa->npoints < 4)
1829  {
1830  if (i == 0)
1831  {
1832  /* If the outter ring is dropped, all can be dropped */
1833  for (i = 0; i < g->nrings; i++)
1834  {
1835  pa = g->rings[i];
1836  ptarray_free(pa);
1837  }
1838  break;
1839  }
1840  else
1841  {
1842  /* Drop this inner ring only */
1843  ptarray_free(pa);
1844  continue;
1845  }
1846  }
1847  g->rings[j++] = pa;
1848  }
1849  /* Update ring count */
1850  g->nrings = j;
1851  break;
1852  }
1853  /* Can process all multi* types as generic collection */
1854  case MULTIPOINTTYPE:
1855  case MULTILINETYPE:
1856  case MULTIPOLYGONTYPE:
1857  case TINTYPE:
1858  case COLLECTIONTYPE:
1859  {
1860  uint32_t i, j = 0;
1861  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1862  for (i = 0; i < col->ngeoms; i++)
1863  {
1864  LWGEOM *g = col->geoms[i];
1865  if (!g) continue;
1866  modified |= lwgeom_simplify_in_place(g, epsilon, preserve_collapsed);
1867  /* Drop zero'ed out geometries */
1868  if(lwgeom_is_empty(g))
1869  {
1870  lwgeom_free(g);
1871  continue;
1872  }
1873  col->geoms[j++] = g;
1874  }
1875  /* Update geometry count */
1876  col->ngeoms = j;
1877  break;
1878  }
1879  default:
1880  {
1881  lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(geom->type));
1882  break;
1883  }
1884  }
1885 
1886  if (modified)
1887  {
1888  lwgeom_drop_bbox(geom);
1889  }
1890  return modified;
1891 }
#define LW_FALSE
Definition: liblwgeom.h:109
#define COLLECTIONTYPE
Definition: liblwgeom.h:123
#define MULTILINETYPE
Definition: liblwgeom.h:121
#define LINETYPE
Definition: liblwgeom.h:118
#define MULTIPOINTTYPE
Definition: liblwgeom.h:120
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:117
#define TINTYPE
Definition: liblwgeom.h:131
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:122
#define POLYGONTYPE
Definition: liblwgeom.h:119
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:130
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:108
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: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:1760
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:595
LWGEOM ** geoms
Definition: liblwgeom.h:590
uint8_t type
Definition: liblwgeom.h:477
POINTARRAY * points
Definition: liblwgeom.h:498
POINTARRAY ** rings
Definition: liblwgeom.h:534
uint32_t nrings
Definition: liblwgeom.h:539
POINTARRAY * points
Definition: liblwgeom.h:510
uint32_t maxpoints
Definition: liblwgeom.h:443
uint32_t npoints
Definition: liblwgeom.h:442

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: