1857{
1858 uint64_t numfaceedges, i, j;
1859 int newface_outside;
1860 uint64_t num_signed_edge_ids;
1864 int forward_edges_count = 0;
1866 int backward_edges_count = 0;
1867
1869 if (!signed_edge_ids)
1870 {
1872 sedge,
1874 return -2;
1875 }
1876 LWDEBUGF(1,
"getRingEdges returned %d edges", num_signed_edge_ids);
1877
1878
1879 for (i=0; i<num_signed_edge_ids; ++i) {
1880 if ( signed_edge_ids[i] == -sedge ) {
1881
1883 lwfree( signed_edge_ids );
1884 return 0;
1885 }
1886 }
1887
1889 sedge, face, mbr_only);
1890
1891
1892
1893
1894
1895
1896
1898 num_signed_edge_ids);
1899 if ( ! shell ) {
1900 lwfree( signed_edge_ids );
1901
1903 return -2;
1904 }
1907 {
1909 lwfree( signed_edge_ids );
1911 " is geometrically not-closed", sedge);
1912 return -2;
1913 }
1914
1917 sedge, isccw ? "counter" : "");
1919
1920 if ( face == 0 )
1921 {
1922
1923 if ( ! isccw )
1924 {
1926 lwfree( signed_edge_ids );
1927
1928
1929
1930 LWDEBUG(1,
"The left face of this clockwise ring is the universe, "
1931 "won't create a new face there");
1932 return -1;
1933 }
1934 }
1935
1936 if ( mbr_only && face != 0 )
1937 {
1938 if ( isccw )
1939 {{
1942 updface.
mbr = (
GBOX *)shellbox;
1944 if ( ret == -1 )
1945 {
1946 lwfree( signed_edge_ids );
1949 return -2;
1950 }
1951 if ( ret != 1 )
1952 {
1953 lwfree( signed_edge_ids );
1955 lwerror(
"Unexpected error: %d faces found when expecting 1", ret);
1956 return -2;
1957 }
1958 }}
1959 lwfree( signed_edge_ids );
1961 return -1;
1962 }
1963
1967 if ( face != 0 && ! isccw)
1968 {{
1969
1970 uint64_t nfaces = 1;
1972 if (nfaces == UINT64_MAX)
1973 {
1974 lwfree( signed_edge_ids );
1977 return -2;
1978 }
1979 if ( nfaces != 1 )
1980 {
1981 lwfree( signed_edge_ids );
1983 lwerror(
"Unexpected error: %d faces found when expecting 1", nfaces);
1984 return -2;
1985 }
1986 newface.
mbr = oldface->
mbr;
1987 }}
1988 else
1989 {
1990 newface.
mbr = (
GBOX *)shellbox;
1991 }
1992
1993
1995 if ( ret == -1 )
1996 {
1997 lwfree( signed_edge_ids );
2000 return -2;
2001 }
2002 if ( ret != 1 )
2003 {
2004 lwfree( signed_edge_ids );
2006 lwerror(
"Unexpected error: %d faces inserted when expecting 1", ret);
2007 return -2;
2008 }
2009 if ( oldface ) {
2012 }
2013
2014
2015
2016
2017 if ( face != 0 && ! isccw ) {
2018
2019 LWDEBUG(1,
"New face is on the outside of the ring, updating rings in former shell");
2020 newface_outside = 1;
2021
2022 } else {
2023 LWDEBUG(1,
"New face is on the inside of the ring, updating forward edges in new ring");
2024 newface_outside = 0;
2025
2026 }
2027
2028
2029
2034 ;
2035 numfaceedges = 1;
2037 if (numfaceedges == UINT64_MAX)
2038 {
2041 return -2;
2042 }
2043 LWDEBUGF(1,
"_lwt_AddFaceSplit: lwt_be_getEdgeByFace(%d) returned %d edges", face, numfaceedges);
2044
2045 if ( numfaceedges )
2046 {
2048 forward_edges_count = 0;
2050 backward_edges_count = 0;
2051
2052
2053 for ( i=0; i<numfaceedges; ++i )
2054 {
2056 int found = 0;
2059
2060
2061 for ( j=0; j<num_signed_edge_ids; ++j )
2062 {
2063 int seid = signed_edge_ids[j];
2065 {
2066
2067 LWDEBUGF(1,
"Edge %d is a known forward edge of the new ring", e->
edge_id);
2070 found++;
2071 if ( found == 2 ) break;
2072 }
2073 else if ( -seid == e->
edge_id )
2074 {
2075
2076 LWDEBUGF(1,
"Edge %d is a known backward edge of the new ring", e->
edge_id);
2079 found++;
2080 if ( found == 2 ) break;
2081 }
2082 }
2083 if ( found ) continue;
2084 LWDEBUGF(1,
"Edge %d is not a known edge of the new ring", e->
edge_id);
2085
2086
2087
2089 {
2096 return -2;
2097 }
2098
2099
2100
2102
2103 LWDEBUGF(1,
"Edge %d first point %s new ring",
2106
2107
2108 if ( newface_outside )
2109 {
2111 {
2112 LWDEBUGF(1,
"Edge %d not outside of the new ring, not updating it",
2114 continue;
2115 }
2116 }
2117 else
2118 {
2120 {
2121 LWDEBUGF(1,
"Edge %d not inside the new ring, not updating it",
2123 continue;
2124 }
2125 }
2126
2127
2129 {
2133 }
2134
2135
2137 {
2141 }
2142 }
2143
2144
2145 if ( forward_edges_count )
2146 {
2148 forward_edges_count,
2150 if ( ret == -1 )
2151 {
2152 lwfree( signed_edge_ids );
2154 return -2;
2155 }
2156 if ( ret != forward_edges_count )
2157 {
2158 lwfree( signed_edge_ids );
2159 lwerror(
"Unexpected error: %d edges updated when expecting %d",
2160 ret, forward_edges_count);
2161 return -2;
2162 }
2163 }
2164
2165
2166 if ( backward_edges_count )
2167 {
2169 backward_edges_count,
2171 if ( ret == -1 )
2172 {
2173 lwfree( signed_edge_ids );
2175 return -2;
2176 }
2177 if ( ret != backward_edges_count )
2178 {
2179 lwfree( signed_edge_ids );
2180 lwerror(
"Unexpected error: %d edges updated when expecting %d",
2181 ret, backward_edges_count);
2182 return -2;
2183 }
2184 }
2185
2188
2189 }
2190
2192
2193
2194 uint64_t numisonodes = 1;
2197 &numisonodes, fields, newface.
mbr);
2198 if (numisonodes == UINT64_MAX)
2199 {
2202 return -2;
2203 }
2204 if ( numisonodes ) {
2206 int nodes_to_update = 0;
2207 for (i=0; i<numisonodes; ++i)
2208 {
2212 LWDEBUGF(1,
"Node %d is %scontained in new ring, newface is %s",
2214 newface_outside ? "outside" : "inside" );
2215 if ( newface_outside )
2216 {
2218 {
2219 LWDEBUGF(1,
"Node %d contained in an hole of the new face",
2221 continue;
2222 }
2223 }
2224 else
2225 {
2227 {
2228 LWDEBUGF(1,
"Node %d not contained in the face shell",
2230 continue;
2231 }
2232 }
2237 }
2239 if ( nodes_to_update )
2240 {
2242 nodes_to_update,
2244 if ( ret == -1 ) {
2245 lwfree( signed_edge_ids );
2247 return -2;
2248 }
2249 }
2251 }
2252
2255
2257}
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)
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)
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.
static uint64_t lwt_be_updateFacesById(LWT_TOPOLOGY *topo, const LWT_ISO_FACE *faces, uint64_t numfaces)
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 int lwt_be_insertFaces(LWT_TOPOLOGY *topo, LWT_ISO_FACE *face, uint64_t numelems)
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)
static LWPOLY * _lwt_MakeRingShell(LWT_TOPOLOGY *topo, LWT_ELEMID *signed_edge_ids, uint64_t num_signed_edge_ids)
static void _lwt_release_faces(LWT_ISO_FACE *faces, int num_faces)
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)
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)
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Datum contains(PG_FUNCTION_ARGS)
LWT_ELEMID containing_face
const LWT_BE_IFACE * be_iface