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

◆ _lwt_MakeRingShell()

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

Definition at line 1779 of file lwgeom_topo.c.

1780{
1781 LWT_ELEMID *edge_ids;
1782 uint64_t numedges, i, j;
1783 LWT_ISO_EDGE *ring_edges;
1784
1785 /* Construct a polygon using edges of the ring */
1786 numedges = 0;
1787 edge_ids = lwalloc(sizeof(LWT_ELEMID)*num_signed_edge_ids);
1788 for (i=0; i<num_signed_edge_ids; ++i) {
1789 int absid = llabs(signed_edge_ids[i]);
1790 int found = 0;
1791 /* Do not add the same edge twice */
1792 for (j=0; j<numedges; ++j) {
1793 if ( edge_ids[j] == absid ) {
1794 found = 1;
1795 break;
1796 }
1797 }
1798 if ( ! found ) edge_ids[numedges++] = absid;
1799 }
1800 i = numedges;
1801 ring_edges = lwt_be_getEdgeById(topo, edge_ids, &i,
1803 lwfree( edge_ids );
1804 if (i == UINT64_MAX)
1805 {
1807 return NULL;
1808 }
1809 else if ( i != numedges )
1810 {
1811 lwfree( signed_edge_ids );
1812 _lwt_release_edges(ring_edges, i);
1813 lwerror("Unexpected error: %" LWTFMT_ELEMID
1814 " edges found when expecting %" PRIu64, i, numedges);
1815 return NULL;
1816 }
1817
1818 /* Should now build a polygon with those edges, in the order
1819 * given by GetRingEdges.
1820 */
1821 POINTARRAY *pa = NULL;
1822 for ( i=0; i<num_signed_edge_ids; ++i )
1823 {
1824 LWT_ELEMID eid = signed_edge_ids[i];
1825 LWDEBUGF(2, "Edge %llu in ring is edge %" LWTFMT_ELEMID, i, eid);
1826 LWT_ISO_EDGE *edge = NULL;
1827 POINTARRAY *epa;
1828 for ( j=0; j<numedges; ++j )
1829 {
1830 if ( ring_edges[j].edge_id == llabs(eid) )
1831 {
1832 edge = &(ring_edges[j]);
1833 break;
1834 }
1835 }
1836 if ( edge == NULL )
1837 {
1838 _lwt_release_edges(ring_edges, numedges);
1839 lwerror("missing edge that was found in ring edges loop");
1840 return NULL;
1841 }
1842
1843 if ( pa == NULL )
1844 {
1845 pa = ptarray_clone_deep(edge->geom->points);
1846 if ( eid < 0 ) ptarray_reverse_in_place(pa);
1847 }
1848 else
1849 {
1850 if ( eid < 0 )
1851 {
1852 epa = ptarray_clone_deep(edge->geom->points);
1854 ptarray_append_ptarray(pa, epa, 0);
1855 ptarray_free(epa);
1856 }
1857 else
1858 {
1859 /* avoid a clone here */
1860 ptarray_append_ptarray(pa, edge->geom->points, 0);
1861 }
1862 }
1863 }
1864 _lwt_release_edges(ring_edges, numedges);
1865 POINTARRAY **points = lwalloc(sizeof(POINTARRAY*));
1866 points[0] = pa;
1867
1868 /* NOTE: the ring may very well have collapsed components,
1869 * which would make it topologically invalid
1870 */
1871 LWPOLY* shell = lwpoly_construct(0, 0, 1, points);
1872 return shell;
1873}
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:177
void * lwalloc(size_t size)
Definition lwutil.c:227
void lwfree(void *mem)
Definition lwutil.c:248
void ptarray_free(POINTARRAY *pa)
Definition ptarray.c:327
LWPOLY * lwpoly_construct(int32_t srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Definition lwpoly.c:43
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition ptarray.c:643
void ptarray_reverse_in_place(POINTARRAY *pa)
Definition ptarray.c:339
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
#define LWT_COL_EDGE_GEOM
#define PGTOPO_BE_ERROR()
#define LWTFMT_ELEMID
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
LWT_ISO_EDGE * lwt_be_getEdgeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
POINTARRAY * points
Definition liblwgeom.h:483

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

Referenced by _lwt_AddFaceSplit(), and lwt_ChangeEdgeGeom().

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