7022{
7024 LWPOINT *start_point, *end_point;
7030 uint64_t nn, i;
7031 int moved=0, mm;
7032 int pointSplitEdges = -666;
7033
7034 if ( numNewEdges ) *numNewEdges = 0;
7035
7037 LWDEBUGF(1,
"_lwtAddLineEdge with tolerance %g", tol);
7038
7040 if ( ! start_point )
7041 {
7042 lwnotice(
"Empty component of noded line");
7043 return 0;
7044 }
7047 handleFaceSplit, &mm, &pointSplitEdges );
7049 if ( nid[0] == -1 ) return -1;
7050 if ( numNewEdges ) *numNewEdges += pointSplitEdges;
7051 moved += mm;
7052 LWDEBUGF(1,
"node for start point added or found to be %" LWTFMT_ELEMID " (moved ? %d; split %d edges)", nid[0], mm, pointSplitEdges);
7053
7054
7056 if ( ! end_point )
7057 {
7058 lwerror(
"could not get last point of line "
7059 "after successfully getting first point !?");
7060 return -1;
7061 }
7064 handleFaceSplit, &mm, &pointSplitEdges );
7066 if ( nid[1] == -1 ) return -1;
7067 if ( numNewEdges ) *numNewEdges += pointSplitEdges;
7068 moved += mm;
7069 LWDEBUGF(1,
"node for end point added or found to be %" LWTFMT_ELEMID " (moved ? %d; split %d edges)", nid[1], mm, pointSplitEdges);
7070
7071
7072
7073
7074
7075 if ( moved )
7076 {
7077
7078 LWDEBUG(1,
"One or both line endpoints moved by snap, updating line");
7079
7080 nn = nid[0] == nid[1] ? 1 : 2;
7083 if (nn == UINT64_MAX)
7084 {
7086 return -1;
7087 }
7088 start_point = NULL; end_point = NULL;
7089 for (i=0; i<nn; ++i)
7090 {
7091 if ( node[i].node_id == nid[0] ) start_point = node[i].
geom;
7092 if ( node[i].node_id == nid[1] ) end_point = node[i].
geom;
7093 }
7094 if ( ! start_point || ! end_point )
7095 {
7099 return -1;
7100 }
7101
7102
7103
7106
7109
7111
7113
7114
7116
7117 LWDEBUGG(2, tmp,
"Made-valid after snap to drifted endpoints");
7118
7120 if ( col )
7121 {{
7122
7124
7125
7126 if ( colex->
ngeoms == 0 )
7127 {
7130 LWDEBUG(1,
"Made-valid snapped edge collapsed");
7131 return 0;
7132 }
7133
7136 tmp = tmp2;
7139 if ( ! edge )
7140 {
7141
7142 lwerror(
"lwcollection_extract(LINETYPE) returned a non-line?");
7143 return -1;
7144 }
7145 }}
7146 else
7147 {
7149 if ( ! edge )
7150 {
7151 LWDEBUGF(1,
"Made-valid snapped edge collapsed to %s",
7154 return 0;
7155 }
7156 }
7157
7158 }
7159
7160
7163 if ( id == -1 )
7164 {
7166 return -1;
7167 }
7168 if ( id )
7169 {
7171 return id;
7172 }
7173
7174
7175
7176
7177
7178
7179 if ( tol )
7180 {{
7182 LWDEBUGG(2, tmp2,
"Repeated-point removed");
7185 tmp = tmp2;
7186
7187
7189 {
7191 LWDEBUG(1,
"Repeated-point removed edge collapsed");
7192 return 0;
7193 }
7194
7195
7198 if ( id == -1 )
7199 {
7201 return -1;
7202 }
7203 if ( id )
7204 {
7206 return id;
7207 }
7208 }}
7209
7210
7211
7212
7213 id =
_lwt_AddEdge( topo, nid[0], nid[1], edge, 0, handleFaceSplit ? 1 : -1 );
7215 if ( id == -1 )
7216 {
7218 return -1;
7219 }
7221
7222 if ( numNewEdges ) ++*numNewEdges;
7223 *forward = 1;
7224
7225 return id;
7226}
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
void lwpoint_free(LWPOINT *pt)
void lwgeom_free(LWGEOM *geom)
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
void lwcollection_free(LWCOLLECTION *col)
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
void lwline_setPoint4d(LWLINE *line, uint32_t which, POINT4D *newpoint)
LWCOLLECTION * lwcollection_extract(const LWCOLLECTION *col, uint32_t type)
LWGEOM * lwgeom_make_valid(LWGEOM *geom)
Attempts to make an invalid geometries valid w/out losing points.
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
LWGEOM * lwline_remove_repeated_points(const LWLINE *in, double tolerance)
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_NODE_GEOM
#define LWT_COL_NODE_NODE_ID
Node fields.
#define PGTOPO_BE_ERROR()
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwnotice(const char *fmt,...) __attribute__((format(printf
Write a notice out to the notice handler.
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
#define LWDEBUGG(level, geom, msg)
static LWT_ELEMID _lwt_AddEdge(LWT_TOPOLOGY *topo, LWT_ELEMID start_node, LWT_ELEMID end_node, LWLINE *geom, int skipChecks, int modFace)
static void _lwt_release_nodes(LWT_ISO_NODE *nodes, int num_nodes)
static double _lwt_minTolerance(LWGEOM *g)
static LWT_ELEMID _lwt_AddPoint(LWT_TOPOLOGY *topo, LWPOINT *point, double tol, int findFace, int *moved, int *numSplitEdges)
static LWT_ELEMID _lwt_GetEqualEdge(LWT_TOPOLOGY *topo, LWLINE *edge, int *forward)
LWT_ISO_NODE * lwt_be_getNodeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.