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

◆ _lwt_FindAdjacentEdges()

static int _lwt_FindAdjacentEdges ( LWT_TOPOLOGY topo,
LWT_ELEMID  node,
edgeend data,
edgeend other,
int  myedge_id 
)
static

Definition at line 1489 of file lwgeom_topo.c.

1491{
1492 LWT_ISO_EDGE *edges;
1493 uint64_t numedges = 1;
1494 uint64_t i;
1495 double minaz, maxaz;
1496 double az, azdif;
1497
1498 data->nextCW = data->nextCCW = 0;
1499 data->cwFace = data->ccwFace = -1;
1500
1501 if ( other ) {
1502 azdif = other->myaz - data->myaz;
1503 if ( azdif < 0 ) azdif += 2 * M_PI;
1504 minaz = maxaz = azdif;
1505 /* TODO: set nextCW/nextCCW/cwFace/ccwFace to other->something ? */
1506 LWDEBUGF(1, "Other edge end has cwFace=%d and ccwFace=%d",
1507 other->cwFace, other->ccwFace);
1508 } else {
1509 minaz = maxaz = -1;
1510 }
1511
1512 LWDEBUGF(1, "Looking for edges incident to node %" LWTFMT_ELEMID
1513 " and adjacent to azimuth %g", node, data->myaz);
1514
1515 /* Get incident edges */
1516 edges = lwt_be_getEdgeByNode( topo, &node, &numedges, LWT_COL_EDGE_ALL );
1517 if (numedges == UINT64_MAX)
1518 {
1519 lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
1520 return 0;
1521 }
1522
1523 LWDEBUGF(1, "getEdgeByNode returned %d edges, minaz=%g, maxaz=%g",
1524 numedges, minaz, maxaz);
1525
1526 /* For each incident edge-end (1 or 2): */
1527 for ( i = 0; i < numedges; ++i )
1528 {
1529 LWT_ISO_EDGE *edge;
1530 LWGEOM *g;
1531 LWGEOM *cleangeom;
1532 POINT2D p1, p2;
1533 POINTARRAY *pa;
1534
1535 edge = &(edges[i]);
1536
1537 if ( edge->edge_id == myedge_id ) continue;
1538
1539 g = lwline_as_lwgeom(edge->geom);
1540 /* NOTE: remove_repeated_points call could be replaced by
1541 * some other mean to pick two distinct points for endpoints */
1542 cleangeom = lwgeom_remove_repeated_points( g, 0 );
1543 pa = lwgeom_as_lwline(cleangeom)->points;
1544
1545 if ( pa->npoints < 2 ) {{
1546 LWT_ELEMID id = edge->edge_id;
1547 _lwt_release_edges(edges, numedges);
1548 lwgeom_free(cleangeom);
1549 lwerror("corrupted topology: edge %" LWTFMT_ELEMID
1550 " does not have two distinct points", id);
1551 return -1;
1552 }}
1553
1554 if ( edge->start_node == node ) {
1555 getPoint2d_p(pa, 0, &p1);
1556 if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, 0, 1, &p2) )
1557 {
1558 lwerror("Edge %d has no distinct vertices: [%.15g %.15g,%.15g %.15g]: ",
1559 edge->edge_id, p1.x, p1.y, p2.x, p2.y);
1560 return -1;
1561 }
1562 LWDEBUGF(1, "edge %" LWTFMT_ELEMID
1563 " starts on node %" LWTFMT_ELEMID
1564 ", edgeend is %g,%g-%g,%g",
1565 edge->edge_id, node, p1.x, p1.y, p2.x, p2.y);
1566 if ( ! azimuth_pt_pt(&p1, &p2, &az) ) {{
1567 LWT_ELEMID id = edge->edge_id;
1568 _lwt_release_edges(edges, numedges);
1569 lwgeom_free(cleangeom);
1570 lwerror("error computing azimuth of edge %d first edgeend [%.15g %.15g,%.15g %.15g]",
1571 id, p1.x, p1.y, p2.x, p2.y);
1572 return -1;
1573 }}
1574 azdif = az - data->myaz;
1575 LWDEBUGF(1, "azimuth of edge %" LWTFMT_ELEMID
1576 ": %g (diff: %g)", edge->edge_id, az, azdif);
1577
1578 if ( azdif < 0 ) azdif += 2 * M_PI;
1579 if ( minaz == -1 ) {
1580 minaz = maxaz = azdif;
1581 data->nextCW = data->nextCCW = edge->edge_id; /* outgoing */
1582 data->cwFace = edge->face_left;
1583 data->ccwFace = edge->face_right;
1584 LWDEBUGF(1, "new nextCW and nextCCW edge is %" LWTFMT_ELEMID
1585 ", outgoing, "
1586 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1587 " (face_right is new ccwFace, face_left is new cwFace)",
1588 edge->edge_id, edge->face_left,
1589 edge->face_right);
1590 } else {
1591 if ( azdif < minaz ) {
1592 data->nextCW = edge->edge_id; /* outgoing */
1593 data->cwFace = edge->face_left;
1594 LWDEBUGF(1, "new nextCW edge is %" LWTFMT_ELEMID
1595 ", outgoing, "
1596 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1597 " (previous had minaz=%g, face_left is new cwFace)",
1598 edge->edge_id, edge->face_left,
1599 edge->face_right, minaz);
1600 minaz = azdif;
1601 }
1602 else if ( azdif > maxaz ) {
1603 data->nextCCW = edge->edge_id; /* outgoing */
1604 data->ccwFace = edge->face_right;
1605 LWDEBUGF(1, "new nextCCW edge is %" LWTFMT_ELEMID
1606 ", outgoing, "
1607 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1608 " (previous had maxaz=%g, face_right is new ccwFace)",
1609 edge->edge_id, edge->face_left,
1610 edge->face_right, maxaz);
1611 maxaz = azdif;
1612 }
1613 }
1614 }
1615
1616 if ( edge->end_node == node ) {
1617 getPoint2d_p(pa, pa->npoints-1, &p1);
1618 if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, pa->npoints-1, -1, &p2) )
1619 {
1620 lwerror("Edge %d has no distinct vertices: [%.15g %.15g,%.15g %.15g]: ",
1621 edge->edge_id, p1.x, p1.y, p2.x, p2.y);
1622 return -1;
1623 }
1624 LWDEBUGF(1, "edge %" LWTFMT_ELEMID " ends on node %" LWTFMT_ELEMID
1625 ", edgeend is %g,%g-%g,%g",
1626 edge->edge_id, node, p1.x, p1.y, p2.x, p2.y);
1627 if ( ! azimuth_pt_pt(&p1, &p2, &az) ) {{
1628 LWT_ELEMID id = edge->edge_id;
1629 _lwt_release_edges(edges, numedges);
1630 lwgeom_free(cleangeom);
1631 lwerror("error computing azimuth of edge %d last edgeend [%.15g %.15g,%.15g %.15g]",
1632 id, p1.x, p1.y, p2.x, p2.y);
1633 return -1;
1634 }}
1635 azdif = az - data->myaz;
1636 LWDEBUGF(1, "azimuth of edge %" LWTFMT_ELEMID
1637 ": %g (diff: %g)", edge->edge_id, az, azdif);
1638 if ( azdif < 0 ) azdif += 2 * M_PI;
1639 if ( minaz == -1 ) {
1640 minaz = maxaz = azdif;
1641 data->nextCW = data->nextCCW = -edge->edge_id; /* incoming */
1642 data->cwFace = edge->face_right;
1643 data->ccwFace = edge->face_left;
1644 LWDEBUGF(1, "new nextCW and nextCCW edge is %" LWTFMT_ELEMID
1645 ", incoming, "
1646 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1647 " (face_right is new cwFace, face_left is new ccwFace)",
1648 edge->edge_id, edge->face_left,
1649 edge->face_right);
1650 } else {
1651 if ( azdif < minaz ) {
1652 data->nextCW = -edge->edge_id; /* incoming */
1653 data->cwFace = edge->face_right;
1654 LWDEBUGF(1, "new nextCW edge is %" LWTFMT_ELEMID
1655 ", incoming, "
1656 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1657 " (previous had minaz=%g, face_right is new cwFace)",
1658 edge->edge_id, edge->face_left,
1659 edge->face_right, minaz);
1660 minaz = azdif;
1661 }
1662 else if ( azdif > maxaz ) {
1663 data->nextCCW = -edge->edge_id; /* incoming */
1664 data->ccwFace = edge->face_left;
1665 LWDEBUGF(1, "new nextCCW edge is %" LWTFMT_ELEMID
1666 ", outgoing, from start point, "
1667 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1668 " (previous had maxaz=%g, face_left is new ccwFace)",
1669 edge->edge_id, edge->face_left,
1670 edge->face_right, maxaz);
1671 maxaz = azdif;
1672 }
1673 }
1674 }
1675
1676 lwgeom_free(cleangeom);
1677 }
1678 if ( numedges ) _lwt_release_edges(edges, numedges);
1679
1680 LWDEBUGF(1, "edges adjacent to azimuth %g"
1681 " (incident to node %" LWTFMT_ELEMID ")"
1682 ": CW:%" LWTFMT_ELEMID "(%g) CCW:%" LWTFMT_ELEMID "(%g)",
1683 data->myaz, node, data->nextCW, minaz,
1684 data->nextCCW, maxaz);
1685
1686 if ( myedge_id < 1 && numedges && data->cwFace != data->ccwFace )
1687 {
1688 if ( data->cwFace != -1 && data->ccwFace != -1 ) {
1689 lwerror("Corrupted topology: adjacent edges %" LWTFMT_ELEMID " and %" LWTFMT_ELEMID
1690 " bind different face (%" LWTFMT_ELEMID " and %" LWTFMT_ELEMID ")",
1691 data->nextCW, data->nextCCW,
1692 data->cwFace, data->ccwFace);
1693 return -1;
1694 }
1695 }
1696
1697 /* Return number of incident edges found */
1698 return numedges;
1699}
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
Definition measures.c:2461
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1138
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition lwgeom_api.c:349
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition lwgeom.c:321
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition lwgeom.c:161
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Definition lwgeom.c:1454
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_ALL
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition lwutil.c:190
static LWT_ISO_EDGE * lwt_be_getEdgeByNode(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
static int _lwt_FirstDistinctVertex2D(const POINTARRAY *pa, POINT2D *ref, int from, int dir, POINT2D *op)
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
#define LWTFMT_ELEMID
Definition lwgeom_topo.c:43
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
POINTARRAY * points
Definition liblwgeom.h:469
LWT_ELEMID face_right
LWT_ELEMID end_node
LWT_ELEMID face_left
LWT_ELEMID edge_id
LWT_ELEMID start_node
const LWT_BE_IFACE * be_iface
double y
Definition liblwgeom.h:376
double x
Definition liblwgeom.h:376
uint32_t npoints
Definition liblwgeom.h:413
double myaz
LWT_ELEMID ccwFace
LWT_ELEMID cwFace

References _lwt_FirstDistinctVertex2D(), _lwt_release_edges(), azimuth_pt_pt(), LWT_TOPOLOGY_T::be_iface, edgeend_t::ccwFace, edgeend_t::cwFace, LWT_ISO_EDGE::edge_id, LWT_ISO_EDGE::end_node, LWT_ISO_EDGE::face_left, LWT_ISO_EDGE::face_right, LWT_ISO_EDGE::geom, getPoint2d_p(), LWDEBUGF, lwerror(), lwgeom_as_lwline(), lwgeom_free(), lwgeom_remove_repeated_points(), lwline_as_lwgeom(), lwt_be_getEdgeByNode(), lwt_be_lastErrorMessage(), LWT_COL_EDGE_ALL, LWTFMT_ELEMID, edgeend_t::myaz, POINTARRAY::npoints, LWLINE::points, LWT_ISO_EDGE::start_node, POINT2D::x, and POINT2D::y.

Referenced by _lwt_AddEdge(), and lwt_ChangeEdgeGeom().

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