PostGIS  2.5.7dev-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 1492 of file lwgeom_topo.c.

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

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(), and lwt_ChangeEdgeGeom().

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