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

◆ lwt_ChangeEdgeGeom()

int lwt_ChangeEdgeGeom ( LWT_TOPOLOGY topo,
LWT_ELEMID  edge,
LWLINE curve 
)

Changes the shape of an edge without affecting the topology structure.

For ST_ChangeEdgeGeom

Parameters
topothe topology to operate on
curvethe edge geometry
Returns
0 on success, -1 on error (liblwgeom error handler will be invoked with error message)

Definition at line 3377 of file lwgeom_topo.c.

3378{
3379 LWT_ISO_EDGE *oldedge;
3380 LWT_ISO_EDGE newedge;
3381 POINT2D p1, p2, pt;
3382 uint64_t i;
3383 int isclosed = 0;
3384 int leftRingIsCCW = -1;
3385
3386 /* curve must be simple */
3387 if ( ! lwgeom_is_simple(lwline_as_lwgeom(geom)) )
3388 {
3389 lwerror("SQL/MM Spatial exception - curve not simple");
3390 return -1;
3391 }
3392
3393 i = 1;
3394 oldedge = lwt_be_getEdgeById(topo, &edge_id, &i, LWT_COL_EDGE_ALL);
3395 if ( ! oldedge )
3396 {
3397 LWDEBUGF(1, "lwt_ChangeEdgeGeom: "
3398 "lwt_be_getEdgeById returned NULL and set i=%llu", i);
3399 if (i == UINT64_MAX)
3400 {
3402 return -1;
3403 }
3404 else if ( i == 0 )
3405 {
3406 lwerror("SQL/MM Spatial exception - non-existent edge %"
3407 LWTFMT_ELEMID, edge_id);
3408 return -1;
3409 }
3410 else
3411 {
3412 lwerror("Backend coding error: getEdgeById callback returned NULL "
3413 "but numelements output parameter has value %" PRIu64 " "
3414 "(expected 0 or 1)", i);
3415 return -1;
3416 }
3417 }
3418
3419 LWDEBUGF(1, "lwt_ChangeEdgeGeom: "
3420 "old edge has %d points, new edge has %d points",
3421 oldedge->geom->points->npoints, geom->points->npoints);
3422
3423 /*
3424 * e) Check StartPoint consistency
3425 */
3426 getPoint2d_p(oldedge->geom->points, 0, &p1);
3427 getPoint2d_p(geom->points, 0, &pt);
3428 if ( ! P2D_SAME_STRICT(&p1, &pt) )
3429 {
3430 _lwt_release_edges(oldedge, 1);
3431 lwerror("SQL/MM Spatial exception - "
3432 "start node not geometry start point.");
3433 return -1;
3434 }
3435
3436 /*
3437 * f) Check EndPoint consistency
3438 */
3439 if ( oldedge->geom->points->npoints < 2 )
3440 {
3441 _lwt_release_edges(oldedge, 1);
3442 lwerror("Corrupted topology: edge %" LWTFMT_ELEMID
3443 " has less than 2 vertices", oldedge->edge_id);
3444 return -1;
3445 }
3446 getPoint2d_p(oldedge->geom->points, oldedge->geom->points->npoints-1, &p2);
3447 if ( geom->points->npoints < 2 )
3448 {
3449 _lwt_release_edges(oldedge, 1);
3450 lwerror("Invalid edge: less than 2 vertices");
3451 return -1;
3452 }
3453 getPoint2d_p(geom->points, geom->points->npoints-1, &pt);
3454 if ( ! P2D_SAME_STRICT(&pt, &p2) )
3455 {
3456 _lwt_release_edges(oldedge, 1);
3457 lwerror("SQL/MM Spatial exception - "
3458 "end node not geometry end point.");
3459 return -1;
3460 }
3461
3462 /* Not in the specs:
3463 * if the edge is closed, check we didn't change winding !
3464 * (should be part of isomorphism checking)
3465 */
3466 if ( oldedge->start_node == oldedge->end_node )
3467 {
3468 isclosed = 1;
3469#if 1 /* TODO: this is actually bogus as a test */
3470 /* check for valid edge (distinct vertices must exist) */
3471 if ( ! _lwt_GetInteriorEdgePoint(geom, &pt) )
3472 {
3473 _lwt_release_edges(oldedge, 1);
3474 lwerror("Invalid edge (no two distinct vertices exist)");
3475 return -1;
3476 }
3477#endif
3478
3479 if ( ptarray_isccw(oldedge->geom->points) !=
3480 ptarray_isccw(geom->points) )
3481 {
3482 _lwt_release_edges(oldedge, 1);
3483 lwerror("Edge twist at node POINT(%g %g)", p1.x, p1.y);
3484 return -1;
3485 }
3486 }
3487
3488 if ( _lwt_CheckEdgeCrossing(topo, oldedge->start_node,
3489 oldedge->end_node, geom, edge_id ) )
3490 {
3491 /* would have called lwerror already, leaking :( */
3492 _lwt_release_edges(oldedge, 1);
3493 return -1;
3494 }
3495
3496 LWDEBUG(1, "lwt_ChangeEdgeGeom: "
3497 "edge crossing check passed ");
3498
3499 /*
3500 * Not in the specs:
3501 * Check topological isomorphism
3502 */
3503
3504 /* Check that the "motion range" doesn't include any node */
3505 // 1. compute combined bbox of old and new edge
3506 GBOX mbox; /* motion box */
3507 lwgeom_add_bbox((LWGEOM*)oldedge->geom); /* just in case */
3508 lwgeom_add_bbox((LWGEOM*)geom); /* just in case */
3509 gbox_union(oldedge->geom->bbox, geom->bbox, &mbox);
3510 // 2. fetch all nodes in the combined box
3511 LWT_ISO_NODE *nodes;
3512 uint64_t numnodes;
3513 nodes = lwt_be_getNodeWithinBox2D(topo, &mbox, &numnodes,
3514 LWT_COL_NODE_ALL, 0);
3515 LWDEBUGF(1, "lwt_be_getNodeWithinBox2D returned %llu nodes", numnodes);
3516 if (numnodes == UINT64_MAX)
3517 {
3518 _lwt_release_edges(oldedge, 1);
3520 return -1;
3521 }
3522 // 3. if any node beside endnodes are found:
3523 if ( numnodes > ( 1 + isclosed ? 0 : 1 ) )
3524 {{
3525 // 3.2. bail out if any node is in one and not the other
3526 for (i=0; i<numnodes; ++i)
3527 {
3528 LWT_ISO_NODE *n = &(nodes[i]);
3529 if ( n->node_id == oldedge->start_node ) continue;
3530 if ( n->node_id == oldedge->end_node ) continue;
3531 const POINT2D *pt = getPoint2d_cp(n->geom->point, 0);
3532 int ocont = ptarray_contains_point_partial(oldedge->geom->points, pt, isclosed, NULL) == LW_INSIDE;
3533 int ncont = ptarray_contains_point_partial(geom->points, pt, isclosed, NULL) == LW_INSIDE;
3534 if (ocont != ncont)
3535 {
3536 size_t sz;
3537 char *wkt = lwgeom_to_wkt(lwpoint_as_lwgeom(n->geom), WKT_ISO, 15, &sz);
3538 _lwt_release_nodes(nodes, numnodes);
3539 lwerror("Edge motion collision at %s", wkt);
3540 lwfree(wkt); /* would not necessarely reach this point */
3541 return -1;
3542 }
3543 }
3544 }}
3545 if ( numnodes ) _lwt_release_nodes(nodes, numnodes);
3546
3547 LWDEBUG(1, "nodes containment check passed");
3548
3549 /*
3550 * Check edge adjacency before
3551 * TODO: can be optimized to gather azimuths of all edge ends once
3552 */
3553
3554 edgeend span_pre, epan_pre;
3555 /* initialize span_pre.myaz and epan_pre.myaz with existing edge */
3556 int res = _lwt_InitEdgeEndByLine(&span_pre, &epan_pre, oldedge->geom, &p1, &p2);
3557 if (res)
3558 return -1; /* lwerror should have been raised */
3559 _lwt_FindAdjacentEdges( topo, oldedge->start_node, &span_pre,
3560 isclosed ? &epan_pre : NULL, edge_id );
3561 _lwt_FindAdjacentEdges( topo, oldedge->end_node, &epan_pre,
3562 isclosed ? &span_pre : NULL, edge_id );
3563
3564 LWDEBUGF(1, "edges adjacent to old edge are %" LWTFMT_ELEMID
3565 " and %" LWTFMT_ELEMID " (first point), %" LWTFMT_ELEMID
3566 " and %" LWTFMT_ELEMID " (last point)",
3567 span_pre.nextCW, span_pre.nextCCW,
3568 epan_pre.nextCW, epan_pre.nextCCW);
3569
3570 /* If the same edge is both on CW and CCW direction on both start
3571 * and end points we need to verify winding of the left and right
3572 * rings to verify we didn't twist.
3573 * See https://trac.osgeo.org/postgis/ticket/5787
3574 *
3575 * NOTE: this could probably replace the "isclosed" test.
3576 *
3577 * NOTE: if either start or end node had different CW and CCW
3578 * edges a twist would be caught in the previous check.
3579 */
3580 if ( ! isclosed &&
3581 oldedge->face_left != oldedge->face_right &&
3582 span_pre.nextCW == span_pre.nextCCW &&
3583 epan_pre.nextCW == epan_pre.nextCCW )
3584 {{
3585 uint64_t num_signed_edge_ids;
3586 LWT_ELEMID *signed_edge_ids;
3587 LWPOLY *shell;
3588
3589 LWDEBUG(1, "Twist check before");
3590 signed_edge_ids = lwt_be_getRingEdges(topo, edge_id, &num_signed_edge_ids, 0);
3591 /* Get winding of left face ring */
3592 if (!signed_edge_ids)
3593 {
3594 //PGTOPO_BE_ERRORF("no ring edges for edge %" LWTFMT_ELEMID, sedge);
3596 return -1;
3597 }
3598 LWDEBUGF(1, "getRingEdges returned %llu edges", num_signed_edge_ids);
3599
3600 shell = _lwt_MakeRingShell(topo, signed_edge_ids, num_signed_edge_ids);
3601 if ( ! shell ) {
3602 lwfree( signed_edge_ids );
3603 /* ring_edges should be NULL */
3604 lwerror("Could not create ring shell: %s", lwt_be_lastErrorMessage(topo->be_iface));
3605 return -1;
3606 }
3607
3608 const POINTARRAY *pa = shell->rings[0];
3609 if ( ! ptarray_is_closed_2d(pa) )
3610 {
3611 lwpoly_free(shell);
3612 lwfree( signed_edge_ids );
3613 lwerror("Corrupted topology: ring of edge %" LWTFMT_ELEMID
3614 " is geometrically not-closed", edge_id);
3615 return -1;
3616 }
3617
3618 leftRingIsCCW = ptarray_isccw(pa);
3619 lwpoly_free(shell);
3620 lwfree( signed_edge_ids );
3621
3622 LWDEBUGF(1, "Ring of edge %" LWTFMT_ELEMID " is %sclockwise", edge_id, leftRingIsCCW ? "counter" : "");
3623 }}
3624
3625
3626 /* update edge geometry */
3627 newedge.edge_id = edge_id;
3628 newedge.geom = geom;
3629 res = lwt_be_updateEdgesById(topo, &newedge, 1, LWT_COL_EDGE_GEOM);
3630 if (res == -1)
3631 {
3632 _lwt_release_edges(oldedge, 1);
3634 return -1;
3635 }
3636 if (!res)
3637 {
3638 _lwt_release_edges(oldedge, 1);
3639 lwerror("Unexpected error: %" PRIu64 " edges updated when expecting 1", i);
3640 return -1;
3641 }
3642
3643 /*
3644 * Check edge adjacency after
3645 */
3646 edgeend span_post, epan_post;
3647 /* initialize epan_post.myaz and epan_post.myaz */
3648 res = _lwt_InitEdgeEndByLine(&span_post, &epan_post, geom, &p1, &p2);
3649 if (res)
3650 return -1; /* lwerror should have been raised */
3651 _lwt_FindAdjacentEdges( topo, oldedge->start_node, &span_post,
3652 isclosed ? &epan_post : NULL, edge_id );
3653 _lwt_FindAdjacentEdges( topo, oldedge->end_node, &epan_post,
3654 isclosed ? &span_post : NULL, edge_id );
3655
3656 LWDEBUGF(1, "edges adjacent to new edge are %" LWTFMT_ELEMID
3657 " and %" LWTFMT_ELEMID " (first point), %" LWTFMT_ELEMID
3658 " and %" LWTFMT_ELEMID " (last point)",
3659 span_pre.nextCW, span_pre.nextCCW,
3660 epan_pre.nextCW, epan_pre.nextCCW);
3661
3662
3663 /* Bail out if next CW or CCW edge on start node changed */
3664 if ( span_pre.nextCW != span_post.nextCW ||
3665 span_pre.nextCCW != span_post.nextCCW )
3666 {{
3667 LWT_ELEMID nid = oldedge->start_node;
3668 _lwt_release_edges(oldedge, 1);
3669 lwerror("Edge changed disposition around start node %"
3670 LWTFMT_ELEMID, nid);
3671 return -1;
3672 }}
3673
3674 /* Bail out if next CW or CCW edge on end node changed */
3675 if ( epan_pre.nextCW != epan_post.nextCW ||
3676 epan_pre.nextCCW != epan_post.nextCCW )
3677 {{
3678 LWT_ELEMID nid = oldedge->end_node;
3679 _lwt_release_edges(oldedge, 1);
3680 lwerror("Edge changed disposition around end node %"
3681 LWTFMT_ELEMID, nid);
3682 return -1;
3683 }}
3684
3685 /* Check winding of left face ring did not change */
3686 if ( leftRingIsCCW != -1 )
3687 {{
3688 uint64_t num_signed_edge_ids;
3689 LWT_ELEMID *signed_edge_ids;
3690 LWPOLY *shell;
3691 int isCCW;
3692
3693 LWDEBUG(1, "Twist check after");
3694 signed_edge_ids = lwt_be_getRingEdges(topo, edge_id, &num_signed_edge_ids, 0);
3695 /* Get winding of left face ring */
3696 if (!signed_edge_ids)
3697 {
3698 //PGTOPO_BE_ERRORF("no ring edges for edge %" LWTFMT_ELEMID, sedge);
3700 return -1;
3701 }
3702 LWDEBUGF(1, "getRingEdges returned %llu edges", num_signed_edge_ids);
3703
3704 shell = _lwt_MakeRingShell(topo, signed_edge_ids, num_signed_edge_ids);
3705 if ( ! shell ) {
3706 lwfree( signed_edge_ids );
3707 /* ring_edges should be NULL */
3708 lwerror("Could not create ring shell: %s", lwt_be_lastErrorMessage(topo->be_iface));
3709 return -1;
3710 }
3711
3712 const POINTARRAY *pa = shell->rings[0];
3713 if ( ! ptarray_is_closed_2d(pa) )
3714 {
3715 lwpoly_free(shell);
3716 lwfree( signed_edge_ids );
3717 lwerror("Corrupted topology: ring of edge %" LWTFMT_ELEMID
3718 " is geometrically not-closed", edge_id);
3719 return -1;
3720 }
3721
3722 isCCW = ptarray_isccw(pa);
3723 lwpoly_free(shell);
3724 lwfree( signed_edge_ids );
3725
3726 if ( isCCW != leftRingIsCCW )
3727 {
3728 _lwt_release_edges(oldedge, 1);
3729 lwerror("Edge ring changes winding");
3730 return -1;
3731 }
3732 }}
3733
3734 /*
3735 -- Update faces MBR of left and right faces
3736 -- TODO: think about ways to optimize this part, like see if
3737 -- the old edge geometry participated in the definition
3738 -- of the current MBR (for shrinking) or the new edge MBR
3739 -- would be larger than the old face MBR...
3740 --
3741 */
3742 LWGEOM *oldgeom = lwline_as_lwgeom(oldedge->geom);
3743 LWGEOM *newgeom = lwline_as_lwgeom(geom);
3744 lwgeom_refresh_bbox(oldgeom); /* Ensure we use a fit mbr, see #5709 -- TODO: fix this at lower level */
3745 lwgeom_refresh_bbox(newgeom); /* Ensure we use a fit mbr, see #5709 -- TODO: fix this at lower level */
3746 const GBOX* oldbox = lwgeom_get_bbox(oldgeom);
3747 const GBOX* newbox = lwgeom_get_bbox(newgeom);
3748 if ( ! gbox_same(oldbox, newbox) )
3749 {
3750 GBOX* updatedBox;
3751 uint64_t facestoupdate = 0;
3752 LWT_ISO_FACE faces[2];
3753 if ( oldedge->face_left > 0 )
3754 {
3755 updatedBox = lwt_be_computeFaceMBR(topo, oldedge->face_left);
3756 if ( ! updatedBox )
3757 {
3758 lwerror("Corrupted topology: face %" LWTFMT_ELEMID
3759 ", left of edge %" LWTFMT_ELEMID ", has no bbox",
3760 oldedge->face_left, edge_id);
3761 return -1;
3762 }
3763 faces[facestoupdate].face_id = oldedge->face_left;
3764 /* ownership transferred to faces[] */
3765 faces[facestoupdate++].mbr = updatedBox;
3766 }
3767 if ( oldedge->face_right > 0
3768 /* no need to update twice the same face.. */
3769 && oldedge->face_right != oldedge->face_left )
3770 {
3771 updatedBox = lwt_be_computeFaceMBR(topo, oldedge->face_right);
3772 if ( ! updatedBox )
3773 {
3774 lwerror("Corrupted topology: face %"
3775 LWTFMT_ELEMID ", right of edge %" LWTFMT_ELEMID ", has no bbox",
3776 oldedge->face_right, edge_id);
3777 return -1;
3778 }
3779 faces[facestoupdate].face_id = oldedge->face_right;
3780 /* ownership transferred to faces[] */
3781 faces[facestoupdate++].mbr = updatedBox;
3782 }
3783 LWDEBUGF(1, "%llu faces to update", facestoupdate);
3784 if ( facestoupdate )
3785 {
3786 uint64_t updatedFaces = lwt_be_updateFacesById(topo, &(faces[0]), facestoupdate);
3787 if (updatedFaces != facestoupdate)
3788 {
3789 while ( facestoupdate-- ) lwfree(faces[facestoupdate].mbr);
3790 _lwt_release_edges(oldedge, 1);
3791 if (updatedFaces == UINT64_MAX)
3793 else
3794 lwerror("Unexpected error: %" PRIu64 " faces updated when expecting 1", updatedFaces);
3795 return -1;
3796 }
3797 }
3798 while ( facestoupdate-- ) lwfree(faces[facestoupdate].mbr);
3799 }
3800 else
3801 {
3802 LWDEBUG(1, "BBOX of changed edge did not change");
3803 }
3804
3805 LWDEBUG(1, "all done, cleaning up edges");
3806
3807 _lwt_release_edges(oldedge, 1);
3808 return 0; /* success */
3809}
int gbox_same(const GBOX *g1, const GBOX *g2)
Check if 2 given Gbox are the same.
Definition gbox.c:164
int gbox_union(const GBOX *g1, const GBOX *g2, GBOX *gout)
Update the output GBOX to be large enough to include both inputs.
Definition gbox.c:135
void lwgeom_refresh_bbox(LWGEOM *lwgeom)
Drop current bbox and calculate a fresh one.
Definition lwgeom.c:735
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition lwgeom.c:372
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition lwout_wkt.c:708
int lwgeom_is_simple(const LWGEOM *lwgeom)
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition lwgeom_api.c:342
void lwfree(void *mem)
Definition lwutil.c:248
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition lwgeom.c:367
#define WKT_ISO
Definition liblwgeom.h:2219
int ptarray_is_closed_2d(const POINTARRAY *pa)
Definition ptarray.c:710
void lwpoly_free(LWPOLY *poly)
Definition lwpoly.c:175
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
Definition lwgeom.c:771
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Definition lwgeom.c:723
int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number)
Definition ptarray.c:1031
#define LW_INSIDE
Constants for point-in-polygon return values.
int ptarray_isccw(const POINTARRAY *pa)
Definition ptarray.c:1182
#define P2D_SAME_STRICT(a, b)
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_ALL
#define LWT_COL_EDGE_GEOM
#define LWT_COL_NODE_ALL
#define PGTOPO_BE_ERROR()
#define LWTFMT_ELEMID
#define LWDEBUG(level, msg)
Definition lwgeom_log.h:101
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
static GBOX * lwt_be_computeFaceMBR(const LWT_TOPOLOGY *topo, LWT_ELEMID face)
static uint64_t lwt_be_updateFacesById(LWT_TOPOLOGY *topo, const LWT_ISO_FACE *faces, uint64_t numfaces)
static int _lwt_InitEdgeEndByLine(edgeend *fee, edgeend *lee, LWLINE *edge, POINT2D *fp, POINT2D *lp)
static int _lwt_GetInteriorEdgePoint(const LWLINE *edge, POINT2D *ip)
LWT_ISO_EDGE * lwt_be_getEdgeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
static int _lwt_CheckEdgeCrossing(LWT_TOPOLOGY *topo, LWT_ELEMID start_node, LWT_ELEMID end_node, const LWLINE *geom, LWT_ELEMID myself)
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)
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)
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
static LWT_ISO_NODE * lwt_be_getNodeWithinBox2D(const LWT_TOPOLOGY *topo, const GBOX *box, uint64_t *numelems, int fields, uint64_t limit)
static int _lwt_FindAdjacentEdges(LWT_TOPOLOGY *topo, LWT_ELEMID node, edgeend *data, edgeend *other, LWT_ELEMID myedge_id)
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition lwinline.h:97
tuple res
Definition window.py:79
GBOX * bbox
Definition liblwgeom.h:482
POINTARRAY * points
Definition liblwgeom.h:483
POINTARRAY * point
Definition liblwgeom.h:471
POINTARRAY ** rings
Definition liblwgeom.h:519
LWT_ELEMID face_right
LWT_ELEMID end_node
LWT_ELEMID face_left
LWT_ELEMID edge_id
LWT_ELEMID start_node
LWT_ELEMID face_id
LWT_ELEMID node_id
LWPOINT * geom
const LWT_BE_IFACE * be_iface
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390
uint32_t npoints
Definition liblwgeom.h:427
LWT_ELEMID nextCCW
LWT_ELEMID nextCW

