PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ lwgeom_boundary()

LWGEOM* lwgeom_boundary ( LWGEOM lwgeom)

Definition at line 2586 of file lwgeom.c.

2587 {
2588  int32_t srid = lwgeom_get_srid(lwgeom);
2589  uint8_t hasz = lwgeom_has_z(lwgeom);
2590  uint8_t hasm = lwgeom_has_m(lwgeom);
2591 
2592  switch (lwgeom->type)
2593  {
2594  case POINTTYPE:
2595  case MULTIPOINTTYPE: {
2596  return lwgeom_construct_empty(lwgeom->type, srid, hasz, hasm);
2597  }
2598  case LINETYPE:
2599  case CIRCSTRINGTYPE: {
2600  if (lwgeom_is_closed(lwgeom) || lwgeom_is_empty(lwgeom))
2601  return (LWGEOM *)lwmpoint_construct_empty(srid, hasz, hasm);
2602  else
2603  {
2604  LWLINE *lwline = (LWLINE *)lwgeom;
2605  LWMPOINT *lwmpoint = lwmpoint_construct_empty(srid, hasz, hasm);
2606  POINT4D pt;
2607  getPoint4d_p(lwline->points, 0, &pt);
2608  lwmpoint_add_lwpoint(lwmpoint, lwpoint_make(srid, hasz, hasm, &pt));
2609  getPoint4d_p(lwline->points, lwline->points->npoints - 1, &pt);
2610  lwmpoint_add_lwpoint(lwmpoint, lwpoint_make(srid, hasz, hasm, &pt));
2611 
2612  return (LWGEOM *)lwmpoint;
2613  }
2614  }
2615  case MULTILINETYPE:
2616  case MULTICURVETYPE: {
2617  LWMLINE *lwmline = (LWMLINE *)lwgeom;
2618  POINT4D *out = lwalloc(sizeof(POINT4D) * lwmline->ngeoms * 2);
2619  uint32_t n = 0;
2620 
2621  for (uint32_t i = 0; i < lwmline->ngeoms; i++)
2622  {
2623  LWMPOINT *points = lwgeom_as_lwmpoint(lwgeom_boundary((LWGEOM *)lwmline->geoms[i]));
2624  if (!points)
2625  continue;
2626 
2627  for (uint32_t k = 0; k < points->ngeoms; k++)
2628  {
2629  POINT4D pt = getPoint4d(points->geoms[k]->point, 0);
2630 
2631  uint8_t seen = LW_FALSE;
2632  for (uint32_t j = 0; j < n; j++)
2633  {
2634  if (memcmp(&(out[j]), &pt, sizeof(POINT4D)) == 0)
2635  {
2636  seen = LW_TRUE;
2637  out[j] = out[--n];
2638  break;
2639  }
2640  }
2641  if (!seen)
2642  out[n++] = pt;
2643  }
2644 
2645  lwgeom_free((LWGEOM *)points);
2646  }
2647 
2648  LWMPOINT *lwmpoint = lwmpoint_construct_empty(srid, hasz, hasm);
2649 
2650  for (uint32_t i = 0; i < n; i++)
2651  lwmpoint_add_lwpoint(lwmpoint, lwpoint_make(srid, hasz, hasm, &(out[i])));
2652 
2653  lwfree(out);
2654 
2655  return (LWGEOM *)lwmpoint;
2656  }
2657  case TRIANGLETYPE: {
2658  LWTRIANGLE *lwtriangle = (LWTRIANGLE *)lwgeom;
2659  POINTARRAY *points = ptarray_clone_deep(lwtriangle->points);
2660  return (LWGEOM *)lwline_construct(srid, 0, points);
2661  }
2662  case POLYGONTYPE: {
2663  LWPOLY *lwpoly = (LWPOLY *)lwgeom;
2664 
2665  LWMLINE *lwmline = lwmline_construct_empty(srid, hasz, hasm);
2666  for (uint32_t i = 0; i < lwpoly->nrings; i++)
2667  {
2668  POINTARRAY *ring = ptarray_clone_deep(lwpoly->rings[i]);
2669  lwmline_add_lwline(lwmline, lwline_construct(srid, 0, ring));
2670  }
2671 
2672  /* Homogenize the multilinestring to hopefully get a single LINESTRING */
2673  LWGEOM *lwout = lwgeom_homogenize((LWGEOM *)lwmline);
2674  lwgeom_free((LWGEOM *)lwmline);
2675  return lwout;
2676  }
2677  case CURVEPOLYTYPE: {
2678  LWCURVEPOLY *lwcurvepoly = (LWCURVEPOLY *)lwgeom;
2679  LWCOLLECTION *lwcol = lwcollection_construct_empty(MULTICURVETYPE, srid, hasz, hasm);
2680 
2681  for (uint32_t i = 0; i < lwcurvepoly->nrings; i++)
2682  lwcol = lwcollection_add_lwgeom(lwcol, lwgeom_clone_deep(lwcurvepoly->rings[i]));
2683 
2684  return (LWGEOM *)lwcol;
2685  }
2686  case MULTIPOLYGONTYPE:
2687  case COLLECTIONTYPE:
2688  case TINTYPE: {
2689  LWCOLLECTION *lwcol = (LWCOLLECTION *)lwgeom;
2690  LWCOLLECTION *lwcol_boundary = lwcollection_construct_empty(COLLECTIONTYPE, srid, hasz, hasm);
2691 
2692  for (uint32_t i = 0; i < lwcol->ngeoms; i++)
2693  lwcollection_add_lwgeom(lwcol_boundary, lwgeom_boundary(lwcol->geoms[i]));
2694 
2695  LWGEOM *lwout = lwgeom_homogenize((LWGEOM *)lwcol_boundary);
2696  lwgeom_free((LWGEOM *)lwcol_boundary);
2697 
2698  return lwout;
2699  }
2700  default:
2701  lwerror("%s: unsupported geometry type: %s", __func__, lwtype_name(lwgeom->type));
2702  return NULL;
2703  }
2704 }
POINT4D getPoint4d(const POINTARRAY *pa, uint32_t n)
Definition: lwgeom_api.c:108
#define LW_FALSE
Definition: liblwgeom.h:109
#define COLLECTIONTYPE
Definition: liblwgeom.h:123
#define CURVEPOLYTYPE
Definition: liblwgeom.h:126
#define MULTILINETYPE
Definition: liblwgeom.h:121
#define LINETYPE
Definition: liblwgeom.h:118
#define MULTIPOINTTYPE
Definition: liblwgeom.h:120
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition: ptarray.c:634
LWMLINE * lwmline_add_lwline(LWMLINE *mobj, const LWLINE *obj)
Definition: lwmline.c:46
LWMLINE * lwmline_construct_empty(int32_t srid, char hasz, char hasm)
Definition: lwmline.c:38
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:117
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
LWMPOINT * lwmpoint_add_lwpoint(LWMPOINT *mobj, const LWPOINT *obj)
Definition: lwmpoint.c:45
#define TINTYPE
Definition: liblwgeom.h:131
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:122
LWGEOM * lwgeom_homogenize(const LWGEOM *geom)
Definition: lwhomogenize.c:208
void lwfree(void *mem)
Definition: lwutil.c:242
#define POLYGONTYPE
Definition: liblwgeom.h:119
LWMPOINT * lwmpoint_construct_empty(int32_t srid, char hasz, char hasm)
Definition: lwmpoint.c:39
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:124
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
Definition: lwcollection.c:92
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition: lwgeom_api.c:126
#define MULTICURVETYPE
Definition: liblwgeom.h:127
#define TRIANGLETYPE
Definition: liblwgeom.h:130
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
Definition: lwcollection.c:188
void * lwalloc(size_t size)
Definition: lwutil.c:227
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:108
LWPOINT * lwpoint_make(int32_t srid, int hasz, int hasm, const POINT4D *p)
Definition: lwpoint.c:206
int lwgeom_is_closed(const LWGEOM *geom)
Return true or false depending on whether a geometry is a linear feature that closes on itself.
Definition: lwgeom.c:1053
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
Definition: lwgeom.c:927
LWMPOINT * lwgeom_as_lwmpoint(const LWGEOM *lwgeom)
Definition: lwgeom.c:242
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep-clone an LWGEOM object.
Definition: lwgeom.c:529
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:934
LWGEOM * lwgeom_boundary(LWGEOM *lwgeom)
Definition: lwgeom.c:2586
void lwgeom_free(LWGEOM *lwgeom)
Definition: lwgeom.c:1155
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:941
LWGEOM * lwgeom_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
Definition: lwgeom.c:2128
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
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
LWGEOM ** rings
Definition: liblwgeom.h:618
uint32_t nrings
Definition: liblwgeom.h:623
uint8_t type
Definition: liblwgeom.h:477
POINTARRAY * points
Definition: liblwgeom.h:498
LWLINE ** geoms
Definition: liblwgeom.h:562
uint32_t ngeoms
Definition: liblwgeom.h:567
uint32_t ngeoms
Definition: liblwgeom.h:553
LWPOINT ** geoms
Definition: liblwgeom.h:548
POINTARRAY * point
Definition: liblwgeom.h:486
POINTARRAY ** rings
Definition: liblwgeom.h:534
uint32_t nrings
Definition: liblwgeom.h:539
POINTARRAY * points
Definition: liblwgeom.h:510
uint32_t npoints
Definition: liblwgeom.h:442

