def test_way_relation_reset_location_variables(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) self.make_wayRelation_location_dirty(wayRelation) wayRelation.reset_location_variables() self.assert_wayRelation_variables_reset(wayRelation)
def test_way_relation_node_ahead(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) # ahead_ids is None on init self.assertIsNone(wayRelation.node_ahead) wayRelation.ahead_idx = 15 self.assertEqual(wayRelation.node_ahead, wayRelation.way.nodes[15])
def test_way_relation_is_location_in_bbox(self): wayRelation = WayRelation(mockOSMWay_01_02_Loop) bbox = wayRelation.bbox loc_avg = np.average(bbox, axis=0) loc_min = np.min(bbox, axis=0) loc_max = np.max(bbox, axis=0) locations = [ loc_avg, loc_min, loc_max, [loc_avg[0], loc_min[1]], [loc_avg[0], loc_max[1]], [loc_min[0], loc_avg[1]], [loc_max[0], loc_avg[1]], loc_min - 0.1, loc_max + 0.1, [loc_avg[0], loc_min[1] - 0.1], [loc_avg[0], loc_max[1] + 0.1], [loc_min[0] - 0.1, loc_avg[1]], [loc_max[0] + 0.1, loc_avg[1]], ] is_in = [wayRelation.is_location_in_bbox(loc) for loc in locations] self.assertEqual(is_in, [ True, True, True, True, True, True, True, False, False, False, False, False, False ])
def test_way_relation_update_direction_from_starting_node_resets_speed_limit( self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) wayRelation._speed_limit = 10. wayRelation.update_direction_from_starting_node( wayRelation.way.nodes[0].id) self.assertIsNone(wayRelation._speed_limit)
def test_way_relation_split_on_edge_node(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) edge_node_ids = wayRelation.edge_nodes_ids for edge_node_id in edge_node_ids: wrs = wayRelation.split(edge_node_id) self.assertEqual(len(wrs), 1) self.assertEqual(wrs[0], wayRelation) self.assertEqual(wrs[0].way.tags, wayRelation.way.tags)
def test_way_relation_update_only_resets_if_no_possible_found(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) location_rad = wayRelation.bbox[ 0] # Location inside bbox but outside actual way (due to padding) wayRelation.update(location_rad, 0., 10.) self.assertTrue(wayRelation.is_location_in_bbox(location_rad)) self.assert_wayRelation_variables_reset(wayRelation)
def test_way_relation_update_resets_on_update(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) self.make_wayRelation_location_dirty(wayRelation) location_rad = np.array([0., 0.]) # Location outside bbox wayRelation.update(location_rad, 0., 10.) self.assertFalse(wayRelation.is_location_in_bbox(location_rad)) self.assert_wayRelation_variables_reset(wayRelation)
def test_way_relation_road_name(self): # road name when no tag for name or ref wayRelation = WayRelation(mockOSMWay_01_02_Loop) self.assertIsNone(wayRelation.road_name) # road name based on ref tag wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) self.assertEqual(wayRelation.road_name, "B 96") # road name based on name tag wayRelation = WayRelation(mockOSMWay_02_01_CurvyTownWithIntersections) self.assertEqual(wayRelation.road_name, "Hauptstraße")
def test_way_relation_speed_limit_maxspeed(self): # Reset all tags before teting mockOSMWay_01_02_Loop.tags = {} wayRelation = WayRelation(mockOSMWay_01_02_Loop) # No Value self.assertEqual(wayRelation.speed_limit, 0.) # Value on both directions wayRelation._speed_limit = None wayRelation.way.tags["maxspeed"] = "100" self.assertEqual(wayRelation.speed_limit, 100. * CV.KPH_TO_MS) # Value on forward wayRelation.way.tags.pop("maxspeed") wayRelation._speed_limit = None wayRelation.direction = DIRECTION.FORWARD self.assertEqual(wayRelation.speed_limit, 0.) wayRelation._speed_limit = None wayRelation.way.tags["maxspeed:forward"] = "100" self.assertEqual(wayRelation.speed_limit, 100. * CV.KPH_TO_MS) # Value on backward wayRelation._speed_limit = None wayRelation.direction = DIRECTION.BACKWARD self.assertEqual(wayRelation.speed_limit, 0.) wayRelation._speed_limit = None wayRelation.way.tags["maxspeed:backward"] = "100" self.assertEqual(wayRelation.speed_limit, 100. * CV.KPH_TO_MS)
def test_way_relation_last_node(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) # direction is NONE on init self.assertIsNone(wayRelation.last_node) # forward wayRelation.direction = DIRECTION.FORWARD self.assertEqual(wayRelation.last_node, wayRelation.way.nodes[-1]) # backward wayRelation.direction = DIRECTION.BACKWARD self.assertEqual(wayRelation.last_node, wayRelation.way.nodes[0])
def test_nodes_raw_data_array_for_wr_flips_when_backwards(self): wr = WayRelation(mockOSMWay_01_01_LongCurvy) wr.direction = DIRECTION.BACKWARD data_e = np.array([(n.id, n.lat, n.lon, wr.speed_limit) for n in wr.way.nodes], dtype=float) data_e = np.flip(data_e, axis=0) data = nodes_raw_data_array_for_wr(wr) assert_array_almost_equal(data, data_e)
def test_way_relation_init(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) nodes_np_expected = np.radians( np.array([[nd.lat, nd.lon] for nd in wayRelation.way.nodes], dtype=float)) v = vectors(wayRelation._nodes_np) way_distances_expected = np.linalg.norm(v * R, axis=1) way_bearings_expected = np.arctan2(v[:, 0], v[:, 1]) bbox_expected = np.array([[0.91321784, 0.2346417], [0.91344672, 0.23475751]]) self.assertEqual(wayRelation.way.id, 179532213) self.assertIsNone(wayRelation.parent_wr_id) self.assertEqual(wayRelation.direction, DIRECTION.NONE) self.assertEqual(wayRelation._speed_limit, None) self.assertEqual(wayRelation._one_way, 'yes') self.assertEqual(wayRelation.name, None) self.assertEqual(wayRelation.ref, 'B 96') self.assertEqual(wayRelation.highway_type, 'trunk') self.assertEqual(wayRelation.highway_rank, 10) self.assertEqual(wayRelation.lanes, 2) assert_array_almost_equal(wayRelation._nodes_np, nodes_np_expected) assert_array_almost_equal(wayRelation._way_distances, way_distances_expected) assert_array_almost_equal(wayRelation._way_bearings, way_bearings_expected) assert_array_almost_equal(wayRelation.bbox, bbox_expected) self.assertEqual( wayRelation.edge_nodes_ids, [wayRelation.way.nodes[0].id, wayRelation.way.nodes[-1].id])
def test_way_relation_equality(self): wayRelation1 = WayRelation(mockOSMWay_01_01_LongCurvy) wayRelation2 = copy.copy(wayRelation1) wayRelation3 = copy.deepcopy(wayRelation1) wayRelation3.way.id = 123 self.assertEqual(wayRelation1, wayRelation2) self.assertNotEqual(wayRelation1, wayRelation3)
def test_nodes_raw_data_array_for_wr_drops_last(self): wr = WayRelation(mockOSMWay_01_01_LongCurvy) data_e = np.array([(n.id, n.lat, n.lon, wr.speed_limit) for n in wr.way.nodes], dtype=float)[:-1] data = nodes_raw_data_array_for_wr(wr, drop_last=True) assert_array_almost_equal(data, data_e)
def test_way_relation_split_on_internal_node(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) way_ids = [-10, -20] for idx, node_id in enumerate(wayRelation._nodes_ids): if idx == 0 or idx == len(wayRelation._nodes_ids) - 1: continue wrs = wayRelation.split(node_id, way_ids) self.assertEqual(len(wrs), 2) assert_array_almost_equal(wrs[0]._nodes_ids, wayRelation._nodes_ids[:idx + 1]) assert_array_almost_equal(wrs[1]._nodes_ids, wayRelation._nodes_ids[idx:]) self.assertIn(node_id, wrs[0].edge_nodes_ids) self.assertIn(node_id, wrs[1].edge_nodes_ids) self.assertEqual(wrs[0].way.tags, wayRelation.way.tags) self.assertEqual(wrs[1].way.tags, wayRelation.way.tags) self.assertEqual(way_ids, [wr.id for wr in wrs])
def test_init_with_less_than_4_nodes(self): wr_t = WayRelation(mockOSMWay_02_03_Short_3_node_way) nd = NodesData([wr_t], {}) self.assertEqual(len(nd._nodes_data), 0) num_diverstions = sum([len(d) for d in nd._divertions]) self.assertEqual(num_diverstions, 0) self.assertEqual(len(nd._curvature_speed_sections_data), 0)
def test_way_relation_is_one_way(self): # Setup initial tags mockOSMWay_01_02_Loop.tags = { 'oneway': 'yes', 'highway': 'unclassified' } wayRelation = WayRelation(mockOSMWay_01_02_Loop) # oneway = yes self.assertTrue(wayRelation.is_one_way) # oneway non existing wayRelation._one_way = None self.assertFalse(wayRelation.is_one_way) # highway = motorway wayRelation.highway_type = 'motorway' self.assertTrue(wayRelation.is_one_way)
def test_way_relation_last_node_coordinates(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) # direction is NONE on init self.assertIsNone(wayRelation.last_node_coordinates) # forward wayRelation.direction = DIRECTION.FORWARD coords = np.radians( np.array( [wayRelation.way.nodes[-1].lat, wayRelation.way.nodes[-1].lon], dtype=float)) assert_array_almost_equal(wayRelation.last_node_coordinates, coords) # backward wayRelation.direction = DIRECTION.BACKWARD coords = np.radians( np.array( [wayRelation.way.nodes[0].lat, wayRelation.way.nodes[0].lon], dtype=float)) assert_array_almost_equal(wayRelation.last_node_coordinates, coords)
def test_way_relation_update_direction_from_starting_node_updates_correctly( self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) wayRelation.update_direction_from_starting_node( wayRelation.way.nodes[0].id) self.assertEqual(wayRelation.direction, DIRECTION.FORWARD) wayRelation.update_direction_from_starting_node( wayRelation.way.nodes[-1].id) self.assertEqual(wayRelation.direction, DIRECTION.BACKWARD) wayRelation.update_direction_from_starting_node(0) self.assertEqual(wayRelation.direction, DIRECTION.NONE)
def __init__(self, ways, query_center): """Creates a WayCollection with a set of OSM way objects. Args: ways (Array): Collection of Way objects fetched from OSM in a radius around `query_center` query_center (Numpy Array): [lat, lon] numpy array in radians indicating the center of the data query. """ self.id = uuid.uuid4() self.way_relations = [WayRelation(way) for way in ways] self.query_center = query_center self.wr_index = WayRelationIndex(self.way_relations)
def test_way_relation_node_before_edge_coordinates(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) coords = wayRelation.node_before_edge_coordinates(0) assert_array_almost_equal(coords, np.array([0., 0.])) coords = wayRelation.node_before_edge_coordinates( wayRelation.way.nodes[0].id) coords_e = np.radians( np.array( [wayRelation.way.nodes[1].lat, wayRelation.way.nodes[1].lon], dtype=float)) assert_array_almost_equal(coords, coords_e) coords = wayRelation.node_before_edge_coordinates( wayRelation.way.nodes[-1].id) coords_e = np.radians( np.array( [wayRelation.way.nodes[-2].lat, wayRelation.way.nodes[-2].lon], dtype=float)) assert_array_almost_equal(coords, coords_e)
def test_is_wr_a_valid_divertion_from_node(self): wr = WayRelation(mockOSMWay_02_01_CurvyTownWithIntersections) mockOSMWay_02_02_Divertion_34785115.tags['oneway'] = 'yes' wr_div = WayRelation(mockOSMWay_02_02_Divertion_34785115) # False if id already in route wr_ids = [wr.id, wr_div.id] self.assertFalse( is_wr_a_valid_divertion_from_node(wr_div, 34785115, wr_ids)) # True if id not in route, node_id is edge and not prohibited wr_ids = [wr.id, 11111, 22222] self.assertTrue( is_wr_a_valid_divertion_from_node(wr_div, 34785115, wr_ids)) # False if id not in route, node_id is edge but prohibited (wrong direction from node 319503453) self.assertFalse( is_wr_a_valid_divertion_from_node(wr_div, 319503453, wr_ids)) # False if id not in route, node_id is not edge self.assertFalse( is_wr_a_valid_divertion_from_node(wr_div, 44444, wr_ids))
def test_way_relation_updates_with_location_closest_to_way_when_multiple_possible( self): wayRelation = WayRelation(mockOSMWay_01_02_Loop) location_rad = np.radians( np.array([52.313303275461564, 13.437729236325788])) bearing_rad = np.radians(10.) wayRelation.update(location_rad, bearing_rad, 10.) self.assertTrue(wayRelation.is_location_in_bbox(location_rad)) self.assertEqual(wayRelation.direction, DIRECTION.BACKWARD) self.assertEqual(wayRelation.ahead_idx, 26) self.assertEqual(wayRelation.behind_idx, 27) self.assertAlmostEqual(wayRelation._distance_to_way, 10.151775235257011) self.assertAlmostEqual(wayRelation._active_bearing_delta, 0.06371131069242782) self.assertAlmostEqual(wayRelation.distance_to_node_ahead, 10.174073707120915) self.assertTrue(wayRelation.active) self.assertFalse(wayRelation.diverting) assert_array_almost_equal(wayRelation.location_rad, location_rad) self.assertEqual(wayRelation.bearing_rad, bearing_rad) self.assertIsNone(wayRelation._speed_limit)
def __init__(self, ways, query_center): """Creates a WayCollection with a set of OSM way objects. Args: ways (Array): Collection of Way objects fetched from OSM in a radius around `query_center` query_center (Numpy Array): [lat, lon] numpy array in radians indicating the center of the data query. """ self.id = uuid.uuid4() self.way_relations = [WayRelation(way) for way in ways] self.query_center = query_center # Create the index by edge node ids. self.wr_index = {} for wr in self.way_relations: for node_id in wr.edge_nodes_ids: self.wr_index[node_id] = self.wr_index.get(node_id, []) + [wr]
def test_way_relation_speed_limit_conditional(self, mock_dt): tz = timezone(timedelta(hours=1), 'berlin') wed_10_10_am = dt(2021, 9, 1, 10, 10, 0) mock_dt.now.return_value = wed_10_10_am mock_dt.tzinfo = tz mock_dt.combine = dt.combine mock_dt.strptime = dt.strptime # Reset all tags before teting mockOSMWay_01_02_Loop.tags = {} wayRelation = WayRelation(mockOSMWay_01_02_Loop) # No Value self.assertEqual(wayRelation.speed_limit, 0.) # Value on both directions wayRelation._speed_limit = None wayRelation.way.tags["maxspeed:conditional"] = "100 @ (We 10:00-10:30)" self.assertEqual(wayRelation.speed_limit, 100. * CV.KPH_TO_MS) # Value on forward wayRelation.way.tags.pop("maxspeed:conditional") wayRelation._speed_limit = None wayRelation.direction = DIRECTION.FORWARD self.assertEqual(wayRelation.speed_limit, 0.) wayRelation._speed_limit = None wayRelation.way.tags[ "maxspeed:forward:conditional"] = "100 @ (We 10:00-10:30)" self.assertEqual(wayRelation.speed_limit, 100. * CV.KPH_TO_MS) # Value on backward wayRelation._speed_limit = None wayRelation.direction = DIRECTION.BACKWARD self.assertEqual(wayRelation.speed_limit, 0.) wayRelation._speed_limit = None wayRelation.way.tags[ "maxspeed:backward:conditional"] = "100 @ (We 10:00-10:30)" self.assertEqual(wayRelation.speed_limit, 100. * CV.KPH_TO_MS)
def test_way_relation_updates_in_the_correct_direction_with_correct_property_values( self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) location_rad = np.radians( np.array([52.32855593146639, 13.445320150125069])) bearing_rad = 0. wayRelation.update(location_rad, bearing_rad, 10.) self.assertTrue(wayRelation.is_location_in_bbox(location_rad)) self.assertEqual(wayRelation.direction, DIRECTION.FORWARD) self.assertEqual(wayRelation.ahead_idx, 17) self.assertEqual(wayRelation.behind_idx, 16) self.assertAlmostEqual(wayRelation._distance_to_way, 3.43290781621360) self.assertAlmostEqual(wayRelation._active_bearing_delta, 0.320717420388962) self.assertAlmostEqual(wayRelation.distance_to_node_ahead, 25.4998961709014) self.assertTrue(wayRelation.active) self.assertFalse(wayRelation.diverting) assert_array_almost_equal(wayRelation.location_rad, location_rad) self.assertEqual(wayRelation.bearing_rad, bearing_rad) self.assertIsNone(wayRelation._speed_limit) bearing_rad = 180. wayRelation.update(location_rad, bearing_rad, 10.) self.assertTrue(wayRelation.is_location_in_bbox(location_rad)) self.assertEqual(wayRelation.direction, DIRECTION.BACKWARD) self.assertEqual(wayRelation.ahead_idx, 16) self.assertEqual(wayRelation.behind_idx, 17) self.assertAlmostEqual(wayRelation._distance_to_way, 3.43290781621360) self.assertAlmostEqual(wayRelation._active_bearing_delta, 0.9507682562504284) self.assertAlmostEqual(wayRelation.distance_to_node_ahead, 11.11623371145368) self.assertTrue(wayRelation.active) self.assertFalse(wayRelation.diverting) assert_array_almost_equal(wayRelation.location_rad, location_rad) self.assertEqual(wayRelation.bearing_rad, bearing_rad) self.assertIsNone(wayRelation._speed_limit)
def test_way_relation_updates_will_become_inactive_if_too_far_from_way( self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) # Location is 24.9 mts away from the way. There are 2 Lanes in this way. location_rad = np.radians( np.array([52.328634560607746, 13.445609877522788])) location_stdev = 5.5 # threshold is 4 * location_stdev + LANE_WIDTH distance_threshold = 4. * location_stdev + wayRelation.lanes * LANE_WIDTH / 2. wayRelation.update(location_rad, 0., location_stdev) self.assertTrue(wayRelation.active) self.assertLess(wayRelation._distance_to_way, distance_threshold) location_stdev = 5. wayRelation.update(location_rad, 0., location_stdev) self.assertFalse(wayRelation.active)
def test_way_relation_is_prohibited(self): # Setup initial tags mockOSMWay_01_02_Loop.tags = {'oneway': 'yes'} wayRelation = WayRelation(mockOSMWay_01_02_Loop) # Direction undefined wayRelation.direction = DIRECTION.NONE self.assertTrue(wayRelation.is_prohibited) # oneway = yes wayRelation.direction = DIRECTION.BACKWARD self.assertTrue(wayRelation.is_prohibited) wayRelation.direction = DIRECTION.FORWARD self.assertFalse(wayRelation.is_prohibited) # oneway non existing wayRelation._one_way = None self.assertFalse(wayRelation.is_one_way) wayRelation.direction = DIRECTION.BACKWARD self.assertFalse(wayRelation.is_prohibited)
def test_way_relation_updates_will_update_diverting_correctly(self): wayRelation = WayRelation(mockOSMWay_01_01_LongCurvy) # Location is 24.9 mts away from the way. There are 2 Lanes in this way. location_rad = np.radians( np.array([52.328634560607746, 13.445609877522788])) location_stdev = 11. distance_threshold = 2. * location_stdev + wayRelation.lanes * LANE_WIDTH / 2. wayRelation.update(location_rad, 0., location_stdev) self.assertLess(wayRelation._distance_to_way, distance_threshold) self.assertFalse(wayRelation.diverting) location_stdev = 10. distance_threshold = 2. * location_stdev + wayRelation.lanes * LANE_WIDTH / 2. wayRelation.update(location_rad, 0., location_stdev) self.assertGreater(wayRelation._distance_to_way, distance_threshold) self.assertTrue(wayRelation.diverting)
def test_distance_to_end_from_empty(self): wr_t = WayRelation(mockOSMWay_02_03_Short_3_node_way) nd = NodesData([wr_t], {}) self.assertIsNone(nd.distance_to_end(1, 10.))