コード例 #1
0
    def test_find_extreme_point_indicies(self):
        # A line of Lat Longs around the Equator
        LATITUDES = np.zeros(10, dtype=float)
        LONGITUDES = np.array([-5 + i for i in range(10)], dtype=float)
        ecef_points_0 = global_Point3d(LATITUDES, LONGITUDES)

        indicies_0 = find_extreme_point_indicies(
            ecef_points_0, threshold=ACROSS_TRACK_TOLERANCE, xtd_ratio=0.1)

        self.assertEqual(len(indicies_0), 2)
        assert_array_almost_equal(indicies_0, [0, 9])

        LATITUDES[4] = 1
        LATITUDES[8] = -1
        ecef_points_1 = global_Point3d(LATITUDES, LONGITUDES)

        indicies_1 = find_extreme_point_indicies(
            ecef_points_1, threshold=ACROSS_TRACK_TOLERANCE, xtd_ratio=0.1)
        self.assertEqual(len(indicies_1), 7)
        assert_array_almost_equal(indicies_1, [0, 3, 4, 5, 7, 8, 9])

        indicies_3 = find_extreme_point_indicies(ecef_points_1,
                                                 threshold=np.deg2rad(1.0),
                                                 xtd_ratio=0.1)
        self.assertEqual(len(indicies_3), 7)
コード例 #2
0
    def test_fit_arc_to_points(self):
        LATS_0 = np.zeros(4, dtype=np.float)
        LONS_0 = np.array([0.0, 1.0, 2.0, 3.0])

        # Test points along arc
        ecef_points_0 = global_Point3d(LATS_0, LONS_0)
        ecef_arc_0 = Arc3d(ecef_points_0[0], ecef_points_0[-1])
        new_arc_0 = fit_arc_to_points(ecef_points_0, ecef_arc_0)
        assert_almost_equal(distance_radians(new_arc_0.a(), ecef_arc_0.a()),
                            0.0)
        assert_almost_equal(distance_radians(new_arc_0.b(), ecef_arc_0.b()),
                            0.0)

        # Test slope away from start of arc
        ecef_points_1 = global_Point3d(LONS_0, LONS_0)
        ecef_arc_1 = Arc3d(ecef_points_1[0], ecef_points_1[-1])

        new_arc_1 = fit_arc_to_points(ecef_points_1, ecef_arc_0)
        assert_almost_equal(distance_radians(new_arc_1.a(), ecef_arc_0.a()),
                            0.0)
        assert_almost_equal(
            distance_radians(new_arc_1.pole(), ecef_arc_1.pole()), 0.0)

        # Test slope towards end of arc
        LATS_2 = np.array([3.0, 2.0, 1.0, 0.0])
        ecef_points_2 = global_Point3d(LATS_2, LONS_0)
        ecef_arc_2 = Arc3d(ecef_points_2[0], ecef_points_2[-1])

        new_arc_2 = fit_arc_to_points(ecef_points_2, ecef_arc_0)
        assert_almost_equal(
            distance_radians(new_arc_2.pole(), ecef_arc_2.pole()), 0.0)
        assert_almost_equal(distance_radians(new_arc_2.b(), ecef_arc_0.b()),
                            0.0)
コード例 #3
0
    def test_find_extreme_point_index_3(self):
        # A line of Lat Longs around the Equator
        LATITUDES = np.zeros(10, dtype=float)
        LONGITUDES = np.array(range(-5, 5), dtype=float)
        ecef_points_0 = global_Point3d(LATITUDES, LONGITUDES)

        # same point
        max_index = len(ecef_points_0) - 1
        result_0 = find_extreme_point_index(ecef_points_0,
                                            0,
                                            max_index,
                                            threshold=ACROSS_TRACK_TOLERANCE,
                                            xtd_ratio=0.1,
                                            calc_along_track=True)
        self.assertEqual(result_0, max_index)

        # route "doubles back" on itself
        LONGITUDES[-1] = LONGITUDES[-3]
        ecef_points_1 = global_Point3d(LATITUDES, LONGITUDES)
        result_1 = find_extreme_point_index(ecef_points_1,
                                            0,
                                            max_index,
                                            threshold=ACROSS_TRACK_TOLERANCE,
                                            xtd_ratio=0.1,
                                            calc_along_track=True)
        self.assertEqual(result_1, max_index - 1)
