PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ lwt_ModEdgeSplit()

LWT_ELEMID lwt_ModEdgeSplit ( LWT_TOPOLOGY topo,
LWT_ELEMID  edge,
LWPOINT pt,
int  skipChecks 
)

Split an edge by a node, modifying the original edge and adding a new one.

For ST_ModEdgeSplit

Parameters
topothe topology to operate on
edgeidentifier of the edge to be split
ptgeometry of the new node
skipChecksif non-zero skips consistency checks (coincident node, point not on edge...)
Returns
the id of newly created node, or -1 on error (liblwgeom error handler will be invoked with error message)

Definition at line 1016 of file lwgeom_topo.c.

1018{
1019 LWT_ISO_NODE node;
1020 LWT_ISO_EDGE* oldedge = NULL;
1021 LWCOLLECTION *split_col;
1022 const LWGEOM *oldedge_geom;
1023 const LWGEOM *newedge_geom;
1024 LWT_ISO_EDGE newedge1;
1025 LWT_ISO_EDGE seledge, updedge, excedge;
1026 int ret;
1027
1028 split_col = _lwt_EdgeSplit( topo, edge, pt, skipISOChecks, &oldedge );
1029 if ( ! split_col ) return -1; /* should have raised an exception */
1030 oldedge_geom = split_col->geoms[0];
1031 newedge_geom = split_col->geoms[1];
1032 /* Make sure the SRID is set on the subgeom */
1033 ((LWGEOM*)oldedge_geom)->srid = split_col->srid;
1034 ((LWGEOM*)newedge_geom)->srid = split_col->srid;
1035
1036 /* Add new node, getting new id back */
1037 node.node_id = -1;
1038 node.containing_face = -1; /* means not-isolated */
1039 node.geom = pt;
1040 if ( ! lwt_be_insertNodes(topo, &node, 1) )
1041 {
1042 _lwt_release_edges(oldedge, 1);
1043 lwcollection_free(split_col);
1044 lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
1045 return -1;
1046 }
1047 if (node.node_id == -1) {
1048 /* should have been set by backend */
1049 _lwt_release_edges(oldedge, 1);
1050 lwcollection_free(split_col);
1051 lwerror("Backend coding error: "
1052 "insertNodes callback did not return node_id");
1053 return -1;
1054 }
1055
1056 /* Insert the new edge */
1057 newedge1.edge_id = lwt_be_getNextEdgeId(topo);
1058 if ( newedge1.edge_id == -1 ) {
1059 _lwt_release_edges(oldedge, 1);
1060 lwcollection_free(split_col);
1061 lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
1062 return -1;
1063 }
1064 newedge1.start_node = node.node_id;
1065 newedge1.end_node = oldedge->end_node;
1066 newedge1.face_left = oldedge->face_left;
1067 newedge1.face_right = oldedge->face_right;
1068 newedge1.next_left = oldedge->next_left == -oldedge->edge_id ?
1069 -newedge1.edge_id : oldedge->next_left;
1070 newedge1.next_right = -oldedge->edge_id;
1071 newedge1.geom = lwgeom_as_lwline(newedge_geom);
1072 /* lwgeom_split of a line should only return lines ... */
1073 if ( ! newedge1.geom ) {
1074 _lwt_release_edges(oldedge, 1);
1075 lwcollection_free(split_col);
1076 lwerror("first geometry in lwgeom_split output is not a line");
1077 return -1;
1078 }
1079 ret = lwt_be_insertEdges(topo, &newedge1, 1);
1080 if ( ret == -1 ) {
1081 _lwt_release_edges(oldedge, 1);
1082 lwcollection_free(split_col);
1083 lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
1084 return -1;
1085 } else if ( ret == 0 ) {
1086 _lwt_release_edges(oldedge, 1);
1087 lwcollection_free(split_col);
1088 lwerror("Insertion of split edge failed (no reason)");
1089 return -1;
1090 }
1091
1092 /* Update the old edge */
1093 updedge.geom = lwgeom_as_lwline(oldedge_geom);
1094 /* lwgeom_split of a line should only return lines ... */
1095 if ( ! updedge.geom ) {
1096 _lwt_release_edges(oldedge, 1);
1097 lwcollection_free(split_col);
1098 lwerror("second geometry in lwgeom_split output is not a line");
1099 return -1;
1100 }
1101 updedge.next_left = newedge1.edge_id;
1102 updedge.end_node = node.node_id;
1103 ret = lwt_be_updateEdges(topo,
1104 oldedge, LWT_COL_EDGE_EDGE_ID,
1106 NULL, 0);
1107 if ( ret == -1 ) {
1108 _lwt_release_edges(oldedge, 1);
1109 lwcollection_free(split_col);
1110 lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
1111 return -1;
1112 } else if ( ret == 0 ) {
1113 _lwt_release_edges(oldedge, 1);
1114 lwcollection_free(split_col);
1115 lwerror("Edge being split (%d) disappeared during operations?", oldedge->edge_id);
1116 return -1;
1117 } else if ( ret > 1 ) {
1118 _lwt_release_edges(oldedge, 1);
1119 lwcollection_free(split_col);
1120 lwerror("More than a single edge found with id %d !", oldedge->edge_id);
1121 return -1;
1122 }
1123
1124 /* Update all next edge references to match new layout (ST_ModEdgeSplit) */
1125
1126 updedge.next_right = -newedge1.edge_id;
1127 excedge.edge_id = newedge1.edge_id;
1128 seledge.next_right = -oldedge->edge_id;
1129 seledge.start_node = oldedge->end_node;
1130 ret = lwt_be_updateEdges(topo,
1132 &updedge, LWT_COL_EDGE_NEXT_RIGHT,
1133 &excedge, LWT_COL_EDGE_EDGE_ID);
1134 if ( ret == -1 ) {
1135 _lwt_release_edges(oldedge, 1);
1136 lwcollection_free(split_col);
1137 lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
1138 return -1;
1139 }
1140
1141 updedge.next_left = -newedge1.edge_id;
1142 excedge.edge_id = newedge1.edge_id;
1143 seledge.next_left = -oldedge->edge_id;
1144 seledge.end_node = oldedge->end_node;
1145 ret = lwt_be_updateEdges(topo,
1147 &updedge, LWT_COL_EDGE_NEXT_LEFT,
1148 &excedge, LWT_COL_EDGE_EDGE_ID);
1149 if ( ret == -1 ) {
1150 _lwt_release_edges(oldedge, 1);
1151 lwcollection_free(split_col);
1152 lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
1153 return -1;
1154 }
1155
1156 /* Update TopoGeometries composition */
1157 ret = lwt_be_updateTopoGeomEdgeSplit(topo, oldedge->edge_id, newedge1.edge_id, -1);
1158 if ( ! ret ) {
1159 _lwt_release_edges(oldedge, 1);
1160 lwcollection_free(split_col);
1161 lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
1162 return -1;
1163 }
1164
1165 _lwt_release_edges(oldedge, 1);
1166 lwcollection_free(split_col);
1167
1168 /* return new node id */
1169 return node.node_id;
1170}
void lwcollection_free(LWCOLLECTION *col)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition lwgeom.c:161
#define LWT_COL_EDGE_START_NODE
#define LWT_COL_EDGE_NEXT_RIGHT
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
#define LWT_COL_EDGE_END_NODE
#define LWT_COL_EDGE_NEXT_LEFT
#define LWT_COL_EDGE_GEOM
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition lwutil.c:190
LWT_ELEMID lwt_be_getNextEdgeId(LWT_TOPOLOGY *topo)
int lwt_be_updateTopoGeomEdgeSplit(LWT_TOPOLOGY *topo, LWT_ELEMID split_edge, LWT_ELEMID new_edge1, LWT_ELEMID new_edge2)
int lwt_be_insertNodes(LWT_TOPOLOGY *topo, LWT_ISO_NODE *node, uint64_t numelems)
int lwt_be_updateEdges(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *sel_edge, int sel_fields, const LWT_ISO_EDGE *upd_edge, int upd_fields, const LWT_ISO_EDGE *exc_edge, int exc_fields)
int lwt_be_insertEdges(LWT_TOPOLOGY *topo, LWT_ISO_EDGE *edge, uint64_t numelems)
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
static LWCOLLECTION * _lwt_EdgeSplit(LWT_TOPOLOGY *topo, LWT_ELEMID edge, LWPOINT *pt, int skipISOChecks, LWT_ISO_EDGE **oldedge)
LWGEOM ** geoms
Definition liblwgeom.h:561
int32_t srid
Definition liblwgeom.h:562
int32_t srid
Definition liblwgeom.h:446
LWT_ELEMID face_right
LWT_ELEMID next_right
LWT_ELEMID end_node
LWT_ELEMID face_left
LWT_ELEMID next_left
LWT_ELEMID edge_id
LWT_ELEMID start_node
LWT_ELEMID node_id
LWT_ELEMID containing_face
LWPOINT * geom
const LWT_BE_IFACE * be_iface

References _lwt_EdgeSplit(), _lwt_release_edges(), LWT_TOPOLOGY_T::be_iface, LWT_ISO_NODE::containing_face, LWT_ISO_EDGE::edge_id, LWT_ISO_EDGE::end_node, LWT_ISO_EDGE::face_left, LWT_ISO_EDGE::face_right, LWT_ISO_NODE::geom, LWT_ISO_EDGE::geom, LWCOLLECTION::geoms, lwcollection_free(), lwerror(), lwgeom_as_lwline(), lwt_be_getNextEdgeId(), lwt_be_insertEdges(), lwt_be_insertNodes(), lwt_be_lastErrorMessage(), lwt_be_updateEdges(), lwt_be_updateTopoGeomEdgeSplit(), LWT_COL_EDGE_EDGE_ID, LWT_COL_EDGE_END_NODE, LWT_COL_EDGE_GEOM, LWT_COL_EDGE_NEXT_LEFT, LWT_COL_EDGE_NEXT_RIGHT, LWT_COL_EDGE_START_NODE, LWT_ISO_EDGE::next_left, LWT_ISO_EDGE::next_right, LWT_ISO_NODE::node_id, LWGEOM::srid, LWCOLLECTION::srid, and LWT_ISO_EDGE::start_node.

Referenced by _lwt_AddPoint().

Here is the call graph for this function:
Here is the caller graph for this function: