1860 int numfaceedges, i, j;
1861 int newface_outside;
1862 int num_signed_edge_ids;
1866 int forward_edges_count = 0;
1868 int backward_edges_count = 0;
1871 &num_signed_edge_ids, 0);
1872 if ( ! signed_edge_ids ) {
1877 LWDEBUGF(1,
"getRingEdges returned %d edges", num_signed_edge_ids);
1880 for (i=0; i<num_signed_edge_ids; ++i) {
1881 if ( signed_edge_ids[i] == -sedge ) {
1884 lwfree( signed_edge_ids );
1890 sedge, face, mbr_only);
1894 num_signed_edge_ids);
1896 lwfree( signed_edge_ids );
1905 lwfree( signed_edge_ids );
1907 " is geometrically not-closed", sedge);
1913 sedge, isccw ?
"counter" :
"");
1922 lwfree( signed_edge_ids );
1926 LWDEBUG(1,
"The left face of this clockwise ring is the universe, "
1927 "won't create a new face there");
1932 if ( mbr_only && face != 0 )
1938 updface.
mbr = (
GBOX *)shellbox;
1942 lwfree( signed_edge_ids );
1949 lwfree( signed_edge_ids );
1951 lwerror(
"Unexpected error: %d faces found when expecting 1", ret);
1955 lwfree( signed_edge_ids );
1963 if ( face != 0 && ! isccw)
1970 lwfree( signed_edge_ids );
1977 lwfree( signed_edge_ids );
1979 lwerror(
"Unexpected error: %d faces found when expecting 1", nfaces);
1982 newface.
mbr = oldface->
mbr;
1986 newface.
mbr = (
GBOX *)shellbox;
1993 lwfree( signed_edge_ids );
2000 lwfree( signed_edge_ids );
2002 lwerror(
"Unexpected error: %d faces inserted when expecting 1", ret);
2013 if ( face != 0 && ! isccw ) {
2015 LWDEBUG(1,
"New face is on the outside of the ring, updating rings in former shell");
2016 newface_outside = 1;
2019 LWDEBUG(1,
"New face is on the inside of the ring, updating forward edges in new ring");
2020 newface_outside = 0;
2033 if ( numfaceedges == -1 ) {
2034 lwfree( signed_edge_ids );
2038 LWDEBUGF(1,
"lwt_be_getEdgeByFace returned %d edges", numfaceedges);
2043 forward_edges_count = 0;
2045 backward_edges_count = 0;
2048 for ( i=0; i<numfaceedges; ++i )
2056 for ( j=0; j<num_signed_edge_ids; ++j )
2058 int seid = signed_edge_ids[j];
2066 if ( found == 2 )
break;
2068 else if ( -seid == e->
edge_id )
2071 LWDEBUGF(1,
"Edge %d is a backward edge of the new ring", e->
edge_id);
2075 if ( found == 2 )
break;
2078 if ( found )
continue;
2092 lwerror(
"Could not find interior point for edge %d: %s",
2105 if ( newface_outside )
2109 LWDEBUGF(1,
"Edge %d contained in an hole of the new face",
2118 LWDEBUGF(1,
"Edge %d not contained in the face shell",
2142 if ( forward_edges_count )
2145 forward_edges_count,
2149 lwfree( signed_edge_ids );
2153 if ( ret != forward_edges_count )
2155 lwfree( signed_edge_ids );
2156 lwerror(
"Unexpected error: %d edges updated when expecting %d",
2157 ret, forward_edges_count);
2163 if ( backward_edges_count )
2166 backward_edges_count,
2170 lwfree( signed_edge_ids );
2174 if ( ret != backward_edges_count )
2176 lwfree( signed_edge_ids );
2177 lwerror(
"Unexpected error: %d edges updated when expecting %d",
2178 ret, backward_edges_count);
2191 int numisonodes = 1;
2194 &numisonodes, fields, newface.
mbr);
2195 if ( numisonodes == -1 ) {
2196 lwfree( signed_edge_ids );
2200 if ( numisonodes ) {
2202 int nodes_to_update = 0;
2203 for (i=0; i<numisonodes; ++i)
2208 LWDEBUGF(1,
"Node %d is %scontained in new ring, newface is %s",
2210 newface_outside ?
"outside" :
"inside" );
2211 if ( newface_outside )
2215 LWDEBUGF(1,
"Node %d contained in an hole of the new face",
2224 LWDEBUGF(1,
"Node %d not contained in the face shell",
2235 if ( nodes_to_update )
2241 lwfree( signed_edge_ids );
char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE]
int ptarray_is_closed(const POINTARRAY *pa)
Check for ring closure using whatever dimensionality is declared on the pointarray.
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
void * lwalloc(size_t size)
void lwpoly_free(LWPOLY *poly)
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
#define LW_INSIDE
Constants for point-in-polygon return values.
int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt)
Return 1 if the point is inside the POINTARRAY, -1 if it is outside, and 0 if it is on the boundary.
int ptarray_isccw(const POINTARRAY *pa)
#define LWT_COL_EDGE_FACE_RIGHT
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_FACE_LEFT
#define LWT_COL_NODE_CONTAINING_FACE
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
#define LWT_COL_NODE_GEOM
#define LWT_COL_NODE_NODE_ID
Node fields.
#define LWT_COL_EDGE_GEOM
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
static int _lwt_GetInteriorEdgePoint(const LWLINE *edge, POINT2D *ip)
static int lwt_be_updateFacesById(LWT_TOPOLOGY *topo, const LWT_ISO_FACE *faces, int numfaces)
static LWT_ISO_NODE * lwt_be_getNodeByFace(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, int *numelems, int fields, const GBOX *box)
static int lwt_be_updateNodesById(LWT_TOPOLOGY *topo, const LWT_ISO_NODE *nodes, int numnodes, int upd_fields)
static void _lwt_release_nodes(LWT_ISO_NODE *nodes, int num_nodes)
static LWT_ISO_EDGE * lwt_be_getEdgeByFace(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, int *numelems, int fields, const GBOX *box)
static LWT_ISO_FACE * lwt_be_getFaceById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, int *numelems, int fields)
static LWPOLY * _lwt_MakeRingShell(LWT_TOPOLOGY *topo, LWT_ELEMID *signed_edge_ids, int num_signed_edge_ids)
static int lwt_be_insertFaces(LWT_TOPOLOGY *topo, LWT_ISO_FACE *face, int numelems)
static LWT_ELEMID * lwt_be_getRingEdges(LWT_TOPOLOGY *topo, LWT_ELEMID edge, int *numedges, int limit)
static void _lwt_release_faces(LWT_ISO_FACE *faces, int num_faces)
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
static int lwt_be_updateEdgesById(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *edges, int numedges, int upd_fields)
Datum contains(PG_FUNCTION_ARGS)
LWT_ELEMID containing_face
const LWT_BE_IFACE * be_iface