コード例 #4
0
    def test_find_extreme_point_along_track_index(self):
        # A line of Lat Longs around the Equator
        LATITUDES = np.zeros(10, dtype=float)
        LONGITUDES = np.array(range(-5, 5), dtype=float)
        ecef_points_0 = global_Point3d(LATITUDES, LONGITUDES)

        # All points within arc
        arc = Arc3d(ecef_points_0[0], ecef_points_0[-1])
        index_0 = find_extreme_point_along_track_index(arc, ecef_points_0,
                                                       1.0 * NM)
        self.assertEqual(index_0, 0)

        # Point 2 before start of arc
        LONGITUDES[2] = -6
        ecef_points_1 = global_Point3d(LATITUDES, LONGITUDES)
        index_1 = find_extreme_point_along_track_index(arc, ecef_points_1,
                                                       1.0 * NM)
        self.assertEqual(index_1, 2)

        # Point 8 past end of arc
        LONGITUDES[8] = 8
        ecef_points_2 = global_Point3d(LATITUDES, LONGITUDES)
        index_2 = find_extreme_point_along_track_index(arc, ecef_points_2,
                                                       1.0 * NM)
        self.assertEqual(index_2, 8)
コード例 #5
0
def verify_matches(flight_matches, positions1, positions2, flight_ids,
                   delta_time, max_speed):
    """
    Verifies the pairs of flight ids in flight_matches by calling
    compare_trajectory_positions with the cpr_positions and adsb_positions
    of each flight against the delta_time threshold.

    It adds new matches to the flight_ids dicts and returns the number of newly
    matched flights.
    """
    matches = 0
    next_pos_match = pd.merge(positions2,
                              flight_matches,
                              left_index=True,
                              right_on='FLIGHT_ID_y')

    for next_id, next_pos in next_pos_match.groupby('FLIGHT_ID_y'):
        # Ensure that next_pos is new has more than one value!
        if next_id not in flight_ids and \
                isinstance(next_pos['TIME'], pd.Series):

            next_times = next_pos['TIME'].values
            next_points = global_Point3d(next_pos['LAT'].values,
                                         next_pos['LON'].values)
            next_alts = next_pos['ALT'].values

            for prev_id in next_pos['FLIGHT_ID_x'].unique():
                prev_pos = positions1.loc[prev_id]
                # Ensure that prev_pos has more than one value!
                if isinstance(prev_pos['TIME'], pd.Series):
                    prev_times = prev_pos['TIME'].values
                    prev_points = global_Point3d(prev_pos['LAT'].values,
                                                 prev_pos['LON'].values)
                    prev_alts = prev_pos['ALT'].values
                    valid_match = compare_trajectory_positions(
                        next_times,
                        prev_times,
                        next_points,
                        prev_points,
                        next_alts,
                        prev_alts,
                        time_threshold=delta_time,
                        speed_threshold=max_speed)
                    if (valid_match):
                        matches += 1
                        flight_ids[next_id] = prev_id

    return matches
コード例 #6
0
    def test_find_extreme_point_index_2(self):
        # A line of Lat Longs by the Equator
        LATITUDES = np.array([0.0, -0.001, 0.01, -0.001, 0.0])
        LONGITUDES = np.array([0.0, 0.0005, 0.001, 0.0014, 0.0015])
        ecef_points_0 = global_Point3d(LATITUDES, LONGITUDES)

        # mid point
        max_index = len(ecef_points_0) - 1
        result_0 = find_extreme_point_index(ecef_points_0,
                                            0,
                                            max_index,
                                            threshold=ACROSS_TRACK_TOLERANCE,
                                            xtd_ratio=0.1,
                                            calc_along_track=False)
        self.assertEqual(result_0, 2)

        # first half
        max_index = 2
        result_1 = find_extreme_point_index(ecef_points_0,
                                            0,
                                            max_index,
                                            threshold=ACROSS_TRACK_TOLERANCE,
                                            xtd_ratio=0.1,
                                            calc_along_track=False)
        self.assertEqual(result_1, 2)

        # second half
        max_index = len(ecef_points_0) - 1
        result_2 = find_extreme_point_index(ecef_points_0,
                                            2,
                                            max_index,
                                            threshold=ACROSS_TRACK_TOLERANCE,
                                            xtd_ratio=0.1,
                                            calc_along_track=False)
        self.assertEqual(result_2, max_index)
