def test_teleporting_service_with_some_stops_snapped_to_non_existing_links(test_network, test_service): test_network.schedule = Schedule(epsg='epsg:27700', services=[test_service]) test_network.schedule._graph.nodes['490000252X']['linkRefId'] = 'some_bogus_link_lololol' test_network.apply_attributes_to_links({'5221366094904818311_5221366094903752729': { 'modes': test_network.link('5221366094904818311_5221366094903752729')['modes'] | {'bus'}}}) test_network.teleport_service('service_bus') rep = test_network.generate_validation_report() assert rep['graph']['graph_connectivity']['car']['number_of_connected_subgraphs'] == 1 assert rep['schedule']['schedule_level']['is_valid_schedule'] assert rep['routing']['services_have_routes_in_the_graph'] assert test_network.schedule.route('route_1').route == ['artificial_link===from:490004695A===to:490004695A', 'artificial_link===from:490004695A===to:490000235C', 'artificial_link===from:490000235C===to:490000235C', 'artificial_link===from:490000235C===to:490000089A', 'artificial_link===from:490000089A===to:490000089A'] assert test_network.schedule.route('route_2').route == ['artificial_link===from:490000089A===to:490000089A', 'artificial_link===from:490000089A===to:490000252X', 'artificial_link===from:490000252X===to:490000252X', 'artificial_link===from:490000252X===to:490000078Q', 'artificial_link===from:490000078Q===to:490000078Q'] for link in {'artificial_link===from:490004695A===to:490004695A', 'artificial_link===from:490004695A===to:490000235C', 'artificial_link===from:490000235C===to:490000235C', 'artificial_link===from:490000235C===to:490000089A', 'artificial_link===from:490000089A===to:490000089A', 'artificial_link===from:490000089A===to:490000089A', 'artificial_link===from:490000089A===to:490000252X', 'artificial_link===from:490000252X===to:490000252X', 'artificial_link===from:490000252X===to:490000078Q', 'artificial_link===from:490000078Q===to:490000078Q' }: assert test_network.has_link(link)
def test_teleporting_service(test_network, test_service): test_network.schedule = Schedule(epsg='epsg:27700', services=[test_service]) test_network.teleport_service('service_bus') rep = test_network.generate_validation_report() assert rep['graph']['graph_connectivity']['car']['number_of_connected_subgraphs'] == 1 assert rep['schedule']['schedule_level']['is_valid_schedule'] assert rep['routing']['services_have_routes_in_the_graph'] assert test_network.schedule.route('route_1').route == ['artificial_link===from:490004695A===to:490004695A', 'artificial_link===from:490004695A===to:490000235C', 'artificial_link===from:490000235C===to:490000235C', 'artificial_link===from:490000235C===to:490000089A', 'artificial_link===from:490000089A===to:490000089A'] assert test_network.schedule.route('route_2').route == ['artificial_link===from:490000089A===to:490000089A', 'artificial_link===from:490000089A===to:490000252X', 'artificial_link===from:490000252X===to:490000252X', 'artificial_link===from:490000252X===to:490000078Q', 'artificial_link===from:490000078Q===to:490000078Q'] for link in {'artificial_link===from:490000252X===to:490000252X', 'artificial_link===from:490000078Q===to:490000078Q', 'artificial_link===from:490000235C===to:490000235C', 'artificial_link===from:490000235C===to:490000089A', 'artificial_link===from:490004695A===to:490004695A', 'artificial_link===from:490000089A===to:490000089A', 'artificial_link===from:490000089A===to:490000252X', 'artificial_link===from:490000252X===to:490000078Q', 'artificial_link===from:490004695A===to:490000235C'}: assert test_network.has_link(link)
def test_routing_services_with_stops_that_have_colons_in_id_and_are_unsnapped(test_network, mocker): mocker.patch.object(nx, 'is_empty', return_value=True) test_network.schedule = Schedule(epsg='epsg:27700', services=[ Service( id='service_bus', routes=[ Route(id='other_route', route_short_name='', mode='bus', stops=[Stop(epsg='epsg:27700', id='490000235C', x=529741.7652299237, y=181516.3450505745), Stop(epsg='epsg:27700', id='A:heyo', x=529871.7641447927, y=181148.2259665833), Stop(epsg='epsg:27700', id='490000089A', x=529488.7339130711, y=181894.12649680028)], trips={'trip_id': ['trip_1'], 'trip_departure_time': ['15:30:00'], 'vehicle_id': ['veh_bus_0']}, arrival_offsets=['00:00:00', '00:02:00', '00:05:00'], departure_offsets=['00:00:00', '00:03:00', '00:07:00'] ) ])]) test_network.route_service('service_bus', additional_modes='car') rep = test_network.generate_validation_report() assert rep['graph']['graph_connectivity']['car']['number_of_connected_subgraphs'] == 1 assert rep['schedule']['schedule_level']['is_valid_schedule'] assert rep['routing']['services_have_routes_in_the_graph']
def test_routing_services_with_shared_stops(test_network, test_service): test_network.schedule = Schedule(epsg='epsg:27700', services=[ test_service, Service( id='other_service_bus', routes=[ Route(id='other_route', route_short_name='', mode='bus', stops=[Stop(epsg='epsg:27700', id='A', x=529871.7641447927, y=181148.2259665833), Stop(epsg='epsg:27700', id='490000235C', x=529741.7652299237, y=181516.3450505745), Stop(epsg='epsg:27700', id='490000089A', x=529488.7339130711, y=181894.12649680028)], trips={'trip_id': ['trip_1'], 'trip_departure_time': ['15:30:00'], 'vehicle_id': ['veh_bus_0']}, arrival_offsets=['00:00:00', '00:02:00', '00:05:00'], departure_offsets=['00:00:00', '00:03:00', '00:07:00'] ) ])]) test_network.route_service('service_bus', additional_modes='car') assert test_network.schedule['other_service_bus'].reference_edges() == {('A', '490000235C'), ('490000235C', '490000089A')} test_network.route_service('other_service_bus', additional_modes='car') rep = test_network.generate_validation_report() assert rep['graph']['graph_connectivity']['car']['number_of_connected_subgraphs'] == 1 assert rep['schedule']['schedule_level']['is_valid_schedule'] assert rep['routing']['services_have_routes_in_the_graph']
def schedule(): route_1 = Route(route_short_name='name', mode='bus', id='1', stops=[Stop(id='1', x=4, y=2, epsg='epsg:27700', name='Stop_1'), Stop(id='2', x=1, y=2, epsg='epsg:27700', name='Stop_2'), Stop(id='3', x=3, y=3, epsg='epsg:27700', name='Stop_3'), Stop(id='4', x=7, y=5, epsg='epsg:27700')], trips={'trip_id': ['1', '2'], 'trip_departure_time': ['17:00:00', '18:30:00'], 'vehicle_id': ['veh_1_bus', 'veh_2_bus']}, arrival_offsets=['00:00:00', '00:03:00', '00:07:00', '00:13:00'], departure_offsets=['00:00:00', '00:05:00', '00:09:00', '00:15:00']) route_2 = Route(route_short_name='name_2', mode='bus', id='2', stops=[Stop(id='4', x=7, y=5, epsg='epsg:27700'), Stop(id='3', x=3, y=3, epsg='epsg:27700', name='Stop_3'), Stop(id='2', x=1, y=2, epsg='epsg:27700', name='Stop_2'), Stop(id='1', x=4, y=2, epsg='epsg:27700', name='Stop_1')], trips={'trip_id': ['1', '2'], 'trip_departure_time': ['17:00:00', '18:30:00'], 'vehicle_id': ['veh_3_bus', 'veh_4_bus']}, arrival_offsets=['00:00:00', '00:03:00', '00:07:00', '00:13:00'], departure_offsets=['00:00:00', '00:05:00', '00:09:00', '00:15:00']) service = Service(id='service', routes=[route_1, route_2]) return Schedule(epsg='epsg:27700', services=[service])
def test_routing_schedule_specifying_services(test_network, test_service): test_network.schedule = Schedule(epsg='epsg:27700', services=[test_service]) test_network.route_schedule(services=['service_bus']) rep = test_network.generate_validation_report() assert rep['graph']['graph_connectivity']['car']['number_of_connected_subgraphs'] == 1 assert rep['schedule']['schedule_level']['is_valid_schedule'] assert rep['routing']['services_have_routes_in_the_graph']
def test_routing_schedule_with_additional_modes(test_network, test_service): test_network.schedule = Schedule(epsg='epsg:27700', services=[test_service]) test_network.route_schedule(additional_modes={'bus': {'car'}, 'tram': ['rail', 'car'], 'subway': 'rail'}) rep = test_network.generate_validation_report() assert rep['graph']['graph_connectivity']['car']['number_of_connected_subgraphs'] == 1 assert rep['schedule']['schedule_level']['is_valid_schedule'] assert rep['routing']['services_have_routes_in_the_graph']
def test_teleporting_more_than_one_service(test_network, test_service): test_network.schedule = Schedule( epsg='epsg:27700', services=[test_service, Service( id='service_rail', routes=[ Route(id='route_1_rail', route_short_name='', mode='rail', stops=[ Stop(epsg='epsg:27700', id='490004695A', x=529871.7641447927, y=181148.2259665833), Stop(epsg='epsg:27700', id='490000235C', x=529741.7652299237, y=181516.3450505745), Stop(epsg='epsg:27700', id='49000008900000', x=529488.7339130711, y=181894.12649680028)], trips={'trip_id': ['trip_1'], 'trip_departure_time': ['15:30:00'], 'vehicle_id': ['veh_rail_1']}, arrival_offsets=['00:00:00', '00:02:00', '00:05:00'], departure_offsets=['00:00:00', '00:03:00', '00:07:00'] )]) ]) test_network.teleport_service(['service_bus', 'service_rail']) rep = test_network.generate_validation_report() assert rep['graph']['graph_connectivity']['car']['number_of_connected_subgraphs'] == 1 assert rep['schedule']['schedule_level']['is_valid_schedule'] assert rep['routing']['services_have_routes_in_the_graph'] assert test_network.schedule.route('route_1').route == ['artificial_link===from:490004695A===to:490004695A', 'artificial_link===from:490004695A===to:490000235C', 'artificial_link===from:490000235C===to:490000235C', 'artificial_link===from:490000235C===to:490000089A', 'artificial_link===from:490000089A===to:490000089A'] assert test_network.schedule.route('route_2').route == ['artificial_link===from:490000089A===to:490000089A', 'artificial_link===from:490000089A===to:490000252X', 'artificial_link===from:490000252X===to:490000252X', 'artificial_link===from:490000252X===to:490000078Q', 'artificial_link===from:490000078Q===to:490000078Q'] assert test_network.schedule.route('route_1_rail').route == ['artificial_link===from:490004695A===to:490004695A', 'artificial_link===from:490004695A===to:490000235C', 'artificial_link===from:490000235C===to:490000235C', 'artificial_link===from:490000235C===to:49000008900000', 'artificial_link===from:49000008900000===to:49000008900000'] for link in {'artificial_link===from:490000252X===to:490000252X', 'artificial_link===from:490000078Q===to:490000078Q', 'artificial_link===from:490000235C===to:490000235C', 'artificial_link===from:490000235C===to:490000089A', 'artificial_link===from:490004695A===to:490004695A', 'artificial_link===from:490000089A===to:490000089A', 'artificial_link===from:490000089A===to:490000252X', 'artificial_link===from:490000252X===to:490000078Q', 'artificial_link===from:490004695A===to:490000235C', 'artificial_link===from:490000235C===to:49000008900000', 'artificial_link===from:49000008900000===to:49000008900000'}: assert test_network.has_link(link) assert test_network.link('artificial_link===from:490004695A===to:490000235C')['modes'] == {'rail', 'bus'} assert test_network.link('artificial_link===from:490000235C===to:490000235C')['modes'] == {'rail', 'bus'} assert test_network.link('artificial_link===from:49000008900000===to:49000008900000')['modes'] == {'rail'}
def test_routing_services_to_network_with_clashing_artificial_links(test_network, test_service): test_network.schedule = Schedule(epsg='epsg:27700', services=[test_service]) # teleport first to create artificial links - recreates a InvalidMaxStableSetProblem of completely connected # catchments test_network.teleport_service('service_bus') test_network.route_service('service_bus', additional_modes='car') rep = test_network.generate_validation_report() assert rep['graph']['graph_connectivity']['car']['number_of_connected_subgraphs'] == 1 assert rep['schedule']['schedule_level']['is_valid_schedule'] assert rep['routing']['services_have_routes_in_the_graph']
def schedule_with_a_couple_services_that_overlap_stations(): route_1 = Route(route_short_name='name', mode='bus', id='1', stops=[Stop(id='1', x=4, y=2, epsg='epsg:27700', name='Stop_1'), Stop(id='2', x=1, y=2, epsg='epsg:27700', name='Stop_2'), Stop(id='3', x=3, y=3, epsg='epsg:27700', name='Stop_3'), Stop(id='4', x=7, y=5, epsg='epsg:27700')], trips={'1': '17:00:00', '2': '18:30:00'}, arrival_offsets=['00:00:00', '00:03:00', '00:07:00', '00:13:00'], departure_offsets=['00:00:00', '00:05:00', '00:09:00', '00:15:00']) route_2 = Route(route_short_name='name_2', mode='bus', id='2', stops=[Stop(id='04', x=7, y=5, epsg='epsg:27700'), Stop(id='03', x=3, y=3, epsg='epsg:27700', name='Stop_3'), Stop(id='02', x=1, y=2, epsg='epsg:27700', name='Stop_2'), Stop(id='01', x=4, y=2, epsg='epsg:27700', name='Stop_1')], trips={'1': '17:00:00', '2': '18:30:00'}, arrival_offsets=['00:00:00', '00:03:00', '00:07:00', '00:13:00'], departure_offsets=['00:00:00', '00:05:00', '00:09:00', '00:15:00']) service = Service(id='service', routes=[route_1, route_2]) route_11 = Route(route_short_name='name', mode='bus', id='11', stops=[Stop(id='1', x=4, y=2, epsg='epsg:27700', name='Stop_1'), Stop(id='2', x=1, y=2, epsg='epsg:27700', name='Stop_2'), Stop(id='3', x=3, y=3, epsg='epsg:27700', name='Stop_3'), Stop(id='4', x=7, y=5, epsg='epsg:27700')], trips={'1': '17:00:00'}, arrival_offsets=['00:00:00', '00:03:00', '00:07:00', '00:13:00'], departure_offsets=['00:00:00', '00:05:00', '00:09:00', '00:15:00']) route_12 = Route(route_short_name='name_2', mode='bus', id='012', stops=[Stop(id='04', x=7, y=5, epsg='epsg:27700'), Stop(id='03', x=3, y=3, epsg='epsg:27700', name='Stop_3'), Stop(id='02', x=1, y=2, epsg='epsg:27700', name='Stop_2'), Stop(id='01', x=4, y=2, epsg='epsg:27700', name='Stop_1')], trips={'1': '17:00:00'}, arrival_offsets=['00:00:00', '00:03:00', '00:07:00', '00:13:00'], departure_offsets=['00:00:00', '00:05:00', '00:09:00', '00:15:00']) service_2 = Service(id='service_2', routes=[route_11, route_12]) return Schedule(epsg='epsg:27700', services=[service, service_2])
def test_generating_standard_outputs(network, tmpdir): network.schedule = Schedule(epsg='epsg:27700', services=[ Service(id='bus_service', routes=[ Route(id='1', route_short_name='', mode='bus', stops=[ Stop(id='0', x=529455.7452394223, y=182401.37630677427, epsg='epsg:27700', linkRefId='link_1'), Stop(id='1', x=529350.7866124967, y=182388.0201078112, epsg='epsg:27700', linkRefId='link_2')], trips={'trip_id': ['VJ00938baa194cee94700312812d208fe79f3297ee_04:40:00'], 'trip_departure_time': ['04:40:00'], 'vehicle_id': ['veh_1_bus']}, arrival_offsets=['00:00:00', '00:02:00'], departure_offsets=['00:00:00', '00:02:00'], route=['link_1', 'link_2']), Route(id='2', route_short_name='route2', mode='bus', stops=[ Stop(id='0', x=529455.7452394223, y=182401.37630677427, epsg='epsg:27700', linkRefId='link_1'), Stop(id='1', x=529350.7866124967, y=182388.0201078112, epsg='epsg:27700', linkRefId='link_2')], trips={'trip_id': ['1_05:40:00', '2_05:45:00', '3_05:50:00', '4_06:40:00', '5_06:46:00'], 'trip_departure_time': ['05:40:00', '05:45:00', '05:50:00', '06:40:00', '06:46:00'], 'vehicle_id': ['veh_2_bus', 'veh_3_bus', 'veh_4_bus', 'veh_5_bus', 'veh_6_bus']}, arrival_offsets=['00:00:00', '00:03:00'], departure_offsets=['00:00:00', '00:05:00'], route=['link_1', 'link_2']) ]), Service(id='rail_service', routes=[Route( route_short_name=r"RTR_I/love\_being//difficult", mode='rail', stops=[ Stop(id='RSN', x=-0.1410946, y=51.5231335, epsg='epsg:4326', name=r"I/love\_being//difficult"), Stop(id='RSE', x=-0.1421595, y=51.5192615, epsg='epsg:4326')], trips={'trip_id': ['RT1', 'RT2', 'RT3', 'RT4'], 'trip_departure_time': ['03:21:00', '03:31:00', '03:41:00', '03:51:00'], 'vehicle_id': ['veh_7_rail', 'veh_8_rail', 'veh_9_rail', 'veh_10_rail']}, arrival_offsets=['0:00:00', '0:02:00'], departure_offsets=['0:00:00', '0:02:00'] )]) ]) assert os.listdir(tmpdir) == [] network.generate_standard_outputs(tmpdir, include_shp_files=True) assert set(os.listdir(tmpdir)) == {'graph', 'schedule_links_geometry_only.geojson', 'network_nodes_geometry_only.geojson', 'network_links.geojson', 'network_links_geometry_only.geojson', 'schedule_nodes.geojson', 'schedule_nodes_geometry_only.geojson', 'schedule', 'network_nodes.geojson', 'schedule_links.geojson', 'network_change_log.csv', 'schedule_change_log.csv', 'routing'} assert set(os.listdir(os.path.join(tmpdir, 'graph'))) == {'car_capacity_subgraph.geojson', 'car_freespeed_subgraph.geojson', 'car_osm_highway_unclassified.geojson', 'geometry_only_subgraphs', 'shp_files'} assert set(os.listdir(os.path.join(tmpdir, 'graph', 'shp_files'))) == {'car_osm_highway_unclassified.dbf', 'car_capacity_subgraph.cpg', 'car_freespeed_subgraph.shx', 'car_freespeed_subgraph.cpg', 'car_capacity_subgraph.prj', 'car_osm_highway_unclassified.prj', 'car_osm_highway_unclassified.shp', 'car_freespeed_subgraph.prj', 'car_osm_highway_unclassified.shx', 'car_capacity_subgraph.shp', 'car_capacity_subgraph.dbf', 'car_capacity_subgraph.shx', 'car_freespeed_subgraph.dbf', 'car_freespeed_subgraph.shp', 'car_osm_highway_unclassified.cpg'} assert set(os.listdir(os.path.join(tmpdir, 'graph', 'geometry_only_subgraphs'))) == { 'subgraph_geometry_walk.geojson', 'subgraph_geometry_rail.geojson', 'subgraph_geometry_car.geojson', 'shp_files', 'subgraph_geometry_bike.geojson'} assert set(os.listdir(os.path.join(tmpdir, 'graph', 'geometry_only_subgraphs', 'shp_files'))) == { 'subgraph_geometry_walk.shp', 'subgraph_geometry_rail.prj', 'subgraph_geometry_bike.dbf', 'subgraph_geometry_rail.shx', 'subgraph_geometry_car.cpg', 'subgraph_geometry_car.dbf', 'subgraph_geometry_car.shp', 'subgraph_geometry_bike.shp', 'subgraph_geometry_walk.dbf', 'subgraph_geometry_bike.shx', 'subgraph_geometry_rail.cpg', 'subgraph_geometry_bike.cpg', 'subgraph_geometry_car.shx', 'subgraph_geometry_walk.cpg', 'subgraph_geometry_car.prj', 'subgraph_geometry_rail.dbf', 'subgraph_geometry_walk.prj', 'subgraph_geometry_walk.shx', 'subgraph_geometry_bike.prj', 'subgraph_geometry_rail.shp'} assert set(os.listdir(os.path.join(tmpdir, 'schedule'))) == {'vehicles_per_hour', 'subgraphs', 'trips_per_day_per_service.csv', 'trips_per_day_per_route.csv', 'trips_per_day_per_route_aggregated_per_stop_id_pair.csv', 'trips_per_day_per_route_aggregated_per_stop_name_pair.csv' } assert set(os.listdir(os.path.join(tmpdir, 'schedule', 'vehicles_per_hour'))) == {'vph_per_service.csv', 'vehicles_per_hour_all_modes.geojson', 'vph_per_stop_departing_from.csv', 'vph_all_modes_within_6:30-7:30.geojson', 'vph_per_stop_arriving_at.csv', 'shp_files', 'vehicles_per_hour_bus.geojson', 'vehicles_per_hour_rail.geojson'} assert set(os.listdir(os.path.join(tmpdir, 'schedule', 'vehicles_per_hour', 'shp_files'))) == { 'vehicles_per_hour_all_modes.cpg', 'vph_all_modes_within_6:30-7:30.shx', 'vehicles_per_hour_rail.prj', 'vehicles_per_hour_bus.shp', 'vehicles_per_hour_bus.dbf', 'vehicles_per_hour_rail.shx', 'vehicles_per_hour_bus.prj', 'vehicles_per_hour_all_modes.prj', 'vehicles_per_hour_bus.shx', 'vehicles_per_hour_rail.dbf', 'vph_all_modes_within_6:30-7:30.dbf', 'vehicles_per_hour_rail.cpg', 'vph_all_modes_within_6:30-7:30.shp', 'vehicles_per_hour_rail.shp', 'vehicles_per_hour_all_modes.shx', 'vehicles_per_hour_bus.cpg', 'vehicles_per_hour_all_modes.shp', 'vph_all_modes_within_6:30-7:30.prj', 'vehicles_per_hour_all_modes.dbf', 'vph_all_modes_within_6:30-7:30.cpg'} assert set(os.listdir(os.path.join(tmpdir, 'schedule', 'subgraphs'))) == {'schedule_subgraph_links_bus.geojson', 'schedule_subgraph_links_rail.geojson', 'shp_files', 'schedule_subgraph_nodes_bus.geojson', 'schedule_subgraph_nodes_rail.geojson'} assert set(os.listdir(os.path.join(tmpdir, 'schedule', 'subgraphs', 'shp_files'))) == { 'schedule_subgraph_nodes_rail.prj', 'schedule_subgraph_links_bus.shx', 'schedule_subgraph_links_bus.prj', 'schedule_subgraph_nodes_rail.dbf', 'schedule_subgraph_nodes_rail.shx', 'schedule_subgraph_links_rail.dbf', 'schedule_subgraph_links_rail.shx', 'schedule_subgraph_nodes_bus.cpg', 'schedule_subgraph_links_rail.shp', 'schedule_subgraph_nodes_bus.prj', 'schedule_subgraph_nodes_bus.dbf', 'schedule_subgraph_links_rail.cpg', 'schedule_subgraph_links_bus.dbf', 'schedule_subgraph_links_bus.shp', 'schedule_subgraph_links_rail.prj', 'schedule_subgraph_nodes_bus.shx', 'schedule_subgraph_links_bus.cpg', 'schedule_subgraph_nodes_bus.shp', 'schedule_subgraph_nodes_rail.cpg', 'schedule_subgraph_nodes_rail.shp'} assert set(os.listdir(os.path.join(tmpdir, 'routing'))) == {'shp_files', 'schedule_network_routes_geodataframe.geojson'} assert os.path.exists(tmpdir + '.zip')
def network(): n = Network('epsg:27700') n.add_nodes({'node_1': {'id': 'node_1', 'x': 1, 'y': 2, 'lat': 49.766825803756994, 'lon': -7.557148039524952, 's2_id': 5205973754090365183}, 'node_2': {'id': 'node_2', 'x': 1, 'y': 3, 'lat': 49.766834755586814, 'lon': -7.557149066139435, 's2_id': 5205973754090333257}, 'node_3': {'id': 'node_3', 'x': 2, 'y': 3, 'lat': 49.766835420540474, 'lon': -7.557135245523688, 's2_id': 5205973754090257181}, 'node_4': {'id': 'node_4', 'x': 2, 'y': 2, 'lat': 49.766826468710484, 'lon': -7.557134218911724, 's2_id': 5205973754090480551}, 'node_5': {'id': 'node_5', 'x': 3, 'y': 2, 'lat': 49.76682713366229, 'lon': -7.557120398297983, 's2_id': 5205973754090518939}, 'node_6': {'id': 'node_6', 'x': 4, 'y': 2, 'lat': 49.76682779861249, 'lon': -7.557106577683727, 's2_id': 5205973754090531959}, 'node_7': {'id': 'node_7', 'x': 5, 'y': 2, 'lat': 49.76682846356101, 'lon': -7.557092757068958, 's2_id': 5205973754096484927}, 'node_8': {'id': 'node_8', 'x': 6, 'y': 2, 'lat': 49.766829128507936, 'lon': -7.55707893645368, 's2_id': 5205973754096518199}, 'node_9': {'id': 'node_9', 'x': 6, 'y': 2, 'lat': 49.766829128507936, 'lon': -7.55707893645368, 's2_id': 5205973754096518199}}, silent=True) n.add_links( {'link_1_2_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_1', 'to': 'node_2', 'id': 'link_1_2_car'}, 'link_2_1_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_2', 'to': 'node_1', 'id': 'link_2_1_car'}, 'link_1_2_bus': {'length': 1, 'modes': ['bus'], 'freespeed': 1, 'from': 'node_1', 'to': 'node_2', 'id': 'link_1_2_bus'}, 'link_2_1_bus': {'length': 1, 'modes': ['bus'], 'freespeed': 1, 'from': 'node_2', 'to': 'node_1', 'id': 'link_2_1_bus'}, 'link_2_3_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_2', 'to': 'node_3', 'id': 'link_2_3_car'}, 'link_3_2_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_3', 'to': 'node_2', 'id': 'link_3_2_car'}, 'link_3_4_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_3', 'to': 'node_4', 'id': 'link_3_4_car'}, 'link_4_3_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_4', 'to': 'node_3', 'id': 'link_4_3_car'}, 'link_1_4_bus': {'length': 1, 'modes': ['bus'], 'freespeed': 1, 'from': 'node_1', 'to': 'node_4', 'id': 'link_1_4_bus'}, 'link_4_1_bus': {'length': 1, 'modes': ['bus'], 'freespeed': 1, 'from': 'node_4', 'to': 'node_1', 'id': 'link_4_1_bus'}, 'link_4_5_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_4', 'to': 'node_5', 'id': 'link_4_5_car'}, 'link_5_4_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_5', 'to': 'node_4', 'id': 'link_5_4_car'}, 'link_5_6_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_5', 'to': 'node_6', 'id': 'link_5_6_car'}, 'link_6_5_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_6', 'to': 'node_5', 'id': 'link_6_5_car'}, 'link_6_7_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_6', 'to': 'node_7', 'id': 'link_6_7_car'}, 'link_7_6_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_7', 'to': 'node_6', 'id': 'link_7_6_car'}, 'link_7_8_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_7', 'to': 'node_8', 'id': 'link_7_8_car'}, 'link_8_7_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_8', 'to': 'node_7', 'id': 'link_8_7_car'}, 'link_8_9_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_8', 'to': 'node_9', 'id': 'link_8_9_car'}, 'link_9_8_car': {'length': 1, 'modes': ['car'], 'freespeed': 1, 'from': 'node_9', 'to': 'node_8', 'id': 'link_9_8_car'} }, silent=True) n.schedule = Schedule(epsg='epsg:27700', services=[ Service(id='bus_service', routes=[ Route(id='service_1_route_1', route_short_name='', mode='bus', stops=[Stop(epsg='epsg:27700', id='stop_1', x=1, y=2.5), Stop(epsg='epsg:27700', id='stop_2', x=2, y=2.5), Stop(epsg='epsg:27700', id='stop_3', x=5.5, y=2)], trips={'trip_id': ['trip_1'], 'trip_departure_time': ['15:30:00'], 'vehicle_id': ['veh_bus_0']}, arrival_offsets=['00:00:00', '00:02:00', '00:05:00'], departure_offsets=['00:00:00', '00:03:00', '00:07:00'] ), Route(id='service_1_route_2', route_short_name='', mode='bus', stops=[Stop(epsg='epsg:27700', id='stop_3', x=5.5, y=2), Stop(epsg='epsg:27700', id='stop_2', x=2, y=2.5), Stop(epsg='epsg:27700', id='stop_1', x=1, y=2.5)], trips={'trip_id': ['trip_2'], 'trip_departure_time': ['16:30:00'], 'vehicle_id': ['veh_bus_1']}, arrival_offsets=['00:00:00', '00:02:00', '00:05:00'], departure_offsets=['00:00:00', '00:03:00', '00:07:00'] ) ])]) return n