def make_sample_trajectory():
    coordinates = [(0, 80), (90, 80), (180, 80), (-90, 80), (0, 80)]

    time_strings = [
        "2000-01-01 00:00:00", "2000-01-01 02:00:00", "2000-01-01 03:00:00",
        "2000-01-01 04:00:00", "2000-01-01 06:00:00"
    ]

    trajectory = TerrestrialTrajectory()
    for (coords, time_string) in zip(coordinates, time_strings):
        point = TerrestrialTrajectoryPoint(coords)
        point.object_id = 'terrestrial_dg_test'
        point.timestamp = datetime.datetime.strptime(time_string,
                                                     '%Y-%m-%d %H:%M:%S')
        trajectory.append(point)

    return trajectory
Exemplo n.º 2
0
def test_trajectory():
    print("Testing Trajectory class.")
    error_count = 0

    right_now = datetime.datetime.now(pytz.utc)

    boston = TerrestrialTrajectoryPoint(-71.0636, 42.3581)
    boston.timestamp = right_now
    boston.object_id = 'ContinentalExpress'
    boston.set_property('favorite_food', 'baked_beans')
    boston.set_property('name', 'Boston')

    miami = TerrestrialTrajectoryPoint(-80.2241, 25.7877)
    miami.timestamp = right_now + datetime.timedelta(hours=4)
    miami.object_id = 'ContinentalExpress'
    miami.set_property('favorite_food', 'cuban_sandwich')
    miami.set_property('name', 'Miami')

    san_francisco = TerrestrialTrajectoryPoint(-122.4167, 37.7833)
    san_francisco.timestamp = right_now + datetime.timedelta(hours=8)
    san_francisco.object_id = 'ContinentalExpress'
    san_francisco.set_property('favorite_food', 'Ghirardelli chocolate')
    san_francisco.set_property('name', 'San Francisco')

    seattle = TerrestrialTrajectoryPoint(-122.3331, 47.6097)
    seattle.timestamp = right_now + datetime.timedelta(hours=12)
    seattle.object_id = 'ContinentalExpress'
    seattle.set_property('favorite_food', 'seafood')
    seattle.set_property('name', 'Seattle')

    boston_return = TerrestrialTrajectoryPoint(-71.0636, 42.3581)
    boston_return.timestamp = right_now + datetime.timedelta(hours=16)
    boston_return.object_id = 'ContinentalExpress'
    boston_return.set_property('favorite_food', 'baked_beans')
    boston_return.set_property('name', 'Boston')

    round_trip = [boston, miami, san_francisco, seattle, boston_return]

    my_trajectory = TerrestrialTrajectory.from_position_list(round_trip)

    print("Testing from_position_list")
    if len(my_trajectory) != 5:
        sys.stderr.write(
            'ERROR: Expected length of trajectory to be 5 points but it was {}\n'
            .format(len(my_trajectory)))
        error_count += 1

    print("Sanity-checking first and last points")
    restored_point = my_trajectory[0]
    if restored_point != boston:
        sys.stderr.write(
            'ERROR: Expected first point in trajectory to be Boston.  Instead it claims to be {}.  Dumps of original and restored points follow.\n'
            .format(restored_point.property('name')))
        sys.stderr.write(str(boston))
        sys.stderr.write('\n')
        sys.stderr.write(str(my_trajectory[0]))
        sys.stderr.write('\n')

        error_count += 1

    if my_trajectory[-1] != boston_return:
        sys.stderr.write(
            'ERROR: Expected last point in trajectory to be Boston.  Instead it claims to be {}.\n'
            .format(my_trajectory[-1].property('name')))
        error_count += 1

    print("Testing duration")
    duration = my_trajectory.duration
    if (duration != datetime.timedelta(hours=16)):
        sys.stderr.write(
            'ERROR: Expected duration to be 16 hours.  Instead it claims to be {}.\n'
            .format(duration))
        error_count += 1

    print("Testing time_at_fraction, 0.25")
    first_quarter_time = geomath.time_at_fraction(my_trajectory, 0.25)
    delta = my_trajectory[-1].timestamp - right_now
    expected_first_quarter_time = right_now + (delta // 4)
    error_count += verify_time(expected_first_quarter_time, first_quarter_time,
                               "Time at fraction 0.25")

    print("Testing time_at_fraction, 0.75")
    last_quarter_time = geomath.time_at_fraction(my_trajectory, 0.75)
    delta = my_trajectory[-1].timestamp - right_now
    expected_last_quarter_time = right_now + ((3 * delta) // 4)
    error_count += verify_time(expected_last_quarter_time, last_quarter_time,
                               "Time at fraction 0.75")

    print("Testing time_at_fraction, 0.5")
    midpoint_time = geomath.time_at_fraction(my_trajectory, 0.5)
    expected_midpoint_time = (right_now +
                              (my_trajectory[-1].timestamp - right_now) // 2)
    error_count += verify_time(expected_midpoint_time, midpoint_time,
                               "Time at fraction 0.5")

    print("Testing time_at_fraction, 0.0")
    start_time = geomath.time_at_fraction(my_trajectory, 0.0)
    expected_start_time = right_now
    error_count += verify_time(expected_start_time, start_time,
                               "Time at fraction 0.0")

    print("Testing time_at_fraction, 1.0")
    end_time = geomath.time_at_fraction(my_trajectory, 1.0)
    expected_end_time = my_trajectory[-1].timestamp
    error_count += verify_time(expected_end_time, end_time,
                               "Time at fraction 1.0")

    print("Testing time_at_fraction, -0.5")
    before_time = geomath.time_at_fraction(my_trajectory, -0.5)
    expected_before_time = right_now
    error_count += verify_time(expected_before_time, before_time,
                               "Time at fraction -0.5")

    print("Testing time_at_fraction, 1.5")
    after_time = geomath.time_at_fraction(my_trajectory, 1.5)
    expected_after_time = my_trajectory[-1].timestamp
    error_count += verify_time(expected_after_time, after_time,
                               "Time at fraction 1.5")

    print("Testing time_at_fraction, 0.33")
    first_third_time = geomath.time_at_fraction(my_trajectory, 1.0 / 3.0)
    expected_third_quarter_time = (
        right_now + (my_trajectory[-1].timestamp - right_now) // 3)
    error_count += verify_time(expected_third_quarter_time, first_third_time,
                               "Time at fraction 0.33")

    print("Testing time_at_fraction, No Points")
    empty_trajectory = TerrestrialTrajectory()
    empty_time = geomath.time_at_fraction(empty_trajectory, 0.5)
    error_count += verify_time(
        datetime.datetime(1900, 1, 1, 0, 0, 0, 0, pytz.utc), empty_time,
        "Time at fraction (no points)")

    print("Testing point_at_fraction, 0.25")
    first_quarter_point = geomath.point_at_fraction(my_trajectory, 0.25)
    expected_first_quarter_point = TerrestrialTrajectoryPoint(
        -80.2241, 25.7877)
    expected_first_quarter_point.timestamp = right_now + datetime.timedelta(
        hours=4)
    error_count += verify_point(expected_first_quarter_point,
                                first_quarter_point, "Point at fraction 0.25")

    print("Testing point_at_fraction, 0.75")
    third_quarter_point = geomath.point_at_fraction(my_trajectory, 0.75)
    expected_third_quarter_point = TerrestrialTrajectoryPoint(
        -122.3331, 47.6097)
    expected_third_quarter_point.timestamp = right_now + datetime.timedelta(
        hours=12)
    error_count += verify_point(expected_third_quarter_point,
                                third_quarter_point, "Point at fraction 0.75")

    print("Testing point_at_fraction, 0.5")
    mid_point = geomath.point_at_fraction(my_trajectory, 0.5)
    expected_mid_point = TerrestrialTrajectoryPoint(-122.4167, 37.7833)
    expected_mid_point.timestamp = right_now + datetime.timedelta(hours=8)
    error_count += verify_point(expected_mid_point, mid_point,
                                "Point at fraction 0.5")

    print("Testing point_at_fraction, 0.0")
    start_point = geomath.point_at_fraction(my_trajectory, 0.0)
    expected_start_point = TerrestrialTrajectoryPoint(-71.0636, 42.3581)
    expected_start_point.timestamp = right_now
    error_count += verify_point(expected_start_point, start_point,
                                "Point at fraction 0.0")

    print("Testing point_at_fraction, 1.0")
    end_point = geomath.point_at_fraction(my_trajectory, 1.0)
    expected_end_point = TerrestrialTrajectoryPoint(-71.0636, 42.3581)
    expected_end_point.timestamp = right_now + datetime.timedelta(hours=16)
    error_count += verify_point(expected_end_point, end_point,
                                "Point at fraction 1.0")

    print("Testing point_at_fraction, -0.5")
    before_point = geomath.point_at_fraction(my_trajectory, -0.5)
    expected_before_point = TerrestrialTrajectoryPoint(-71.0636, 42.3581)
    expected_before_point.timestamp = right_now
    error_count += verify_point(expected_before_point, before_point,
                                "Point at fraction -0.5")

    print("Testing point_at_fraction, 1.5")
    after_point = geomath.point_at_fraction(my_trajectory, 1.5)
    expected_after_point = TerrestrialTrajectoryPoint(-71.0636, 42.3581)
    expected_after_point.timestamp = right_now + datetime.timedelta(hours=16)
    error_count += verify_point(expected_after_point, after_point,
                                "Point at fraction 1.5")

    print("Testing point_at_fraction, 0.33")
    first_third_point = geomath.point_at_fraction(my_trajectory, 1.0 / 3.0)
    expected_first_third_point = TerrestrialTrajectoryPoint(-92.9849, 31.3181)
    expected_first_third_point.timestamp = (
        right_now + (my_trajectory[-1].timestamp - right_now) // 3)
    error_count += verify_point(expected_first_third_point, first_third_point,
                                "Point at fraction 0.33")

    print("Testing point_at_fraction, No Points")
    no_point = geomath.point_at_fraction(empty_trajectory, 0.5)
    empty_point = TerrestrialTrajectoryPoint.zero()
    error_count += verify_point(no_point, empty_point,
                                "Point at fraction (no points)")

    print("Testing point_at_length_fraction, 0.25")
    first_quarter_point = geomath.point_at_length_fraction(my_trajectory, 0.25)
    expected_first_quarter_point = TerrestrialTrajectoryPoint(
        -87.3824, 29.1092)
    expected_first_quarter_point.timestamp = first_quarter_point.timestamp
    error_count += verify_point(expected_first_quarter_point,
                                first_quarter_point,
                                "Point at length fraction 0.25")

    print("Testing point_at_length_fraction, 0.75")
    third_quarter_point = geomath.point_at_length_fraction(my_trajectory, 0.75)
    expected_third_quarter_point = TerrestrialTrajectoryPoint(
        -106.489, 48.5709)
    expected_third_quarter_point.timestamp = third_quarter_point.timestamp
    error_count += verify_point(expected_third_quarter_point,
                                third_quarter_point,
                                "Point at length fraction 0.75")

    print("Testing point_at_length_fraction, 0.5")
    mid_point = geomath.point_at_length_fraction(my_trajectory, 0.5)
    expected_mid_point = TerrestrialTrajectoryPoint(-116.267, 37.0967)
    expected_mid_point.timestamp = mid_point.timestamp
    error_count += verify_point(expected_mid_point, mid_point,
                                "Point at length fraction 0.5")

    print("Testing point_at_length_fraction, 0.0")
    start_point = geomath.point_at_length_fraction(my_trajectory, 0.0)
    expected_start_point = TerrestrialTrajectoryPoint(-71.0636, 42.3581)
    expected_start_point.timestamp = right_now
    error_count += verify_point(expected_start_point, start_point,
                                "Point at length fraction 0.0")

    print("Testing point_at_length_fraction, 1.0")
    end_point = geomath.point_at_length_fraction(my_trajectory, 1.0)
    expected_end_point = TerrestrialTrajectoryPoint(-71.0636, 42.3581)
    expected_end_point.timestamp = right_now + datetime.timedelta(hours=16)
    error_count += verify_point(expected_end_point, end_point,
                                "Point at length fraction 1.0")

    print("Testing point_at_length_fraction, -0.5")
    before_point = geomath.point_at_length_fraction(my_trajectory, -0.5)
    expected_before_point = TerrestrialTrajectoryPoint(-71.0636, 42.3581)
    expected_before_point.timestamp = right_now
    error_count += verify_point(expected_before_point, before_point,
                                "Point at length fraction -0.5")

    print("Testing point_at_length_fraction, 1.5")
    after_point = geomath.point_at_length_fraction(my_trajectory, 1.5)
    expected_after_point = TerrestrialTrajectoryPoint(-71.0636, 42.3581)
    expected_after_point.timestamp = right_now + datetime.timedelta(hours=16)
    error_count += verify_point(expected_after_point, after_point,
                                "Point at length fraction 1.5")

    print("Testing point_at_length_fraction, 0.33")
    first_third_point = geomath.point_at_length_fraction(
        my_trajectory, 1.0 / 3.0)
    expected_first_third_point = TerrestrialTrajectoryPoint(-96.4035, 32.5023)
    expected_first_third_point.timestamp = first_third_point.timestamp
    error_count += verify_point(expected_first_third_point, first_third_point,
                                "Point at length fraction 0.33")

    print("Testing point_at_length_fraction, No Points")
    no_point = geomath.point_at_length_fraction(empty_trajectory, 0.5)
    empty_point = TerrestrialTrajectoryPoint.zero()
    error_count += verify_point(no_point, empty_point,
                                "Point at length fraction (no points)")

    print("Testing interpolation at timestamp before trajectory")
    before_time = right_now - datetime.timedelta(hours=4)
    before_point = geomath.point_at_time(my_trajectory, before_time)
    error_count += verify_point(boston, before_point,
                                "Point at time (-4 hours)")

    print("Testing interpolation at start timestamp of trajectory")
    start_time = right_now
    start_point = geomath.point_at_time(my_trajectory, start_time)
    error_count += verify_point(boston, start_point, "Point at time (0 hours)")

    print("Testing interpolation at first third timestamp of trajectory")
    first_third_time = right_now + datetime.timedelta(hours=16.0 / 3.0)
    first_third_point = geomath.point_at_time(my_trajectory, first_third_time)
    expected_first_third_point = TerrestrialTrajectoryPoint(-92.9849, 31.3181)
    expected_first_third_point.timestamp = right_now + datetime.timedelta(
        hours=16.0 / 3.0)
    error_count += verify_point(expected_first_third_point, first_third_point,
                                "Point at time (+5.33 hours)")

    print("Testing interpolation at mid timestamp of trajectory")
    mid_time = right_now + datetime.timedelta(hours=8)
    mid_point = geomath.point_at_time(my_trajectory, mid_time)
    error_count += verify_point(san_francisco, mid_point,
                                "Point at time (+8 hours)")

    print("Testing interpolation at end timestamp of trajectory")
    end_time = right_now + datetime.timedelta(hours=16)
    end_point = geomath.point_at_time(my_trajectory, end_time)
    error_count += verify_point(boston_return, end_point,
                                "Point at time (+16 hours)")

    print("Testing interpolation at timestamp after trajectory")
    after_time = right_now + datetime.timedelta(hours=20)
    after_point = geomath.point_at_time(my_trajectory, after_time)
    error_count += verify_point(boston_return, after_point,
                                "Point at time (+20 hours)")

    print("Testing interpolation at timestamp with no points trajectory")
    no_point = geomath.point_at_time(empty_trajectory,
                                     right_now + datetime.timedelta(hours=8))
    empty_point = TerrestrialTrajectoryPoint()
    error_count += verify_point(empty_point, no_point,
                                "Point at time (no points)")

    #    print("Testing pickle support")
    #    picklebuf = StringIO()
    #    pickle.dump(my_trajectory, picklebuf)
    #    restorebuf = StringIO(picklebuf.getvalue())
    #    restored_trajectory = pickle.load(restorebuf)

    #    if my_trajectory != restored_trajectory:
    #        sys.stderr.write('ERROR: Original trajectory is not the same as the one being restored from pickle jar.\n')
    #        sys.stderr.write('Original trajectory: {}'.format(my_trajectory))
    #        sys.stderr.write('Restored trajectory: {}'.format(restored_trajectory))
    #        error_count += 1

    if error_count == 0:
        print("Surface trajectory passed all tests.")

    return error_count
def test_convex_hull_perimeter():

    print("Testing Convex Hull Perimeter")

    error_count = 0

    albuquerque = create_point(35.0844, -106.6504, "short_flight")
    denver = create_point(39.7392, -104.9903, "short_flight")
    el_paso = create_point(31.7619, -106.4850, "short_flight")
    san_francisco = create_point(37.7749, -122.4194, "long_flight")
    new_york = create_point(40.7128, -74.0060, "long_flight")
    london = create_point(51.5074, -0.1278, "long_flight")
    london = create_point(51.5074, -0.1278, "long_flight")
    point1 = create_cart2_point(0, 0, "2d cartesian trajectory")
    point2 = create_cart2_point(0, 1, "2d cartesian trajectory")
    point3 = create_cart2_point(1, 1, "2d cartesian trajectory")
    point4 = create_cart2_point(1, 0, "2d cartesian trajectory")

    short_trajectory = TerrestrialTrajectory.from_position_list(
        [el_paso, albuquerque, denver])

    #Short trajectorty should have small perimeter
    expected_short_perimeter = 1804.9

    short_flight_perimeter = geomath.convex_hull_perimeter(short_trajectory)
    error_count += verify_result(expected_short_perimeter,
                                 short_flight_perimeter, "Short flight")

    long_trajectory = TerrestrialTrajectory.from_position_list(
        [san_francisco, new_york, london])

    #/Longer flight should have larger perimeter
    expected_long_perimeter = 18315.7

    long_flight_perimeter = geomath.convex_hull_perimeter(long_trajectory)
    error_count += verify_result(expected_long_perimeter,
                                 long_flight_perimeter, "Long flight")

    combined_trajectory = TerrestrialTrajectory.from_position_list(
        [el_paso, albuquerque, denver, san_francisco, new_york, london])

    #Combined flight should have slightly larger perimeter since there are more points relatively further away
    expected_combined_perimeter = 18843.2

    combined_perimeter = geomath.convex_hull_perimeter(combined_trajectory)
    error_count += verify_result(expected_combined_perimeter,
                                 combined_perimeter, "Combined flight")

    #No points in a trajectory should return 0
    expected_no_point_perimeter = 0.0

    no_points = TerrestrialTrajectory()
    no_point_perimeter = geomath.convex_hull_perimeter(no_points)
    error_count += verify_result(expected_no_point_perimeter,
                                 no_point_perimeter, "Empty flight")

    #One point in a trajectory should return 0
    expected_one_point_perimeter = 0.0

    one_point = TerrestrialTrajectory.from_position_list([el_paso])

    one_point_perimeter = geomath.convex_hull_perimeter(one_point)
    error_count += verify_result(expected_one_point_perimeter,
                                 one_point_perimeter, "One point flight")

    #Test Cartesian for good measure
    expected_cartesian2d_perimeter = 4

    cart_trajectory = Cartesian2dTrajectory.from_position_list(
        [point1, point2, point3, point4])

    cart2d_perimeter = geomath.convex_hull_perimeter(cart_trajectory)
    error_count += verify_result(expected_cartesian2d_perimeter,
                                 cart2d_perimeter, "Four points cartesian")

    print("\n")
    return error_count
def test_radius_of_gyration():

    print("Testing Radius of Gyration")

    error_count = 0;
    
    albuquerque = create_point(35.0844, -106.6504, "short_flight")
    denver = create_point(39.7392, -104.9903, "short_flight")
    el_paso = create_point(31.7619, -106.4850, "short_flight")
    san_francisco = create_point(37.7749, -122.4194, "long_flight")
    new_york = create_point(40.7128, -74.0060, "long_flight")
    london = create_point(51.5074, -0.1278, "long_flight")
    point1 = create_cart2_point(0,0, "2d cartesian trajectory")
    point2 = create_cart2_point(0,1, "2d cartesian trajectory")
    point3 = create_cart2_point(1,0, "2d cartesian trajectory")
    point4 = create_cart2_point(1,1, "2d cartesian trajectory")

    short_trajectory = TerrestrialTrajectory.from_position_list([el_paso, albuquerque, denver])

    #Short trajectorty should have small radius
    expected_short_radius = 0.0580509 * 6371.0

    short_flight_radius = geomath.radius_of_gyration(short_trajectory)
    error_count += verify_result(expected_short_radius, short_flight_radius, "Short flight")

    long_trajectory = TerrestrialTrajectory.from_position_list([san_francisco, new_york, london])

    #/Longer flight should have larger radius
    expected_long_radius = 0.581498 * 6371.0

    long_flight_radius = geomath.radius_of_gyration(long_trajectory)
    error_count += verify_result(expected_long_radius, long_flight_radius, "Long flight")

    combined_trajectory = TerrestrialTrajectory.from_position_list([el_paso, albuquerque, denver, san_francisco, new_york, london])

    #Combined flight should have smaller radius since there are more points relatively clustered together
    expected_combined_radius = 0.523586 * 6371.0

    combined_radius = geomath.radius_of_gyration(combined_trajectory)
    error_count += verify_result(expected_combined_radius, combined_radius, "Combined flight")

    #No points in a trajectory should return 0
    expected_no_point_radius = 0.0

    no_points = TerrestrialTrajectory()
    no_point_radius = geomath.radius_of_gyration(no_points)
    error_count += verify_result(expected_no_point_radius, no_point_radius, "Empty flight")

    #One point in a trajectory should return 0
    expected_one_point_radius = 0.0

    one_point = TerrestrialTrajectory.from_position_list([el_paso])
    
    one_point_radius = geomath.radius_of_gyration(one_point)
    error_count += verify_result(expected_one_point_radius, one_point_radius, "One point flight")

    #Test Cartesian for good measure
    expected_cartesian2d_radius = 0.707

    cart_trajectory = Cartesian2dTrajectory.from_position_list([point1, point2, point3, point4])
    
    cart2d_radius = geomath.radius_of_gyration(cart_trajectory)
    error_count += verify_result(expected_cartesian2d_radius, cart2d_radius, "Four points cartesian")

    print("\n")
    return error_count
def test_convex_hull_aspect_ratio():

    print("Testing Convex Hull Aspect_Ratio")

    error_count = 0

    albuquerque = create_point(35.0844, -106.6504, "short_flight")
    denver = create_point(39.7392, -104.9903, "short_flight")
    el_paso = create_point(31.7619, -106.4850, "short_flight")
    san_francisco = create_point(37.7749, -122.4194, "long_flight")
    new_york = create_point(40.7128, -74.0060, "long_flight")
    london = create_point(51.5074, -0.1278, "long_flight")
    point1 = create_cart2_point(0, 0, "2d cartesian trajectory")
    point2 = create_cart2_point(1, 0, "2d cartesian trajectory")
    point3 = create_cart2_point(1, 1, "2d cartesian trajectory")
    point4 = create_cart2_point(0, 1, "2d cartesian trajectory")

    short_trajectory = TerrestrialTrajectory.from_position_list(
        [el_paso, albuquerque, denver])

    #Short trajectorty should have small aspect_ratio
    expected_short_aspect_ratio = 21.14811

    short_flight_aspect_ratio = geomath.convex_hull_aspect_ratio(
        short_trajectory)
    error_count += verify_result(expected_short_aspect_ratio,
                                 short_flight_aspect_ratio, "Short flight")

    long_trajectory = TerrestrialTrajectory.from_position_list(
        [san_francisco, new_york, london])

    #/Longer flight should have larger aspect_ratio
    expected_long_aspect_ratio = 5.27049

    long_flight_aspect_ratio = geomath.convex_hull_aspect_ratio(
        long_trajectory)
    error_count += verify_result(expected_long_aspect_ratio,
                                 long_flight_aspect_ratio, "Long flight")

    combined_trajectory = TerrestrialTrajectory.from_position_list(
        [el_paso, albuquerque, denver, san_francisco, new_york, london])

    #Combined flight should have about the same aspect_ratio even though there are more points relatively further away
    expected_combined_aspect_ratio = 5.29825

    combined_aspect_ratio = geomath.convex_hull_aspect_ratio(
        combined_trajectory)
    error_count += verify_result(expected_combined_aspect_ratio,
                                 combined_aspect_ratio, "Combined flight")

    #No points in a trajectory should return 1
    expected_no_point_aspect_ratio = 1.0

    no_points = TerrestrialTrajectory()
    no_point_aspect_ratio = geomath.convex_hull_aspect_ratio(no_points)
    error_count += verify_result(expected_no_point_aspect_ratio,
                                 no_point_aspect_ratio, "Empty flight")

    #One point in a trajectory should return 0
    expected_one_point_aspect_ratio = 0.0

    one_point = TerrestrialTrajectory.from_position_list([el_paso])

    one_point_aspect_ratio = geomath.convex_hull_aspect_ratio(one_point)
    error_count += verify_result(expected_one_point_aspect_ratio,
                                 one_point_aspect_ratio, "One point flight")

    #Test Cartesian for good measure
    expected_cartesian2d_aspect_ratio = 1.41421

    cart_trajectory = Cartesian2dTrajectory.from_position_list(
        [point1, point2, point3, point4])

    cart2d_aspect_ratio = geomath.convex_hull_aspect_ratio(cart_trajectory)
    error_count += verify_result(expected_cartesian2d_aspect_ratio,
                                 cart2d_aspect_ratio, "Four points cartesian")

    print("\n")
    return error_count
def test_convex_hull_centroid():

    print("Testing Convex Hull Centroid")

    error_count = 0

    albuquerque = create_point(35.0844, -106.6504, "short_flight")
    denver = create_point(39.7392, -104.9903, "short_flight")
    el_paso = create_point(31.7619, -106.4850, "short_flight")
    san_francisco = create_point(37.7749, -122.4194, "long_flight")
    new_york = create_point(40.7128, -74.0060, "long_flight")
    london = create_point(51.5074, -0.1278, "long_flight")
    london = create_point(51.5074, -0.1278, "long_flight")
    point1 = create_cart2_point(0, 0, "2d cartesian trajectory")
    point2 = create_cart2_point(0, 1, "2d cartesian trajectory")
    point3 = create_cart2_point(1, 1, "2d cartesian trajectory")
    point4 = create_cart2_point(1, 0, "2d cartesian trajectory")

    short_trajectory = TerrestrialTrajectory.from_position_list(
        [el_paso, albuquerque, denver])

    #Short trajectorty should have centroid around albuquerque
    expected_short_centroid = create_point(35.5314, -106.069,
                                           "short_flight_centroid")

    short_flight_centroid = geomath.convex_hull_centroid(short_trajectory)
    error_count += verify_result(expected_short_centroid,
                                 short_flight_centroid, "Short flight")

    long_trajectory = TerrestrialTrajectory.from_position_list(
        [san_francisco, new_york, london])

    #/Longer flight should have larger centroid
    expected_long_centroid = create_point(55.4714, -72.1941,
                                          "long_flight_centroid")

    long_flight_centroid = geomath.convex_hull_centroid(long_trajectory)
    error_count += verify_result(expected_long_centroid, long_flight_centroid,
                                 "Long flight")

    combined_trajectory = TerrestrialTrajectory.from_position_list(
        [el_paso, albuquerque, denver, san_francisco, new_york, london])

    #Combined flight should have slightly larger centroid since there are more points relatively further away
    expected_combined_centroid = create_point(53.0855, -79.1866,
                                              "combined_flight_centroid")

    combined_centroid = geomath.convex_hull_centroid(combined_trajectory)
    error_count += verify_result(expected_combined_centroid, combined_centroid,
                                 "Combined flight")

    #No points in a trajectory should return 0
    expected_no_point_centroid = create_point(0.0, 0.0, "no_point_centroid")

    no_points = TerrestrialTrajectory()
    no_point_centroid = geomath.convex_hull_centroid(no_points)
    error_count += verify_result(expected_no_point_centroid, no_point_centroid,
                                 "Empty flight")

    #One point in a trajectory should return 0
    expected_one_point_centroid = create_point(0.0, 0.0, "one_point_centroid")

    one_point = TerrestrialTrajectory.from_position_list(
        [create_point(0.0, 0.0, "one_point_centroid")])

    one_point_centroid = geomath.convex_hull_centroid(one_point)
    error_count += verify_result(expected_one_point_centroid,
                                 one_point_centroid, "One point flight")

    #Test Cartesian for good measure
    expected_cartesian2d_centroid = create_cart2_point(0.5, 0.5,
                                                       "four_point_centroid")

    cart_trajectory = Cartesian2dTrajectory.from_position_list(
        [point1, point2, point3, point4])

    cart2d_centroid = geomath.convex_hull_centroid(cart_trajectory)
    error_count += verify_result(expected_cartesian2d_centroid,
                                 cart2d_centroid, "Four points cartesian")

    print("\n")
    return error_count