コード例 #7
0
    def test_SpherePath_turn_points(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)
        turn_points_0 = ecef_path.turn_points(number_of_points=0)
        self.assertEqual(len(turn_points_0), len(ecef_path) + 8)

        # Ensure that start and end points are along inbound and outboud arcs
        arc_1 = Arc3d(ecef_points[1], ecef_points[2])
        assert_almost_equal(arc_1.cross_track_distance(turn_points_0[2]), 0.0)

        arc_2 = Arc3d(ecef_points[2], ecef_points[3])
        assert_almost_equal(arc_2.cross_track_distance(turn_points_0[3]), 0.0)
        assert_almost_equal(arc_2.cross_track_distance(turn_points_0[4]), 0.0)

        arc_last = Arc3d(ecef_points[-2], ecef_points[-1])
        assert_almost_equal(arc_last.cross_track_distance(turn_points_0[-2]),
                            0.0)

        turn_points_1 = ecef_path.turn_points(number_of_points=1)
        self.assertEqual(len(turn_points_1), len(ecef_path) + 16)

        turn_points_3 = ecef_path.turn_points()
        self.assertEqual(len(turn_points_3), len(ecef_path) + 32)

        turn_points_5 = ecef_path.turn_points(number_of_points=5)
        self.assertEqual(len(turn_points_5), len(ecef_path) + 48)
コード例 #8
0
    def test_calculate_turn_initiation_distance_20(self):
        # A shallow turn at the Equator
        LATS = np.array([0.0, 0.0, 0.2])
        LONS = np.array([-1.0, 0.0, 1.0])
        ecef_points = global_Point3d(LATS, LONS)

        prev_arc = Arc3d(ecef_points[0], ecef_points[1])
        arc = Arc3d(ecef_points[1], ecef_points[2])
        TEN_NM = TWENTY_NM / 2
        turn_0 = SphereTurnArc(prev_arc, arc, TEN_NM)
        turn_angle_0 = turn_0.angle

        distance_start = calculate_turn_initiation_distance(
            prev_arc, arc, turn_0.start, TWENTY_NM, ACROSS_TRACK_TOLERANCE)
        assert_almost_equal(distance_start, TEN_NM)

        distance_finish = calculate_turn_initiation_distance(
            prev_arc, arc, turn_0.finish, TWENTY_NM, ACROSS_TRACK_TOLERANCE)
        assert_almost_equal(distance_finish, TEN_NM)

        point_1 = turn_0.position(turn_angle_0 / 2)
        distance_1 = calculate_turn_initiation_distance(
            prev_arc, arc, point_1, TWENTY_NM, ACROSS_TRACK_TOLERANCE)
        assert_almost_equal(distance_1, TEN_NM, decimal=6)

        point_2 = turn_0.position(turn_angle_0 / 4)
        distance_2 = calculate_turn_initiation_distance(
            prev_arc, arc, point_2, TWENTY_NM, ACROSS_TRACK_TOLERANCE / 4)
        assert_almost_equal(distance_2, TEN_NM, decimal=6)

        point_3 = turn_0.position(3 * turn_angle_0 / 4)
        distance_3 = calculate_turn_initiation_distance(
            prev_arc, arc, point_3, TWENTY_NM, ACROSS_TRACK_TOLERANCE / 4)
        assert_almost_equal(distance_3, TEN_NM, decimal=5)
コード例 #9
0
    def test_SpherefPath_init(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)
        self.assertEqual(len(ecef_points), 12)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)
        self.assertEqual(len(ecef_path.points), 12)
        # assert_array_almost_equal(ecef_path.points, ecef_points)
        self.assertEqual(len(ecef_path.turn_initiation_distances), 12)
        assert_array_almost_equal(ecef_path.turn_initiation_distances,
                                  TURN_DISTANCES)
        self.assertEqual(len(ecef_path.leg_lengths), 12)
        assert_array_almost_equal(rad2nm(ecef_path.leg_lengths),
                                  EXPECTED_LEG_LENGTHS)
        self.assertEqual(len(ecef_path.turn_angles), 12)
        assert_array_almost_equal(np.rad2deg(ecef_path.turn_angles),
                                  EXPECTED_TURN_ANGLES)
        self.assertEqual(len(ecef_path.path_lengths), 12)
        assert_array_almost_equal(rad2nm(ecef_path.path_lengths),
                                  EXPECTED_PATH_LENGTHS)

        lats, lons = ecef_path.point_lat_longs()
        assert_array_almost_equal(lats, ROUTE_LATS)
        assert_array_almost_equal(lons, ROUTE_LONS)

        assert_array_almost_equal(ecef_path.turn_initiation_distances_nm(),
                                  rad2nm(TURN_DISTANCES))
