예제 #1
0
def edges_to_graph(edges):
    """Construct an `open_cp.network` style graph from an "edges" input.
    Merges very close vertices (<0.1 meters).  From "edges" data there should
    not be repeated edges.

    :param roads: Iterable of `(name, geo)`

    :return: `(graph, names)` where `names` is a dictionary from the edge
      index to an instance of `EdgeNoLine`.
    """
    edges = list(edges)
    all_nodes = []
    for edge in edges:
        for pt in edge.line:
            all_nodes.append(pt)

    b = _network.PlanarGraphNodeOneShot(all_nodes)
    name_lookup = _collections.defaultdict(set)
    for edge in edges:
        for e in b.add_path(edge.line):
            name_lookup[e].add(_to_edge_noline(edge))

    graph = b.build()
    names = dict()
    for e, ns in name_lookup.items():
        index, _ = graph.find_edge(*e)
        if index in names:
            raise Exception("Repeated edge: {}".format(e))
        if len(ns) > 1:
            raise Exception("Edge {} has multiple data: {}".format(e, ns))
        names[index] = list(ns)[0]
    return graph, names
예제 #2
0
def roads_to_graph(roads):
    """Construct an `open_cp.network` style graph from a "roads" input.
    Merges very close vertices (<0.1 meters) and repeated edges.

    :param roads: Iterable of `(name, geo)`

    :return: `(graph, names)` where `names` is a dictionary from the edge
      index to the set of road names which make use of that edge (in
      either direction).
    """
    roads = list(roads)
    all_nodes = []
    for _, geo in roads:
        for pt in geo:
            all_nodes.append(pt)

    b = _network.PlanarGraphNodeOneShot(all_nodes)
    name_lookup = _collections.defaultdict(set)
    for name, geo in roads:
        for e in b.add_path(geo):
            name_lookup[e].add(name)

    b.remove_duplicate_edges()
    graph = b.build()
    names = _collections.defaultdict(set)
    for e, ns in name_lookup.items():
        index, _ = graph.find_edge(*e)
        names[index].update(ns)
    return graph, dict(names)
예제 #3
0
def test_PlanarGraphNodeOneShot():
    nodes = [(0, 0), (1, 1), (5.1, 1.2), (0.1, 0.01), (2, 2)]
    b = network.PlanarGraphNodeOneShot(nodes, 0.2)

    r = b.add_path([(0, 0), (1, 1), (5.1, 1.2)])
    assert r == [(0, 1), (1, 2)]
    r = b.add_edge(0.1, 0.01, 2, 2)
    assert r == (0, 3)

    g = b.build()
    assert set(g.vertices.values()) == {(0, 0), (1, 1), (5.1, 1.2), (2, 2)}
    assert len(g.edges) == 3
    assert [g.vertices[x] for x in g.edges[0]] == [(0, 0), (1, 1)]
    assert [g.vertices[x] for x in g.edges[1]] == [(1, 1), (5.1, 1.2)]
    assert [g.vertices[x] for x in g.edges[2]] == [(0, 0), (2, 2)]
예제 #4
0
def test_PlanarGraphNodeOneShot_remove_duplicates():
    nodes = [(0, 0), (1, 1), (5.1, 1.2), (0.1, 0.01), (2, 2)]
    b = network.PlanarGraphNodeOneShot(nodes, 0.2)

    b.add_path([(0, 0), (1, 1), (5.1, 1.2)])
    b.add_edge(0.1, 0.01, 2, 2)
    b.add_edge(1, 1, 1, 1)
    b.add_edge(0.1, 0.01, 2, 2)

    with pytest.raises(ValueError):
        b.build()

    b.remove_duplicate_edges()
    g = b.build()
    assert set(g.vertices.values()) == {(0, 0), (1, 1), (5.1, 1.2), (2, 2)}
    assert len(g.edges) == 3
    assert [g.vertices[x] for x in g.edges[0]] == [(0, 0), (1, 1)]
    assert [g.vertices[x] for x in g.edges[1]] == [(1, 1), (5.1, 1.2)]
    assert [g.vertices[x] for x in g.edges[2]] == [(0, 0), (2, 2)]
예제 #5
0
def graph_from_streets(streets, to_projected_line):
    """Constructs a graph from a generic collection of "streets".
    
    :param streets: Iterator of "street" objects
    :param to_projected_line: Callable object which takes a "street" object
      as from the iterable `streets`, and returns a "line" which is
      suitable projected (if necessary).  A "line" is an iterable of points,
      where each point is a pair `(x,y)`.
      
    :return: Pair `(graph, names)` where `graph` is a graph object, and
      `names` is a dictionary from edge index (in graph) to a list of
      "street" instances which are the street(s) associated with that
      edge.
    """
    all_streets, projected_lines = [], []
    for street in streets:
        all_streets.append(street)
        projected_lines.append(to_projected_line(street))

    all_nodes = []
    for line in projected_lines:
        for pt in line:
            all_nodes.append(pt)

    b = _network.PlanarGraphNodeOneShot(all_nodes)
    name_lookup = _collections.defaultdict(list)
    for street, line in zip(all_streets, projected_lines):
        for e in b.add_path(line):
            name_lookup[e].append(street)

    b.remove_duplicate_edges()
    graph = b.build()
    names = _collections.defaultdict(list)
    for e, ns in name_lookup.items():
        if e[0] == e[1]:
            # These have been removed
            continue
        index, _ = graph.find_edge(*e)
        names[index].extend(ns)

    return graph, names