plan_gen.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #!/usr/bin/env python3
  2. ''' Python generator for MATSim plans. '''
  3. import sys
  4. import numpy as np
  5. import lxml.etree as etree
  6. def read_nodes(input_network):
  7. ''' returns all network nodes as a list '''
  8. tree = etree.parse(input_network)
  9. return [node for node in tree.xpath("/network/nodes/node")]
  10. def rand_person(nodes):
  11. ''' returns a person as a dict of random home and work coordinates '''
  12. len_nodes = len(nodes)
  13. home_node = nodes[np.random.randint(len_nodes)]
  14. work_node = nodes[np.random.randint(len_nodes)]
  15. home_xy = (home_node.get('x'), home_node.get('y'))
  16. work_xy = (work_node.get('x'), work_node.get('y'))
  17. return {'home': home_xy, 'work': work_xy}
  18. def create_child(parent_node, child_name, child_attrs={}):
  19. ''' creates an xml child element and set its attributes '''
  20. child = etree.SubElement(parent_node, child_name)
  21. for attr, value in child_attrs.items():
  22. child.set(attr, value)
  23. return child
  24. def make_plans(persons):
  25. ''' makes xml tree of plans based on persons list '''
  26. plans = etree.Element('plans')
  27. for n, p in enumerate(persons):
  28. person = create_child(plans, 'person', {'id': str(n+1)})
  29. plan = create_child(person, 'plan')
  30. # plan
  31. create_child(plan, 'act', {'type': 'h', 'x': p['home'][0], 'y': p['home'][1], 'end_time': '09:00:00'})
  32. create_child(plan, 'leg', {'mode': 'car'})
  33. create_child(plan, 'act', {'type': 'w', 'x': p['work'][0], 'y': p['work'][1], 'dur': '03:00:00'})
  34. create_child(plan, 'leg', {'mode': 'car'})
  35. create_child(plan, 'act', {'type': 'h', 'x': p['home'][0], 'y': p['home'][1]})
  36. return plans
  37. if __name__ == '__main__':
  38. # command line arguments
  39. if len(sys.argv) != 3:
  40. print('usage:', sys.argv[0], '<input_network> <nb_persons>')
  41. sys.exit(-1)
  42. INPUT_NETWORK = sys.argv[1]
  43. NB_PERSONS = int(sys.argv[2])
  44. NODES = read_nodes(INPUT_NETWORK)
  45. PERSONS = [rand_person(NODES) for _ in range(NB_PERSONS)]
  46. PLANS = make_plans(PERSONS)
  47. # print XML
  48. print('<?xml version="1.0" ?>')
  49. print('<!DOCTYPE plans SYSTEM "http://www.matsim.org/files/dtd/plans_v4.dtd">')
  50. print(etree.tostring(PLANS, pretty_print=True).decode('utf-8'))