PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ lwgeom_remove_repeated_points_in_place()

int lwgeom_remove_repeated_points_in_place ( LWGEOM in,
double  tolerance 
)
extern

Definition at line 1554 of file lwgeom.c.

1555{
1556 int geometry_modified = LW_FALSE;
1557 switch (geom->type)
1558 {
1559 /* No-op! Cannot remote points */
1560 case POINTTYPE:
1561 case TRIANGLETYPE:
1562 return geometry_modified;
1563 case LINETYPE:
1564 {
1565 LWLINE *g = (LWLINE*)(geom);
1566 POINTARRAY *pa = g->points;
1567 uint32_t npoints = pa->npoints;
1569 geometry_modified = npoints != pa->npoints;
1570 /* Invalid output */
1571 if (pa->npoints == 1 && pa->maxpoints > 1)
1572 {
1573 /* Use first point as last point */
1574 pa->npoints = 2;
1575 ptarray_copy_point(pa, 0, 1);
1576 }
1577 break;
1578 }
1579 case POLYGONTYPE:
1580 {
1581 uint32_t i, j = 0;
1582 LWPOLY *g = (LWPOLY*)(geom);
1583 for (i = 0; i < g->nrings; i++)
1584 {
1585 POINTARRAY *pa = g->rings[i];
1586 int minpoints = 4;
1587 uint32_t npoints = 0;
1588 /* Skip zero'ed out rings */
1589 if(!pa)
1590 continue;
1591 npoints = pa->npoints;
1592 ptarray_remove_repeated_points_in_place(pa, tolerance, minpoints);
1593 geometry_modified |= npoints != pa->npoints;
1594 /* Drop collapsed rings */
1595 if(pa->npoints < 4)
1596 {
1597 geometry_modified = LW_TRUE;
1598 ptarray_free(pa);
1599 continue;
1600 }
1601 g->rings[j++] = pa;
1602 }
1603 /* Update ring count */
1604 g->nrings = j;
1605 break;
1606 }
1607 case MULTIPOINTTYPE:
1608 {
1609 static uint32_t out_stack_size = 32;
1610 double tolsq = tolerance*tolerance;
1611 uint32_t i, j, n = 0;
1612 LWMPOINT *mpt = (LWMPOINT *)(geom);
1613 LWPOINT **out;
1614 LWPOINT *out_stack[out_stack_size];
1615 int use_heap = (mpt->ngeoms > out_stack_size);
1616
1617 /* No-op on empty */
1618 if (mpt->ngeoms < 2)
1619 return geometry_modified;
1620
1621 /* We cannot write directly back to the multipoint */
1622 /* geoms array because we're reading out of it still */
1623 /* so we use a side array */
1624 if (use_heap)
1625 out = lwalloc(sizeof(LWMPOINT *) * mpt->ngeoms);
1626 else
1627 out = out_stack;
1628
1629 /* Inefficient O(n^2) implementation */
1630 for (i = 0; i < mpt->ngeoms; i++)
1631 {
1632 int seen = 0;
1633 LWPOINT *p1 = mpt->geoms[i];
1634 const POINT2D *pt1 = getPoint2d_cp(p1->point, 0);
1635 for (j = 0; j < n; j++)
1636 {
1637 LWPOINT *p2 = out[j];
1638 const POINT2D *pt2 = getPoint2d_cp(p2->point, 0);
1639 if (distance2d_sqr_pt_pt(pt1, pt2) <= tolsq)
1640 {
1641 seen = 1;
1642 break;
1643 }
1644 }
1645 if (seen)
1646 {
1647 lwpoint_free(p1);
1648 continue;
1649 }
1650 out[n++] = p1;
1651 }
1652
1653 /* Copy remaining points back into the input */
1654 /* array */
1655 memcpy(mpt->geoms, out, sizeof(LWPOINT *) * n);
1656 geometry_modified = mpt->ngeoms != n;
1657 mpt->ngeoms = n;
1658 if (use_heap) lwfree(out);
1659 break;
1660 }
1661
1662 case CIRCSTRINGTYPE:
1663 /* Dunno how to handle these, will return untouched */
1664 return geometry_modified;
1665
1666 /* Can process most multi* types as generic collection */
1667 case MULTILINETYPE:
1668 case MULTIPOLYGONTYPE:
1669 case TINTYPE:
1670 case COLLECTIONTYPE:
1671 /* Curve types we mostly ignore, but allow the linear */
1672 /* portions to be processed by recursing into them */
1673 case MULTICURVETYPE:
1674 case CURVEPOLYTYPE:
1675 case MULTISURFACETYPE:
1676 case COMPOUNDTYPE:
1677 {
1678 uint32_t i, j = 0;
1679 LWCOLLECTION *col = (LWCOLLECTION*)(geom);
1680 for (i = 0; i < col->ngeoms; i++)
1681 {
1682 LWGEOM *g = col->geoms[i];
1683 if (!g) continue;
1684 geometry_modified |= lwgeom_remove_repeated_points_in_place(g, tolerance);
1685 /* Drop zero'ed out geometries */
1686 if(lwgeom_is_empty(g))
1687 {
1688 lwgeom_free(g);
1689 continue;
1690 }
1691 col->geoms[j++] = g;
1692 }
1693 /* Update geometry count */
1694 col->ngeoms = j;
1695 break;
1696 }
1697 default:
1698 {
1699 lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(geom->type));
1700 break;
1701 }
1702 }
1703
1704 if (geometry_modified)
1705 {
1706 lwgeom_drop_bbox(geom);
1707 }
1708 return geometry_modified;
1709}
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition lwutil.c:216
#define LW_FALSE
Definition liblwgeom.h:108
#define COLLECTIONTYPE
Definition liblwgeom.h:122
#define COMPOUNDTYPE
Definition liblwgeom.h:124
void lwpoint_free(LWPOINT *pt)
Definition lwpoint.c:213
#define CURVEPOLYTYPE
Definition liblwgeom.h:125
#define MULTILINETYPE
Definition liblwgeom.h:120
#define MULTISURFACETYPE
Definition liblwgeom.h:127
#define LINETYPE
Definition liblwgeom.h:117
#define MULTIPOINTTYPE
Definition liblwgeom.h:119
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:116
void * lwalloc(size_t size)
Definition lwutil.c:227
#define TINTYPE
Definition liblwgeom.h:130
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:121
void lwfree(void *mem)
Definition lwutil.c:242
#define POLYGONTYPE
Definition liblwgeom.h:118
#define CIRCSTRINGTYPE
Definition liblwgeom.h:123
void ptarray_free(POINTARRAY *pa)
Definition ptarray.c:327
#define MULTICURVETYPE
Definition liblwgeom.h:126
#define TRIANGLETYPE
Definition liblwgeom.h:129
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:107
void ptarray_remove_repeated_points_in_place(POINTARRAY *pa, double tolerance, uint32_t min_points)
Definition ptarray.c:1460
void ptarray_copy_point(POINTARRAY *pa, uint32_t from, uint32_t to)
Definition lwgeom_api.c:401
int lwgeom_remove_repeated_points_in_place(LWGEOM *geom, double tolerance)
Definition lwgeom.c:1554
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition lwgeom.c:664
void lwgeom_free(LWGEOM *lwgeom)
Definition lwgeom.c:1138
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition lwutil.c:190
static double distance2d_sqr_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition lwinline.h:35
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
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
uint32_t ngeoms
Definition liblwgeom.h:566
LWGEOM ** geoms
Definition liblwgeom.h:561
POINTARRAY * points
Definition liblwgeom.h:469
uint32_t ngeoms
Definition liblwgeom.h:524
LWPOINT ** geoms
Definition liblwgeom.h:519
POINTARRAY * point
Definition liblwgeom.h:457
POINTARRAY ** rings
Definition liblwgeom.h:505
uint32_t nrings
Definition liblwgeom.h:510
uint32_t maxpoints
Definition liblwgeom.h:414
uint32_t npoints
Definition liblwgeom.h:413

