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])
Example #11
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)
Example #14
0
    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])
Example #16
0
    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)
Example #22
0
    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)
Example #24
0
    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)
Example #30
0
    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.))