1896{
1897 uint64_t numfaceedges, i, j;
1898 int newface_outside;
1899 uint64_t num_signed_edge_ids;
1903 int forward_edges_count = 0;
1905 int backward_edges_count = 0;
1906
1908 if (!signed_edge_ids)
1909 {
1910
1912 return -2;
1913 }
1914 LWDEBUGF(1,
"getRingEdges returned %llu edges", num_signed_edge_ids);
1915
1916
1917 for (i=0; i<num_signed_edge_ids; ++i) {
1918 if ( signed_edge_ids[i] == -sedge ) {
1919
1921 lwfree( signed_edge_ids );
1922 return 0;
1923 }
1924 }
1925
1927 sedge, face, mbr_only);
1928
1929
1930
1931
1932
1933
1934
1936 num_signed_edge_ids);
1937 if ( ! shell ) {
1938 lwfree( signed_edge_ids );
1939
1941 return -2;
1942 }
1945 {
1947 lwfree( signed_edge_ids );
1949 " is geometrically not-closed", sedge);
1950 return -2;
1951 }
1952
1955 sedge, isccw ? "counter" : "");
1957
1958 if ( face == 0 )
1959 {
1960
1961 if ( ! isccw )
1962 {
1964 lwfree( signed_edge_ids );
1965
1966
1967
1968 LWDEBUG(1,
"The left face of this clockwise ring is the universe, "
1969 "won't create a new face there");
1970 return -1;
1971 }
1972 }
1973
1974 if ( mbr_only && face != 0 )
1975 {
1976 if ( isccw )
1977 {{
1980 updface.
mbr = (
GBOX *)shellbox;
1982 if ( ret == -1 )
1983 {
1984 lwfree( signed_edge_ids );
1987 return -2;
1988 }
1989 if ( ret != 1 )
1990 {
1991 lwfree( signed_edge_ids );
1993 lwerror(
"Unexpected error: %d faces found when expecting 1", ret);
1994 return -2;
1995 }
1996 }}
1997 lwfree( signed_edge_ids );
1999 return -1;
2000 }
2001
2005 if ( face != 0 && ! isccw)
2006 {{
2007
2008 uint64_t nfaces = 1;
2010 if (nfaces == UINT64_MAX)
2011 {
2012 lwfree( signed_edge_ids );
2015 return -2;
2016 }
2017 if ( nfaces != 1 )
2018 {
2019 lwfree( signed_edge_ids );
2021 lwerror(
"Unexpected error: %" PRIu64
" faces found when expecting 1", nfaces);
2022 return -2;
2023 }
2024 newface.
mbr = oldface->
mbr;
2025 }}
2026 else
2027 {
2028 newface.
mbr = (
GBOX *)shellbox;
2029 }
2030
2031
2033 if ( ret == -1 )
2034 {
2035 lwfree( signed_edge_ids );
2038 return -2;
2039 }
2040 if ( ret != 1 )
2041 {
2042 lwfree( signed_edge_ids );
2044 lwerror(
"Unexpected error: %d faces inserted when expecting 1", ret);
2045 return -2;
2046 }
2047 if ( oldface ) {
2050 }
2051
2052
2053
2054
2055 if ( face != 0 && ! isccw ) {
2056
2057 LWDEBUG(1,
"New face is on the outside of the ring, updating rings in former shell");
2058 newface_outside = 1;
2059
2060 } else {
2061 LWDEBUG(1,
"New face is on the inside of the ring, updating forward edges in new ring");
2062 newface_outside = 0;
2063
2064 }
2065
2066
2067
2072 ;
2073 numfaceedges = 1;
2075 if (numfaceedges == UINT64_MAX)
2076 {
2079 return -2;
2080 }
2081 LWDEBUGF(1,
"_lwt_AddFaceSplit: lwt_be_getEdgeByFace(%" LWTFMT_ELEMID ") returned %llu edges", face, numfaceedges);
2082
2083 if ( numfaceedges )
2084 {
2086 forward_edges_count = 0;
2088 backward_edges_count = 0;
2089
2090
2091 for ( i=0; i<numfaceedges; ++i )
2092 {
2094 int found = 0;
2097
2098
2099 for ( j=0; j<num_signed_edge_ids; ++j )
2100 {
2101 int seid = signed_edge_ids[j];
2103 {
2104
2108 found++;
2109 if ( found == 2 ) break;
2110 }
2111 else if ( -seid == e->
edge_id )
2112 {
2113
2117 found++;
2118 if ( found == 2 ) break;
2119 }
2120 }
2121 if ( found ) continue;
2123
2124
2125
2127 {
2134 return -2;
2135 }
2136
2139
2143
2144
2145 if ( newface_outside )
2146 {
2148 {
2151 continue;
2152 }
2153 }
2154 else
2155 {
2157 {
2160 continue;
2161 }
2162 }
2163
2164
2166 {
2170 }
2171
2172
2174 {
2178 }
2179 }
2180
2181
2182 if ( forward_edges_count )
2183 {
2185 forward_edges_count,
2187 if ( ret == -1 )
2188 {
2189 lwfree( signed_edge_ids );
2191 return -2;
2192 }
2193 if ( ret != forward_edges_count )
2194 {
2195 lwfree( signed_edge_ids );
2196 lwerror(
"Unexpected error: %d edges updated when expecting %d",
2197 ret, forward_edges_count);
2198 return -2;
2199 }
2200 }
2201
2202
2203 if ( backward_edges_count )
2204 {
2206 backward_edges_count,
2208 if ( ret == -1 )
2209 {
2210 lwfree( signed_edge_ids );
2212 return -2;
2213 }
2214 if ( ret != backward_edges_count )
2215 {
2216 lwfree( signed_edge_ids );
2217 lwerror(
"Unexpected error: %d edges updated when expecting %d",
2218 ret, backward_edges_count);
2219 return -2;
2220 }
2221 }
2222
2225
2227 }
2228
2229
2230 uint64_t numisonodes = 1;
2233 &numisonodes, fields, newface.
mbr);
2234 if (numisonodes == UINT64_MAX)
2235 {
2238 return -2;
2239 }
2240 if ( numisonodes ) {
2242 int nodes_to_update = 0;
2243 for (i=0; i<numisonodes; ++i)
2244 {
2250 newface_outside ? "outside" : "inside" );
2251 if ( newface_outside )
2252 {
2254 {
2257 continue;
2258 }
2259 }
2260 else
2261 {
2263 {
2266 continue;
2267 }
2268 }
2273 }
2275 if ( nodes_to_update )
2276 {
2278 nodes_to_update,
2280 if ( ret == -1 ) {
2281 lwfree( signed_edge_ids );
2283 return -2;
2284 }
2285 }
2287 }
2288
2291
2293}
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