References CIRCSTRINGTYPE, COLLECTIONTYPE, CURVEPOLYTYPE, LWMPOINT::geoms, LWMLINE::geoms, LWCOLLECTION::geoms, getPoint4d(), getPoint4d_p(), LINETYPE, LW_FALSE, LW_TRUE, lwalloc(), lwcollection_add_lwgeom(), lwcollection_construct_empty(), lwerror(), lwfree(), lwgeom_as_lwmpoint(), lwgeom_boundary(), lwgeom_clone_deep(), lwgeom_construct_empty(), lwgeom_free(), lwgeom_get_srid(), lwgeom_has_m(), lwgeom_has_z(), lwgeom_homogenize(), lwgeom_is_closed(), lwgeom_is_empty(), lwline_construct(), lwmline_add_lwline(), lwmline_construct_empty(), lwmpoint_add_lwpoint(), lwmpoint_construct_empty(), lwpoint_make(), lwtype_name(), MULTICURVETYPE, MULTILINETYPE, MULTIPOINTTYPE, MULTIPOLYGONTYPE, LWMPOINT::ngeoms, LWMLINE::ngeoms, LWCOLLECTION::ngeoms, POINTARRAY::npoints, LWPOLY::nrings, LWCURVEPOLY::nrings, LWPOINT::point, LWLINE::points, LWTRIANGLE::points, POINTTYPE, POLYGONTYPE, ptarray_clone_deep(), LWPOLY::rings, LWCURVEPOLY::rings, TINTYPE, TRIANGLETYPE, and LWGEOM::type.

Referenced by boundary(), and lwgeom_boundary().

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