def network_object(): network_xml_path = os.path.abspath( os.path.join(os.path.dirname(__file__), "test_data/road_pricing/network.xml")) n = Network(epsg='epsg:27700') n.read_matsim_network(network_xml_path) yield n
def test_consolidating_node_ids_does_nothing_to_matching_nodes_in_matching_coordinate_system( ): n_left = Network('epsg:27700') n_left.epsg = 'epsg:27700' n_left.add_node( '101982', { 'id': '101982', 'x': '528704.1425925883', 'y': '182068.78193707118', 'lon': -0.14625948709424305, 'lat': 51.52287873323954, 's2_id': 5221390329378179879 }) n_right = Network('epsg:27700') n_right.epsg = 'epsg:27700' n_right.add_node( '101982', { 'id': '101982', 'x': '528704.1425925883', 'y': '182068.78193707118', 'lon': -0.14625948709424305, 'lat': 51.52287873323954, 's2_id': 5221390329378179879 }) output_n_right = graph_operations.consolidate_node_indices(n_left, n_right) assert output_n_right.graph.has_node('101982') assert output_n_right.node('101982') == { 'id': '101982', 'x': '528704.1425925883', 'y': '182068.78193707118', 'lon': -0.14625948709424305, 'lat': 51.52287873323954, 's2_id': 5221390329378179879 }
def test_extract_graph_links_with_flat_condition(): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_link('1', 2, 3, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_link('2', 3, 4, attribs={'attributes': 'yes'}) links = graph_operations.extract_on_attributes( n.links(), conditions={'attributes': 'yes'}, ) assert links == ['2']
def test_extract_graph_links_with_flat_condition_and_list_value_specifying_to_ignore_mixed_types( ): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_link('1', 2, 3, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_link('2', 3, 4, attribs={'attributes': ['yes', 'no', 'bobby']}) links = graph_operations.extract_on_attributes( n.links(), conditions={'attributes': 'yes'}, mixed_dtypes=False) assert links == []
def test_saving_network_with_geometry_produces_polyline_if_link_already_has_other_attributes( tmpdir): 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 }) network.add_link('0', '0', '1', 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.write_to_matsim(tmpdir) 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_generating_requests_on_non_simplified_graphs(): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={'modes': ['car']}) n.add_link('1', 2, 3, attribs={'modes': ['car']}) n.add_link('2', 4, 3, attribs={'modes': ['car']}) n.add_link('3', 5, 4, attribs={'modes': ['car']}) n.add_link('4', 1, 10, attribs={'modes': ['car']}) for node in n.graph.nodes: n.apply_attributes_to_node(node, {'lat': 1, 'lon': 2}) api_requests = google_directions.generate_requests(n) 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 } }, (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 } } })
def test_extract_graph_nodes_with_callable_condition(): n = Network('epsg:27700') n.add_node( 1, { 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 9 } } }) n.add_node( 2, { 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 1 } } }) n.add_node(3, {'attributes': 'yes'}) def condition(val): return val == 9 nodes = graph_operations.extract_nodes_on_node_attributes( n, conditions={'attributes': { 'osm:way:highway': { 'text': condition } }}) assert nodes == [1]
def test_extract_graph_nodes_with_list_condition_with(): n = Network('epsg:27700') n.add_node( 1, { 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_node( 2, { 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_node(3, {'attributes': 'yes'}) nodes = graph_operations.extract_nodes_on_node_attributes( n, conditions={ 'attributes': { 'osm:way:highway': { 'text': ['primary', 'some_other_highway'] } } }) assert nodes == [1, 2]
def test_send_requests_for_road_network(mocker, tmpdir, generated_request, google_directions_api_response): mocker.patch.object(google_directions, 'generate_requests', return_value={('107316', '107352'): generated_request}) mocker.patch.object(google_directions, 'send_requests', return_value={ ('107316', '107352'): { **generated_request, **{ 'request': Future(), 'timestamp': 12345 } } }) mocker.patch.object(Future, 'result', return_value=google_directions_api_response) n = Network('epsg:27700') google_directions.send_requests_for_network(n, 10, tmpdir, None) google_directions.generate_requests.assert_called_once_with(n) google_directions.send_requests.assert_called_once_with( google_directions.generate_requests.return_value, None, None, None, None, None)
def test_consolidating_link_ids_generates_unique_index_for_non_matching_link_with_clashing_link_id( ): n_left = Network('epsg:27700') n_left.add_link('1', 1, 2, 1, attribs={'modes': ['walk']}) n_right = Network('epsg:27700') n_right.add_link('1', 10, 20, 0, attribs={'modes': ['bike']}) output_n_right = graph_operations.consolidate_link_indices(n_left, n_right) assert list(output_n_right.graph.edges) == [(10, 20, 0)] assert not '1' in output_n_right.link_id_mapping assert len(output_n_right.link_id_mapping) == 1 assert output_n_right.graph[10][20][0]['id'] != '1'
def test_consolidating_link_ids_generates_unique_indices_for_non_overlapping_link_with_clashing_multiindex( ): n_left = Network('epsg:27700') n_left.add_link('1', 1, 2, 1, attribs={'modes': ['walk']}) n_right = Network('epsg:27700') n_right.add_link('2', 1, 2, 1, attribs={'modes': ['bike']}) output_n_right = graph_operations.consolidate_link_indices(n_left, n_right) assert list(output_n_right.graph.edges) != [(1, 2, 1)] assert not '1' in output_n_right.link_id_mapping assert len(output_n_right.link_id_mapping) == 1 u, v, midx = list(output_n_right.graph.edges)[0] assert midx != 1
def test_network_with_elevation_data_produces_valid_matsim_network_xml_file( tmpdir, network_dtd): network = Network('epsg:27700') network.add_node('0', attribs={ 'id': '0', 'x': 1, 'y': 2, 'z': 3, 'lat': 1, 'lon': 2 }) network.add_node('1', attribs={ 'id': '1', 'x': 2, 'y': 2, 'z': 0, 'lat': 2, 'lon': 2 }) network.add_link('0', '0', '1', attribs={ 'id': '0', 'from': '0', 'to': '1', 'length': 1, 'freespeed': 1, 'capacity': 20, 'permlanes': 1, 'oneway': '1', 'modes': ['car'] }) network.write_to_matsim(tmpdir) generated_network_file_path = os.path.join(tmpdir, 'network.xml') xml_obj = lxml.etree.parse(generated_network_file_path) assert network_dtd.validate(xml_obj), \ 'Doc generated at {} is not valid against DTD due to {}'.format(generated_network_file_path, network_dtd.error_log.filter_from_errors())
def test_consolidating_link_ids_does_nothing_to_completely_matching_links(): n_left = Network('epsg:27700') n_left.add_link('1', 1, 2, attribs={'modes': ['walk']}) n_right = Network('epsg:27700') n_right.add_link('1', 1, 2, attribs={'modes': ['walk']}) output_n_right = graph_operations.consolidate_link_indices(n_left, n_right) assert output_n_right.graph.has_edge(1, 2, 0) assert '1' in output_n_right.link_id_mapping assert output_n_right.graph[1][2][0] == { 'modes': ['walk'], 'from': 1, 'to': 2, 'id': '1' }
def test_consolidating_link_ids_imposes_multiindex_and_link_id_on_overlapping_links_not_matching_link_ids( ): n_left = Network('epsg:27700') n_left.add_link('1', 1, 2, 1, attribs={'modes': ['walk']}) n_right = Network('epsg:27700') n_right.add_link('100', 1, 2, 0, attribs={'modes': ['walk']}) output_n_right = graph_operations.consolidate_link_indices(n_left, n_right) assert output_n_right.graph.has_edge(1, 2, 1) assert '1' in output_n_right.link_id_mapping assert output_n_right.graph[1][2][1] == { 'modes': ['walk'], 'from': 1, 'to': 2, 'id': '1' }
def test_extract_graph_links_with_callable_condition_and_list_value_specifying_to_ignore_mixed_types( ): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': {9, 10} } } }) n.add_link('1', 2, 3, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': [1, 2] } } }) n.add_link('2', 3, 4, attribs={'attributes': 'yes'}) def condition(val): return val == 9 links = graph_operations.extract_on_attributes( n.links(), conditions={'attributes': { 'osm:way:highway': { 'text': condition } }}, mixed_dtypes=False) assert links == []
def test_extract_graph_links_with_list_of_conditions_strict(): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway:to:hell', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_link('1', 2, 3, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_link('2', 3, 4, attribs={'attributes': 'yes'}) links = graph_operations.extract_links_on_edge_attributes( n, conditions=[{ 'attributes': { 'osm:way:highway': { 'text': 'primary' } } }, { 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway' } } }], how=all) assert links == ['1']
def test_convert_list_of_link_ids_to_network_nodes_with_connected_link_id_list( ): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={}) n.add_link('1', 2, 3, attribs={}) n.add_link('2', 3, 4, attribs={}) network_nodes = graph_operations.convert_list_of_link_ids_to_network_nodes( n, ['0', '1', '2']) assert network_nodes == [[1, 2, 3, 4]]
def test_extract_graph_links_with_callable_condition(): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 9 } } }) n.add_link('1', 2, 3, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 1 } } }) n.add_link('2', 3, 4, attribs={'attributes': 'yes'}) def condition(val): return val == 9 links = graph_operations.extract_on_attributes( n.links(), conditions={'attributes': { 'osm:way:highway': { 'text': condition } }}) assert links == ['0']
def test_extract_graph_links_with_list_condition_and_list_value(): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': ['primary', 'secondary'] } } }) n.add_link('1', 2, 3, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': {'primary', 'other'} } } }) n.add_link('2', 3, 4, attribs={'attributes': 'yes'}) links = graph_operations.extract_on_attributes( n.links(), conditions={ 'attributes': { 'osm:way:highway': { 'text': ['primary', 'some_other_highway'] } } }) assert links == ['0', '1']
def test_convert_list_of_link_ids_to_network_nodes_with_disconnected_link_id_list( mocker): mocker.patch.object(logging, 'Logger') n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={}) n.add_link('1', 2, 3, attribs={}) n.add_link('2', 3, 4, attribs={}) network_nodes = graph_operations.convert_list_of_link_ids_to_network_nodes( n, ['0', '2']) assert network_nodes == [[1, 2], [3, 4]]
def test_extract_graph_nodes_with_list_of_conditions_strict(): n = Network('epsg:27700') n.add_node( 1, { 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway:to:hell', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_node( 2, { 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_node(3, {'attributes': 'yes'}) nodes = graph_operations.extract_nodes_on_node_attributes( n, conditions=[{ 'attributes': { 'osm:way:highway': { 'text': 'primary' } } }, { 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway' } } }], how=all) assert nodes == [2]
def test_extract_graph_links_with_bound_condition_and_list_value(): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': [9, 1] } } }) n.add_link('1', 2, 3, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': [0, 1] } } }) n.add_link('2', 3, 4, attribs={'attributes': 'yes'}) links = graph_operations.extract_on_attributes( n.links(), conditions={'attributes': { 'osm:way:highway': { 'text': (2, 10) } }}) assert links == ['0']
def test_network_from_test_osm_data_produces_valid_matsim_network_xml_file( full_fat_default_config_path, network_dtd, tmpdir): osm_test_file = os.path.abspath( os.path.join(os.path.dirname(__file__), "test_data", "osm", "osm.xml")) network = Network('epsg:27700') network.read_osm(osm_test_file, full_fat_default_config_path, 1) network.write_to_matsim(tmpdir) generated_network_file_path = os.path.join(tmpdir, 'network.xml') xml_obj = lxml.etree.parse(generated_network_file_path) assert network_dtd.validate(xml_obj), \ 'Doc generated at {} is not valid against DTD due to {}'.format(generated_network_file_path, network_dtd.error_log.filter_from_errors())
def test_extract_graph_links_with_bound_condition_and_list_value_specifying_to_ignore_mixed_types( ): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': [9, 1] } } }) n.add_link('1', 2, 3, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': [0, 1] } } }) n.add_link('2', 3, 4, attribs={'attributes': 'yes'}) links = graph_operations.extract_links_on_edge_attributes( n, conditions={'attributes': { 'osm:way:highway': { 'text': (2, 10) } }}, mixed_dtypes=False) assert links == []
def test_extract_graph_links_with_nested_condition(): n = Network('epsg:27700') n.add_link('0', 1, 2, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }) n.add_link('1', 2, 3, attribs={ 'attributes': { 'osm:way:highway': { 'name': 'osm:way:highway', 'class': 'java.lang.String', 'text': 'primary' } } }) links = graph_operations.extract_links_on_edge_attributes( n, conditions={'attributes': { 'osm:way:highway': { 'text': 'primary' } }}, ) assert links == ['0', '1']
def test_add_reindexes_node_if_clashes_with_spatially_unmatched_nodes(): n_left = Network('epsg:27700') n_left.epsg = 'epsg:27700' n_left.add_node( '101982', { 'id': '101982', 'x': '528704.1425925883', 'y': '182068.78193707118', 'lon': -0.14625948709424305, 'lat': 51.52287873323954, 's2_id': 5221390329378179879 }) n_right = Network('epsg:27700') n_right.epsg = 'epsg:4326' n_right.add_node( '101982', { 'id': '101982', 'x': -0.1477018870962475, 'y': 51.5205729332399, 'lon': -0.14770188709624754, 'lat': 51.5205729332399, 's2_id': 5221390304444511271 }) n_right.reproject('epsg:27700') output_n_right = graph_operations.consolidate_node_indices(n_left, n_right) assert not output_n_right.graph.has_node('101982') the_node = [i for i, a in output_n_right.nodes()][0] assert_semantically_equal( output_n_right.node(the_node), { 'id': the_node, 'x': 528610.5722059759, 'y': 181809.83345613896, 'lon': -0.14770188709624754, 'lat': 51.5205729332399, 's2_id': 5221390304444511271 })
def test_consolidating_node_ids_updates_nodes_data_for_overlapping_nodes_of_different_coordinate_system( ): n_left = Network('epsg:27700') n_left.epsg = 'epsg:27700' n_left.add_node( '101982', { 'id': '101982', 'x': '528704.1434730452', 'y': '182068.78144827875', 'lon': -0.14625948709424305, 'lat': 51.52287873323954, 's2_id': 5221390329378179879 }) n_right = Network('epsg:27700') n_right.epsg = 'epsg:4326' n_right.add_node( '101982', { 'id': '101982', 'x': -0.14625948709424305, 'y': 51.52287873323954, 'lon': -0.14625948709424305, 'lat': 51.52287873323954, 's2_id': 5221390329378179879 }) n_right.reproject('epsg:27700') output_n_right = graph_operations.consolidate_node_indices(n_left, n_right) assert_semantically_equal( output_n_right.node('101982'), { 'id': '101982', 'x': 528704.1434730452, 'y': 182068.78144827875, 'lon': -0.14625948709424305, 'lat': 51.52287873323954, 's2_id': 5221390329378179879 })
def test_nodes_with_elevation_written_correctly_to_xml_network( tmpdir, network_dtd): network = Network('epsg:27700') network.add_node('0', attribs={ 'id': '0', 'x': 1, 'y': 2, 'z': 3, 'lat': 1, 'lon': 2 }) network.add_node('1', attribs={ 'id': '1', 'x': 2, 'y': 2, 'z': 0, 'lat': 2, 'lon': 2 }) network.add_link('0', '0', '1', attribs={ 'id': '0', 'from': '0', 'to': '1', 'length': 1, 'freespeed': 1, 'capacity': 20, 'permlanes': 1, 'oneway': '1', 'modes': ['car'] }) network.write_to_matsim(tmpdir) generated_network_file_path = os.path.join(tmpdir, 'network.xml') _network_from_file = read.read_matsim( path_to_network=generated_network_file_path, epsg='epsg:27700') assert_semantically_equal( dict(_network_from_file.nodes()), { '0': { 'id': '0', 'x': 1.0, 'y': 2.0, 'z': 3.0, 'lon': -7.557148039524952, 'lat': 49.766825803756994, 's2_id': 5205973754090365183 }, '1': { 'id': '1', 'x': 2.0, 'y': 2.0, 'z': 0.0, 'lon': -7.557134218911724, 'lat': 49.766826468710484, 's2_id': 5205973754090480551 } })
def test_consolidating_node_ids_reprojects_non_overlapping_nodes(): n_left = Network('epsg:27700') n_left.epsg = 'epsg:27700' n_left.add_node( '101986', { 'id': '101986', 'x': '528835.203274008', 'y': '182006.27331298392', 'lon': -0.14439428709377497, 'lat': 51.52228713323965, 's2_id': 5221390328605860387 }) n_right = Network('epsg:27700') n_right.epsg = 'epsg:4326' n_right.add_node( '101990', { 'id': '101990', 'x': -0.14770188709624754, 'y': 51.5205729332399, 'lon': -0.14770188709624754, 'lat': 51.5205729332399, 's2_id': 5221390304444511271 }) n_right.reproject('epsg:27700') output_n_right = graph_operations.consolidate_node_indices(n_left, n_right) assert_semantically_equal( output_n_right.node('101990'), { 'id': '101990', 'x': 528610.5722059759, 'y': 181809.83345613896, 'lon': -0.14770188709624754, 'lat': 51.5205729332399, 's2_id': 5221390304444511271 })
def test_add_reindexes_node_if_clashes_with_spatially_matched_nodes(): n_left = Network('epsg:27700') n_left.epsg = 'epsg:27700' n_left.add_node( '101982', { 'id': '101982', 'x': '528704.1434730452', 'y': '182068.78144827875', 'lon': -0.14625948709424305, 'lat': 51.52287873323954, 's2_id': 5221390329378179879 }) n_right = Network('epsg:27700') n_right.epsg = 'epsg:4326' n_right.add_node( '101990', { 'id': '101990', 'x': -0.14625948709424305, 'y': 51.52287873323954, 'lon': -0.14625948709424305, 'lat': 51.52287873323954, 's2_id': 5221390329378179879 }) n_right.reproject('epsg:27700') output_n_right = graph_operations.consolidate_node_indices(n_left, n_right) assert output_n_right.graph.has_node('101982') assert not output_n_right.graph.has_node('101990') assert_semantically_equal( output_n_right.node('101982'), { 'id': '101982', 'x': 528704.1434730452, 'y': 182068.78144827875, 'lon': -0.14625948709424305, 'lat': 51.52287873323954, 's2_id': 5221390329378179879 })