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

◆ lwt_NewEdgesSplit()

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

Split an edge by a node, replacing it with two new edges.

For ST_NewEdgesSplit

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

Definition at line 1326 of file lwgeom_topo.c.

1328{
1329 LWT_ISO_NODE node;
1330 LWT_ISO_EDGE* oldedge = NULL;
1331 LWCOLLECTION *split_col;
1332 const LWGEOM *oldedge_geom;
1333 const LWGEOM *newedge_geom;
1334 LWT_ISO_EDGE newedges[2];
1335 LWT_ISO_EDGE seledge, updedge;
1336 int ret;
1337
1338 split_col = _lwt_EdgeSplit( topo, edge, pt, skipISOChecks, &oldedge );
1339 if ( ! split_col ) return -1; /* should have raised an exception */
1340 oldedge_geom = split_col->geoms[0];
1341 newedge_geom = split_col->geoms[1];
1342 /* Make sure the SRID is set on the subgeom */
1343 ((LWGEOM*)oldedge_geom)->srid = split_col->srid;
1344 ((LWGEOM*)newedge_geom)->srid = split_col->srid;
1345
1346 /* Add new node, getting new id back */
1347 node.node_id = -1;
1348 node.containing_face = -1; /* means not-isolated */
1349 node.geom = pt;
1350 if ( ! lwt_be_insertNodes(topo, &node, 1) )
1351 {
1352 _lwt_release_edges(oldedge, 1);
1353 lwcollection_free(split_col);
1355 return -1;
1356 }
1357 if (node.node_id == -1) {
1358 _lwt_release_edges(oldedge, 1);
1359 lwcollection_free(split_col);
1360 /* should have been set by backend */
1361 lwerror("Backend coding error: "
1362 "insertNodes callback did not return node_id");
1363 return -1;
1364 }
1365
1366 /* Delete the old edge */
1367 seledge.edge_id = edge;
1368 ret = lwt_be_deleteEdges(topo, &seledge, LWT_COL_EDGE_EDGE_ID);
1369 if ( ret == -1 ) {
1370 _lwt_release_edges(oldedge, 1);
1371 lwcollection_free(split_col);
1373 return -1;
1374 }
1375
1376 /* Get new edges identifiers */
1377 newedges[0].edge_id = lwt_be_getNextEdgeId(topo);
1378 if ( newedges[0].edge_id == -1 ) {
1379 _lwt_release_edges(oldedge, 1);
1380 lwcollection_free(split_col);
1382 return -1;
1383 }
1384 newedges[1].edge_id = lwt_be_getNextEdgeId(topo);
1385 if ( newedges[1].edge_id == -1 ) {
1386 _lwt_release_edges(oldedge, 1);
1387 lwcollection_free(split_col);
1389 return -1;
1390 }
1391
1392 /* Define the first new edge (to new node) */
1393 newedges[0].start_node = oldedge->start_node;
1394 newedges[0].end_node = node.node_id;
1395 newedges[0].face_left = oldedge->face_left;
1396 newedges[0].face_right = oldedge->face_right;
1397 newedges[0].next_left = newedges[1].edge_id;
1398 if ( oldedge->next_right == edge )
1399 newedges[0].next_right = newedges[0].edge_id;
1400 else if ( oldedge->next_right == -edge )
1401 newedges[0].next_right = -newedges[1].edge_id;
1402 else
1403 newedges[0].next_right = oldedge->next_right;
1404 newedges[0].geom = lwgeom_as_lwline(oldedge_geom);
1405 /* lwgeom_split of a line should only return lines ... */
1406 if ( ! newedges[0].geom ) {
1407 _lwt_release_edges(oldedge, 1);
1408 lwcollection_free(split_col);
1409 lwerror("first geometry in lwgeom_split output is not a line");
1410 return -1;
1411 }
1412
1413 /* Define the second new edge (from new node) */
1414 newedges[1].start_node = node.node_id;
1415 newedges[1].end_node = oldedge->end_node;
1416 newedges[1].face_left = oldedge->face_left;
1417 newedges[1].face_right = oldedge->face_right;
1418 newedges[1].next_right = -newedges[0].edge_id;
1419 if ( oldedge->next_left == -edge )
1420 newedges[1].next_left = -newedges[1].edge_id;
1421 else if ( oldedge->next_left == edge )
1422 newedges[1].next_left = newedges[0].edge_id;
1423 else
1424 newedges[1].next_left = oldedge->next_left;
1425 newedges[1].geom = lwgeom_as_lwline(newedge_geom);
1426 /* lwgeom_split of a line should only return lines ... */
1427 if ( ! newedges[1].geom ) {
1428 _lwt_release_edges(oldedge, 1);
1429 lwcollection_free(split_col);
1430 lwerror("second geometry in lwgeom_split output is not a line");
1431 return -1;
1432 }
1433
1434 /* Insert both new edges */
1435 ret = lwt_be_insertEdges(topo, newedges, 2);
1436 if ( ret == -1 ) {
1437 _lwt_release_edges(oldedge, 1);
1439 return -1;
1440 } else if ( ret == 0 ) {
1441 _lwt_release_edges(oldedge, 1);
1442 lwcollection_free(split_col);
1443 lwerror("Insertion of split edge failed (no reason)");
1444 return -1;
1445 }
1446
1447 /* Update all next edge references pointing to old edge id */
1448
1449 updedge.next_right = newedges[0].edge_id;
1450 seledge.next_right = edge;
1451 seledge.start_node = oldedge->start_node;
1452 ret = lwt_be_updateEdges(topo,
1454 &updedge, LWT_COL_EDGE_NEXT_RIGHT,
1455 NULL, 0);
1456 if ( ret == -1 ) {
1457 _lwt_release_edges(oldedge, 1);
1458 lwcollection_free(split_col);
1460 return -1;
1461 }
1462
1463 updedge.next_right = -newedges[1].edge_id;
1464 seledge.next_right = -edge;
1465 seledge.start_node = oldedge->end_node;
1466 ret = lwt_be_updateEdges(topo,
1468 &updedge, LWT_COL_EDGE_NEXT_RIGHT,
1469 NULL, 0);
1470 if ( ret == -1 ) {
1471 _lwt_release_edges(oldedge, 1);
1472 lwcollection_free(split_col);
1474 return -1;
1475 }
1476
1477 updedge.next_left = newedges[0].edge_id;
1478 seledge.next_left = edge;
1479 seledge.end_node = oldedge->start_node;
1480 ret = lwt_be_updateEdges(topo,
1482 &updedge, LWT_COL_EDGE_NEXT_LEFT,
1483 NULL, 0);
1484 if ( ret == -1 ) {
1485 _lwt_release_edges(oldedge, 1);
1486 lwcollection_free(split_col);
1488 return -1;
1489 }
1490
1491 updedge.next_left = -newedges[1].edge_id;
1492 seledge.next_left = -edge;
1493 seledge.end_node = oldedge->end_node;
1494 ret = lwt_be_updateEdges(topo,
1496 &updedge, LWT_COL_EDGE_NEXT_LEFT,
1497 NULL, 0);
1498 if ( ret == -1 ) {
1499 _lwt_release_edges(oldedge, 1);
1500 lwcollection_release(split_col);
1502 return -1;
1503 }
1504
1505 /* Update TopoGeometries composition */
1506 ret = lwt_be_updateTopoGeomEdgeSplit(topo, oldedge->edge_id, newedges[0].edge_id, newedges[1].edge_id);
1507 if ( ! ret ) {
1508 _lwt_release_edges(oldedge, 1);
1509 lwcollection_free(split_col);
1511 return -1;
1512 }
1513
1514 _lwt_release_edges(oldedge, 1);
1515 lwcollection_free(split_col);
1516
1517 /* return new node id */
1518 return node.node_id;
1519}
void lwcollection_release(LWCOLLECTION *lwcollection)
void lwcollection_free(LWCOLLECTION *col)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition lwgeom.c:207
#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 PGTOPO_BE_ERROR()
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
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_deleteEdges(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *sel_edge, int sel_fields)
void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
int lwt_be_insertEdges(LWT_TOPOLOGY *topo, LWT_ISO_EDGE *edge, uint64_t numelems)
static LWCOLLECTION * _lwt_EdgeSplit(LWT_TOPOLOGY *topo, LWT_ELEMID edge, LWPOINT *pt, int skipISOChecks, LWT_ISO_EDGE **oldedge)
LWGEOM ** geoms
Definition liblwgeom.h:575
int32_t srid
Definition liblwgeom.h:576
int32_t srid
Definition liblwgeom.h:460
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

References _lwt_EdgeSplit(), _lwt_release_edges(), 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(), lwcollection_release(), lwerror(), lwgeom_as_lwline(), lwt_be_deleteEdges(), lwt_be_getNextEdgeId(), lwt_be_insertEdges(), lwt_be_insertNodes(), lwt_be_updateEdges(), lwt_be_updateTopoGeomEdgeSplit(), LWT_COL_EDGE_EDGE_ID, LWT_COL_EDGE_END_NODE, 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, PGTOPO_BE_ERROR, LWGEOM::srid, LWCOLLECTION::srid, and LWT_ISO_EDGE::start_node.

Here is the call graph for this function: