PostGIS  2.5.0dev-r@@SVN_REVISION@@

◆ _lwt_MakeRingShell()

static LWPOLY* _lwt_MakeRingShell ( LWT_TOPOLOGY topo,
LWT_ELEMID signed_edge_ids,
int  num_signed_edge_ids 
)
static

Definition at line 1770 of file lwgeom_topo.c.

References _lwt_release_edges(), LWT_TOPOLOGY_T::be_iface, LWT_ISO_EDGE::geom, lwalloc(), LWDEBUGF, lwerror(), lwfree(), lwpoly_construct(), lwt_be_getEdgeById(), lwt_be_lastErrorMessage(), LWT_COL_EDGE_EDGE_ID, LWT_COL_EDGE_GEOM, LWTFMT_ELEMID, LWLINE::points, ptarray_append_ptarray(), ptarray_clone_deep(), ptarray_free(), and ptarray_reverse_in_place().

Referenced by _lwt_AddFaceSplit().

1771 {
1772  LWT_ELEMID *edge_ids;
1773  int numedges, i, j;
1774  LWT_ISO_EDGE *ring_edges;
1775 
1776  /* Construct a polygon using edges of the ring */
1777  numedges = 0;
1778  edge_ids = lwalloc(sizeof(LWT_ELEMID)*num_signed_edge_ids);
1779  for (i=0; i<num_signed_edge_ids; ++i) {
1780  int absid = llabs(signed_edge_ids[i]);
1781  int found = 0;
1782  /* Do not add the same edge twice */
1783  for (j=0; j<numedges; ++j) {
1784  if ( edge_ids[j] == absid ) {
1785  found = 1;
1786  break;
1787  }
1788  }
1789  if ( ! found ) edge_ids[numedges++] = absid;
1790  }
1791  i = numedges;
1792  ring_edges = lwt_be_getEdgeById(topo, edge_ids, &i,
1794  lwfree( edge_ids );
1795  if ( i == -1 )
1796  {
1797  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
1798  return NULL;
1799  }
1800  else if ( i != numedges )
1801  {
1802  lwfree( signed_edge_ids );
1803  _lwt_release_edges(ring_edges, numedges);
1804  lwerror("Unexpected error: %d edges found when expecting %d", i, numedges);
1805  return NULL;
1806  }
1807 
1808  /* Should now build a polygon with those edges, in the order
1809  * given by GetRingEdges.
1810  */
1811  POINTARRAY *pa = NULL;
1812  for ( i=0; i<num_signed_edge_ids; ++i )
1813  {
1814  LWT_ELEMID eid = signed_edge_ids[i];
1815  LWDEBUGF(2, "Edge %d in ring is edge %" LWTFMT_ELEMID, i, eid);
1816  LWT_ISO_EDGE *edge = NULL;
1817  POINTARRAY *epa;
1818  for ( j=0; j<numedges; ++j )
1819  {
1820  if ( ring_edges[j].edge_id == llabs(eid) )
1821  {
1822  edge = &(ring_edges[j]);
1823  break;
1824  }
1825  }
1826  if ( edge == NULL )
1827  {
1828  _lwt_release_edges(ring_edges, numedges);
1829  lwerror("missing edge that was found in ring edges loop");
1830  return NULL;
1831  }
1832 
1833  if ( pa == NULL )
1834  {
1835  pa = ptarray_clone_deep(edge->geom->points);
1836  if ( eid < 0 ) ptarray_reverse_in_place(pa);
1837  }
1838  else
1839  {
1840  if ( eid < 0 )
1841  {
1842  epa = ptarray_clone_deep(edge->geom->points);
1844  ptarray_append_ptarray(pa, epa, 0);
1845  ptarray_free(epa);
1846  }
1847  else
1848  {
1849  /* avoid a clone here */
1850  ptarray_append_ptarray(pa, edge->geom->points, 0);
1851  }
1852  }
1853  }
1854  _lwt_release_edges(ring_edges, numedges);
1855  POINTARRAY **points = lwalloc(sizeof(POINTARRAY*));
1856  points[0] = pa;
1857 
1858  /* NOTE: the ring may very well have collapsed components,
1859  * which would make it topologically invalid
1860  */
1861  LWPOLY* shell = lwpoly_construct(0, 0, 1, points);
1862  return shell;
1863 }
void lwfree(void *mem)
Definition: lwutil.c:244
void ptarray_free(POINTARRAY *pa)
Definition: ptarray.c:328
LWLINE * geom
LWT_ISO_EDGE * lwt_be_getEdgeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, int *numelems, int fields)
Definition: lwgeom_topo.c:225
LWPOLY * lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Definition: lwpoly.c:43
const LWT_BE_IFACE * be_iface
int ptarray_append_ptarray(POINTARRAY *pa1, POINTARRAY *pa2, double gap_tolerance)
Append a POINTARRAY, pa2 to the end of an existing POINTARRAY, pa1.
Definition: ptarray.c:187
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition: ptarray.c:628
void ptarray_reverse_in_place(POINTARRAY *pa)
Definition: ptarray.c:341
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
Definition: lwgeom_topo.c:457
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_GEOM
void * lwalloc(size_t size)
Definition: lwutil.c:229
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
Definition: lwgeom_topo.c:120
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
#define LWTFMT_ELEMID
Definition: lwgeom_topo.c:44
POINTARRAY * points
Definition: liblwgeom.h:424
Here is the call graph for this function:
Here is the caller graph for this function: