PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ _lwt_FindAdjacentEdges()

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

Definition at line 1524 of file lwgeom_topo.c.

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

References _lwt_FirstDistinctVertex2D(), _lwt_release_edges(), azimuth_pt_pt(), 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_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: