PostGIS  2.2.8dev-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 1511 of file lwgeom_topo.c.

References _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().

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