PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ _lwt_FindAdjacentEdges()

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

Definition at line 1536 of file lwgeom_topo.c.

1538 {
1539  LWT_ISO_EDGE *edges;
1540  uint64_t numedges = 1;
1541  uint64_t i;
1542  double minaz, maxaz;
1543  double az, azdif;
1544 
1545  data->nextCW = data->nextCCW = 0;
1546  data->cwFace = data->ccwFace = -1;
1547 
1548  if ( other ) {
1549  azdif = other->myaz - data->myaz;
1550  if ( azdif < 0 ) azdif += 2 * M_PI;
1551  minaz = maxaz = azdif;
1552  /* TODO: set nextCW/nextCCW/cwFace/ccwFace to other->something ? */
1553  LWDEBUGF(1, "Other edge end has cwFace=%d and ccwFace=%d",
1554  other->cwFace, other->ccwFace);
1555  } else {
1556  minaz = maxaz = -1;
1557  }
1558 
1559  LWDEBUGF(1, "Looking for edges incident to node %" LWTFMT_ELEMID
1560  " and adjacent to azimuth %g", node, data->myaz);
1561 
1562  /* Get incident edges */
1563  edges = lwt_be_getEdgeByNode( topo, &node, &numedges, LWT_COL_EDGE_ALL );
1564  if (numedges == UINT64_MAX)
1565  {
1566  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
1567  return 0;
1568  }
1569 
1570  LWDEBUGF(1, "getEdgeByNode returned %d edges, minaz=%g, maxaz=%g",
1571  numedges, minaz, maxaz);
1572 
1573  /* For each incident edge-end (1 or 2): */
1574  for ( i = 0; i < numedges; ++i )
1575  {
1576  LWT_ISO_EDGE *edge;
1577  LWGEOM *g;
1578  LWGEOM *cleangeom;
1579  POINT2D p1, p2;
1580  POINTARRAY *pa;
1581 
1582  edge = &(edges[i]);
1583 
1584  if ( edge->edge_id == myedge_id ) continue;
1585 
1586  g = lwline_as_lwgeom(edge->geom);
1587  /* NOTE: remove_repeated_points call could be replaced by
1588  * some other mean to pick two distinct points for endpoints */
1589  cleangeom = lwgeom_remove_repeated_points( g, 0 );
1590  pa = lwgeom_as_lwline(cleangeom)->points;
1591 
1592  if ( pa->npoints < 2 ) {{
1593  LWT_ELEMID id = edge->edge_id;
1594  _lwt_release_edges(edges, numedges);
1595  lwgeom_free(cleangeom);
1596  lwerror("corrupted topology: edge %" LWTFMT_ELEMID
1597  " does not have two distinct points", id);
1598  return -1;
1599  }}
1600 
1601  if ( edge->start_node == node ) {
1602  getPoint2d_p(pa, 0, &p1);
1603  if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, 0, 1, &p2) )
1604  {
1605  lwerror("Edge %d has no distinct vertices: [%.15g %.15g,%.15g %.15g]: ",
1606  edge->edge_id, p1.x, p1.y, p2.x, p2.y);
1607  return -1;
1608  }
1609  LWDEBUGF(1, "edge %" LWTFMT_ELEMID
1610  " starts on node %" LWTFMT_ELEMID
1611  ", edgeend is [%.15g %.15g,%.15g %.15g]",
1612  edge->edge_id, node, p1.x, p1.y, p2.x, p2.y);
1613  if ( ! azimuth_pt_pt(&p1, &p2, &az) ) {{
1614  LWT_ELEMID id = edge->edge_id;
1615  _lwt_release_edges(edges, numedges);
1616  lwgeom_free(cleangeom);
1617  lwerror("error computing azimuth of edge %d first edgeend [%.15g %.15g,%.15g %.15g]",
1618  id, p1.x, p1.y, p2.x, p2.y);
1619  return -1;
1620  }}
1621  azdif = az - data->myaz;
1622  LWDEBUGF(1, "azimuth of edge %" LWTFMT_ELEMID
1623  ": %.15g (diff: %.15g)", edge->edge_id, az, azdif);
1624 
1625  if ( azdif < 0 ) azdif += 2 * M_PI;
1626  if ( minaz == -1 ) {
1627  minaz = maxaz = azdif;
1628  data->nextCW = data->nextCCW = edge->edge_id; /* outgoing */
1629  data->cwFace = edge->face_left;
1630  data->ccwFace = edge->face_right;
1631  LWDEBUGF(1, "new nextCW and nextCCW edge is %" LWTFMT_ELEMID
1632  ", outgoing, "
1633  "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1634  " (face_right is new ccwFace, face_left is new cwFace)",
1635  edge->edge_id, edge->face_left,
1636  edge->face_right);
1637  } else {
1638  if ( azdif < minaz ) {
1639  data->nextCW = edge->edge_id; /* outgoing */
1640  data->cwFace = edge->face_left;
1641  LWDEBUGF(1, "new nextCW edge is %" LWTFMT_ELEMID
1642  ", outgoing, "
1643  "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1644  " (previous had minaz=%g, face_left is new cwFace)",
1645  edge->edge_id, edge->face_left,
1646  edge->face_right, minaz);
1647  minaz = azdif;
1648  }
1649  else if ( azdif > maxaz ) {
1650  data->nextCCW = edge->edge_id; /* outgoing */
1651  data->ccwFace = edge->face_right;
1652  LWDEBUGF(1, "new nextCCW edge is %" LWTFMT_ELEMID
1653  ", outgoing, "
1654  "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1655  " (previous had maxaz=%g, face_right is new ccwFace)",
1656  edge->edge_id, edge->face_left,
1657  edge->face_right, maxaz);
1658  maxaz = azdif;
1659  }
1660  }
1661  }
1662 
1663  if ( edge->end_node == node ) {
1664  getPoint2d_p(pa, pa->npoints-1, &p1);
1665  if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, pa->npoints-1, -1, &p2) )
1666  {
1667  lwerror("Edge %d has no distinct vertices: [%.15g %.15g,%.15g %.15g]: ",
1668  edge->edge_id, p1.x, p1.y, p2.x, p2.y);
1669  return -1;
1670  }
1671  LWDEBUGF(1, "edge %" LWTFMT_ELEMID " ends on node %" LWTFMT_ELEMID
1672  ", edgeend is [%.15g %.15g,%.15g %.15g]",
1673  edge->edge_id, node, p1.x, p1.y, p2.x, p2.y);
1674  if ( ! azimuth_pt_pt(&p1, &p2, &az) ) {{
1675  LWT_ELEMID id = edge->edge_id;
1676  _lwt_release_edges(edges, numedges);
1677  lwgeom_free(cleangeom);
1678  lwerror("error computing azimuth of edge %d last edgeend [%.15g %.15g,%.15g %.15g]",
1679  id, p1.x, p1.y, p2.x, p2.y);
1680  return -1;
1681  }}
1682  azdif = az - data->myaz;
1683  LWDEBUGF(1, "azimuth of edge %" LWTFMT_ELEMID
1684  ": %.15g (diff: %.15g)", edge->edge_id, az, azdif);
1685  if ( azdif < 0 ) azdif += 2 * M_PI;
1686  if ( minaz == -1 ) {
1687  minaz = maxaz = azdif;
1688  data->nextCW = data->nextCCW = -edge->edge_id; /* incoming */
1689  data->cwFace = edge->face_right;
1690  data->ccwFace = edge->face_left;
1691  LWDEBUGF(1, "new nextCW and nextCCW edge is %" LWTFMT_ELEMID
1692  ", incoming, "
1693  "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1694  " (face_right is new cwFace, face_left is new ccwFace)",
1695  edge->edge_id, edge->face_left,
1696  edge->face_right);
1697  } else {
1698  if ( azdif < minaz ) {
1699  data->nextCW = -edge->edge_id; /* incoming */
1700  data->cwFace = edge->face_right;
1701  LWDEBUGF(1, "new nextCW edge is %" LWTFMT_ELEMID
1702  ", incoming, "
1703  "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1704  " (previous had minaz=%g, face_right is new cwFace)",
1705  edge->edge_id, edge->face_left,
1706  edge->face_right, minaz);
1707  minaz = azdif;
1708  }
1709  else if ( azdif > maxaz ) {
1710  data->nextCCW = -edge->edge_id; /* incoming */
1711  data->ccwFace = edge->face_left;
1712  LWDEBUGF(1, "new nextCCW edge is %" LWTFMT_ELEMID
1713  ", outgoing, from start point, "
1714  "with face_left %" LWTFMT_ELEMID " and face_right %" LWTFMT_ELEMID
1715  " (previous had maxaz=%g, face_left is new ccwFace)",
1716  edge->edge_id, edge->face_left,
1717  edge->face_right, maxaz);
1718  maxaz = azdif;
1719  }
1720  }
1721  }
1722 
1723  lwgeom_free(cleangeom);
1724  }
1725  if ( numedges ) _lwt_release_edges(edges, numedges);
1726 
1727  LWDEBUGF(1, "edges adjacent to azimuth %g"
1728  " (incident to node %" LWTFMT_ELEMID ")"
1729  ": CW:%" LWTFMT_ELEMID "(%g) CCW:%" LWTFMT_ELEMID "(%g)",
1730  data->myaz, node, data->nextCW, minaz,
1731  data->nextCCW, maxaz);
1732 
1733  if ( myedge_id < 1 && numedges && data->cwFace != data->ccwFace )
1734  {
1735  if ( data->cwFace != -1 && data->ccwFace != -1 ) {
1736  lwerror("Corrupted topology: adjacent edges %" LWTFMT_ELEMID " and %" LWTFMT_ELEMID
1737  " bind different face (%" LWTFMT_ELEMID " and %" LWTFMT_ELEMID ")",
1738  data->nextCW, data->nextCCW,
1739  data->cwFace, data->ccwFace);
1740  return -1;
1741  }
1742  }
1743 
1744  /* Return number of incident edges found */
1745  return numedges;
1746 }
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:179
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:339
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
Definition: measures.c:2509
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1155
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition: lwgeom_api.c:343
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Definition: lwgeom.c:1471
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
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
Definition: lwgeom_topo.c:119
static LWT_ISO_EDGE * lwt_be_getEdgeByNode(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
Definition: lwgeom_topo.c:232
static int _lwt_FirstDistinctVertex2D(const POINTARRAY *pa, POINT2D *ref, int from, int dir, POINT2D *op)
Definition: lwgeom_topo.c:1439
#define LWTFMT_ELEMID
Definition: lwgeom_topo.c:43
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
Definition: lwgeom_topo.c:465
data
Definition: ovdump.py:104
POINTARRAY * points
Definition: liblwgeom.h:498
LWT_ELEMID face_right
LWT_ELEMID end_node
LWT_ELEMID face_left
LWLINE * geom
LWT_ELEMID edge_id
LWT_ELEMID start_node
const LWT_BE_IFACE * be_iface
double y
Definition: liblwgeom.h:405
double x
Definition: liblwgeom.h:405
uint32_t npoints
Definition: liblwgeom.h:442
double myaz
Definition: lwgeom_topo.c:1426
LWT_ELEMID ccwFace
Definition: lwgeom_topo.c:1424
LWT_ELEMID cwFace
Definition: lwgeom_topo.c:1420

References _lwt_FirstDistinctVertex2D(), _lwt_release_edges(), azimuth_pt_pt(), LWT_TOPOLOGY_T::be_iface, edgeend_t::ccwFace, edgeend_t::cwFace, ovdump::data, 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(), lwt_ChangeEdgeGeom(), and lwt_GetFaceContainingPoint().

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