References _lwt_CheckEdgeCrossing(), _lwt_FindAdjacentEdges(), _lwt_GetInteriorEdgePoint(), _lwt_InitEdgeEndByLine(), _lwt_MakeRingShell(), _lwt_release_edges(), _lwt_release_nodes(), LWLINE::bbox, LWT_TOPOLOGY_T::be_iface, LWT_ISO_EDGE::edge_id, LWT_ISO_EDGE::end_node, LWT_ISO_FACE::face_id, LWT_ISO_EDGE::face_left, LWT_ISO_EDGE::face_right, gbox_same(), gbox_union(), LWT_ISO_NODE::geom, LWT_ISO_EDGE::geom, getPoint2d_cp(), getPoint2d_p(), LW_INSIDE, LWDEBUG, LWDEBUGF, lwerror(), lwfree(), lwgeom_add_bbox(), lwgeom_get_bbox(), lwgeom_is_simple(), lwgeom_refresh_bbox(), lwgeom_to_wkt(), lwline_as_lwgeom(), lwpoint_as_lwgeom(), lwpoly_free(), lwt_be_computeFaceMBR(), lwt_be_getEdgeById(), lwt_be_getNodeWithinBox2D(), lwt_be_getRingEdges(), lwt_be_lastErrorMessage(), lwt_be_updateEdgesById(), lwt_be_updateFacesById(), LWT_COL_EDGE_ALL, LWT_COL_EDGE_GEOM, LWT_COL_NODE_ALL, LWTFMT_ELEMID, LWT_ISO_FACE::mbr, edgeend_t::nextCCW, edgeend_t::nextCW, LWT_ISO_NODE::node_id, POINTARRAY::npoints, P2D_SAME_STRICT, PGTOPO_BE_ERROR, LWPOINT::point, LWLINE::points, ptarray_contains_point_partial(), ptarray_is_closed_2d(), ptarray_isccw(), LWPOLY::rings, LWT_ISO_EDGE::start_node, WKT_ISO, POINT2D::x, and POINT2D::y.

Referenced by _lwt_SplitAllEdgesToNewNode().

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