-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate_graph.py
136 lines (111 loc) · 4.92 KB
/
create_graph.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import json
import math
from types import SimpleNamespace
class Node:
def __init__(self, node_as_dict):
self.id = node_as_dict['id']
self.label = node_as_dict['label']
self.x = node_as_dict['metadata']['x']
self.y = node_as_dict['metadata']['y']
self.degree = 0
self.neighbours = []
class Edge:
def __init__(self, edge_as_dict, reverse=False):
if reverse:
self.source = edge_as_dict['target']
self.target = edge_as_dict['source']
# self.relation = edge_as_dict['relation']
# self.time = edge_as_dict['metadata']['time']
self.lines = edge_as_dict['metadata']['lines']
self.feas_sections = []
else:
self.source = edge_as_dict['source']
self.target = edge_as_dict['target']
# self.relation = edge_as_dict['relation']
# self.time = edge_as_dict['metadata']['time']
self.lines = edge_as_dict['metadata']['lines']
self.feas_sections = []
class Graph:
def __init__(self, folder, JSON_graph_name):
with open(folder + JSON_graph_name) as f:
x = json.load(f)
self.file_name = JSON_graph_name
self.folder = folder
self.nodes = {node['id']: Node(node) for node in x['nodes']}
self.fwd_edges = {i: Edge(edge) for i, edge in enumerate(x['edges'])} #edges as they are given in JSON
self.rev_edges = {i: Edge(edge, reverse=True) for i, edge in enumerate(x['edges'])}
self.lines = x['lines'] #
self.__find_neighbours()
self.__sort_neighbours()
self.__calc_sections()
def __find_neighbours(self):
fwd_edges = self.fwd_edges
rev_edges = self.rev_edges
nodes = self.nodes
for node_id, node in nodes.items():
for edgeset in (fwd_edges, rev_edges):
for edge in edgeset.values():
if edge.source == node_id:
node.neighbours.append(edge.target)
node.degree += 1
def __calc_sections(self):
'''
Determines the "sections" of all edges in the graph.
:param sections: a list of section numbers, starting from 0. Sections are assumed to go counterclockwise from 3:00 [0,1,2...]
'''
sections = [0,1,2,3,4,5,6,7]
nodes = self.nodes
fwd_edges = self.fwd_edges
rev_edges = self.rev_edges
num_sections = len(sections)
get_angle = lambda vector: (math.atan2(vector.y, vector.x) + 2*math.pi) % (2*math.pi) #angle between 0 and 2pi
get_opposite_section = lambda section: (section+4)%8
for edgeset in (fwd_edges, rev_edges):
for edge in edgeset.values():
#determine angle of edge
source_node = nodes[edge.source]
target_node = nodes[edge.target]
vector = SimpleNamespace()
vector.x = target_node.x - source_node.x
vector.y = target_node.y - source_node.y
a = get_angle(vector)
del vector
#determine feasible sections for a given angle
section = round((a / (2*math.pi)) * num_sections)
next_section = sections[(section+1)%len(sections)]
prev_section = sections[(section-1)%len(sections)]
edge.feas_sections = [prev_section, section, next_section]
# edge.target_directions = list(map(get_opposite_section, edge.source_directions))
def __sort_neighbours(self):
'''
sorts a list of neighbours counterclockwise from positive x direction
'''
nodes = self.nodes
get_angle = lambda vector: (math.atan2(vector.y, vector.x) + 2*math.pi) % (2*math.pi) #angle between 0 and 2p
for node_id, node in nodes.items():
to_sort = []
for neighbour_id in node.neighbours:
vector = SimpleNamespace()
vector.x = nodes[neighbour_id].x - node.x
vector.y = nodes[neighbour_id].y - node.y
a = get_angle(vector)
del vector
to_sort.append([neighbour_id, a])
sorted_neighbours = sorted(to_sort, key=lambda l:l[1])
node.neighbours = [sorted_neighbours[i][0] for i,_ in enumerate(sorted_neighbours)]
if __name__ == '__main__':
#test code
graph = Graph('./graphs/test.input.json')
for node in graph.nodes.values():
print(node.id)
print(node.degree)
print(node.neighbours, '\n')\
# graph.sort_neighbours()
# for node in graph.nodes.values():
# print(node.id)
# print(node.degree)
# print(node.neighbours, '\n')\
for edgeset in (graph.fwd_edges, graph.rev_edges):
for id, edge in edgeset.items():
print(id)
print(edge.feas_sections)