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

◆ _lwt_FindAdjacentEdges()

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

Definition at line 1641 of file lwgeom_topo.c.

1643{
1644 LWT_ISO_EDGE *edges;
1645 uint64_t numedges = 1;
1646 uint64_t i;
1647 double minaz, maxaz;
1648 double az, azdif;
1649
1650 data->nextCW = data->nextCCW = 0;
1651 data->cwFace = data->ccwFace = -1;
1652
1653 if ( other ) {
1654 azdif = other->myaz - data->myaz;
1655 if ( azdif < 0 ) azdif += 2 * M_PI;
1656 minaz = maxaz = azdif;
1657 /* TODO: set nextCW/nextCCW/cwFace/ccwFace to other->something ? */
1658 LWDEBUGF(1, "Other edge end has cwFace=%" LWTFMT_ELEMID
1659 " and ccwFace=%" LWTFMT_ELEMID,
1660 other->cwFace, other->ccwFace);
1661 } else {
1662 minaz = maxaz = -1;
1663 }
1664
1665 LWDEBUGF(1, "Looking for edges incident to node %" LWTFMT_ELEMID
1666 " and adjacent to azimuth %g", node, data->myaz);
1667
1668 /* Get incident edges */
1669 edges = lwt_be_getEdgeByNode( topo, &node, &numedges, LWT_COL_EDGE_ALL );
1670 if (numedges == UINT64_MAX)
1671 {
1673 return 0;
1674 }
1675
1676 LWDEBUGF(1, "getEdgeByNode returned %llu edges, minaz=%g, maxaz=%g",
1677 numedges, minaz, maxaz);
1678
1679 /* For each incident edge-end (1 or 2): */
1680 for ( i = 0; i < numedges; ++i )
1681 {
1682 LWT_ISO_EDGE *edge;
1683 LWGEOM *g;
1684 LWGEOM *cleangeom;
1685 POINT2D p1, p2;
1686 POINTARRAY *pa;
1687
1688 edge = &(edges[i]);
1689
1690 if ( edge->edge_id == myedge_id ) continue;
1691
1692 g = lwline_as_lwgeom(edge->geom);
1693 /* NOTE: remove_repeated_points call could be replaced by
1694 * some other mean to pick two distinct points for endpoints */
1695 cleangeom = lwgeom_remove_repeated_points( g, 0 );
1696 pa = lwgeom_as_lwline(cleangeom)->points;
1697
1698 if ( pa->npoints < 2 ) {{
1699 LWT_ELEMID id = edge->edge_id;
1700 _lwt_release_edges(edges, numedges);
1701 lwgeom_free(cleangeom);
1702 lwerror("corrupted topology: edge %" LWTFMT_ELEMID
1703 " does not have two distinct points", id);
1704 return -1;
1705 }}
1706
1707 if ( edge->start_node == node ) {
1708 getPoint2d_p(pa, 0, &p1);
1709 if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, 0, 1, &p2) )
1710 {
1711 lwerror("Edge %" LWTFMT_ELEMID " has no distinct vertices: [%.15g %.15g,%.15g %.15g]: ",
1712 edge->edge_id, p1.x, p1.y, p2.x, p2.y);
1713 return -1;
1714 }
1715 LWDEBUGF(1, "edge %" LWTFMT_ELEMID
1716 " starts on node %" LWTFMT_ELEMID
1717 ", edgeend is [%.15g %.15g,%.15g %.15g]",
1718 edge->edge_id, node, p1.x, p1.y, p2.x, p2.y);
1719 if ( ! azimuth_pt_pt(&p1, &p2, &az) ) {{
1720 LWT_ELEMID id = edge->edge_id;
1721 _lwt_release_edges(edges, numedges);
1722 lwgeom_free(cleangeom);
1723 lwerror("error computing azimuth of edge %"
1724 LWTFMT_ELEMID " first edgeend [%.15g %.15g,%.15g %.15g]",
1725 id, p1.x, p1.y, p2.x, p2.y);
1726 return -1;
1727 }}
1728 azdif = az - data->myaz;
1729 LWDEBUGF(1, "azimuth of edge %" LWTFMT_ELEMID
1730 ": %.15g (diff: %.15g)", edge->edge_id, az, azdif);
1731
1732 if ( azdif < 0 ) azdif += 2 * M_PI;
1733 if ( minaz == -1 ) {
1734 minaz = maxaz = azdif;
1735 data->nextCW = data->nextCCW = edge->edge_id; /* outgoing */
1736 data->cwFace = edge->face_left;
1737 data->ccwFace = edge->face_right;
1738 LWDEBUGF(1, "new nextCW and nextCCW edge is %" LWTFMT_ELEMID
1739 ", outgoing, "
1740 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1741 " (face_right is new ccwFace, face_left is new cwFace)",
1742 edge->edge_id, edge->face_left,
1743 edge->face_right);
1744 } else {
1745 if ( azdif < minaz ) {
1746 data->nextCW = edge->edge_id; /* outgoing */
1747 data->cwFace = edge->face_left;
1748 LWDEBUGF(1, "new nextCW edge is %" LWTFMT_ELEMID
1749 ", outgoing, "
1750 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1751 " (previous had minaz=%g, face_left is new cwFace)",
1752 edge->edge_id, edge->face_left,
1753 edge->face_right, minaz);
1754 minaz = azdif;
1755 }
1756 else if ( azdif > maxaz ) {
1757 data->nextCCW = edge->edge_id; /* outgoing */
1758 data->ccwFace = edge->face_right;
1759 LWDEBUGF(1, "new nextCCW edge is %" LWTFMT_ELEMID
1760 ", outgoing, "
1761 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1762 " (previous had maxaz=%g, face_right is new ccwFace)",
1763 edge->edge_id, edge->face_left,
1764 edge->face_right, maxaz);
1765 maxaz = azdif;
1766 }
1767 }
1768 }
1769
1770 if ( edge->end_node == node ) {
1771 getPoint2d_p(pa, pa->npoints-1, &p1);
1772 if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, pa->npoints-1, -1, &p2) )
1773 {
1774 lwerror("Edge %" LWTFMT_ELEMID " has no distinct vertices: [%.15g %.15g,%.15g %.15g]: ",
1775 edge->edge_id, p1.x, p1.y, p2.x, p2.y);
1776 return -1;
1777 }
1778 LWDEBUGF(1, "edge %" LWTFMT_ELEMID " ends on node %" LWTFMT_ELEMID
1779 ", edgeend is [%.15g %.15g,%.15g %.15g]",
1780 edge->edge_id, node, p1.x, p1.y, p2.x, p2.y);
1781 if ( ! azimuth_pt_pt(&p1, &p2, &az) ) {{
1782 LWT_ELEMID id = edge->edge_id;
1783 _lwt_release_edges(edges, numedges);
1784 lwgeom_free(cleangeom);
1785 lwerror("error computing azimuth of edge %"
1786 LWTFMT_ELEMID " last edgeend [%.15g %.15g,%.15g %.15g]",
1787 id, p1.x, p1.y, p2.x, p2.y);
1788 return -1;
1789 }}
1790 azdif = az - data->myaz;
1791 LWDEBUGF(1, "azimuth of edge %" LWTFMT_ELEMID
1792 ": %.15g (diff: %.15g)", edge->edge_id, az, azdif);
1793 if ( azdif < 0 ) azdif += 2 * M_PI;
1794 if ( minaz == -1 ) {
1795 minaz = maxaz = azdif;
1796 data->nextCW = data->nextCCW = -edge->edge_id; /* incoming */
1797 data->cwFace = edge->face_right;
1798 data->ccwFace = edge->face_left;
1799 LWDEBUGF(1, "new nextCW and nextCCW edge is %" LWTFMT_ELEMID
1800 ", incoming, "
1801 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1802 " (face_right is new cwFace, face_left is new ccwFace)",
1803 edge->edge_id, edge->face_left,
1804 edge->face_right);
1805 } else {
1806 if ( azdif < minaz ) {
1807 data->nextCW = -edge->edge_id; /* incoming */
1808 data->cwFace = edge->face_right;
1809 LWDEBUGF(1, "new nextCW edge is %" LWTFMT_ELEMID
1810 ", incoming, "
1811 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1812 " (previous had minaz=%g, face_right is new cwFace)",
1813 edge->edge_id, edge->face_left,
1814 edge->face_right, minaz);
1815 minaz = azdif;
1816 }
1817 else if ( azdif > maxaz ) {
1818 data->nextCCW = -edge->edge_id; /* incoming */
1819 data->ccwFace = edge->face_left;
1820 LWDEBUGF(1, "new nextCCW edge is %" LWTFMT_ELEMID
1821 ", outgoing, from start point, "
1822 "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1823 " (previous had maxaz=%g, face_left is new ccwFace)",
1824 edge->edge_id, edge->face_left,
1825 edge->face_right, maxaz);
1826 maxaz = azdif;
1827 }
1828 }
1829 }
1830
1831 lwgeom_free(cleangeom);
1832 }
1833 if ( numedges ) _lwt_release_edges(edges, numedges);
1834
1835 LWDEBUGF(1, "edges adjacent to azimuth %g"
1836 " (incident to node %" LWTFMT_ELEMID ")"
1837 ": CW:%" LWTFMT_ELEMID "(%g) CCW:%" LWTFMT_ELEMID "(%g)",
1838 data->myaz, node, data->nextCW, minaz,
1839 data->nextCCW, maxaz);
1840
1841 if ( myedge_id < 1 && numedges && data->cwFace != data->ccwFace )
1842 {
1843 if ( data->cwFace != -1 && data->ccwFace != -1 ) {
1844 lwerror("Corrupted topology: adjacent edges %" LWTFMT_ELEMID " and %" LWTFMT_ELEMID
1845 " bind different face (%" LWTFMT_ELEMID " and %" LWTFMT_ELEMID ")",
1846 data->nextCW, data->nextCCW,
1847 data->cwFace, data->ccwFace);
1848 return -1;
1849 }
1850 }
1851
1852 /* Return number of incident edges found */
1853 return numedges;
1854}
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
Definition measures.c:2408
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition lwgeom_api.c:342
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition lwgeom.c:367
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition lwgeom.c:207
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Definition lwgeom.c:1562
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_ALL
#define PGTOPO_BE_ERROR()
#define LWTFMT_ELEMID
#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.
void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
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, const POINT2D *ref, int from, int dir, POINT2D *op)
POINTARRAY * points
Definition liblwgeom.h:483
LWT_ELEMID face_right
LWT_ELEMID end_node
LWT_ELEMID face_left
LWT_ELEMID edge_id
LWT_ELEMID start_node
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390
uint32_t npoints
Definition liblwgeom.h:427
double myaz
LWT_ELEMID ccwFace
LWT_ELEMID cwFace

References _lwt_FirstDistinctVertex2D(), _lwt_release_edges(), azimuth_pt_pt(), 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_COL_EDGE_ALL, LWTFMT_ELEMID, edgeend_t::myaz, POINTARRAY::npoints, PGTOPO_BE_ERROR, LWLINE::points, LWT_ISO_EDGE::start_node, POINT2D::x, and POINT2D::y.

Referenced by _lwt_AddEdge(), _lwt_SnapEdgeToExistingNode(), lwt_ChangeEdgeGeom(), and lwt_GetFaceContainingPoint().

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