optiwindnet.crossings¶

Module Contents¶

optiwindnet.crossings.get_interferences_list(Edge: numpy.ndarray, VertexC: numpy.ndarray, fnT: numpy.ndarray | None = None, EPSILON=1e-15) list[tuple[tuple[int, int, int, int], int | None]][source]¶

List all crossings between edges in the Edge (E×2) numpy array.

Coordinates must be provided in the VertexC (V×2) array.

Edge contains indices to VertexC. If Edge includes detour nodes (i.e. indices go beyond VertexC’s length), fnT translation table must be provided.

Should be used when edges are not limited to the expanded Delaunay set.

Returns:

((4 vertices of the two edges involved), one of the vertices or None) the last tuple element indicates the index (0..3) of the vertex that lays exactly on the edge in cases of touching (not crossing)

Return type:

list of interferences, where each interference is

optiwindnet.crossings.edge_conflicts(u: int, v: int, diagonals: bidict.bidict) collections.abc.Iterator[tuple[int, int]][source]¶

Iterate over edges conflicting with (u, v).

Parameters:
  • u – node

  • v – node

  • diagonals – map of crossings Delaunay<->diagonals

optiwindnet.crossings.edge_crossings(u: int, v: int, G: networkx.Graph, diagonals: bidict.bidict) list[tuple[int, int]][source]¶
optiwindnet.crossings.edgeset_edgeXing_iter(diagonals: bidict.bidict) collections.abc.Iterator[list[tuple[int, int]]][source]¶

Iterator over all edge crossings in an expanded Delaunay edge set A.

Each crossing is a 2 or 3-tuple of (u, v) edges. Does not include gates.

optiwindnet.crossings.gateXing_iter(G: networkx.Graph, *, hooks: collections.abc.Iterable | None = None, touch_is_cross: bool = True) collections.abc.Iterator[tuple[tuple[int, int], tuple[int, int]]][source]¶

Iterate over all crossings between gates and edges/borders in G.

If hooks is None, all nodes that are not a root neighbor are considered. Used in constraint generation for ILP model.

Parameters:
  • G – Routeset or edgeset (A) to examine.

  • hooks – Nodes to check, grouped by root in sub-sequences from root -R to -1. If None, all non-root nodes are checked using ‘root’ node attribute.

  • touch_is_cross – If True, count as crossing a gate going over a node.

Yields:

Pair of (edge, gate) that cross (each a 2-tuple of nodes).

optiwindnet.crossings.validate_routeset(G: networkx.Graph) list[tuple[int, int, int, int]][source]¶

Validate G’s tree topology and absence of crossings.

Check if the routeset represented by G’s edges is topologically sound, repects capacity and has no edge crossings nor branch splitting.

Parameters:

G – graph to evaluate

Returns:

list of crossings/splits, G is valid if an empty list is returned

Example:

Xings = validate_routeset(G)
  for u, v, s, t in Xings:
    if u != v:
      print(f'{u}–{v} crosses {s}–{t}')
    else:
      print(f'detour @ {u} splits {s}–{v}–{t}')
optiwindnet.crossings.find_geometric_crossings(G: networkx.Graph, *, include_touches: bool = False, length_tol: float = 1e-12, angle_tol: float = 1e-10, endpoint_tol: float = 1e-09) list[dict][source]¶

Find route intersections in a routeset using Shapely geometries.

Geometry-first diagnostic complement to validate_routeset() and list_edge_crossings(). Unlike list_edge_crossings(), which only detects crossings between extended-Delaunay edges (i.e. it requires a routeset built from A, OptiWindNet’s available-edges graph), this routine works on any routeset graph that exposes VertexC (and fnT if it carries contour or detour clones). It can therefore validate routes produced by external tools, hand-built test graphs, or post-edited OptiWindNet results — at the cost of a heavier geometry-based check.

Polylines are extracted from G (one per feeder, plus one per junction-to-junction link) and translated through fnT so that contour and detour clones are tested at their prime coordinates.

Parameters:
  • G – routeset graph. Must have graph attributes T, R, B, and VertexC; fnT is required iff C > 0 or D > 0.

  • include_touches – also report point contacts that are not proper crossings (otherwise touches are silently dropped).

  • length_tol – collinear overlaps shorter than this are not classified.

  • angle_tol – minimum cross-product magnitude used to deduplicate co-directional rays in the local crossing test.

  • endpoint_tol – distance below which an intersection point is treated as coincident with a path endpoint, shared node, or detour-split prime.

Returns:

  • kind: one of
    • 'cross': two polylines cross at one or more isolated points;

    • 'overlap_cross': two polylines share a sub-run and exit the overlap on opposite sides at both ends (a true cross expressed as a coincident segment);

    • 'branch_split': a detour-clone whose prime is a real terminal cuts that terminal’s subtree into pieces;

    • 'touch' (only when include_touches=True): point contact that is not classified as a cross (e.g. tangent kiss).

  • path_nodes_a, path_nodes_b: the raw polyline node sequences.

  • path_a, path_b: canonical prime-path tuples (sorted so that path_a < path_b lexicographically).

  • geometry: WKT string of the offending Shapely geometry (Point, MultiPoint, LineString, MultiLineString, …).

Return type:

One dict per finding, with keys

optiwindnet.crossings.list_edge_crossings(S: networkx.Graph, A: networkx.Graph) list[tuple[tuple[int, int], tuple[int, int]]][source]¶

List edge×edge crossings for the network topology in S.

S must only use extended Delaunay edges. It will not detect crossings of non-extDelaunay gates or detours.

Parameters:
  • S – solution topology

  • A – available edges used in creating S

Returns:

list of 2-tuple (crossing) of 2-tuple (edge, ordered)