PostGIS  2.4.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 1507 of file lwgeom_topo.c.

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, edgeend_t::nextCCW, edgeend_t::nextCW, POINTARRAY::npoints, LWLINE::points, LWT_ISO_EDGE::start_node, POINT2D::x, and POINT2D::y.

Referenced by _lwt_AddEdge(), and lwt_ChangeEdgeGeom().

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