PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ lwgeom_simplify_in_place()

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

Definition at line 1823 of file lwgeom.c.

1824 {
1825  int modified = LW_FALSE;
1826  switch (geom->type)
1827  {
1828  /* No-op! Cannot simplify points or triangles */
1829  case POINTTYPE:
1830  return modified;
1831  case TRIANGLETYPE:
1832  {
1833  if (preserve_collapsed)
1834  return modified;
1835  LWTRIANGLE *t = lwgeom_as_lwtriangle(geom);
1836  POINTARRAY *pa = t->points;
1837  ptarray_simplify_in_place(pa, epsilon, 0);
1838  if (pa->npoints < 3)
1839  {
1840  pa->npoints = 0;
1841  modified = LW_TRUE;
1842  }
1843  break;
1844  }
1845  case LINETYPE:
1846  {
1847  LWLINE *g = (LWLINE*)(geom);
1848  POINTARRAY *pa = g->points;
1849  uint32_t in_npoints = pa->npoints;
1850  ptarray_simplify_in_place(pa, epsilon, 2);
1851  modified = in_npoints != pa->npoints;
1852  /* Invalid output */
1853  if (pa->npoints == 1 && pa->maxpoints > 1)
1854  {
1855  /* Use first point as last point */
1856  if (preserve_collapsed)
1857  {
1858  pa->npoints = 2;
1859  ptarray_copy_point(pa, 0, 1);
1860  }
1861  /* Finish the collapse process */
1862  else
1863  {
1864  pa->npoints = 0;
1865  }
1866  }
1867  /* Duped output, force collapse */
1868  if (pa->npoints == 2 && !preserve_collapsed)
1869  {
1870  if (p2d_same(getPoint2d_cp(pa, 0), getPoint2d_cp(pa, 1)))
1871  pa->npoints = 0;
1872  }
1873  break;
1874  }
1875  case POLYGONTYPE:
1876  {
1877  uint32_t i, j = 0;
1878  LWPOLY *g = (LWPOLY*)(geom);
1879  for (i = 0; i < g->nrings; i++)
1880  {
1881  POINTARRAY *pa = g->rings[i];
1882  /* Only stop collapse on first ring */
1883  int minpoints = (preserve_collapsed && i == 0) ? 4 : 0;
1884  /* Skip zero'ed out rings */
1885  if(!pa)
1886  continue;
1887  uint32_t in_npoints = pa->npoints;
1888  ptarray_simplify_in_place(pa, epsilon, minpoints);
1889  modified |= in_npoints != pa->npoints;
1890  /* Drop collapsed rings */
1891  if(pa->npoints < 4)
1892  {
1893  if (i == 0)
1894  {
1895  /* If the outer ring is dropped, all can be dropped */
1896  for (i = 0; i < g->nrings; i++)
1897  {
1898  pa = g->rings[i];
1899  ptarray_free(pa);
1900  }
1901  break;
1902  }
1903  else
1904  {
1905  /* Drop this inner ring only */
1906  ptarray_free(pa);
1907  continue;
1908  }
1909  }
1910  g->rings[j++] = pa;
1911  }
1912  /* Update ring count */
1913  g->nrings = j;
1914  break;
1915  }
1916  /* Can process all multi* types as generic collection */
1917  case MULTIPOINTTYPE:
1918  case MULTILINETYPE:
1919  case MULTIPOLYGONTYPE:
1920  case TINTYPE:
1921  case COLLECTIONTYPE:
1922  {
1923  uint32_t i, j = 0;
1924  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1925  for (i = 0; i < col->ngeoms; i++)
1926  {
1927  LWGEOM *g = col->geoms[i];
1928  if (!g) continue;
1929  modified |= lwgeom_simplify_in_place(g, epsilon, preserve_collapsed);
1930  /* Drop zero'ed out geometries */
1931  if(lwgeom_is_empty(g))
1932  {
1933  lwgeom_free(g);
1934  continue;
1935  }
1936  col->geoms[j++] = g;
1937  }
1938  /* Update geometry count */
1939  col->ngeoms = j;
1940  break;
1941  }
1942  default:
1943  {
1944  lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(geom->type));
1945  break;
1946  }
1947  }
1948 
1949  if (modified)
1950  {
1951  lwgeom_drop_bbox(geom);
1952  }
1953  return modified;
1954 }
#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:327
#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:1721
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:57
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:1218
int lwgeom_simplify_in_place(LWGEOM *geom, double epsilon, int preserve_collapsed)
Definition: lwgeom.c:1823
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
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:97
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:199
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: