|
@@ -41,9 +41,41 @@ def get_seconds(time_str):
|
|
|
h, m, s = time_str.split(':')
|
|
|
return int(h) * 3600 + int(m) * 60 + int(s)
|
|
|
|
|
|
+def make_gaussian(size, radius=10, center=None):
|
|
|
+ ''' make a square gaussian kernel '''
|
|
|
+ x = np.arange(0, size, 1, float)
|
|
|
+ y = x[:, np.newaxis]
|
|
|
+ if center is None:
|
|
|
+ x0 = y0 = size // 2
|
|
|
+ else:
|
|
|
+ x0 = center[0]
|
|
|
+ y0 = center[1]
|
|
|
+ return np.exp(-4*np.log(2) * ((x-x0)**2 + (y-y0)**2) / radius**2)
|
|
|
+
|
|
|
# main functions
|
|
|
# ------------------
|
|
|
|
|
|
+def make_clusters(nb_clusters, nodes):
|
|
|
+ ''' make a grid of (nb_clusters*nb_clusters) from a nodes list '''
|
|
|
+ xmin, xmax, ymin, ymax = get_extrem_nodes(nodes)
|
|
|
+ dx = (xmax - xmin) / nb_clusters
|
|
|
+ dy = (ymax - ymin) / nb_clusters
|
|
|
+ clusters = np.empty((nb_clusters, nb_clusters), dtype=object)
|
|
|
+ for node in nodes:
|
|
|
+ x, y = (float(node.get('x')) - xmin, float(node.get('y')) - ymin)
|
|
|
+ i, j = (int(x/dx), int(y/dy))
|
|
|
+ if i >= nb_clusters:
|
|
|
+ i -= 1
|
|
|
+ if j >= nb_clusters:
|
|
|
+ j -= 1
|
|
|
+ if clusters[i][j] is None:
|
|
|
+ clusters[i][j] = []
|
|
|
+ clusters[i][j] += [node]
|
|
|
+ return clusters
|
|
|
+
|
|
|
+# random generators
|
|
|
+# ------------------
|
|
|
+
|
|
|
def rand_time(low, high):
|
|
|
''' returns a random time between low and high bounds '''
|
|
|
low_s = get_seconds(low)
|
|
@@ -67,7 +99,10 @@ def rand_person(nodes, home_clusters, work_clusters):
|
|
|
home_departure = rand_time(MIN_DEPARTURE_TIME, MAX_DEPARTURE_TIME)
|
|
|
return {'home': home_xy, 'work': work_xy, 'home_departure': home_departure}
|
|
|
|
|
|
-def create_child(parent_node, child_name, child_attrs=None):
|
|
|
+# xml builders
|
|
|
+# ------------------
|
|
|
+
|
|
|
+def make_child(parent_node, child_name, child_attrs=None):
|
|
|
''' creates an xml child element and set its attributes '''
|
|
|
child = etree.SubElement(parent_node, child_name)
|
|
|
if child_attrs is None:
|
|
@@ -80,19 +115,28 @@ def make_plans(persons):
|
|
|
''' makes xml tree of plans based on persons list '''
|
|
|
plans = etree.Element('plans')
|
|
|
for n, p in enumerate(persons):
|
|
|
- person = create_child(plans, 'person', {'id': str(n+1)})
|
|
|
- plan = create_child(person, 'plan')
|
|
|
+ person = make_child(plans, 'person', {'id': str(n+1)})
|
|
|
+ plan = make_child(person, 'plan')
|
|
|
# plan
|
|
|
- create_child(plan, 'act', {'type': 'h', 'x': p['home'][0], 'y': p['home'][1], 'end_time': p['home_departure']})
|
|
|
- create_child(plan, 'leg', {'mode': 'car'})
|
|
|
- create_child(plan, 'act', {'type': 'w', 'x': p['work'][0], 'y': p['work'][1], 'dur': WORK_DURATION})
|
|
|
- create_child(plan, 'leg', {'mode': 'car'})
|
|
|
- create_child(plan, 'act', {'type': 'h', 'x': p['home'][0], 'y': p['home'][1]})
|
|
|
+ make_child(plan, 'act', {'type': 'h', 'x': p['home'][0], 'y': p['home'][1], 'end_time': p['home_departure']})
|
|
|
+ make_child(plan, 'leg', {'mode': 'car'})
|
|
|
+ make_child(plan, 'act', {'type': 'w', 'x': p['work'][0], 'y': p['work'][1], 'dur': WORK_DURATION})
|
|
|
+ make_child(plan, 'leg', {'mode': 'car'})
|
|
|
+ make_child(plan, 'act', {'type': 'h', 'x': p['home'][0], 'y': p['home'][1]})
|
|
|
return plans
|
|
|
|
|
|
-def read_nodes(input_network):
|
|
|
+# xml readers
|
|
|
+# ------------------
|
|
|
+
|
|
|
+def get_nodes(input_network):
|
|
|
''' returns all network nodes as a list '''
|
|
|
if not input_network:
|
|
|
return None
|
|
|
tree = etree.parse(input_network)
|
|
|
return [node for node in tree.xpath("/network/nodes/node")]
|
|
|
+
|
|
|
+def get_extrem_nodes(nodes):
|
|
|
+ ''' returns extremum coordinates of a nodeslist '''
|
|
|
+ x = [float(node.get('x')) for node in nodes]
|
|
|
+ y = [float(node.get('y')) for node in nodes]
|
|
|
+ return min(x), max(x), min(y), max(y)
|