2013{
2014 uint64_t numfaceedges, i, j;
2015 int newface_outside;
2016 uint64_t num_signed_edge_ids;
2020 int forward_edges_count = 0;
2022 int backward_edges_count = 0;
2023
2025 if (!signed_edge_ids)
2026 {
2027
2029 return -2;
2030 }
2031 LWDEBUGF(1,
"getRingEdges returned %llu edges", num_signed_edge_ids);
2032
2033
2034 for (i=0; i<num_signed_edge_ids; ++i) {
2035 if ( signed_edge_ids[i] == -sedge ) {
2036
2038 lwfree( signed_edge_ids );
2039 return 0;
2040 }
2041 }
2042
2044 sedge, face, mbr_only);
2045
2046
2047
2048
2049
2050
2051
2053 num_signed_edge_ids);
2054 if ( ! shell ) {
2055 lwfree( signed_edge_ids );
2056
2058 return -2;
2059 }
2062 {
2064 lwfree( signed_edge_ids );
2066 " is geometrically not-closed", sedge);
2067 return -2;
2068 }
2069
2072 sedge, isccw ? "counter" : "");
2074
2075 if ( face == 0 )
2076 {
2077
2078 if ( ! isccw )
2079 {
2081 lwfree( signed_edge_ids );
2082
2083
2084
2085 LWDEBUG(1,
"The left face of this clockwise ring is the universe, "
2086 "won't create a new face there");
2087 return -1;
2088 }
2089 }
2090
2091 if ( mbr_only && face != 0 )
2092 {
2093 if ( isccw )
2094 {{
2097 updface.
mbr = (
GBOX *)shellbox;
2099 if ( ret == -1 )
2100 {
2101 lwfree( signed_edge_ids );
2104 return -2;
2105 }
2106 if ( ret != 1 )
2107 {
2108 lwfree( signed_edge_ids );
2110 lwerror(
"Unexpected error: %d faces found when expecting 1", ret);
2111 return -2;
2112 }
2113 }}
2114 lwfree( signed_edge_ids );
2116 return -1;
2117 }
2118
2122 if ( face != 0 && ! isccw)
2123 {{
2124
2125 uint64_t nfaces = 1;
2127 if (nfaces == UINT64_MAX)
2128 {
2129 lwfree( signed_edge_ids );
2132 return -2;
2133 }
2134 if ( nfaces != 1 )
2135 {
2136 lwfree( signed_edge_ids );
2138 lwerror(
"Unexpected error: %" PRIu64
" faces found when expecting 1", nfaces);
2139 return -2;
2140 }
2141 newface.
mbr = oldface->
mbr;
2142 }}
2143 else
2144 {
2145 newface.
mbr = (
GBOX *)shellbox;
2146 }
2147
2148
2150 if ( ret == -1 )
2151 {
2152 lwfree( signed_edge_ids );
2155 return -2;
2156 }
2157 if ( ret != 1 )
2158 {
2159 lwfree( signed_edge_ids );
2161 lwerror(
"Unexpected error: %d faces inserted when expecting 1", ret);
2162 return -2;
2163 }
2164 if ( oldface ) {
2167 }
2168
2169
2170
2171
2172 if ( face != 0 && ! isccw ) {
2173
2174 LWDEBUG(1,
"New face is on the outside of the ring, updating rings in former shell");
2175 newface_outside = 1;
2176
2177 } else {
2178 LWDEBUG(1,
"New face is on the inside of the ring, updating forward edges in new ring");
2179 newface_outside = 0;
2180
2181 }
2182
2183
2184
2189 ;
2190 numfaceedges = 1;
2192 if (numfaceedges == UINT64_MAX)
2193 {
2196 return -2;
2197 }
2198 LWDEBUGF(1,
"_lwt_AddFaceSplit: lwt_be_getEdgeByFace(%" LWTFMT_ELEMID ") returned %llu edges", face, numfaceedges);
2199
2200 if ( numfaceedges )
2201 {
2203 forward_edges_count = 0;
2205 backward_edges_count = 0;
2206
2207
2208 for ( i=0; i<numfaceedges; ++i )
2209 {
2211 int found = 0;
2214
2215
2216 for ( j=0; j<num_signed_edge_ids; ++j )
2217 {
2218 int seid = signed_edge_ids[j];
2220 {
2221
2225 found++;
2226 if ( found == 2 ) break;
2227 }
2228 else if ( -seid == e->
edge_id )
2229 {
2230
2234 found++;
2235 if ( found == 2 ) break;
2236 }
2237 }
2238 if ( found ) continue;
2240
2241
2242
2244 {
2251 return -2;
2252 }
2253
2256
2260
2261
2262 if ( newface_outside )
2263 {
2265 {
2268 continue;
2269 }
2270 }
2271 else
2272 {
2274 {
2277 continue;
2278 }
2279 }
2280
2281
2283 {
2287 }
2288
2289
2291 {
2295 }
2296 }
2297
2298
2299 if ( forward_edges_count )
2300 {
2302 forward_edges_count,
2304 if ( ret == -1 )
2305 {
2306 lwfree( signed_edge_ids );
2308 return -2;
2309 }
2310 if ( ret != forward_edges_count )
2311 {
2312 lwfree( signed_edge_ids );
2313 lwerror(
"Unexpected error: %d edges updated when expecting %d",
2314 ret, forward_edges_count);
2315 return -2;
2316 }
2317 }
2318
2319
2320 if ( backward_edges_count )
2321 {
2323 backward_edges_count,
2325 if ( ret == -1 )
2326 {
2327 lwfree( signed_edge_ids );
2329 return -2;
2330 }
2331 if ( ret != backward_edges_count )
2332 {
2333 lwfree( signed_edge_ids );
2334 lwerror(
"Unexpected error: %d edges updated when expecting %d",
2335 ret, backward_edges_count);
2336 return -2;
2337 }
2338 }
2339
2342
2344 }
2345
2346
2347 uint64_t numisonodes = 1;
2350 &numisonodes, fields, newface.
mbr);
2351 if (numisonodes == UINT64_MAX)
2352 {
2355 return -2;
2356 }
2357 if ( numisonodes ) {
2359 int nodes_to_update = 0;
2360 for (i=0; i<numisonodes; ++i)
2361 {
2367 newface_outside ? "outside" : "inside" );
2368 if ( newface_outside )
2369 {
2371 {
2374 continue;
2375 }
2376 }
2377 else
2378 {
2380 {
2383 continue;
2384 }
2385 }
2390 }
2392 if ( nodes_to_update )
2393 {
2395 nodes_to_update,
2397 if ( ret == -1 ) {
2398 lwfree( signed_edge_ids );
2400 return -2;
2401 }
2402 }
2404 }
2405
2408
2410}
int gbox_contains_point2d(const GBOX *g, const POINT2D *p)
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
void * lwalloc(size_t size)
int ptarray_is_closed_2d(const POINTARRAY *pa)
void lwpoly_free(LWPOLY *poly)
#define LW_TRUE
Return types for functions with status returns.
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
#define LW_INSIDE
Constants for point-in-polygon return values.
int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt)
The following is based on the "Fast Winding Number Inclusion of a Point in a Polygon" algorithm by Da...
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 PGTOPO_BE_ERROR()
Datum contains(PG_FUNCTION_ARGS)
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
static uint64_t lwt_be_updateFacesById(LWT_TOPOLOGY *topo, const LWT_ISO_FACE *faces, uint64_t numfaces)
void _lwt_release_faces(LWT_ISO_FACE *faces, int num_faces)
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_ELEMID * lwt_be_getRingEdges(LWT_TOPOLOGY *topo, LWT_ELEMID edge, uint64_t *numedges, uint64_t limit)
static LWT_ISO_FACE * lwt_be_getFaceById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
static LWT_ISO_EDGE * lwt_be_getEdgeByFace(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields, const GBOX *box)
void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
static LWPOLY * _lwt_MakeRingShell(LWT_TOPOLOGY *topo, LWT_ELEMID *signed_edge_ids, uint64_t num_signed_edge_ids)
int lwt_be_updateEdgesById(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *edges, int numedges, int upd_fields)
static LWT_ISO_NODE * lwt_be_getNodeByFace(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields, const GBOX *box)
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
int lwt_be_insertFaces(LWT_TOPOLOGY *topo, LWT_ISO_FACE *face, uint64_t numelems)
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
LWT_ELEMID containing_face
const LWT_BE_IFACE * be_iface