References CIRCSTRINGTYPE, COLLECTIONTYPE, COMPOUNDTYPE, CURVEPOLYTYPE, distance2d_sqr_pt_pt(), LWMPOINT::geoms, LWCOLLECTION::geoms, getPoint2d_cp(), LINETYPE, LW_FALSE, LW_TRUE, lwalloc(), lwerror(), lwfree(), lwgeom_drop_bbox(), lwgeom_free(), lwgeom_is_empty(), lwgeom_remove_repeated_points_in_place(), lwpoint_free(), lwtype_name(), POINTARRAY::maxpoints, MULTICURVETYPE, MULTILINETYPE, MULTIPOINTTYPE, MULTIPOLYGONTYPE, MULTISURFACETYPE, LWMPOINT::ngeoms, LWCOLLECTION::ngeoms, POINTARRAY::npoints, LWPOLY::nrings, LWPOINT::point, LWLINE::points, POINTTYPE, POLYGONTYPE, ptarray_copy_point(), ptarray_free(), ptarray_remove_repeated_points_in_place(), LWPOLY::rings, TINTYPE, TRIANGLETYPE, and LWGEOM::type.

Referenced by lwgeom_remove_repeated_points(), lwgeom_remove_repeated_points_in_place(), mvt_geom(), ST_RemoveRepeatedPoints(), and test_lwgeom_remove_repeated_points().

Here is the call graph for this function:
Here is the caller graph for this function: