def test_read_api_requests(): api_requests = google_directions.read_api_requests( example_google_speed_data) assert_semantically_equal( api_requests, { ('9791490', '4698712638'): { 'path_nodes': ('9791490', '4698712638'), 'path_polyline': 'mvmyHpqYb@lA', 'origin': { 'id': '9791490', 'x': 529414.5591563961, 'y': 181898.4902840198, 'lat': 51.5211862, 'lon': -0.1360879, 's2_id': 5221390682074967291 }, 'destination': { 'id': '4698712638', 'x': 529387.9166476472, 'y': 181877.74867097137, 'lat': 51.5210059, 'lon': -0.1364793, 's2_id': 5221390682013665023 }, 'timestamp': 1594385229.635254, 'parsed_response': { 'google_speed': 6.8, 'google_polyline': 'mvmyHpqYb@pA' } } })
def test_build_graph_builds_correct_graph(): route = Route(route_short_name='name', mode='bus', stops=[Stop(id='1', x=4, y=2, epsg='epsg:27700'), Stop(id='2', x=1, y=2, epsg='epsg:27700'), Stop(id='3', x=3, y=3, epsg='epsg:27700'), Stop(id='4', x=7, y=5, epsg='epsg:27700')], trips={'trip_id': ['1', '2'], 'trip_departure_time': ['1', '2'], 'vehicle_id': ['veh_3_bus', 'veh_4_bus']}, arrival_offsets=['1', '2'], departure_offsets=['1', '2']) g = route.graph() assert_semantically_equal(dict(g.nodes(data=True)), {'1': {'routes': {''}, 'id': '1', 'x': 4.0, 'y': 2.0, 'epsg': 'epsg:27700', 'lat': 49.76682779861249, 'lon': -7.557106577683727, 's2_id': 5205973754090531959, 'name': ''}, '2': {'routes': {''}, 'id': '2', 'x': 1.0, 'y': 2.0, 'epsg': 'epsg:27700', 'lat': 49.766825803756994, 'lon': -7.557148039524952, 's2_id': 5205973754090365183, 'name': ''}, '3': {'routes': {''}, 'id': '3', 'x': 3.0, 'y': 3.0, 'epsg': 'epsg:27700', 'lat': 49.76683608549253, 'lon': -7.557121424907424, 's2_id': 5205973754090203369, 'name': ''}, '4': {'routes': {''}, 'id': '4', 'x': 7.0, 'y': 5.0, 'epsg': 'epsg:27700', 'lat': 49.766856648946295, 'lon': -7.5570681956375, 's2_id': 5205973754097123809, 'name': ''}}) assert_semantically_equal(g.edges(data=True)._adjdict, {'1': {'2': {'routes': {''}}}, '2': {'3': {'routes': {''}}}, '3': {'4': {'routes': {''}}}, '4': {}})
def test_merging_nested_dictionaries(): return_d = dict_support.merge_complex_dictionaries( { 'a': 1, 'b': { 3: 5 }, 'c': { 1: 4 } }, { 'b': { 5: 3 }, 'c': { 8: 90 } }) assert_semantically_equal(return_d, { 'a': 1, 'b': { 3: 5, 5: 3 }, 'c': { 1: 4, 8: 90 } })
def test_generating_schedule_graph_geodataframe(network): gdfs = gngeojson.generate_geodataframes(network.schedule.graph()) nodes, links = gdfs['nodes'], gdfs['links'] correct_nodes = {'services': {'0': {'service'}, '1': {'service'}}, 'routes': {'0': {'1', '2'}, '1': {'1', '2'}}, 'id': {'0': '0', '1': '1'}, 'x': {'0': 529455.7452394223, '1': 529350.7866124967}, 'y': {'0': 182401.37630677427, '1': 182388.0201078112}, 'epsg': {'0': 'epsg:27700', '1': 'epsg:27700'}, 'lat': {'0': 51.525696033239186, '1': 51.52560003323918}, 'lon': {'0': -0.13530998708775874, '1': -0.13682698708848137}, 's2_id': {'0': 5221390668020036699, '1': 5221390668558830581}, 'linkRefId': {'0': '1', '1': '2'}, 'name': {'0': '', '1': ''} } correct_links = {'services': {0: {'service'}}, 'routes': {0: {'1', '2'}}, 'u': {0: '0'}, 'v': {0: '1'}} assert_semantically_equal(nodes[set(nodes.columns) - {'geometry'}].to_dict(), correct_nodes) assert_semantically_equal(links[set(links.columns) - {'geometry'}].to_dict(), correct_links) assert round(nodes.loc['0', 'geometry'].coords[:][0][0], 7) == round(529455.7452394223, 7) assert round(nodes.loc['0', 'geometry'].coords[:][0][1], 7) == round(182401.37630677427, 7) assert round(nodes.loc['1', 'geometry'].coords[:][0][0], 7) == round(529350.7866124967, 7) assert round(nodes.loc['1', 'geometry'].coords[:][0][1], 7) == round(182388.0201078112, 7) points = links.loc[0, 'geometry'].coords[:] assert round(points[0][0], 7) == round(529455.7452394223, 7) assert round(points[0][1], 7) == round(182401.37630677427, 7) assert round(points[1][0], 7) == round(529350.7866124967, 7) assert round(points[1][1], 7) == round(182388.0201078112, 7) assert nodes.crs == "EPSG:27700" assert links.crs == "EPSG:27700"
def test_generate_validation_report_with_correct_schedule(correct_schedule): correct_report = { 'schedule_level': { 'is_valid_schedule': True, 'invalid_stages': [], 'has_valid_services': True, 'invalid_services': [] }, 'service_level': { 'service': { 'is_valid_service': True, 'invalid_stages': [], 'has_valid_routes': True, 'invalid_routes': [] } }, 'route_level': { 'service': { '1': { 'is_valid_route': True, 'invalid_stages': [] }, '2': { 'is_valid_route': True, 'invalid_stages': [] } } } } report = schedule_validation.generate_validation_report(correct_schedule) assert_semantically_equal(report, correct_report)
def test_generating_network_graph_geodataframe(network): gdfs = gngeojson.generate_geodataframes(network.graph) nodes, links = gdfs['nodes'], gdfs['links'] correct_nodes = { 'x': {'0': 528704.1425925883, '1': 528804.1425925883}, 'y': {'0': 182068.78193707118, '1': 182168.78193707118}} correct_links = {'u': {'link_0': '0', 'link_1': '0', 'link_2': '1'}, 'v': {'link_0': '1', 'link_1': '1', 'link_2': '0'}, 'length': {'link_0': 123, 'link_1': 123, 'link_2': 123}, 'attributes': {'link_0': float('nan'), 'link_1': { 'osm:way:highway': {'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'unclassified'}}, 'link_2': float('nan')}, 'to': {'link_0': '1', 'link_1': '1', 'link_2': '0'}, 'from': {'link_0': '0', 'link_1': '0', 'link_2': '1'}, 'freespeed': {'link_0': 10.0, 'link_1': float('nan'), 'link_2': float('nan')}, 'id': {'link_0': 'link_0', 'link_1': 'link_1', 'link_2': 'link_2'}, 'capacity': {'link_0': 5.0, 'link_1': float('nan'), 'link_2': float('nan')}, 'modes': {'link_0': ['car', 'walk'], 'link_1': ['bike'], 'link_2': ['rail']}} assert_semantically_equal(nodes[set(nodes.columns) - {'geometry'}].to_dict(), correct_nodes) assert_semantically_equal(links[set(links.columns) - {'geometry'}].to_dict(), correct_links) assert round(nodes.loc['0', 'geometry'].coords[:][0][0], 7) == round(528704.1425925883, 7) assert round(nodes.loc['0', 'geometry'].coords[:][0][1], 7) == round(182068.78193707118, 7) assert round(nodes.loc['1', 'geometry'].coords[:][0][0], 7) == round(528804.1425925883, 7) assert round(nodes.loc['1', 'geometry'].coords[:][0][1], 7) == round(182168.78193707118, 7) points = links.loc['link_0', 'geometry'].coords[:] assert round(points[0][0], 7) == round(528704.1425925883, 7) assert round(points[0][1], 7) == round(182068.78193707118, 7) assert round(points[1][0], 7) == round(528804.1425925883, 7) assert round(points[1][1], 7) == round(182168.78193707118, 7) assert nodes.crs == "EPSG:27700" assert links.crs == "EPSG:27700"
def test_generate_validation_report_with_incorrect_schedule(test_schedule): correct_report = { 'schedule_level': { 'is_valid_schedule': False, 'invalid_stages': ['not_has_valid_services'], 'has_valid_services': False, 'invalid_services': ['service'] }, 'service_level': { 'service': { 'is_valid_service': False, 'invalid_stages': ['not_has_valid_routes'], 'has_valid_routes': False, 'invalid_routes': ['service_0', 'service_1'] } }, 'route_level': { 'service': { 'service_0': { 'is_valid_route': False, 'invalid_stages': ['not_has_correctly_ordered_route', 'has_self_loops'] }, 'service_1': { 'is_valid_route': False, 'invalid_stages': ['not_has_correctly_ordered_route', 'has_self_loops'] } } } } report = schedule_validation.generate_validation_report(test_schedule) assert_semantically_equal(report, correct_report)
def test_problem_with_isolated_catchment_finds_solution_for_viable_stops(mocker, network): closest_links = DataFrame({ 'id': {0: 'stop_2', 1: 'stop_2', 2: 'stop_3', 3: 'stop_3', 4: 'stop_1', 5: 'stop_1'}, 'link_id': {0: 'link_4_5_car', 1: 'link_5_6_car', 2: 'link_7_8_car', 3: 'link_8_9_car', 4: 'isolated_link_1', 5: 'isolated_link_2'}, }).set_index('id', drop=False) closest_links.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=closest_links) network.add_nodes({'node_iso_1': {'id': 'node_iso_1', 'x': 10, 'y': 20, 'lat': 49.8, 'lon': -7.5, 's2_id': 5205973754090365183}, 'node_iso_2': {'id': 'node_iso_2', 'x': 10, 'y': 30, 'lat': 49.9, 'lon': -7.6, 's2_id': 5205973754090333257}}) network.add_link('isolated_link_1', u='node_iso_1', v='node_iso_2', attribs={'modes': {'car', 'bus'}}) network.add_link('isolated_link_2', u='node_iso_2', v='node_iso_1', attribs={'modes': {'car', 'bus'}}) mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=spatial.SpatialTree(network), modes={'car', 'bus'}, distance_threshold=10, step_size=10) mss.solve() assert mss.solution == {'stop_2': 'link_5_6_car', 'stop_3': 'link_7_8_car'} assert_semantically_equal(mss.artificial_stops, { 'stop_2.link:link_5_6_car': {'services': {'bus_service'}, 'routes': {'service_1_route_2', 'service_1_route_1'}, 'id': 'stop_2.link:link_5_6_car', 'x': 2.0, 'y': 2.5, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.557134732217642, 'lat': 49.76683094462549, 's2_id': 5205973754090230267, 'linkRefId': 'link_5_6_car', 'stop_id': 'stop_2'}, 'stop_3.link:link_7_8_car': {'services': {'bus_service'}, 'routes': {'service_1_route_2', 'service_1_route_1'}, 'id': 'stop_3.link:link_7_8_car', 'x': 5.5, 'y': 2.0, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.55708584676138, 'lat': 49.76682879603468, 's2_id': 5205973754096513977, 'linkRefId': 'link_7_8_car', 'stop_id': 'stop_3'}})
def test_splitting_service_on_direction_finds_two_distinct_directions( basic_service): service_split = basic_service.split_by_direction() assert_semantically_equal(service_split, { 'North-East Bound': ['1', '2', '3'], 'South-West Bound': ['4'] })
def test_solving_problem_with_isolated_catchments(mocker, network, network_spatial_tree): closest_links = DataFrame({ 'id': {0: 'stop_2', 1: 'stop_2', 2: 'stop_3', 3: 'stop_3', 4: 'stop_1', 5: 'stop_1', 6: 'stop_1'}, 'link_id': {0: 'link_4_5_car', 1: 'link_5_6_car', 2: 'link_7_8_car', 3: 'link_8_9_car', 4: 'link_1_2_car', 5: 'link_1_2_bus', 6: 'link_2_3_car'} }).set_index('id', drop=False) closest_links.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=closest_links) mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=network_spatial_tree, modes={'car', 'bus'}) mss.solve() assert mss.solution == {'stop_1': 'link_1_2_bus', 'stop_2': 'link_4_5_car', 'stop_3': 'link_7_8_car'} assert_semantically_equal(mss.artificial_stops, { 'stop_1.link:link_1_2_bus': {'services': {'bus_service'}, 'routes': {'service_1_route_2', 'service_1_route_1'}, 'id': 'stop_1.link:link_1_2_bus', 'x': 1.0, 'y': 2.5, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.557148552832129, 'lat': 49.76683027967191, 's2_id': 5205973754090340691, 'linkRefId': 'link_1_2_bus', 'stop_id': 'stop_1'}, 'stop_2.link:link_4_5_car': {'services': {'bus_service'}, 'routes': {'service_1_route_2', 'service_1_route_1'}, 'id': 'stop_2.link:link_4_5_car', 'x': 2.0, 'y': 2.5, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.557134732217642, 'lat': 49.76683094462549, 's2_id': 5205973754090230267, 'linkRefId': 'link_4_5_car', 'stop_id': 'stop_2'}, 'stop_3.link:link_7_8_car': {'services': {'bus_service'}, 'routes': {'service_1_route_2', 'service_1_route_1'}, 'id': 'stop_3.link:link_7_8_car', 'x': 5.5, 'y': 2.0, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.55708584676138, 'lat': 49.76682879603468, 's2_id': 5205973754096513977, 'linkRefId': 'link_7_8_car', 'stop_id': 'stop_3'}})
def test_sending_requests(mocker, google_directions_api_response): mocker.patch.object(time, 'time', return_value=12345) mocker.patch.object(secrets_vault, 'get_google_directions_api_key', return_value='super_awesome_key') mocker.patch.object(google_directions, 'make_request', return_value=google_directions_api_response) api_requests = { (1, 10): {'path_nodes': (1, 10), 'path_polyline': '_ibE_seK??', 'origin': {'lat': 1, 'lon': 2}, 'destination': {'lat': 1, 'lon': 2}}, (1, 3): {'path_nodes': [1, 2, 3], 'path_polyline': '_ibE_seK????', 'origin': {'lat': 1, 'lon': 2}, 'destination': {'lat': 1, 'lon': 2}}, (5, 3): {'path_nodes': [5, 4, 3], 'path_polyline': '_ibE_seK????', 'origin': {'lat': 1, 'lon': 2}, 'destination': {'lat': 1, 'lon': 2}}} api_requests = google_directions.send_requests(api_requests) assert_semantically_equal(api_requests, { (1, 10): {'path_nodes': (1, 10), 'path_polyline': '_ibE_seK??', 'origin': {'lat': 1, 'lon': 2}, 'destination': {'lat': 1, 'lon': 2}, 'request': google_directions_api_response, 'timestamp': 12345}, (1, 3): {'path_nodes': [1, 2, 3], 'path_polyline': '_ibE_seK????', 'origin': {'lat': 1, 'lon': 2}, 'destination': {'lat': 1, 'lon': 2}, 'request': google_directions_api_response, 'timestamp': 12345}, (5, 3): {'path_nodes': [5, 4, 3], 'path_polyline': '_ibE_seK????', 'origin': {'lat': 1, 'lon': 2}, 'destination': {'lat': 1, 'lon': 2}, 'request': google_directions_api_response, 'timestamp': 12345}})
def test_merging_dictionaries_with_nested_lists(): return_d = dict_support.merge_complex_dictionaries( { 'a': 1, 'b': { 'a': [3, 6] }, 'c': { 'b': [1] } }, { 'b': { 'a': [5] }, 'c': { 'b': [8, 90] } }) assert_semantically_equal(return_d, { 'a': 1, 'b': { 'a': [3, 6, 5] }, 'c': { 'b': [8, 90, 1] } })
def test_reproject_stops_with_transformer(): a = Stop(id='0', x=528504.1342843144, y=182155.7435136598, epsg='epsg:27700') transformer = Transformer.from_proj(Proj('epsg:27700'), Proj('epsg:4326'), always_xy=True) a.reproject('epsg:4326', transformer) correct_lat = 51.52370573323939 correct_lon = -0.14910908709500162 assert_semantically_equal({ 'x': a.x, 'y': a.y }, { 'x': correct_lon, 'y': correct_lat }) assert round(a.lat, SPATIAL_TOLERANCE) == round(correct_lat, SPATIAL_TOLERANCE) assert round(a.lon, SPATIAL_TOLERANCE) == round(correct_lon, SPATIAL_TOLERANCE) assert a.epsg == 'epsg:4326'
def test_merging_dictionaries_with_nested_sets(): return_d = dict_support.merge_complex_dictionaries( { 'a': 1, 'b': { 'a': {3, 6} }, 'c': { 'b': {1} } }, { 'b': { 'a': {5} }, 'c': { 'b': {8, 90} } }) assert_semantically_equal(return_d, { 'a': 1, 'b': { 'a': {3, 6, 5} }, 'c': { 'b': {8, 90, 1} } })
def test_mapping_results_to_edges_with_overlapping_edges(): api_requests = {('107316', '107352'): { 'path_nodes': ['107316', '2440643031', '4307345276', '107317', '4307345495', '4307345497', '25495448', '2503102618', '107351', '5411344775', '2440651577', '2440651556', '2440651552', '107352'], 'path_polyline': 'ahmyHzvYGJyBbCGHq@r@EDIJGBu@~@SToAzAEFEDIJ', 'origin': {'lat': 51.5188864, 'lon': -0.1369442}, 'destination': {'lat': 51.5208299, 'lon': -0.1391027}, 'timestamp': 12345, 'parsed_response': {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}}, ('107316', '4307345276'): { 'path_nodes': ['107316', '2440643031', '4307345276'], 'path_polyline': 'ahmyHzvYkC', 'origin': {'lat': 51.5188864, 'lon': -0.1369442}, 'destination': {'lat': 51.5195381, 'lon': -0.1376626}, 'parsed_response': {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCv'} }} google_dir_api_edge_data = google_directions.map_results_to_edges(api_requests) assert_semantically_equal(google_dir_api_edge_data, { ('2440643031', '4307345276'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('4307345276', '107317'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('25495448', '2503102618'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('107316', '2440643031'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('4307345495', '4307345497'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('2440651556', '2440651552'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('107317', '4307345495'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('107351', '5411344775'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('2440651577', '2440651556'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('2503102618', '107351'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('4307345497', '25495448'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('2440651552', '107352'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}, ('5411344775', '2440651577'): {'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB'}})
def test_partial_mss_problem_genrates_new_stops_with_linkrefids(partial_mss): changeset = partial_mss.to_changeset( DataFrame({'ordered_stops': {'service_1_route_2': ['stop_3', 'stop_2', 'stop_1'], 'service_1_route_1': ['stop_1', 'stop_2', 'stop_3']}}) ) assert_semantically_equal( changeset.new_stops, {'stop_2.link:link_5_6_car': {'services': {'bus_service'}, 'routes': {'service_1_route_1', 'service_1_route_2'}, 'id': 'stop_2.link:link_5_6_car', 'x': 2.0, 'y': 2.5, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.557134732217642, 'lat': 49.76683094462549, 's2_id': 5205973754090230267, 'additional_attributes': set(), 'linkRefId': 'link_5_6_car', 'stop_id': 'stop_2'}, 'stop_3.link:link_7_8_car': {'services': {'bus_service'}, 'routes': {'service_1_route_1', 'service_1_route_2'}, 'id': 'stop_3.link:link_7_8_car', 'x': 5.5, 'y': 2.0, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.55708584676138, 'lat': 49.76682879603468, 's2_id': 5205973754096513977, 'additional_attributes': set(), 'linkRefId': 'link_7_8_car', 'stop_id': 'stop_3'}, 'stop_1.link:artificial_link===from:stop_1===to:stop_1': {'services': {'bus_service'}, 'routes': {'service_1_route_1', 'service_1_route_2'}, 'id': 'stop_1.link:artificial_link===from:stop_1===to:stop_1', 'x': 1.0, 'y': 2.5, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.557148552832129, 'lat': 49.76683027967191, 's2_id': 5205973754090340691, 'additional_attributes': set(), 'linkRefId': 'artificial_link===from:stop_1===to:stop_1', 'stop_id': 'stop_1'}})
def test_splitting_service_on_direction_with_loopy_routes(service_with_loopy_routes): service_split = service_with_loopy_routes.split_by_direction() # loopy services are a bit disappointing right now, can't win them all I guess :( assert_semantically_equal(service_split, {'South-West Bound': ['1_dir_1'], 'West Bound': ['2_dir_1'], 'North-West Bound': ['3_dir_2', '4_dir_2']})
def test_get_attribute_data_under_key_with_nested_link_data_and_nested_key(): input_list = [('0', { 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }), ('1', { 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'secondary' } } })] data = graph_operations.get_attribute_data_under_key( input_list, {'attributes': { 'osm:way:highway': 'text' }}) assert_semantically_equal(data, {'0': 'primary', '1': 'secondary'})
def test_adding_services_to_nodes(schedule): schedule._add_services_to_nodes(nodes={'2'}, service_ids={'new_service'}) assert_semantically_equal( dict(schedule._graph.nodes(data='services')), {'4': {'service2'}, '5': {'service2'}, '3': {'service2'}, '0': {'service1'}, '2': {'service1', 'new_service'}, '1': {'service1'}} )
def test_saving_network_with_correct_attributes_and_geometry(tmpdir): # attributes are assumed to be a nested dictionary of very specific format. Due to the fact that user can # do virtually anything to edge attributes, or due to calculation error, this may not be the case. If it's not # of correct format, we don't expect it to get saved to the matsim network.xml network = Network('epsg:27700') network.add_node('0', attribs={ 'id': '0', 'x': 1, 'y': 2, 'lat': 1, 'lon': 2 }) network.add_node('1', attribs={ 'id': '1', 'x': 2, 'y': 2, 'lat': 2, 'lon': 2 }) link_attribs = { 'id': '0', 'from': '0', 'to': '1', 'length': 1, 'freespeed': 1, 'capacity': 20, 'permlanes': 1, 'oneway': '1', 'modes': ['car'], 'geometry': LineString([(1, 2), (2, 3), (3, 4)]), 'attributes': { 'osm:way:lanes': { 'name': 'osm:way:lanes', 'class': 'java.lang.String', 'text': '3' } } } network.add_link('0', '0', '1', attribs=link_attribs) network.write_to_matsim(tmpdir) assert_semantically_equal(dict(network.links()), {'0': link_attribs}) assert_semantically_equal( matsim_xml_writer.check_link_attributes(link_attribs), link_attribs) found_geometry_attrib = False for event, elem in ET.iterparse(os.path.join(tmpdir, 'network.xml'), events=('start', 'end')): if event == 'start': if elem.tag == 'attribute': if elem.attrib['name'] == 'geometry': assert elem.text == '_ibE_seK_ibE_ibE_ibE_ibE' found_geometry_attrib = True assert found_geometry_attrib
def test_splitting_service_edge_case_on_direction_results_in_two_directions( service_edge_case_loopy_and_non_overlapping_graph): service_split = service_edge_case_loopy_and_non_overlapping_graph.split_by_direction( ) assert_semantically_equal(service_split, { 'West Bound': ['1_dir_1', '3_dir_1', '4_dir_1'], 'East Bound': ['2_dir_2'] })
def test_removing_services_from_edges(schedule): schedule._remove_services_from_edges(edges={('1', '2')}, service_ids={'service1'}) assert_semantically_equal( schedule._graph.edges._adjdict, {'4': {'5': {'services': {'service2'}, 'routes': {'4'}}}, '5': {}, '3': {'4': {'services': {'service2'}, 'routes': {'3'}}}, '2': {}, '1': {'2': {'services': set(), 'routes': {'2'}}}, '0': {'1': {'services': {'service1'}, 'routes': {'1'}}}} )
def test_parsing_routes_with_bad_request( caplog, bad_request_google_directions_api_response): with caplog.at_level(logging.INFO): data = google_directions.parse_routes( bad_request_google_directions_api_response, 'ahmyHzvYkCvCuCdDcBrB') assert_semantically_equal(data, {}) assert_logging_warning_caught_with_message_containing( caplog, 'Request was not successful.')
def test_schedule_subgraph(schedule): sub_g = schedule.subgraph({('1', '2'), ('0', '1')}) assert_semantically_equal(list(sub_g.edges(data=True)), [('1', '2', { 'services': ['service1'], 'routes': ['2'], 'modes': ['bus'] }), ('0', '1', { 'services': ['service1'], 'routes': ['1'], 'modes': ['bus'] })]) assert_semantically_equal( dict(sub_g.nodes(data=True)), { '1': { 'services': ['service1'], 'routes': ['2', '1'], 'id': '1', 'x': 529350.7866124967, 'y': 182388.0201078112, 'epsg': 'epsg:27700', 'lat': 51.52560003323918, 'lon': -0.13682698708848137, 's2_id': 5221390668558830581, 'additional_attributes': ['linkRefId'], 'linkRefId': '1' }, '2': { 'services': ['service1'], 'routes': ['2'], 'id': '2', 'x': 529350.7866124967, 'y': 182388.0201078112, 'epsg': 'epsg:27700', 'lat': 51.52560003323918, 'lon': -0.13682698708848137, 's2_id': 5221390668558830581, 'additional_attributes': ['linkRefId'], 'linkRefId': '2' }, '0': { 'services': ['service1'], 'routes': ['1'], 'id': '0', 'x': 529455.7452394223, 'y': 182401.37630677427, 'epsg': 'epsg:27700', 'lat': 51.525696033239186, 'lon': -0.13530998708775874, 's2_id': 5221390668020036699, 'additional_attributes': ['linkRefId'], 'linkRefId': '0' } })
def test_parsing_routes_with_a_good_response(google_directions_api_response, generated_request): data = google_directions.parse_routes(google_directions_api_response, generated_request['path_polyline']) assert_semantically_equal( data, { 'google_speed': 3.7183098591549295, 'google_polyline': 'ahmyHzvYkCvCuCdDcBrB' })
def test_adding_services_to_edges(schedule): schedule._add_services_to_edges(edges={('1', '2')}, service_ids={'new_service'}) assert_semantically_equal( schedule._graph.edges._adjdict, {'4': {'5': {'services': {'service2'}, 'routes': {'4'}}}, '5': {}, '3': {'4': {'services': {'service2'}, 'routes': {'3'}}}, '0': {'1': {'services': {'service1'}, 'routes': {'1'}}}, '1': {'2': {'services': {'service1', 'new_service'}, 'routes': {'2'}}}, '2': {}} )
def test_assume_travel_modes_works_with_other_non_nested_tags( full_fat_default_config): modes_to_assume = ['rail'] full_fat_default_config.MODE_INDICATORS['railway'] = modes_to_assume edge = {'osmid': 0, 'nodes': [0, 1], 'railway': 'yassss'} assumed_modes = osm_reader.assume_travel_modes(edge, full_fat_default_config) assert_semantically_equal(assumed_modes, modes_to_assume)
def test_updating_route_trips_with_headway(route): route.generate_trips_from_headway({('01:00:00', '02:00:00'): 20, ('02:00:00', '03:00:00'): 30}) assert_semantically_equal( route.trips, {'trip_id': ['1_01:00:00', '1_01:20:00', '1_01:40:00', '1_02:00:00', '1_02:30:00', '1_03:00:00'], 'trip_departure_time': ['01:00:00', '01:20:00', '01:40:00', '02:00:00', '02:30:00', '03:00:00'], 'vehicle_id': ['veh_bus_1_01:00:00', 'veh_bus_1_01:20:00', 'veh_bus_1_01:40:00', 'veh_bus_1_02:00:00', 'veh_bus_1_02:30:00', 'veh_bus_1_03:00:00']} )
def test_splitting_service_on_direction_with_non_overlapping_graph_edges_produces_two_directions( service_with_routes_that_have_non_overlapping_graph_edges): service_split = service_with_routes_that_have_non_overlapping_graph_edges.split_by_direction( ) assert_semantically_equal( service_split, { 'North Bound': ['1_dir_1', '2_dir_1'], 'South Bound': ['3_dir_2', '4_dir_2'] })
def test_partial_mss_problem_generates_new_network_nodes_from_unsnapped_stops(partial_mss): changeset = partial_mss.to_changeset( DataFrame({'ordered_stops': {'service_1_route_2': ['stop_3', 'stop_2', 'stop_1'], 'service_1_route_1': ['stop_1', 'stop_2', 'stop_3']}}) ) assert_semantically_equal( changeset.new_nodes, {'stop_1': {'id': 'stop_1', 'x': 1.0, 'y': 2.5, 'name': '', 'lon': -7.557148552832129, 'lat': 49.76683027967191, 's2_id': 5205973754090340691}})