1779 int numedges, numfaceedges, i, j;
1780 int newface_outside;
1781 int num_signed_edge_ids;
1787 int forward_edges_count = 0;
1789 int backward_edges_count = 0;
1792 &num_signed_edge_ids, 0);
1793 if ( ! signed_edge_ids ) {
1798 LWDEBUGF(1,
"getRingEdges returned %d edges", num_signed_edge_ids);
1801 for (i=0; i<num_signed_edge_ids; ++i) {
1802 if ( signed_edge_ids[i] == -sedge ) {
1805 lwfree( signed_edge_ids );
1811 sedge, face, mbr_only);
1816 for (i=0; i<num_signed_edge_ids; ++i) {
1817 int absid = llabs(signed_edge_ids[i]);
1820 for (j=0; j<numedges; ++j) {
1821 if ( edge_ids[j] == absid ) {
1826 if ( ! found ) edge_ids[numedges++] = absid;
1834 lwfree( signed_edge_ids );
1839 else if ( i != numedges )
1841 lwfree( signed_edge_ids );
1843 lwerror(
"Unexpected error: %d edges found when expecting %d", i, numedges);
1851 for ( i=0; i<num_signed_edge_ids; ++i )
1858 for ( j=0; j<numedges; ++j )
1860 if ( ring_edges[j].edge_id == llabs(eid) )
1862 edge = &(ring_edges[j]);
1868 lwfree( signed_edge_ids );
1870 lwerror(
"missing edge that was found in ring edges loop");
1904 sedge, isccw ?
"counter" :
"");
1913 lwfree( signed_edge_ids );
1918 LWDEBUG(1,
"The left face of this clockwise ring is the universe, " 1919 "won't create a new face there");
1924 if ( mbr_only && face != 0 )
1930 updface.
mbr = (
GBOX *)shellbox;
1934 lwfree( signed_edge_ids );
1942 lwfree( signed_edge_ids );
1945 lwerror(
"Unexpected error: %d faces found when expecting 1", ret);
1949 lwfree( signed_edge_ids );
1958 if ( face != 0 && ! isccw)
1965 lwfree( signed_edge_ids );
1973 lwfree( signed_edge_ids );
1976 lwerror(
"Unexpected error: %d faces found when expecting 1", nfaces);
1979 newface.
mbr = oldface->
mbr;
1983 newface.
mbr = (
GBOX *)shellbox;
1990 lwfree( signed_edge_ids );
1998 lwfree( signed_edge_ids );
2001 lwerror(
"Unexpected error: %d faces inserted when expecting 1", ret);
2012 if ( face != 0 && ! isccw ) {
2014 LWDEBUG(1,
"New face is on the outside of the ring, updating rings in former shell");
2015 newface_outside = 1;
2018 LWDEBUG(1,
"New face is on the inside of the ring, updating forward edges in new ring");
2019 newface_outside = 0;
2032 if ( numfaceedges == -1 ) {
2033 lwfree( signed_edge_ids );
2038 LWDEBUGF(1,
"lwt_be_getEdgeByFace returned %d edges", numfaceedges);
2039 GEOSGeometry *shellgg = 0;
2040 const GEOSPreparedGeometry* prepshell = 0;
2050 prepshell = GEOSPrepare( shellgg );
2051 if ( ! prepshell ) {
2052 GEOSGeom_destroy(shellgg);
2064 forward_edges_count = 0;
2066 backward_edges_count = 0;
2069 for ( i=0; i<numfaceedges; ++i )
2079 for ( j=0; j<num_signed_edge_ids; ++j )
2081 int seid = signed_edge_ids[j];
2089 if ( found == 2 )
break;
2091 else if ( -seid == e->
edge_id )
2094 LWDEBUGF(1,
"Edge %d is a backward edge of the new ring", e->
edge_id);
2098 if ( found == 2 )
break;
2101 if ( found )
continue;
2110 GEOSPreparedGeom_destroy(prepshell);
2111 GEOSGeom_destroy(shellgg);
2118 lwerror(
"Could not find interior point for edge %d: %s",
2127 GEOSPreparedGeom_destroy(prepshell);
2128 GEOSGeom_destroy(shellgg);
2135 lwerror(
"Could not convert edge geometry to GEOS: %s",
2143 contains = GEOSPreparedContains( prepshell, egg );
2144 GEOSGeom_destroy(egg);
2145 if ( contains == 2 )
2147 GEOSPreparedGeom_destroy(prepshell);
2148 GEOSGeom_destroy(shellgg);
2159 (contains?
"":
"not "));
2162 if ( newface_outside )
2166 LWDEBUGF(1,
"Edge %d contained in an hole of the new face",
2175 LWDEBUGF(1,
"Edge %d not contained in the face shell",
2199 if ( forward_edges_count )
2202 forward_edges_count,
2206 lwfree( signed_edge_ids );
2210 if ( ret != forward_edges_count )
2212 lwfree( signed_edge_ids );
2213 lwerror(
"Unexpected error: %d edges updated when expecting %d",
2214 ret, forward_edges_count);
2220 if ( backward_edges_count )
2223 backward_edges_count,
2227 lwfree( signed_edge_ids );
2231 if ( ret != backward_edges_count )
2233 lwfree( signed_edge_ids );
2234 lwerror(
"Unexpected error: %d edges updated when expecting %d",
2235 ret, backward_edges_count);
2249 int numisonodes = 1;
2252 &numisonodes, fields, newface.
mbr);
2253 if ( numisonodes == -1 ) {
2254 lwfree( signed_edge_ids );
2258 if ( numisonodes ) {
2260 int nodes_to_update = 0;
2261 for (i=0; i<numisonodes; ++i)
2269 if ( prepshell ) GEOSPreparedGeom_destroy(prepshell);
2270 if ( shellgg ) GEOSGeom_destroy(shellgg);
2273 lwerror(
"Could not convert node geometry to GEOS: %s",
2277 contains = GEOSPreparedContains( prepshell, ngg );
2278 GEOSGeom_destroy(ngg);
2279 if ( contains == 2 )
2282 if ( prepshell ) GEOSPreparedGeom_destroy(prepshell);
2283 if ( shellgg ) GEOSGeom_destroy(shellgg);
2289 LWDEBUGF(1,
"Node %d is %scontained in new ring, newface is %s",
2290 n->
node_id, contains ?
"" :
"not ",
2291 newface_outside ?
"outside" :
"inside" );
2292 if ( newface_outside )
2296 LWDEBUGF(1,
"Node %d contained in an hole of the new face",
2305 LWDEBUGF(1,
"Node %d not contained in the face shell",
2316 if ( nodes_to_update )
2322 lwfree( signed_edge_ids );
2330 GEOSPreparedGeom_destroy(prepshell);
2331 GEOSGeom_destroy(shellgg);
static void _lwt_release_nodes(LWT_ISO_NODE *nodes, int num_nodes)
static int _lwt_GetInteriorEdgePoint(const LWLINE *edge, POINT2D *ip)
static LWT_ISO_FACE * lwt_be_getFaceById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, int *numelems, int fields)
#define LWT_COL_NODE_CONTAINING_FACE
static int lwt_be_insertFaces(LWT_TOPOLOGY *topo, LWT_ISO_FACE *face, int numelems)
#define LWT_COL_EDGE_FACE_LEFT
LWT_ELEMID containing_face
static int lwt_be_updateEdgesById(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *edges, int numedges, int upd_fields)
#define LWT_COL_EDGE_FACE_RIGHT
LWPOINT * lwpoint_make2d(int srid, double x, double y)
void lwpoint_free(LWPOINT *pt)
void ptarray_free(POINTARRAY *pa)
Datum contains(PG_FUNCTION_ARGS)
char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE]
#define LWDEBUG(level, msg)
LWT_ISO_EDGE * lwt_be_getEdgeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, int *numelems, int fields)
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
static LWT_ISO_EDGE * lwt_be_getEdgeByFace(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, int *numelems, int fields, const GBOX *box)
int ptarray_isccw(const POINTARRAY *pa)
static int lwt_be_updateFacesById(LWT_TOPOLOGY *topo, const LWT_ISO_FACE *faces, int numfaces)
LWPOLY * lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
void lwpoly_free(LWPOLY *poly)
const LWT_BE_IFACE * be_iface
static LWT_ISO_NODE * lwt_be_getNodeByFace(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, int *numelems, int fields, const GBOX *box)
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
int ptarray_append_ptarray(POINTARRAY *pa1, POINTARRAY *pa2, double gap_tolerance)
Append a POINTARRAY, pa2 to the end of an existing POINTARRAY, pa1.
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, int autofix)
static LWT_ELEMID * lwt_be_getRingEdges(LWT_TOPOLOGY *topo, LWT_ELEMID edge, int *numedges, int limit)
static int lwt_be_updateNodesById(LWT_TOPOLOGY *topo, const LWT_ISO_NODE *nodes, int numnodes, int upd_fields)
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
#define LWT_COL_NODE_NODE_ID
Node fields.
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
void ptarray_reverse(POINTARRAY *pa)
#define LWT_COL_NODE_GEOM
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
LWT_INT64 LWT_ELEMID
Identifier of topology element.
static void _lwt_release_faces(LWT_ISO_FACE *faces, int num_faces)
#define LWT_COL_EDGE_GEOM
void * lwalloc(size_t size)
#define LWDEBUGF(level, msg,...)
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.