def test_SpatialTree_shortest_path_lengths(network): spatial_tree = spatial.SpatialTree(network) df = DataFrame({ 'u': ['link_1', 'link_2', 'link_2', 'link_1'], 'v': ['link_2', 'link_3', 'link_4', 'link_4'] }) df = spatial_tree.shortest_path_lengths(df, modes='car') assert_semantically_equal( df.T.to_dict(), { 0: { 'u': 'link_1', 'v': 'link_2', 'path_lengths': 153.0294 }, 1: { 'u': 'link_2', 'v': 'link_3', 'path_lengths': float('nan') }, 2: { 'u': 'link_2', 'v': 'link_4', 'path_lengths': 78.443 }, 3: { 'u': 'link_1', 'v': 'link_4', 'path_lengths': 231.4724 } })
def test_SpatialTree_closest_links_in_london_finds_links_within_30_metres( network): spatial_tree = spatial.SpatialTree(network).modal_subtree(modes='car') stops = GeoDataFrame({ 'id': { 0: 'stop_10m_to_link_1', 1: 'stop_15m_to_link_2', 2: 'stop_20m_to_link_1' }, 'geometry': { 0: Point(-0.15186089346604492, 51.51950409732838), 1: Point(-0.15164747576623197, 51.520660715220636), 2: Point(-0.1520233977548685, 51.51952913606585) } }) stops.crs = {'init': 'epsg:4326'} closest_links = spatial_tree.closest_links(stops, 30) assert_semantically_equal( closest_links.reset_index().groupby('id')['link_id'].apply( list).to_dict(), { 'stop_10m_to_link_1': ['link_1'], 'stop_20m_to_link_1': ['link_1'], 'stop_15m_to_link_2': ['link_2', 'link_4'] })
def test_SpatialTree_shortest_paths(network): spatial_tree = spatial.SpatialTree(network) df = DataFrame({ 'u': ['link_1', 'link_2', 'link_2', 'link_1'], 'v': ['link_2', 'link_3', 'link_4', 'link_4'] }) df = spatial_tree.shortest_paths(df, modes='car') assert_semantically_equal( df.T.to_dict(), { 0: { 'u': 'link_1', 'v': 'link_2', 'shortest_path': ['link_1', 'link_2'] }, 1: { 'u': 'link_2', 'v': 'link_3', 'shortest_path': None }, 2: { 'u': 'link_2', 'v': 'link_4', 'shortest_path': ['link_2', 'link_4'] }, 3: { 'u': 'link_1', 'v': 'link_4', 'shortest_path': ['link_1', 'link_2', 'link_4'] } })
def test_SpatialTree_closest_links_in_north_canada_doesnt_find_link_within_10_metres( ): # (out in the boonies) n = Network('epsg:4326') n.add_nodes({ '1': { 'x': -93.25129666354827, 'y': 73.66401680598872 }, '2': { 'x': -93.25140295754169, 'y': 73.66417415921647 } }) n.add_link(link_id='link_1', u='1', v='2', attribs={'modes': ['car']}) spatial_tree = spatial.SpatialTree(n) stops = GeoDataFrame( {'geometry': { 'stop_15m_to_link_1': Point(-93.250971, 73.664114) }}) stops.crs = {'init': 'epsg:4326'} closest_links = spatial_tree.closest_links(stops, 10, modes='car') closest_links = closest_links.dropna() assert closest_links.empty
def test_SpatialTree_closest_links_in_north_canada_finds_link_within_30_metres( ): # (out in the boonies) n = Network('epsg:4326') n.add_nodes({ '1': { 'x': -93.25129666354827, 'y': 73.66401680598872 }, '2': { 'x': -93.25140295754169, 'y': 73.66417415921647 } }) n.add_link(link_id='link_1', u='1', v='2', attribs={'modes': ['car']}) spatial_tree = spatial.SpatialTree(n) stops = GeoDataFrame( {'geometry': { 'stop_15m_to_link_1': Point(-93.250971, 73.664114) }}) stops.crs = {'init': 'epsg:4326'} closest_links = spatial_tree.closest_links(stops, 30, modes='car') assert_semantically_equal( closest_links.reset_index().groupby('index')['link_id'].apply( list).to_dict(), {'stop_15m_to_link_1': ['link_1']})
def test_SpatialTree_closest_links_in_indonesia_doesnt_find_link_within_10_metres( ): # (close to equator) n = Network('epsg:4326') n.add_nodes({ '1': { 'x': 109.380477773586, 'y': 0.3203433505415778 }, '2': { 'x': 109.38042852136014, 'y': 0.32031507655538294 } }) n.add_link(link_id='link_1', u='1', v='2', attribs={'modes': ['car']}) spatial_tree = spatial.SpatialTree(n) stops = GeoDataFrame( {'geometry': { 'stop_15m_to_link_1': Point(109.380607, 0.320333) }}) stops.crs = {'init': 'epsg:4326'} closest_links = spatial_tree.closest_links(stops, 10, modes='car') closest_links = closest_links.dropna() assert closest_links.empty
def test_SpatialTree_closest_links_in_indonesia_finds_link_within_20_metres(): # (close to equator) n = Network('epsg:4326') n.add_nodes({ '1': { 'x': 109.380477773586, 'y': 0.3203433505415778 }, '2': { 'x': 109.38042852136014, 'y': 0.32031507655538294 } }) n.add_link(link_id='link_1', u='1', v='2', attribs={'modes': ['car']}) spatial_tree = spatial.SpatialTree(n) stops = GeoDataFrame( {'geometry': { 'stop_15m_to_link_1': Point(109.380607, 0.320333) }}) stops.crs = {'init': 'epsg:4326'} closest_links = spatial_tree.closest_links(stops, 20, modes='car') closest_links = closest_links.dropna() assert_semantically_equal( closest_links.reset_index().groupby('index')['link_id'].apply( list).to_dict(), {'stop_15m_to_link_1': ['link_1']})
def test_SpatialTree_roots(): spatial_tree = spatial.SpatialTree() links = [('1', {'id': "1", 'from': "25508485", 'to': "21667818", 'length': 52.765151087870265, 's2_from': 5221390301001263407, 's2_to': 5221390302696205321, 'modes': ['subway,metro', 'walk', 'car']}), ('2', {'id': "2", 'from': "25508485", 'to': "21667818", 'length': 52.765151087870265, 's2_from': 5221390301001263407, 's2_to': 5221390302696205321, 'modes': ['bike', 'walk', 'piggy_back']})] spatial_tree.add_links(links=links) assert spatial_tree.roots() == [0]
def test_SpatialTree_closest_edges(): spatial_tree = spatial.SpatialTree() links = [('1', {'id': "1", 'from': "25508485", 'to': "21667818", 'length': 52.765151087870265, 's2_from': 5221390301001263407, 's2_to': 5221390302696205321, 'modes': ['subway,metro', 'walk', 'car']}), ('2', {'id': "2", 'from': "25508485", 'to': "21667818", 'length': 52.765151087870265, 's2_from': 5221390301001263407, 's2_to': 5221390302696205321, 'modes': ['bike', 'walk', 'piggy_back']}) ] spatial_tree.add_links(links=links) assert_semantically_equal(spatial_tree.find_closest_links(5221390301001263407, 30), ['1', '2'])
def partial_mss(network): 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.solution = {'stop_2': 'link_5_6_car', 'stop_3': 'link_7_8_car', 'stop_1': 'artificial_link===from:stop_1===to:stop_1'} mss.artificial_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'}} mss.artificial_links = { 'artificial_link===from:stop_1===to:stop_1': {'from': 'stop_1', 'to': 'stop_1', 'modes': {'bus'}}, 'artificial_link===from:node_6===to:stop_1': {'from': 'node_6', 'to': 'stop_1', 'modes': {'bus'}}, 'artificial_link===from:stop_1===to:node_5': {'from': 'stop_1', 'to': 'node_5', 'modes': {'bus'}}} mss.pt_edges = DataFrame( {'services': {0: {'bus_service'}, 1: {'bus_service'}, 2: {'bus_service'}, 3: {'bus_service'}}, 'routes': {0: {'service_1_route_2'}, 1: {'service_1_route_2'}, 2: {'service_1_route_1'}, 3: {'service_1_route_1'}}, 'u': {0: 'stop_3', 1: 'stop_2', 2: 'stop_2', 3: 'stop_1'}, 'v': {0: 'stop_2', 1: 'stop_1', 2: 'stop_3', 3: 'stop_2'}, 'key': {0: 0, 1: 0, 2: 0, 3: 0}, 'linkRefId_u': {0: 'link_7_8_car', 1: 'link_5_6_car', 2: 'link_5_6_car', 3: 'artificial_link===from:stop_1===to:stop_1'}, 'linkRefId_v': {0: 'link_5_6_car', 1: 'artificial_link===from:stop_1===to:stop_1', 2: 'link_7_8_car', 3: 'link_5_6_car'}, 'shortest_path': {0: ['link_7_8_car', 'link_8_7_car', 'link_7_6_car', 'link_6_5_car', 'link_5_6_car'], 1: ['link_5_6_car', 'artificial_link===from:node_6===to:stop_1', 'artificial_link===from:stop_1===to:stop_1'], 2: ['link_5_6_car', 'link_6_7_car', 'link_7_8_car'], 3: ['artificial_link===from:stop_1===to:stop_1', 'artificial_link===from:stop_1===to:node_5', 'link_5_6_car']}}) mss.unsolved_stops = {'stop_1'} return mss
def test_SpatialTree_adds_a_link(): link, link_attrib = ('1', { 'id': "1", 'from': "25508485", 'to': "21667818", 'length': 52.765151087870265, 's2_from': 5221390301001263407, 's2_to': 5221390302696205321, 'freespeed': "4.166666666666667", 'capacity': "600.0", 'permlanes': "1.0", 'oneway': "1", 'modes': ['subway,metro', 'walk', 'car'], 'attributes': { 'osm:way:access': {'name': 'osm:way:access', 'class': 'java.lang.String', 'text': 'permissive'}, 'osm:way:highway': {'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'unclassified'}, 'osm:way:id': {'name': 'osm:way:id', 'class': 'java.lang.Long', 'text': '26997928'}, 'osm:way:name': {'name': 'osm:way:name', 'class': 'java.lang.String', 'text': 'Brunswick Place'} }}) spatial_tree = spatial.SpatialTree([(link, link_attrib)]) assert list(spatial_tree.edges) == [(5221390298638188544, '1'), (5764607523034234880, 5221642292959379456), (5221642292959379456, 5221378410168713216), (5221378410168713216, 5221390298638188544), (0, 5764607523034234880)] for node, node_attrib in list(spatial_tree.nodes(data=True)): assert_semantically_equal(node_attrib, link_attrib)
def test_build_graph_for_maximum_stable_set_problem_with_no_path_between_isolated_node(mocker, network): 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: 'isolated_link', 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) 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', u='node_iso_1', v='node_iso_2', 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) assert_semantically_equal(dict(mss.problem_graph.nodes()), {'stop_2.link:link_4_5_car': {'id': 'stop_2', 'link_id': 'link_4_5_car', 'catchment': 10, 'coeff': 0.26666666666666666}, 'stop_2.link:link_5_6_car': {'id': 'stop_2', 'link_id': 'link_5_6_car', 'catchment': 10, 'coeff': 0.26666666666666666}, 'stop_3.link:link_7_8_car': {'id': 'stop_3', 'link_id': 'link_7_8_car', 'catchment': 10, 'coeff': 0.2857142857142857}, 'stop_3.link:link_8_9_car': {'id': 'stop_3', 'link_id': 'link_8_9_car', 'catchment': 10, 'coeff': 0.2222222222222222}, 'stop_1.link:link_1_2_bus': {'id': 'stop_1', 'link_id': 'link_1_2_bus', 'catchment': 10, 'coeff': 0.2857142857142857}, 'stop_1.link:link_2_3_car': {'id': 'stop_1', 'link_id': 'link_2_3_car', 'catchment': 10, 'coeff': 0.2857142857142857}}) assert_semantically_equal(list(mss.problem_graph.edges()), [('stop_2.link:link_4_5_car', 'stop_2.link:link_5_6_car'), ('stop_3.link:link_7_8_car', 'stop_3.link:link_8_9_car'), ('stop_1.link:link_1_2_bus', 'stop_1.link:link_2_3_car')])
def test_SpatialTree_adds_links(network): spatial_tree = spatial.SpatialTree(network) assert_semantically_equal(list(spatial_tree.edges(data=True)), [('link_1', 'link_2', { 'length': 153.0294 }), ('link_1', 'link_3', { 'length': 153.0294 }), ('link_2', 'link_4', { 'length': 78.443 }), ('link_3', 'link_4', { 'length': 78.443 }), ('link_4', 'link_2', { 'length': 78.443 }), ('link_4', 'link_3', { 'length': 78.443 })]) assert_semantically_equal(dict(spatial_tree.nodes(data=True)), { 'link_1': {}, 'link_2': {}, 'link_3': {}, 'link_4': {} })
def test_problem_with_isolated_catchment_is_partially_viable(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) assert mss.is_partially_viable()
def test_SpatialTree_combines_link_list_attribs(): spatial_tree = spatial.SpatialTree() links = [('1', {'id': "1", 'from': "25508485", 'to': "21667818", 'length': 52.765151087870265, 's2_from': 5221390301001263407, 's2_to': 5221390302696205321, 'modes': ['subway,metro', 'walk', 'car']}), ('2', {'id': "2", 'from': "25508485", 'to': "21667818", 'length': 52.765151087870265, 's2_from': 5221390301001263407, 's2_to': 5221390302696205321, 'modes': ['bike', 'walk', 'piggy_back']})] spatial_tree.add_links(links=links) assert_semantically_equal(list(spatial_tree.edges), [(5221390298638188544, '1'), (5221390298638188544, '2'), (5764607523034234880, 5221642292959379456), (5221642292959379456, 5221378410168713216), (5221378410168713216, 5221390298638188544), (0, 5764607523034234880)]) for node, node_attrib in list(spatial_tree.nodes(data=True)): if node not in ['1', '2']: assert set(node_attrib['modes']) == {'subway,metro', 'car', 'bike', 'walk', 'piggy_back'} elif node == '1': assert set(node_attrib['modes']) == {'subway,metro', 'walk', 'car'} elif node == '2': assert set(node_attrib['modes']) == {'bike', 'walk', 'piggy_back'}
def test_subsetting_links_df_by_mode_that_isnt_present_throws_error(network): spatial_tree = spatial.SpatialTree(network) with pytest.raises(EmptySpatialTree) as e: df = spatial_tree.modal_links_geodataframe(modes={'piggyback'}) assert 'No links found' in str(e.value)
def network_spatial_tree(network): return spatial.SpatialTree(network)
def test_spatialtree(test_network): return spatial.SpatialTree(test_network)
def test_subsetting_links_df_by_mode(network): spatial_tree = spatial.SpatialTree(network) df = spatial_tree.modal_links_geodataframe(modes={'car'}) assert set(df['link_id']) == {'link_1', 'link_2', 'link_4'}