コード例 #10
0
    def test_SpherePath_section_distances_and_types(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        path_distances = rad2nm(ecef_path.path_distances())

        distances, types = ecef_path.section_distances_and_types()
        self.assertEqual(len(distances), len(ecef_path) + 8)
        self.assertEqual(len(types), len(ecef_path) + 8)

        self.assertEqual(distances[0], 0.0)
        self.assertEqual(types[0], PointType.Waypoint)

        self.assertEqual(distances[1], path_distances[1])
        self.assertEqual(types[1], PointType.Waypoint)

        self.assertTrue(distances[2] < path_distances[2])
        self.assertEqual(types[2], PointType.TurnStart)

        self.assertTrue(distances[3] > path_distances[2])
        self.assertEqual(types[3], PointType.TurnFinish)

        self.assertEqual(distances[-2], path_distances[-2])
        self.assertEqual(types[-2], PointType.Waypoint)

        self.assertEqual(distances[-1], path_distances[-1])
        self.assertEqual(types[-1], PointType.Waypoint)
コード例 #11
0
    def test_calculate_path_cross_track_distance(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        assert_almost_equal(
            ecef_path.calculate_path_cross_track_distance(ecef_points[0], 0),
            0.0)
        assert_almost_equal(
            ecef_path.calculate_path_cross_track_distance(ecef_points[1], 1),
            0.0)

        xtd_2_1 = ecef_path.calculate_path_cross_track_distance(
            ecef_points[2], 1)
        assert_almost_equal(rad2nm(xtd_2_1), 4.1416795658323213)

        xtd_2_2 = ecef_path.calculate_path_cross_track_distance(
            ecef_points[2], 2)
        assert_almost_equal(rad2nm(xtd_2_2), 4.1416795658323213)

        xtd_3_2 = ecef_path.calculate_path_cross_track_distance(
            ecef_points[3], 2)
        assert_almost_equal(rad2nm(xtd_3_2), 8.2824069920496726)

        xtd_3_3 = ecef_path.calculate_path_cross_track_distance(
            ecef_points[3], 3)
        assert_almost_equal(rad2nm(xtd_3_3), 8.2824069920496726)
コード例 #12
0
    def test_SpherePath_calculate_path_leg_distance(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        # Start point
        distance_0 = ecef_path.calculate_path_leg_distance(ecef_points[0], 0)
        self.assertEqual(distance_0, 0.0)

        # Point at end of a straight leg
        distance_1_0 = ecef_path.calculate_path_leg_distance(ecef_points[1], 0)
        assert_almost_equal(rad2nm(distance_1_0), EXPECTED_PATH_LENGTHS[1])

        # Point at start of a straight leg
        distance_1_1 = ecef_path.calculate_path_leg_distance(ecef_points[1], 1)
        self.assertEqual(distance_0, 0.0)

        # Point in middle of a straight leg
        pos_1_5 = ecef_path.calculate_position(1, 0.5)
        distance_1_5 = ecef_path.calculate_path_leg_distance(pos_1_5, 1)
        assert_almost_equal(rad2nm(distance_1_5),
                            0.5 * EXPECTED_PATH_LENGTHS[2])

        # Point toward end of a turning leg
        pos_1_9 = ecef_path.calculate_position(1, 0.99)
        distance_1_9 = ecef_path.calculate_path_leg_distance(pos_1_9, 1)
        assert_almost_equal(rad2nm(distance_1_9),
                            0.99 * EXPECTED_PATH_LENGTHS[2])

        # Before start of a turning leg
        distance_2_9 = ecef_path.calculate_path_leg_distance(pos_1_9, 2)
        assert_almost_equal(rad2nm(distance_2_9), -0.57845277761762326)

        # Point toward start of a turning leg
        pos_2_1 = ecef_path.calculate_position(2, 0.01)
        distance_2_1 = ecef_path.calculate_path_leg_distance(pos_2_1, 2)
        assert_almost_equal(rad2nm(distance_2_1),
                            0.01 * EXPECTED_PATH_LENGTHS[3])

        # Past the ned of a turning leg
        distance_1_2 = ecef_path.calculate_path_leg_distance(pos_2_1, 1)
        self.assertTrue(rad2nm(distance_1_2) > EXPECTED_PATH_LENGTHS[2])
        assert_almost_equal(rad2nm(distance_1_2), 58.980918943627351)

        # Point along a turning leg
        pos_2_75 = ecef_path.calculate_position(2, 0.75)
        distance_2_75 = ecef_path.calculate_path_leg_distance(pos_2_75, 2)
        assert_almost_equal(rad2nm(distance_2_75),
                            0.75 * EXPECTED_PATH_LENGTHS[3])

        # Last point
        distance_last = ecef_path.calculate_path_leg_distance(
            ecef_points[-1], 10)
        assert_almost_equal(rad2nm(distance_last), EXPECTED_PATH_LENGTHS[11])

        # # A waypoint not on path
        distance_2_0 = ecef_path.calculate_path_leg_distance(ecef_points[2], 1)
        assert_almost_equal(rad2nm(distance_2_0),
                            EXPECTED_PATH_LENGTHS[2],
                            decimal=4)
コード例 #13
0
    def test_SpherePath_calculate_position(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        pos_0 = ecef_path.calculate_position(0, 0.0)
        assert_almost_equal(distance_radians(pos_0, ecef_points[0]), 0.0)

        pos_1 = ecef_path.calculate_position(1, 0.0)
        assert_almost_equal(distance_radians(pos_1, ecef_points[1]), 0.0)

        arc2 = Arc3d(ecef_points[1], ecef_points[2])
        arc3 = Arc3d(ecef_points[2], ecef_points[3])

        turn_arc2 = SphereTurnArc(arc2, arc3, TURN_DISTANCES[2])
        turn2_midpoint = turn_arc2.position(0.5 * abs(turn_arc2.angle))

        pos_2 = ecef_path.calculate_position(2, 0.000001)
        assert_almost_equal(distance_radians(pos_2, turn2_midpoint), 0.0)

        pos_1_99999 = ecef_path.calculate_position(1, 0.99999)
        assert_almost_equal(distance_radians(pos_1_99999, pos_2),
                            0.0,
                            decimal=6)

        pos_13 = ecef_path.calculate_position(13, 0.0)
        assert_almost_equal(distance_radians(pos_13, ecef_points[-1]), 0.0)
コード例 #14
0
    def test_SpherePath_subsection_positions(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        positions0 = ecef_path.subsection_positions(0, 1040.0)
        self.assertEqual(len(positions0), len(ecef_path))
        assert_almost_equal(distance_radians(positions0[0], ecef_points[0]),
                            0.0)
        assert_almost_equal(distance_radians(positions0[-1], ecef_points[-1]),
                            0.0)

        positions1 = ecef_path.subsection_positions(0, 1000.0)
        self.assertEqual(len(positions1), len(ecef_path))
        assert_almost_equal(distance_radians(positions1[0], ecef_points[0]),
                            0.0)
        assert_almost_equal(distance_radians(positions1[-2], ecef_points[-2]),
                            0.0)

        positions2 = ecef_path.subsection_positions(100.0, 1040.0)
        self.assertEqual(len(positions2), len(ecef_path) - 1)
        assert_almost_equal(distance_radians(positions2[1], ecef_points[2]),
                            0.0)
        assert_almost_equal(distance_radians(positions2[-1], ecef_points[-1]),
                            0.0)
コード例 #15
0
 def test_SpherePath_invalid_init(self):
     'The route has a duplicate point in the middle, so closer than MIN_LENGTH'
     INVALID_ROUTE_LATS = np.array([1.0, 1.0, 1.0, 1.0, -1.0, 1.0])
     INVALID_ROUTE_LONS = np.array([-3.0, -2.0, -1.0, -1.0, 1.0, 0.0])
     invalid_points = global_Point3d(INVALID_ROUTE_LATS, INVALID_ROUTE_LONS)
     zero_distances = np.zeros(len(invalid_points), dtype=float)
     self.assertRaises(ValueError, SpherePath, invalid_points,
                       zero_distances)
コード例 #16
0
    def test_SpherePath_calculate_ground_tracks(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        distances, types = ecef_path.section_distances_and_types()

        ground_tracks = ecef_path.calculate_ground_tracks(distances)
        self.assertEqual(len(ground_tracks), len(ecef_path) + 8)
        assert_almost_equal(ground_tracks[0], np.pi / 2, decimal=3)
コード例 #17
0
    def test_SpherePath_path_distances(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        path_distances = ecef_path.path_distances()
        self.assertEqual(len(path_distances), 12)

        assert_array_almost_equal(rad2nm(path_distances),
                                  EXPECTED_PATH_DISTANCES)
コード例 #18
0
    def test_derive_horizontal_path(self):
        test_data_home = env.get('TEST_DATA_HOME')
        self.assertTrue(test_data_home)

        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)
        ecef_path = derive_horizontal_path(ecef_points, ACROSS_TRACK_TOLERANCE)
        self.assertEqual(len(ecef_path), 12)
        assert_almost_equal(
            distance_radians(ecef_path.points[0], ecef_points[0]), 0.0)
        assert_almost_equal(
            distance_radians(ecef_path.points[-1], ecef_points[-1]), 0.0)
コード例 #19
0
    def test_SpherePath_calculate_cross_track_distances(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        xtds = ecef_path.calculate_cross_track_distances(
            ecef_points, EXPECTED_PATH_DISTANCES)
        self.assertEqual(len(xtds), len(ecef_points))
        assert_almost_equal(xtds[0], 0.0)
        assert_almost_equal(xtds[1], 0.0)
        assert_almost_equal(xtds[2], 4.1416795658323213)  # 10NM TID
        assert_almost_equal(xtds[3], 8.2824069920496726)  # 20NM TID
        assert_almost_equal(xtds[-1], 0.0)
コード例 #20
0
    def test_SpherePath_calculate_path_distances(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        distances = rad2nm(
            ecef_path.calculate_path_distances(ecef_points,
                                               ACROSS_TRACK_TOLERANCE))
        self.assertEqual(len(distances), len(ecef_points))
        self.assertEqual(distances[0], 0.0)
        assert_almost_equal(distances[11],
                            EXPECTED_PATH_DISTANCES[11],
                            decimal=6)
        assert_array_almost_equal(distances, EXPECTED_PATH_DISTANCES)
コード例 #21
0
    def test_find_index_and_ratio(self):
        ecef_points = global_Point3d(PANDAS_ICOSAHEDRON['LAT'],
                                     PANDAS_ICOSAHEDRON['LON'])

        point0 = ecef_points[0]
        index0, ratio0 = find_index_and_ratio(ecef_points, point0)
        self.assertEqual(index0, 0)
        assert_almost_equal(ratio0, 0.0)

        point0_5 = calculate_position(ecef_points, 0, 0.5)
        index0_5, ratio0_5 = find_index_and_ratio(ecef_points, point0_5)
        self.assertEqual(index0_5, 0)
        assert_almost_equal(ratio0_5, 0.5)

        point0_99 = calculate_position(ecef_points, 0, 0.99)
        index0_99, ratio0_99 = find_index_and_ratio(ecef_points, point0_99)
        self.assertEqual(index0_99, 0)
        assert_almost_equal(ratio0_99, 0.99)

        point1 = ecef_points[1]
        index1, ratio1 = find_index_and_ratio(ecef_points, point1)
        self.assertEqual(index1, 1)
        assert_almost_equal(ratio1, 0.0)

        point1_01 = calculate_position(ecef_points, 1, 0.01)
        index1_01, ratio1_01 = find_index_and_ratio(ecef_points, point1_01)
        self.assertEqual(index1_01, 1)
        assert_almost_equal(ratio1_01, 0.01)

        point5 = calculate_position(ecef_points, 5)
        index5, ratio5 = find_index_and_ratio(ecef_points, point5)
        self.assertEqual(index5, 5)
        assert_almost_equal(ratio5, 0.0)

        point7_5 = calculate_position(ecef_points, 7, 0.5)
        index7_5, ratio7_5 = find_index_and_ratio(ecef_points, point7_5)
        self.assertEqual(index7_5, 7)
        assert_almost_equal(ratio7_5, 0.5)

        point10_99 = calculate_position(ecef_points, 10, 0.99)
        index10_99, ratio10_99 = find_index_and_ratio(ecef_points, point10_99)
        self.assertEqual(index10_99, 10)
        assert_almost_equal(ratio10_99, 0.99)

        point11 = ecef_points[11]
        index11, ratio11 = find_index_and_ratio(ecef_points, point11)
        self.assertEqual(index11, 11)
        assert_almost_equal(ratio11, 0.0)
コード例 #22
0
def find_trajectory_user_airspace_intersections(smooth_traj):
    """
    Find airspace user airspace intersection positions from a smoothed trajectory.

    Parameters
    ----------
    smooth_traj: SmoothedTrajectory
        A SmoothedTrajectory containing the flight id, smoothed horizontal path,
        time profile and altitude profile.

    Returns
    -------
    intersection_positions: a pandas DataFrame
        The trajectory user airspace intersection positions.
        Empty if no intersections found.

    """
    lats = []
    lons = []
    volume_ids = []

    min_altitude = smooth_traj.altp.altitudes.min()
    max_altitude = smooth_traj.altp.altitudes.max()
    lats, lons, volume_ids = find_horizontal_user_airspace_intersections(
        smooth_traj.flight_id, smooth_traj.path.lats, smooth_traj.path.lons,
        min_altitude, max_altitude)
    if len(lats):
        # A dict to hold the intersected volumes
        volumes = {}
        try:
            for volume_id in set(volume_ids):
                volume_name = get_user_sector_name(volume_id)
                bottom_alt, top_alt = get_user_sector_altitude_range(volume_id)
                volumes.setdefault(
                    volume_id, AirspaceVolume(volume_name, bottom_alt,
                                              top_alt))
        except NotFoundException:
            log.exception('user airspace id: %s not found for flight id: %s',
                          volume_id, smooth_traj.flight_id)
            return pd.DataFrame()

        traj_path = smooth_traj.path.ecef_path()
        intersection_points = global_Point3d(np.array(lats), np.array(lons))
        return find_3D_airspace_intersections(smooth_traj, traj_path,
                                              intersection_points, volume_ids,
                                              volumes)
    else:
        return pd.DataFrame()
コード例 #23
0
    def test_find_3D_airspace_intersections(self):

        path_0 = HorizontalPath(ROUTE_LATS, ROUTE_LONS, TURN_DISTANCES)

        timep_0 = TimeProfile(START_TIME, DISTANCES, ELAPSED_TIMES)
        altp_0 = ALTITUDE_PROFILE

        traj_0 = SmoothedTrajectory('123-456-789', path_0, timep_0, altp_0)

        LATS = np.array([0., 20. / 60., 40. / 60., 60. / 60.])
        LONS = np.zeros(4, dtype=float)
        sector_ids = ['1', '2', '3', '1']
        points_0 = global_Point3d(LATS, LONS)
        df_3d = find_3D_airspace_intersections(traj_0, path_0.ecef_path(),
                                               points_0, sector_ids, SECTORS)
        self.assertEqual(df_3d.shape[0], 6)
コード例 #24
0
    def test_SpherePath_calculate_ground_track(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        track_0 = ecef_path.calculate_ground_track(0, 0.0)
        assert_almost_equal(track_0, np.pi / 2, decimal=3)  # close to due East

        track_2_5 = ecef_path.calculate_ground_track(2, 0.5)
        assert_almost_equal(track_2_5, np.pi)  # due south

        track_2_0 = ecef_path.calculate_ground_track(2, 0.0)
        assert_almost_equal(track_2_0, 0.75 * np.pi, decimal=3)  # South East

        track_12_0 = ecef_path.calculate_ground_track(12, 0.0)
        assert_almost_equal(track_12_0, 0.0)  # North
コード例 #25
0
    def test_calculate_turn_initiation_distance_90(self):
        # A 90 degree turn at the Equator
        LATS = np.array([0.0, 0.0, 1.0])
        LONS = np.array([1.0, 0.0, 0.0])
        ecef_points = global_Point3d(LATS, LONS)

        prev_arc = Arc3d(ecef_points[0], ecef_points[1])
        arc = Arc3d(ecef_points[1], ecef_points[2])
        TEN_NM = TWENTY_NM / 2
        turn_0 = SphereTurnArc(prev_arc, arc, TEN_NM)
        turn_angle_0 = turn_0.angle

        distance_start = calculate_turn_initiation_distance(
            prev_arc, arc, turn_0.start, TWENTY_NM, ACROSS_TRACK_TOLERANCE)
        assert_almost_equal(distance_start, TEN_NM)

        distance_finish = calculate_turn_initiation_distance(
            prev_arc, arc, turn_0.finish, TWENTY_NM, ACROSS_TRACK_TOLERANCE)
        assert_almost_equal(distance_finish, TEN_NM)

        point_1 = turn_0.position(turn_angle_0 / 2)
        distance_1 = calculate_turn_initiation_distance(
            prev_arc, arc, point_1, TWENTY_NM, ACROSS_TRACK_TOLERANCE)
        assert_almost_equal(distance_1, TEN_NM)

        point_2 = turn_0.position(turn_angle_0 / 4)
        distance_2 = calculate_turn_initiation_distance(
            prev_arc, arc, point_2, TWENTY_NM, ACROSS_TRACK_TOLERANCE)
        assert_almost_equal(distance_2, TEN_NM)

        point_3 = turn_0.position(3 * turn_angle_0 / 4)
        distance_3 = calculate_turn_initiation_distance(
            prev_arc, arc, point_3, TWENTY_NM, ACROSS_TRACK_TOLERANCE)
        assert_almost_equal(distance_3, TEN_NM)

        # Test with a point further than TWENTY_NM from the intersection
        turn_30 = SphereTurnArc(prev_arc, arc, TWENTY_NM + TEN_NM)
        distance_4 = calculate_turn_initiation_distance(
            prev_arc, arc, turn_30.start, TWENTY_NM, ACROSS_TRACK_TOLERANCE)
        self.assertEqual(distance_4, TWENTY_NM)

        point_30 = turn_30.position(3 * turn_angle_0 / 4)
        distance_30 = calculate_turn_initiation_distance(
            prev_arc, arc, point_30, TWENTY_NM, ACROSS_TRACK_TOLERANCE)
        self.assertEqual(distance_30, TWENTY_NM)
コード例 #26
0
    def test_calculate_2D_intersection_distances(self):
        path_0 = HorizontalPath(ROUTE_LATS, ROUTE_LONS, TURN_DISTANCES)

        LATS = np.array([20. / 60., 40. / 60., 60. / 60.])
        LONS = np.zeros(3, dtype=float)
        intersection_points = global_Point3d(LATS, LONS)
        sector_ids = ['2', '3', '1']
        start_distance = 0.
        distances_1 = calculate_2D_intersection_distances(
            path_0.ecef_path(), intersection_points, sector_ids,
            start_distance)
        self.assertEqual(len(distances_1), 3)

        start_distance = 20.
        distances_2 = calculate_2D_intersection_distances(
            path_0.ecef_path(), intersection_points, sector_ids,
            start_distance)
        self.assertEqual(len(distances_2), 3)
コード例 #27
0
    def test_SpherePath_calculate_positions(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        ecef_path = SpherePath(ecef_points, TURN_DISTANCES)

        distances, types = ecef_path.section_distances_and_types()

        positions = ecef_path.calculate_positions(distances)
        self.assertEqual(len(positions), len(ecef_path) + 8)

        assert_almost_equal(distance_radians(positions[0], ecef_points[0]),
                            0.0)
        assert_almost_equal(distance_radians(positions[1], ecef_points[1]),
                            0.0)
        assert_almost_equal(distance_radians(positions[-2], ecef_points[-2]),
                            0.0)
        assert_almost_equal(distance_radians(positions[-1], ecef_points[-1]),
                            0.0)
コード例 #28
0
    def test_calculate_intersection(self):
        ecef_points = global_Point3d(ROUTE_LATS, ROUTE_LONS)

        # intersection point between arcs on different Great Circles
        prev_arc = Arc3d(ecef_points[0], ecef_points[1])
        arc = Arc3d(ecef_points[1], ecef_points[2])
        point_1 = calculate_intersection(prev_arc, arc)
        assert_almost_equal(distance_radians(point_1, ecef_points[1]), 0.0)

        # intersection point between arcs on same Great Circles
        next_point = arc.position(2 * arc.length())
        next_arc = Arc3d(ecef_points[2], next_point)
        point_2 = calculate_intersection(arc, next_arc)
        assert_almost_equal(distance_radians(point_2, ecef_points[2]), 0.0)

        # intersection point between arcs on different Great Circles,
        # opposite direction turn
        prev_arc = Arc3d(ecef_points[5], ecef_points[6])
        arc = Arc3d(ecef_points[6], ecef_points[7])
        point_3 = calculate_intersection(prev_arc, arc)
        assert_almost_equal(distance_radians(point_3, ecef_points[6]), 0.0)
コード例 #29
0
    def test_find_3D_airspace_no_intersections(self):

        path_0 = HorizontalPath(ROUTE_LATS, ROUTE_LONS, TURN_DISTANCES)

        timep_0 = TimeProfile(START_TIME, DISTANCES, ELAPSED_TIMES)

        # Create a altitude profile above the sectors
        HIGH_ALTITUDES = np.array([
            10000., 11800., 13000., 13600., 14200., 15400., 16000., 16000.,
            16000., 16000., 15400., 14200.
        ])

        alt_p = AltitudeProfile(DISTANCES, HIGH_ALTITUDES)

        traj_0 = SmoothedTrajectory('123-456-789', path_0, timep_0, alt_p)

        LATS = np.array([0., 20. / 60., 40. / 60., 60. / 60.])
        LONS = np.zeros(4, dtype=float)
        sector_ids = ['1', '2', '3', '1']
        points_0 = global_Point3d(LATS, LONS)
        df_3d = find_3D_airspace_intersections(traj_0, path_0.ecef_path(),
                                               points_0, sector_ids, SECTORS)
        self.assertEqual(df_3d.shape[0], 0)
コード例 #30
0
    def test_calculate_position(self):
        ecef_points = global_Point3d(PANDAS_ICOSAHEDRON['LAT'],
                                     PANDAS_ICOSAHEDRON['LON'])

        point_0 = calculate_position(ecef_points, 0)
        assert_almost_equal(distance_radians(point_0, ecef_points[0]), 0.0)

        point_11 = calculate_position(ecef_points, 11)
        assert_almost_equal(distance_radians(point_11, ecef_points[-1]), 0.0)

        point_11_5 = calculate_position(ecef_points, 11, ratio=0.5)
        assert_almost_equal(distance_radians(point_11_5, ecef_points[-1]), 0.0)

        point_5_5 = calculate_position(ecef_points, 5, ratio=0.5)
        assert_almost_equal(distance_radians(point_5_5, ecef_points[5]),
                            0.5 * GOLDEN_ANGLE)
        assert_almost_equal(distance_radians(point_5_5, ecef_points[6]),
                            0.5 * GOLDEN_ANGLE)

        point_7_25 = calculate_position(ecef_points, 7, ratio=0.25)
        assert_almost_equal(distance_radians(point_7_25, ecef_points[7]),
                            0.25 * GOLDEN_ANGLE)
        assert_almost_equal(distance_radians(point_7_25, ecef_points[8]),
                            0.75 * GOLDEN_ANGLE)