1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- #!/usr/bin/env python3
- ''' Python generator for MATSim plans. '''
- import sys
- import time
- import numpy as np
- import lxml.etree as etree
- # constants
- MIN_DEPARTURE_TIME = 8 * 3600 # '08:00:00'
- MAX_DEPARTURE_TIME = 9 * 3600 # '09:00:00'
- WORK_DURATION = '04:00:00'
- def read_nodes(input_network):
- ''' returns all network nodes as a list '''
- tree = etree.parse(input_network)
- return [node for node in tree.xpath("/network/nodes/node")]
- def rand_time(low, high):
- ''' returns a random time between low and high bounds (in seconds) '''
- delta = np.random.randint(high - low);
- return time.strftime('%H:%M:%S', time.gmtime(low + delta))
- def rand_person(nodes):
- ''' returns a person as a dictionnary of random parameters '''
- len_nodes = len(nodes)
- # home coordinates
- home_node = nodes[np.random.randint(len_nodes)]
- home_xy = (home_node.get('x'), home_node.get('y'))
- # work coordinates
- work_node = nodes[np.random.randint(len_nodes)]
- work_xy = (work_node.get('x'), work_node.get('y'))
- # home departure time
- 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={}):
- ''' creates an xml child element and set its attributes '''
- child = etree.SubElement(parent_node, child_name)
- for attr, value in child_attrs.items():
- child.set(attr, value)
- return child
- 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')
- # 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]})
- return plans
- if __name__ == '__main__':
- # command line arguments
- if len(sys.argv) != 3:
- print('usage:', sys.argv[0], '<input_network> <nb_persons>')
- sys.exit(-1)
- INPUT_NETWORK = sys.argv[1]
- NB_PERSONS = int(sys.argv[2])
- NODES = read_nodes(INPUT_NETWORK)
- PERSONS = [rand_person(NODES) for _ in range(NB_PERSONS)]
- PLANS = make_plans(PERSONS)
- # print XML
- print('<?xml version="1.0" ?>')
- print('<!DOCTYPE plans SYSTEM "http://www.matsim.org/files/dtd/plans_v4.dtd">')
- print(etree.tostring(PLANS, pretty_print=True).decode('utf-8'))
|