Ejemplo n.º 1
0
def generate_random_trajectory(prototype, num_point_properties,
                               num_trajectory_properties):
    object_id = 'test_object_{}'.format(random.randint(0, 1000))

    start_minute = random.randint(0, 1440 * 180)
    end_minute = start_minute + random.randint(0, 2880)

    start_time = datetime_from_minute_of_year(start_minute)
    end_time = datetime_from_minute_of_year(end_minute)

    endpoints = generate_random_points(
        prototype.domain_classes['TrajectoryPoint'], 2, num_point_properties)
    endpoints[0].object_id = object_id
    endpoints[1].object_id = object_id
    endpoints[0].timestamp = Timestamp.from_any(start_time)
    endpoints[1].timestamp = Timestamp.from_any(end_time)

    print("generate_random_trajectory: Start point is {}".format(endpoints[0]))

    return generate_trajectory_from_endpoints(
        endpoints[0],
        endpoints[1],
        10,
        #int((end_minute - start_minute) / 2),
        num_trajectory_properties)
Ejemplo n.º 2
0
def trajectory_from_dictionary(dictionary):
    """Returns a trajectory constructed from the given dictionary.
    Args:
       dictionary: the dictionary to convert into a trajectory
    """

    #verify domain is valid and import appropriate domain
    try:
        domain = importlib.import_module("tracktable.domain."+
                                         dictionary['domain'].lower())
    except ImportError:
        raise ValueError("Error: invalid domain name: "+dictionary['domain'].lower())

    dimension = domain.DIMENSION

    #verify each coordinate matches dimension
    points = []
    numPoints = len(dictionary['coordinates'])
    for point in dictionary['coordinates']:
        if len(point) != dimension:
            raise ValueError("Error: point " + str(point) + " has "+ str(len(point)) + " coordinate(s), expected " + str(dimension)+".")

    #verify point properties values lists are of equal length
    for (name, attributes) in dictionary['point_properties'].items():
        if len(attributes['values']) != numPoints:
            raise ValueError("Error: "+name+" property has only " + str(len(attributes['values'])) + " values, but there are " + str(numPoints) + " points in the trajectory.")

    #verify there are the right number of timestamps
    if len(dictionary['timestamps']) != numPoints:
        raise ValueError("Error: Only " + str(len(dictionary['timestamps'])) + " timestamp values, but there are " + str(numPoints) + " points in the trajectory.")

    #verify object_id is a string
    if not isinstance(dictionary['object_id'], str):
        raise ValueError("Error: object_id must be a string, but got a value of type "+type(dictionary['object_id']).__name__)

    #generate points / position list
    for i in range(numPoints):
        point = domain.TrajectoryPoint(dictionary['coordinates'][i])
        point.object_id = dictionary['object_id']
        point.timestamp = Timestamp.from_string(dictionary['timestamps'][i])
        for (name, attributes) in dictionary['point_properties'].items():
            if attributes['type'] == "datetime" or attributes['type'] == "timestamp":  #okay to support both?  todo
                point.set_property(name, Timestamp.from_string(attributes['values'][i], format_string='%Y-%m-%d %H:%M:%S'))
            else:
                point.set_property(name, attributes['values'][i])
        points.append(point)

    #make trajectory
    trajectory = domain.Trajectory.from_position_list(points)

    #add trajectory properties
    for (name, attributes) in dictionary['trajectory_properties'].items():
        if attributes['type'] == "datetime" or attributes['type'] == "timestamp":  #okay to support both?  todo
            trajectory.set_property(name, Timestamp.from_string(attributes['value'], format_string='%Y-%m-%d %H:%M:%S'))
        else:
            trajectory.set_property(name, attributes['value'])

    return trajectory
def truncate_fractional_seconds(timestamp):
    return Timestamp.from_any(datetime.datetime(year=timestamp.year,
                                                month=timestamp.month,
                                                day=timestamp.day,
                                                hour=timestamp.hour,
                                                minute=timestamp.minute,
                                                second=timestamp.second))
Ejemplo n.º 4
0
def generate_random_points(prototype, num_points, num_point_properties=6):
    points = []

    for i in range(num_points):
        next_point = prototype()
        for i in range(len(next_point)):
            coord = random.uniform(-1000, 1000)
            # truncate to 5 significant figures
            coord = 0.01 * int(100 * coord)
            next_point[i] = coord

        if hasattr(next_point, 'object_id'):
            next_point.object_id = 'test_object_{}'.format(num_points)

        if hasattr(next_point, 'timestamp'):
            next_point.timestamp = Timestamp.from_any(
                datetime_from_minute_of_year(random.randint(0, 365 * 1440)))

        if next_point.domain_classes['BasePoint'] == terrestrial.BasePoint:
            restrict_point_to_globe(next_point)

        assign_random_properties(next_point, num_point_properties)
        points.append(next_point)

    return points
def generate_random_points(prototype,
                           num_points,
                           num_point_properties=6):
    points = []

    for i in range(num_points):
        next_point = prototype()
        for i in range(len(next_point)):
            coord = random.uniform(-1000, 1000)
            # truncate to 5 significant figures
            coord = 0.01 * int(100 * coord)
            next_point[i] = coord

        if hasattr(next_point, 'object_id'):
            next_point.object_id = 'test_object_{}'.format(num_points)

        if hasattr(next_point, 'timestamp'):
            next_point.timestamp = Timestamp.from_any(datetime_from_minute_of_year(random.randint(0, 365*1440)))

        if next_point.domain_classes['BasePoint'] == terrestrial.BasePoint:
            restrict_point_to_globe(next_point)

        assign_random_properties(next_point, num_point_properties)
        points.append(next_point)

    return points
Ejemplo n.º 6
0
def run_test():
    figure = pyplot.figure(figsize=(8, 6), dpi=100)
    axes = figure.add_axes([0, 0, 1, 1], frameon=False, axisbg='black')
    axes.set_frame_on(False)

    my_timestamp = Timestamp.from_any('2013-06-07 23:18:54-0500')

    def format_time1(timestamp):
        return Timestamp.to_string(timestamp)

    def format_time2(timestamp):
        hours = timestamp.time().hour
        minutes = timestamp.time().minute
        if minutes < 30:
            minutes = 0
        else:
            minutes = 30

        new_timestamp = datetime.datetime(year=my_timestamp.date().year,
                                          month=my_timestamp.date().month,
                                          day=my_timestamp.date().day,
                                          hour=hours,
                                          minute=minutes,
                                          second=0,
                                          tzinfo=timestamp.tzinfo)

        new_timestamp = new_timestamp.astimezone(pytz.timezone('US/Pacific'))

        print("format_time2: new timestamp is {}".format(str(new_timestamp)))

        return Timestamp.to_string(new_timestamp, format_string='%H:%M', include_tz=False)

    (mymap, artists) = maps.predefined_map('conus', ax=axes)

    clock_artist1 = clock.digital_clock(my_timestamp,
                                        format_time1,
                                        (0.1, 0.1),
                                        family='fantasy',
                                        ha='left',
                                        va='top',
                                        size=24,
#                                        rotation=45,
                                        weight='normal',
                                        zorder=10)

    clock_artist2 = clock.digital_clock(my_timestamp,
                                        format_time2,
                                        (0.95, 0.95),
                                        ha='right',
                                        va='baseline',
                                        family='cursive',
                                        weight='light',
                                        color='white',
                                        size=12,
                                        backgroundcolor='black',
                                        zorder=10)

    pyplot.savefig('/tmp/test_digital_clock.png')
    return 0
Ejemplo n.º 7
0
def truncate_fractional_seconds(timestamp):
    return Timestamp.from_any(
        datetime.datetime(year=timestamp.year,
                          month=timestamp.month,
                          day=timestamp.day,
                          hour=timestamp.hour,
                          minute=timestamp.minute,
                          second=timestamp.second))
Ejemplo n.º 8
0
def format_time(timestamp, utc_offset=0, timezone_name=''):
    minutes = timestamp.time().minute
    minutes = 15 * int(minutes / 15)
    local_timezone = SimpleTimeZone(hours=utc_offset)
    newtime = timestamp.replace(minute=minutes).astimezone(local_timezone)

    timestring = Timestamp.to_string(newtime, format_string='%Y-%m-%d %H:%M', include_tz=False)
    return timestring
    def test_no_time_zone_iso(self):
        timestring = '2014-12-25T13:12:45'
        parsed_timestamp = Timestamp.from_string(timestring)
        constructed_timestamp = datetime(2014, 12, 25,
                                         hour=13, minute=12, second=45,
                                         tzinfo=pytz.utc)

        self.assertTrue(parsed_timestamp.tzinfo is not None)
        self.assertTrue(parsed_timestamp == constructed_timestamp)
def format_time(timestamp, utc_offset=0, timezone_name=''):
    minutes = timestamp.time().minute
    minutes = 15 * int(minutes / 15)
    local_timezone = SimpleTimeZone(hours=utc_offset)
    newtime = timestamp.replace(minute=minutes).astimezone(local_timezone)

    timestring = Timestamp.to_string(newtime,
                                     format_string='%Y-%m-%d %H:%M',
                                     include_tz=False)
    return timestring
Ejemplo n.º 11
0
    def my_format_time(timestamp):
        minutes = timestamp.time().minute
        minutes = 15 * int(minutes / 15)
        local_timezone = SimpleTimeZone(hours=utc_offset)
        newtime = timestamp.replace(minute=minutes).astimezone(local_timezone)

        timestring = Timestamp.to_string(newtime, format_string='%Y-%m-%d\n%H:%M {}'.format(
            timezone_label), include_tz=False)

        return timestring
def write_trajectory(trajectory, outfile):
    writer = csv.writer(outfile, delimiter=',')
    writer.writerow([ '# object_id', 'timestamp', 'longitude', 'latitude', 'altitude' ])
    for point in trajectory:
        latest_row = [ point.object_id,
                       Timestamp.to_string(point.timestamp, include_dst=False),
                       str(point.longitude),
                       str(point.latitude),
                       str(int(point.altitude)) ]
        writer.writerow(latest_row)
    def test_with_time_zone_iso(self):
        timestring = '2014-12-25T10:12:45-0300'
        parsed_timestamp = Timestamp.from_string(
            timestring,
            format_string='%Y-%m-%dT%H:%M:%S%z')
        constructed_timestamp = datetime(2014, 12, 25,
                                         hour=13, minute=12, second=45,
                                         tzinfo=pytz.utc)

        self.assertTrue(parsed_timestamp.tzinfo is not None)
        self.assertTrue(parsed_timestamp == constructed_timestamp)
    def my_format_time(timestamp):
        minutes = timestamp.time().minute
        minutes = 15 * int(minutes / 15)
        local_timezone = SimpleTimeZone(hours=utc_offset)
        newtime = timestamp.replace(minute=minutes).astimezone(local_timezone)

        timestring = Timestamp.to_string(
            newtime,
            format_string='%Y-%m-%d\n%H:%M {}'.format(timezone_label),
            include_tz=False)

        return timestring
Ejemplo n.º 15
0
    def gen_json_and_trajectory(self):
        domain = tracktable.domain.terrestrial
        json = "{\"coordinates\": [[26.995, -81.9731], [27.0447, -81.9844], [27.1136, -82.0458]], \"domain\": \"terrestrial\", \"object_id\": \"AAA001\", \"point_properties\": {\"altitude\": {\"type\": \"int\", \"values\": [2700, 4200, 6700]}, \"heading\": {\"type\": \"float\", \"values\": [108.1, 108.2, 225.3]}, \"note\": {\"type\": \"str\", \"values\": [\"hello\", \"world\", \"!\"]}, \"time2\": {\"type\": \"datetime\", \"values\": [\"2004-01-01 00:00:01\", \"2004-01-01 00:00:02\", \"2004-01-01 00:00:03\"]}}, \"timestamps\": [\"2004-12-07 11:36:18\", \"2004-12-07 11:37:56\", \"2004-12-07 11:39:18\"], \"trajectory_properties\": {\"percent\": {\"type\": \"float\", \"value\": 33.333}, \"platform\": {\"type\": \"str\", \"value\": \"Boeing 747\"}, \"start\": {\"type\": \"datetime\", \"value\": \"2004-12-07 11:36:00\"}, \"tailNum\": {\"type\": \"int\", \"value\": 3878}}}"

        # Manually set up a matching Trajectory object
        p1 = domain.TrajectoryPoint()
        p1[0] = 26.995
        if domain.DIMENSION > 1:
            p1[1] = -81.9731
        if domain.DIMENSION > 2:
            p1[2] = -100.0
        p1.set_property('altitude', 2700)
        p1.set_property('heading', 108.1)
        p1.set_property('note', "hello")
        p1.set_property('time2', Timestamp.from_string('2004-01-01 00:00:01'))
        p1.object_id = 'AAA001'
        p1.timestamp = Timestamp.from_string('2004-12-07 11:36:18',
                                             format_string='%Y-%m-%d %H:%M:%S')

        p2 = domain.TrajectoryPoint()
        p2[0] = 27.0447
        if domain.DIMENSION > 1:
            p2[1] = -81.9844
        if domain.DIMENSION > 2:
            p2[2] = -101.0
        p2.set_property('altitude', 4200)
        p2.set_property('heading', 108.2)
        p2.set_property('note', "world")
        p2.set_property('time2', Timestamp.from_string('2004-01-01 00:00:02'))
        p2.object_id = 'AAA001'
        p2.timestamp = Timestamp.from_string('2004-12-07 11:37:56',
                                             format_string='%Y-%m-%d %H:%M:%S')

        p3 = domain.TrajectoryPoint()
        p3[0] = 27.1136
        if domain.DIMENSION > 1:
            p3[1] = -82.0458
        if domain.DIMENSION > 2:
            p3[2] = -102.0
        p3.set_property('altitude', 6700)
        p3.set_property('heading', 225.3)
        p3.set_property('note', "!")
        p3.set_property('time2', Timestamp.from_string('2004-01-01 00:00:03'))
        p3.object_id = 'AAA001'
        p3.timestamp = Timestamp.from_string('2004-12-07 11:39:18',
                                             format_string='%Y-%m-%d %H:%M:%S')

        trajectory = domain.Trajectory.from_position_list([p1, p2, p3])
        trajectory.set_property('percent', 33.333)
        trajectory.set_property('platform', "Boeing 747")
        trajectory.set_property('start',
                                Timestamp.from_string('2004-12-07 11:36:00'))
        trajectory.set_property('tailNum', 3878)

        return json, trajectory
Ejemplo n.º 16
0
def dictionary_from_trajectory(trajectory):
    """Returns a dictionary constructed from the given trajectory
    Args:
       trajectory: the trajectory to convert into a dictonary representation
    """

    dictionary = {}
    dictionary['domain'] = trajectory.DOMAIN
    dictionary['object_id'] = trajectory[0].object_id

    # set trajectory properties
    dictionary['trajectory_properties'] = {}
    for (name, value) in trajectory.properties.items():
        if isinstance(value, datetime.datetime):
            dictionary['trajectory_properties'].update({name: {'type': type(value).__name__, 'value': Timestamp.to_string(value, include_tz=False)}})
        else:
            dictionary['trajectory_properties'].update({name: {'type': type(value).__name__, 'value': value}})

    # initialize timestamps and coordinates
    dictionary['timestamps'] = []
    dictionary['coordinates'] = []

    # initialize point properties
    dictionary['point_properties'] = {}
    for (name, value) in trajectory[0].properties.items():
        dictionary['point_properties'].update({name: {'type': type(value).__name__, 'values': []}})

    # set timestamps, coordinates and point_properties
    for i in range(len(trajectory)):
        dictionary['timestamps'].append(Timestamp.to_string(trajectory[i].timestamp,
                                                            include_tz=False))
        dictionary['coordinates'].append(tuple(trajectory[i]))
        for (name, value) in trajectory[i].properties.items():
            if isinstance(value, datetime.datetime):
                dictionary['point_properties'][name]['values'].append(Timestamp.to_string(value, include_tz=False))
            else:
                dictionary['point_properties'][name]['values'].append(value)

    return dictionary
    def test_no_time_zone_iso(self):
        timestring = '2014-12-25T13:12:45'
        parsed_timestamp = Timestamp.from_string(timestring)
        constructed_timestamp = datetime(2014,
                                         12,
                                         25,
                                         hour=13,
                                         minute=12,
                                         second=45,
                                         tzinfo=pytz.utc)

        self.assertTrue(parsed_timestamp.tzinfo is not None)
        self.assertTrue(parsed_timestamp == constructed_timestamp)
Ejemplo n.º 18
0
    def test_with_time_zone_iso(self):
        timestring = '2014-12-25T10:12:45-0300'
        parsed_timestamp = Timestamp.from_string(
            timestring, format_string='%Y-%m-%dT%H:%M:%S%z')
        constructed_timestamp = datetime(2014,
                                         12,
                                         25,
                                         hour=13,
                                         minute=12,
                                         second=45,
                                         tzinfo=pytz.utc)

        self.assertTrue(parsed_timestamp.tzinfo is not None)
        self.assertTrue(parsed_timestamp == constructed_timestamp)
def create_trajectory():
    los_angeles = AirTrajectoryPoint( -118.25, 34.05 )
    los_angeles.object_id = 'TEST'
    los_angeles.timestamp = Timestamp.from_any('2014-01-01 00:00:00')
    los_angeles.properties['altitude'] = 0

    new_york = AirTrajectoryPoint( -74.0, 40.71 )



    source = path_point_source.TrajectoryPointSource(AirTrajectoryPoint)
    source.start_time = 
    source.end_time = Timestamp.from_any('2014-01-01 04:00:00')
    source.start_point = los_angeles
    source.end_point = new_york
    source.num_points = 240
    source.object_id = 'TEST'

    all_points = list(source.points())

    # Now we need to add altitude.  Let's say that we get to maximum
    # altitude (50,000 feet) at point 90.  We start descending at
    # point 150 and get back to zero altitude at point 240.
    max_altitude = 50000
    for i in range(240):
        all_points[i].altitude = max_altitude

    for i in range(90):
        x = float(i) / 90

        level = 1 - (x-1)*(x-1)
        altitude = level * max_altitude
        all_points[i].altitude = altitude
        all_points[-(i+1)].altitude = altitude

    trajectory = AirTrajectory.from_position_list(all_points)
    return trajectory
Ejemplo n.º 20
0
    def gen_json_and_trajectory(self):
        domain = tracktable.domain.terrestrial
        json = "{\"coordinates\": [[26.995, -81.9731], [27.0447, -81.9844], [27.1136, -82.0458]], \"domain\": \"terrestrial\", \"object_id\": \"AAA001\", \"point_properties\": {\"altitude\": {\"type\": \"int\", \"values\": [2700, 4200, 6700]}, \"heading\": {\"type\": \"float\", \"values\": [108.1, 108.2, 225.3]}, \"note\": {\"type\": \"str\", \"values\": [\"hello\", \"world\", \"!\"]}, \"time2\": {\"type\": \"datetime\", \"values\": [\"2004-01-01 00:00:01\", \"2004-01-01 00:00:02\", \"2004-01-01 00:00:03\"]}}, \"timestamps\": [\"2004-12-07 11:36:18\", \"2004-12-07 11:37:56\", \"2004-12-07 11:39:18\"], \"trajectory_properties\": {\"percent\": {\"type\": \"float\", \"value\": 33.333}, \"platform\": {\"type\": \"str\", \"value\": \"Boeing 747\"}, \"start\": {\"type\": \"datetime\", \"value\": \"2004-12-07 11:36:00\"}, \"tailNum\": {\"type\": \"int\", \"value\": 3878}}}"

        # Manually set up a matching Trajectory object
        p1 = domain.TrajectoryPoint()
        p1[0] = 26.995;
        if domain.DIMENSION > 1:
            p1[1] = -81.9731
        if domain.DIMENSION > 2:
            p1[2] = -100.0
        p1.set_property('altitude', 2700)
        p1.set_property('heading', 108.1)
        p1.set_property('note', "hello")
        p1.set_property('time2', Timestamp.from_string('2004-01-01 00:00:01'))
        p1.object_id = 'AAA001'
        p1.timestamp = Timestamp.from_string('2004-12-07 11:36:18', format_string='%Y-%m-%d %H:%M:%S')

        p2 = domain.TrajectoryPoint()
        p2[0] = 27.0447;
        if domain.DIMENSION > 1:
            p2[1] = -81.9844
        if domain.DIMENSION > 2:
            p2[2] = -101.0
        p2.set_property('altitude', 4200)
        p2.set_property('heading', 108.2)
        p2.set_property('note', "world")
        p2.set_property('time2', Timestamp.from_string('2004-01-01 00:00:02'))
        p2.object_id = 'AAA001'
        p2.timestamp = Timestamp.from_string('2004-12-07 11:37:56', format_string='%Y-%m-%d %H:%M:%S')

        p3 = domain.TrajectoryPoint()
        p3[0] = 27.1136;
        if domain.DIMENSION > 1:
            p3[1] = -82.0458
        if domain.DIMENSION > 2:
            p3[2] = -102.0
        p3.set_property('altitude', 6700)
        p3.set_property('heading', 225.3)
        p3.set_property('note', "!")
        p3.set_property('time2', Timestamp.from_string('2004-01-01 00:00:03'))
        p3.object_id = 'AAA001'
        p3.timestamp = Timestamp.from_string('2004-12-07 11:39:18', format_string='%Y-%m-%d %H:%M:%S')

        trajectory = domain.Trajectory.from_position_list([p1,p2,p3])
        trajectory.set_property('percent', 33.333)
        trajectory.set_property('platform', "Boeing 747")
        trajectory.set_property('start', Timestamp.from_string('2004-12-07 11:36:00'))
        trajectory.set_property('tailNum', 3878)

        return json, trajectory
def generate_random_trajectory(prototype, num_point_properties, num_trajectory_properties):
    object_id = 'test_object_{}'.format(random.randint(0,1000))

    start_minute = random.randint(0, 1440 * 180)
    end_minute = start_minute + random.randint(0, 2880)

    start_time = datetime_from_minute_of_year(start_minute)
    end_time = datetime_from_minute_of_year(end_minute)

    endpoints = generate_random_points(prototype.domain_classes['TrajectoryPoint'], 2, num_point_properties)
    endpoints[0].object_id = object_id
    endpoints[1].object_id = object_id
    endpoints[0].timestamp = Timestamp.from_any(start_time)
    endpoints[1].timestamp = Timestamp.from_any(end_time)

    print("generate_random_trajectory: Start point is {}".format(endpoints[0]))

    return generate_trajectory_from_endpoints(
        endpoints[0],
        endpoints[1],
        10,
        #int((end_minute - start_minute) / 2),
        num_trajectory_properties
        )
    def test_with_time_zone_iso(self):
        if sys.version_info[0] == 3:
            timestring = '2014-12-25T10:12:45-0300'
            parsed_timestamp = Timestamp.from_string(
                timestring, format_string='%Y-%m-%dT%H:%M:%S%z')
            constructed_timestamp = datetime(2014,
                                             12,
                                             25,
                                             hour=13,
                                             minute=12,
                                             second=45,
                                             tzinfo=pytz.utc)

            self.assertTrue(parsed_timestamp.tzinfo is not None)
            self.assertTrue(parsed_timestamp == constructed_timestamp)
        else:
            print("Time zone parsing is only supported in Python 3")
            self.assertTrue(True)
Ejemplo n.º 23
0
    def format_time2(timestamp):
        hours = timestamp.time().hour
        minutes = timestamp.time().minute
        if minutes < 30:
            minutes = 0
        else:
            minutes = 30

        new_timestamp = datetime.datetime(year=my_timestamp.date().year,
                                          month=my_timestamp.date().month,
                                          day=my_timestamp.date().day,
                                          hour=hours,
                                          minute=minutes,
                                          second=0,
                                          tzinfo=timestamp.tzinfo)

        new_timestamp = new_timestamp.astimezone(pytz.timezone('US/Pacific'))

        print("format_time2: new timestamp is {}".format(str(new_timestamp)))

        return Timestamp.to_string(new_timestamp, format_string='%H:%M', include_tz=False)
Ejemplo n.º 24
0
    def format_time2(timestamp):
        hours = timestamp.time().hour
        minutes = timestamp.time().minute
        if minutes < 30:
            minutes = 0
        else:
            minutes = 30

        new_timestamp = datetime.datetime(year=my_timestamp.date().year,
                                          month=my_timestamp.date().month,
                                          day=my_timestamp.date().day,
                                          hour=hours,
                                          minute=minutes,
                                          second=0,
                                          tzinfo=timestamp.tzinfo)

        new_timestamp = new_timestamp.astimezone(pytz.timezone('US/Pacific'))

        print("format_time2: new timestamp is {}".format(str(new_timestamp)))

        return Timestamp.to_string(new_timestamp,
                                   format_string='%H:%M',
                                   include_tz=False)
    def gen_dictionary_and_trajectory(self, domainString):
        domain = importlib.import_module("tracktable.domain."+domainString.lower())

        # Manually set up a dictionary which contains trajectory info
        dictionary = {'domain'                : domainString.lower(),
                      'object_id'             : 'AAA001',
                      'trajectory_properties' : {'percent' : {'type': 'float',    'value': 33.333},
                                                 'platform': {'type': 'str',      'value': "Boeing 747"},
                                                 'start'   : {'type': 'datetime', 'value': "2004-12-07 11:36:00"},
                                                 'tailNum' : {'type': 'int',      'value': 3878}},
                      'timestamps'            : ['2004-12-07 11:36:18',#-0000',
                                                 '2004-12-07 11:37:56',#-0000',
                                                 '2004-12-07 11:39:18'],#-0000'],
                      'point_properties'      : {'altitude': {'type': 'int',      'values': [2700, 4200, 6700]},
                                                 'heading' : {'type': 'float',    'values': [108.1, 108.2, 225.3]},
                                                 'note'    : {'type': 'str',      'values': ["hello", "world", "!"]},
                                                 'time2'   : {'type': 'datetime', 'values': ["2004-01-01 00:00:01",
                                                                                             "2004-01-01 00:00:02",
                                                                                             "2004-01-01 00:00:03"]} }
        }
        if domain.DIMENSION == 1:
            dictionary.update({'coordinates' : [(26.995), (27.0447), (27.1136)]})
        if domain.DIMENSION == 2:
            dictionary.update({'coordinates' : [(26.995, -81.9731), (27.0447, -81.9844), (27.1136, -82.0458)]})
        if domain.DIMENSION == 3:
            dictionary.update({'coordinates' : [(26.995, -81.9731, -100.0), (27.0447, -81.9844, -101.0), (27.1136, -82.0458, -102.0)]})

        # Manually set up a matching Trajectory object
        p1 = domain.TrajectoryPoint()
        p1[0] = 26.995;
        if domain.DIMENSION > 1:
            p1[1] = -81.9731
        if domain.DIMENSION > 2:
            p1[2] = -100.0
        p1.set_property('altitude', 2700)
        p1.set_property('heading', 108.1)
        p1.set_property('note', "hello")
        p1.set_property('time2', Timestamp.from_string('2004-01-01 00:00:01'))
        p1.object_id = 'AAA001'
        p1.timestamp = Timestamp.from_string('2004-12-07 11:36:18', format_string='%Y-%m-%d %H:%M:%S')

        p2 = domain.TrajectoryPoint()
        p2[0] = 27.0447;
        if domain.DIMENSION > 1:
            p2[1] = -81.9844
        if domain.DIMENSION > 2:
            p2[2] = -101.0
        p2.set_property('altitude', 4200)
        p2.set_property('heading', 108.2)
        p2.set_property('note', "world")
        p2.set_property('time2', Timestamp.from_string('2004-01-01 00:00:02'))
        p2.object_id = 'AAA001'
        p2.timestamp = Timestamp.from_string('2004-12-07 11:37:56', format_string='%Y-%m-%d %H:%M:%S')

        p3 = domain.TrajectoryPoint()
        p3[0] = 27.1136;
        if domain.DIMENSION > 1:
            p3[1] = -82.0458
        if domain.DIMENSION > 2:
            p3[2] = -102.0
        p3.set_property('altitude', 6700)
        p3.set_property('heading', 225.3)
        p3.set_property('note', "!")
        p3.set_property('time2', Timestamp.from_string('2004-01-01 00:00:03'))
        p3.object_id = 'AAA001'
        p3.timestamp = Timestamp.from_string('2004-12-07 11:39:18', format_string='%Y-%m-%d %H:%M:%S')

        trajectory = domain.Trajectory.from_position_list([p1,p2,p3])
        trajectory.set_property('percent', 33.333)
        trajectory.set_property('platform', "Boeing 747")
        trajectory.set_property('start', Timestamp.from_string('2004-12-07 11:36:00'))
        trajectory.set_property('tailNum', 3878)

        return dictionary, trajectory
def render_trajectory_movie(movie_writer,
                            basemap,
                            main_trajectories,
                            num_frames,
                            trail_duration,
                            first_frame=0,
                            num_frames_overall=None,
                            figure=None,
                            dpi=100,
                            filename='movie.mp4',
                            start_time=None,
                            end_time=None,
                            savefig_kwargs=dict(),
                            trajectory_rendering_args=dict(),
                            frame_batch_size=100,
                            utc_offset=0,
                            timezone_label=None,
                            highlight_trajectories=None,
                            axes=None):

    #    pdb.set_trace()

    if timezone_label is None:
        timezone_label = ''

    local_savefig_kwargs = dict(savefig_kwargs)
    local_trajectory_rendering_args = dict(trajectory_rendering_args)

    # First, filter down to just the trajectories that intersect the map
    main_bbox_filter = FilterTrajectoriesByBoundingBox()
    main_bbox_filter.input = main_trajectories
    main_bbox_filter.bounding_box = ((basemap.llcrnrlon, basemap.llcrnrlat),
                                     (basemap.urcrnrlon, basemap.urcrnrlat))
    main_trajectories_on_map = list(main_bbox_filter.trajectories())

    highlight_bbox_filter = FilterTrajectoriesByBoundingBox()
    highlight_bbox_filter.input = highlight_trajectories
    highlight_bbox_filter.bounding_box = ((basemap.llcrnrlon,
                                           basemap.llcrnrlat),
                                          (basemap.urcrnrlon,
                                           basemap.urcrnrlat))
    highlight_trajectories_on_map = list(highlight_bbox_filter.trajectories())
    highlight_rendering_args = dict(trajectory_rendering_args)

    global ANNOTATED_TRAJECTORIES
    if not ANNOTATED_TRAJECTORIES:
        print("Annotating trajectories (should only happen once)")
        annotated_trajectories = list(
            annotate_trajectories(main_trajectories_on_map,
                                  **local_trajectory_rendering_args))
        ANNOTATED_TRAJECTORIES = annotated_trajectories

        if len(highlight_trajectories_on_map) > 0:
            highlight_rendering_args['trajectory_initial_linewidth'] = 2
            highlight_rendering_args['trajectory_final_linewidth'] = 1
            highlight_rendering_args['trajectory_color'] = 'white'
            highlight_annotated_trajectories = list(
                annotate_trajectories(highlight_trajectories_on_map,
                                      **highlight_rendering_args))
            HIGHLIGHT_ANNOTATED_TRAJECTORIES = highlight_annotated_trajectories
    else:
        print("Re-using trajectory annotations")
        annotated_trajectories = ANNOTATED_TRAJECTORIES
        highlight_annotated_trajectories = HIGHLIGHT_ANNOTATED_TRAJECTORIES

    print("Annotated trajectories retrieved.")

    if local_trajectory_rendering_args['trajectory_color_type'] == 'static':
        local_trajectory_rendering_args[
            'trajectory_colormap'] = example_trajectory_rendering.make_constant_colormap(
                local_trajectory_rendering_args['trajectory_color'])

    (data_start_time,
     data_end_time) = compute_trajectory_time_bounds(annotated_trajectories)
    if end_time is None:
        end_time = data_end_time
    else:
        end_time = Timestamp.from_any(end_time)
    if start_time is None:
        start_time = data_start_time
    else:
        start_time = Timestamp.from_any(start_time)

    print("INFO: Movie covers time span from {} to {}".format(
        start_time.strftime("%Y-%m-%d %H:%M:%S"),
        end_time.strftime("%Y-%m-%d %H:%M:%S")))
    print("INFO: Data set covers time span from {} to {}".format(
        data_start_time.strftime("%Y-%m-%d %H:%M:%S"),
        data_end_time.strftime("%Y-%m-%d %H:%M:%S")))

    if num_frames_overall is None:
        num_frames_overall = num_frames
    frame_duration = (end_time - start_time) / num_frames_overall
    first_frame_time = start_time + trail_duration

    if (local_trajectory_rendering_args['trajectory_color_type'] == 'scalar'
            and local_trajectory_rendering_args.get('trajectory_color',
                                                    None) is not None):
        scalar_accessor = annotations.retrieve_feature_accessor(
            local_trajectory_rendering_args['trajectory_color'])
    else:
        scalar_accessor = None

    # We've handled these args ourselves - don't pass them on
    del local_trajectory_rendering_args['trajectory_color_type']
    del local_trajectory_rendering_args['trajectory_color']

    if scalar_accessor is not None:
        local_trajectory_rendering_args[
            'trajectory_scalar_accessor'] = scalar_accessor

    def frame_time(which_frame):
        return first_frame_time + which_frame * frame_duration

    def my_format_time(timestamp):
        minutes = timestamp.time().minute
        minutes = 15 * int(minutes / 15)
        local_timezone = SimpleTimeZone(hours=utc_offset)
        newtime = timestamp.replace(minute=minutes).astimezone(local_timezone)

        timestring = Timestamp.to_string(
            newtime,
            format_string='%Y-%m-%d\n%H:%M {}'.format(timezone_label),
            include_tz=False)

        return timestring

    ## TODO Add arguments to control this
    clock_artist = clock.digital_clock(frame_time(0),
                                       my_format_time, (0.95, 0.85),
                                       ha='right',
                                       va='baseline',
                                       color='white',
                                       size=18,
                                       backgroundcolor='black',
                                       zorder=20)[0]

    if figure is None:
        figure = pyplot.gcf()

    print("Rendering to {}".format(filename))
    current_trajectory_batch = None
    with movie_writer.saving(figure, filename, dpi):

        for i in range(first_frame, first_frame + num_frames):

            current_time = frame_time(i)
            trail_start_time = frame_time(i) - trail_duration

            print("Rendering frame {}: current_time {}, trail_start_time {}".
                  format(i, current_time.strftime("%Y-%m-%d %H:%M:%S"),
                         trail_start_time.strftime("%Y-%m-%d %H:%M:%S")))

            current_trajectory_batch = list(annotated_trajectories)
            #            print("Frame {}: trajectory batch contains {} items".format(i, len(current_trajectory_batch)))

            #            if (i+1) % 10 == 0:
            #                print("Rendering frame {}.  Batch extends to frame {}.".format(i, first_frame+num_frames-1))

            frame_data = render_trajectories_for_frame(
                frame_time=current_time,
                trail_start_time=trail_start_time,
                trajectories=current_trajectory_batch,
                basemap=basemap,
                axes=axes,
                render_args=local_trajectory_rendering_args,
                frame_number=i)

            if len(highlight_annotated_trajectories) > 0:
                frame_data += render_trajectories_for_frame(
                    frame_time=current_frame,
                    trail_start_time=trail_start_time,
                    trajectories=highlight_annotated_trajectories,
                    basemap=basemap,
                    axes=axes,
                    render_args=highlight_rendering_args,
                    frame_number=i)

            clock_artist.set_text(my_format_time(current_time))

            next_filename = 'test_frame_{}.png'.format(i)
            movie_writer.grab_frame(**local_savefig_kwargs)
            cleanup_frame(frame_data)

            current_time += frame_duration
            trail_start_time += frame_duration
Ejemplo n.º 27
0
def render_trajectory_movie(movie_writer,
                            map_projection,
                            trajectories,
                            num_frames,
                            trail_duration,
                            first_frame=0,
                            num_frames_overall=None,
                            figure=None,
                            dpi=100,
                            filename='movie.mp4',
                            start_time=None,
                            end_time=None,
                            savefig_kwargs=dict(),
                            trajectory_rendering_args=dict(),
                            frame_batch_size=100,
                            utc_offset=0,
                            timezone_label=None,
                            axes=None,
                            batch_id='0'):

#    pdb.set_trace()

    if timezone_label is None:
        timezone_label = ''

    local_savefig_kwargs = dict(savefig_kwargs)
    local_trajectory_rendering_args = dict(trajectory_rendering_args)

    # Cull out trajectories that do not overlap the map.  We do not
    # clip them (at least not now) since that would affect measures
    # like progress along the path.
    try:
        map_bbox = map_projection.bbox
        trajectories_on_map = [ traj for traj in trajectories if geomath.intersects(traj, map_bbox) ]
    except AttributeError:
        print("INFO: Map does not contain a bbox attribute.  Trajectory culling will be skipped.")
        trajectories_on_map = list(trajectories)

    if len(trajectories_on_map) == 0:
        print("ERROR: No trajectories intersect the map bounding box ({}).  Is the bounding box set correctly?")
        return

    global ANNOTATED_TRAJECTORIES
    if not ANNOTATED_TRAJECTORIES:
        print("Annotating trajectories (should only happen once)")
        annotated_trajectories = list(annotate_trajectories(trajectories_on_map,
                                                            **local_trajectory_rendering_args))
        ANNOTATED_TRAJECTORIES = annotated_trajectories
    else:
        print("Re-using trajectory annotations")
        annotated_trajectories = ANNOTATED_TRAJECTORIES

    print("Annotated trajectories retrieved.")

    if local_trajectory_rendering_args['trajectory_color_type'] == 'static':
        local_trajectory_rendering_args['trajectory_colormap'] = example_trajectory_rendering.make_constant_colormap(local_trajectory_rendering_args['trajectory_color'])

    (data_start_time, data_end_time) = compute_trajectory_time_bounds(trajectories_on_map)
    if end_time is None:
        end_time = data_end_time
    else:
        end_time = Timestamp.from_any(end_time)
    if start_time is None:
        start_time = data_start_time
    else:
        start_time = Timestamp.from_any(start_time)

    print("INFO: Movie covers time span from {} to {}".format(
        start_time.strftime("%Y-%m-%d %H:%M:%S"),
        end_time.strftime("%Y-%m-%d %H:%M:%S")))
    print("INFO: Data set covers time span from {} to {}".format(
        data_start_time.strftime("%Y-%m-%d %H:%M:%S"),
        data_end_time.strftime("%Y-%m-%d %H:%M:%S")))

    if num_frames_overall is None:
        num_frames_overall = num_frames

        frame_duration_seconds = (end_time - start_time).total_seconds() / num_frames_overall
        frame_duration = datetime.timedelta(seconds=frame_duration_seconds)

    first_frame_time = start_time + trail_duration

    if (local_trajectory_rendering_args['trajectory_color_type'] == 'scalar' and
        local_trajectory_rendering_args.get('trajectory_color', None) is not None):
        scalar_accessor = annotations.retrieve_feature_accessor(local_trajectory_rendering_args['trajectory_color'])
    else:
        scalar_accessor = None

    # We've handled these args ourselves - don't pass them on
    del local_trajectory_rendering_args['trajectory_color_type']
    del local_trajectory_rendering_args['trajectory_color']

    if scalar_accessor is not None:
        local_trajectory_rendering_args['trajectory_scalar_accessor'] = scalar_accessor

    def frame_time(which_frame):
        return first_frame_time + which_frame * frame_duration


    def my_format_time(timestamp):
        minutes = timestamp.time().minute
        minutes = 15 * int(minutes / 15)
        local_timezone = SimpleTimeZone(hours=utc_offset)
        newtime = timestamp.replace(minute=minutes).astimezone(local_timezone)

        timestring = Timestamp.to_string(newtime, format_string='%Y-%m-%d\n%H:%M {}'.format(
            timezone_label), include_tz=False)

        return timestring



    ## TODO Add arguments to control this
    clock_artist = clock.digital_clock(frame_time(0),
                                       my_format_time,
                                       (0.95, 0.85),
                                       ha='right',
                                       va='baseline',
                                       color='white',
                                       size=18,
                                       backgroundcolor='black',
                                       zorder=20)[0]

    if figure is None:
        figure = pyplot.gcf()

    print("Rendering to {}".format(filename))
    current_trajectory_batch = None

    # Matplotlib's file animation writers save all of the frames for
    # the movie-in-progress to the current directory.  This is a bit
    # untidy; worse, it meanst hat multiple movies rendering in one
    # directory will stomp on one another's frames.  We use
    # frame_prefix to try to keep them apart.
    frame_prefix = "movie_chunk_{}".format(batch_id)
#    with movie_writer.saving(figure, filename, dpi, frame_prefix=frame_prefix):
    with movie_writer.saving(figure, filename, dpi):

        for i in range(first_frame, first_frame+num_frames):

            current_time = frame_time(i)
            trail_start_time = frame_time(i) - trail_duration

            print("Rendering frame {}: current_time {}, trail_start_time {}".format(
                i,
                current_time.strftime("%Y-%m-%d %H:%M:%S"),
                trail_start_time.strftime("%Y-%m-%d %H:%M:%S")))

            current_trajectory_batch = list(trajectories_on_map)

            frame_data = render_trajectories_for_frame(
                frame_time=current_time,
                trail_start_time=trail_start_time,
                trajectories=current_trajectory_batch,
                basemap=map_projection,
                axes=axes,
                render_args=local_trajectory_rendering_args,
                frame_number=i
                )

            clock_artist.set_text(my_format_time(current_time))

            next_filename = 'test_frame_{}.png'.format(i)
            movie_writer.grab_frame(**local_savefig_kwargs)
            cleanup_frame(frame_data)

            current_time += frame_duration
            trail_start_time += frame_duration
def add_timestamp_property(target, property_index, minute_of_year):

    property_name = 'timestamp_{}'.format(property_index)
    target.properties[property_name] = Timestamp.from_any(datetime_from_minute_of_year(minute_of_year))
Ejemplo n.º 29
0
def run_test():
    figure = pyplot.figure(figsize=(8, 6), dpi=100)
    axes = figure.add_axes([0, 0, 1, 1], frameon=False, facecolor='black')
    axes.set_frame_on(False)

    my_timestamp = Timestamp.from_any('2013-06-07 23:18:54-0500')

    def format_time1(timestamp):
        return Timestamp.to_string(timestamp)

    def format_time2(timestamp):
        hours = timestamp.time().hour
        minutes = timestamp.time().minute
        if minutes < 30:
            minutes = 0
        else:
            minutes = 30

        new_timestamp = datetime.datetime(year=my_timestamp.date().year,
                                          month=my_timestamp.date().month,
                                          day=my_timestamp.date().day,
                                          hour=hours,
                                          minute=minutes,
                                          second=0,
                                          tzinfo=timestamp.tzinfo)

        new_timestamp = new_timestamp.astimezone(pytz.timezone('US/Pacific'))

        print("format_time2: new timestamp is {}".format(str(new_timestamp)))

        return Timestamp.to_string(new_timestamp,
                                   format_string='%H:%M',
                                   include_tz=False)

    (mymap, artists) = maps.predefined_map('conus', ax=axes)

    clock_artist1 = clock.digital_clock(
        my_timestamp,
        format_time1,
        (0.1, 0.1),
        family='fantasy',
        ha='left',
        va='top',
        size=24,
        #                                        rotation=45,
        weight='normal',
        zorder=10)

    clock_artist2 = clock.digital_clock(my_timestamp,
                                        format_time2, (0.95, 0.95),
                                        ha='right',
                                        va='baseline',
                                        family='cursive',
                                        weight='light',
                                        color='white',
                                        size=12,
                                        backgroundcolor='black',
                                        zorder=10)

    pyplot.savefig('/tmp/test_digital_clock.png')
    return 0
Ejemplo n.º 30
0
def run_test():
    num_errors = 0

    source = TrajectoryPointSource()

    start_time = Timestamp.from_any(datetime.datetime(2010, 10, 13, 12, 00,
                                                      00))
    end_time = Timestamp.from_any(datetime.datetime(2010, 10, 13, 18, 00, 00))

    start_point = TrajectoryPoint(-100, 35.0)
    start_point.object_id = 'foo'
    start_point.timestamp = start_time

    end_point = TrajectoryPoint(-80, 45.0)
    end_point.object_id = 'foo'
    end_point.timestamp = end_time

    num_points = 100

    source.start_point = start_point
    source.end_point = end_point
    source.num_points = num_points

    all_points = list(source.points())

    if len(all_points) != num_points:
        sys.stderr.write(
            'ERROR: GreatCircleTrajectoryPointSource: Expected {} points but got {}\n'
            .format(num_points, len(all_points)))
        num_errors += 1

    traj_start_point = (all_points[0][0], all_points[0][1])
    d_lon = all_points[0][0] - start_point[0]
    d_lat = all_points[0][1] - start_point[1]
    if math.fabs(d_lon) > 1e-5 or math.fabs(d_lat) > 1e-5:
        sys.stderr.write(
            'ERROR: GreatCircleTrajectoryPointSource: Expected first point to be {} but got {} instead\n'
            .format(start_point, traj_start_point))
        num_errors += 1

    traj_end_point = (all_points[-1][0], all_points[-1][1])
    d_lon = all_points[-1][0] - end_point[0]
    d_lat = all_points[-1][1] - end_point[1]
    if math.fabs(d_lon) > 1e-5 or math.fabs(d_lat) > 1e-5:
        sys.stderr.write(
            'ERROR: GreatCircleTrajectoryPointSource: Expected last point to be {} but got {} instead\n'
            .format(end_point, traj_end_point))
        num_errors += 1

    traj_start_time = all_points[0].timestamp
    d_time = math.fabs((traj_start_time - start_time).total_seconds())
    if d_time > 0.001:
        sys.stderr.write(
            'ERROR: GreatCircleTrajectoryPointSource: Expected timestamp on first point to be {} but got {} instead\n'
            .format(start_time, traj_start_time))
        num_errors += 1

    traj_end_time = all_points[-1].timestamp
    d_time = math.fabs((traj_end_time - end_time).total_seconds())
    if d_time > 0.001:
        sys.stderr.write(
            'ERROR: GreatCircleTrajectoryPointSource: Expected timestamp on last point to be {} but got {} instead\n'
            .format(end_time, traj_end_time))
        num_errors += 1

    return num_errors
    def gen_dictionary_and_trajectory(self, domainString):
        domain = importlib.import_module("tracktable.domain." +
                                         domainString.lower())

        # Manually set up a dictionary which contains trajectory info
        dictionary = {
            'domain':
            domainString.lower(),
            'object_id':
            'AAA001',
            'trajectory_properties': {
                'percent': {
                    'type': 'float',
                    'value': 33.333
                },
                'platform': {
                    'type': 'str',
                    'value': "Boeing 747"
                },
                'start': {
                    'type': 'datetime',
                    'value': "2004-12-07 11:36:00"
                },
                'tailNum': {
                    'type': 'str',
                    'value': '3878'
                }
            },
            'timestamps': [
                '2004-12-07 11:36:18', '2004-12-07 11:37:56',
                '2004-12-07 11:39:18'
            ],
            'point_properties': {
                'altitude': {
                    'type': 'float',
                    'values': [2700, 4200, 6700]
                },
                'heading': {
                    'type': 'float',
                    'values': [108.1, 108.2, 225.3]
                },
                'note': {
                    'type': 'str',
                    'values': ["hello", "world", "!"]
                },
                'time2': {
                    'type':
                    'datetime',
                    'values': [
                        "2004-01-01 00:00:01", "2004-01-01 00:00:02",
                        "2004-01-01 00:00:03"
                    ]
                }
            }
        }
        if domain.DIMENSION == 1:
            dictionary.update(
                {'coordinates': [(26.995), (27.0447), (27.1136)]})
        if domain.DIMENSION == 2:
            dictionary.update({
                'coordinates': [(26.995, -81.9731), (27.0447, -81.9844),
                                (27.1136, -82.0458)]
            })
        if domain.DIMENSION == 3:
            dictionary.update({
                'coordinates': [(26.995, -81.9731, -100.0),
                                (27.0447, -81.9844, -101.0),
                                (27.1136, -82.0458, -102.0)]
            })

        # Manually set up a matching Trajectory object
        p1 = domain.TrajectoryPoint()
        p1[0] = 26.995
        if domain.DIMENSION > 1:
            p1[1] = -81.9731
        if domain.DIMENSION > 2:
            p1[2] = -100.0
        p1.set_property('altitude', 2700)
        p1.set_property('heading', 108.1)
        p1.set_property('note', "hello")
        p1.set_property('time2', Timestamp.from_string('2004-01-01 00:00:01'))
        p1.object_id = 'AAA001'
        p1.timestamp = Timestamp.from_string('2004-12-07 11:36:18',
                                             format_string='%Y-%m-%d %H:%M:%S')

        p2 = domain.TrajectoryPoint()
        p2[0] = 27.0447
        if domain.DIMENSION > 1:
            p2[1] = -81.9844
        if domain.DIMENSION > 2:
            p2[2] = -101.0
        p2.set_property('altitude', 4200)
        p2.set_property('heading', 108.2)
        p2.set_property('note', "world")
        p2.set_property('time2', Timestamp.from_string('2004-01-01 00:00:02'))
        p2.object_id = 'AAA001'
        p2.timestamp = Timestamp.from_string('2004-12-07 11:37:56',
                                             format_string='%Y-%m-%d %H:%M:%S')

        p3 = domain.TrajectoryPoint()
        p3[0] = 27.1136
        if domain.DIMENSION > 1:
            p3[1] = -82.0458
        if domain.DIMENSION > 2:
            p3[2] = -102.0
        p3.set_property('altitude', 6700)
        p3.set_property('heading', 225.3)
        p3.set_property('note', "!")
        p3.set_property('time2', Timestamp.from_string('2004-01-01 00:00:03'))
        p3.object_id = 'AAA001'
        p3.timestamp = Timestamp.from_string('2004-12-07 11:39:18',
                                             format_string='%Y-%m-%d %H:%M:%S')

        trajectory = domain.Trajectory.from_position_list([p1, p2, p3])
        trajectory.set_property('percent', 33.333)
        trajectory.set_property('platform', "Boeing 747")
        trajectory.set_property('start',
                                Timestamp.from_string('2004-12-07 11:36:00'))
        trajectory.set_property('tailNum', '3878')

        return dictionary, trajectory
def render_trajectory_movie(movie_writer,
                            basemap,
                            main_trajectories,
                            num_frames,
                            trail_duration,
                            first_frame=0,
                            num_frames_overall=None,
                            figure=None,
                            dpi=100,
                            filename='movie.mp4',
                            start_time=None,
                            end_time=None,
                            savefig_kwargs=dict(),
                            trajectory_rendering_args=dict(),
                            frame_batch_size=100,
                            utc_offset=0,
                            timezone_label=None,
                            highlight_trajectories=None,
                            axes=None):

#    pdb.set_trace()

    if timezone_label is None:
        timezone_label = ''

    local_savefig_kwargs = dict(savefig_kwargs)
    local_trajectory_rendering_args = dict(trajectory_rendering_args)

    # First, filter down to just the trajectories that intersect the map
    main_bbox_filter = FilterTrajectoriesByBoundingBox()
    main_bbox_filter.input = main_trajectories
    main_bbox_filter.bounding_box = ( ( basemap.llcrnrlon,
                                        basemap.llcrnrlat ),
                                      ( basemap.urcrnrlon,
                                        basemap.urcrnrlat ) )
    main_trajectories_on_map = list(main_bbox_filter.trajectories())

    highlight_bbox_filter = FilterTrajectoriesByBoundingBox()
    highlight_bbox_filter.input = highlight_trajectories
    highlight_bbox_filter.bounding_box =  ( ( basemap.llcrnrlon,
                                              basemap.llcrnrlat ),
                                            ( basemap.urcrnrlon,
                                              basemap.urcrnrlat ) )
    highlight_trajectories_on_map = list(highlight_bbox_filter.trajectories())
    highlight_rendering_args = dict(trajectory_rendering_args)

    global ANNOTATED_TRAJECTORIES
    if not ANNOTATED_TRAJECTORIES:
        print("Annotating trajectories (should only happen once)")
        annotated_trajectories = list(annotate_trajectories(main_trajectories_on_map,
                                                            **local_trajectory_rendering_args))
        ANNOTATED_TRAJECTORIES = annotated_trajectories

        if len(highlight_trajectories_on_map) > 0:
            highlight_rendering_args['trajectory_initial_linewidth'] = 2
            highlight_rendering_args['trajectory_final_linewidth'] = 1
            highlight_rendering_args['trajectory_color'] = 'white'
            highlight_annotated_trajectories = list(annotate_trajectories(highlight_trajectories_on_map,
                                                                          **highlight_rendering_args))
            HIGHLIGHT_ANNOTATED_TRAJECTORIES = highlight_annotated_trajectories
    else:
        print("Re-using trajectory annotations")
        annotated_trajectories = ANNOTATED_TRAJECTORIES
        highlight_annotated_trajectories = HIGHLIGHT_ANNOTATED_TRAJECTORIES

    print("Annotated trajectories retrieved.")

    if local_trajectory_rendering_args['trajectory_color_type'] == 'static':
        local_trajectory_rendering_args['trajectory_colormap'] = example_trajectory_rendering.make_constant_colormap(local_trajectory_rendering_args['trajectory_color'])

    (data_start_time, data_end_time) = compute_trajectory_time_bounds(annotated_trajectories)
    if end_time is None:
        end_time = data_end_time
    else:
        end_time = Timestamp.from_any(end_time)
    if start_time is None:
        start_time = data_start_time
    else:
        start_time = Timestamp.from_any(start_time)

    print("INFO: Movie covers time span from {} to {}".format(
        start_time.strftime("%Y-%m-%d %H:%M:%S"),
        end_time.strftime("%Y-%m-%d %H:%M:%S")))
    print("INFO: Data set covers time span from {} to {}".format(
        data_start_time.strftime("%Y-%m-%d %H:%M:%S"),
        data_end_time.strftime("%Y-%m-%d %H:%M:%S")))

    if num_frames_overall is None:
        num_frames_overall = num_frames
    frame_duration = (end_time - start_time) / num_frames_overall
    first_frame_time = start_time + trail_duration

    if (local_trajectory_rendering_args['trajectory_color_type'] == 'scalar' and
        local_trajectory_rendering_args.get('trajectory_color', None) is not None):
        scalar_accessor = annotations.retrieve_feature_accessor(local_trajectory_rendering_args['trajectory_color'])
    else:
        scalar_accessor = None

    # We've handled these args ourselves - don't pass them on
    del local_trajectory_rendering_args['trajectory_color_type']
    del local_trajectory_rendering_args['trajectory_color']

    if scalar_accessor is not None:
        local_trajectory_rendering_args['trajectory_scalar_accessor'] = scalar_accessor

    def frame_time(which_frame):
        return first_frame_time + which_frame * frame_duration


    def my_format_time(timestamp):
        minutes = timestamp.time().minute
        minutes = 15 * int(minutes / 15)
        local_timezone = SimpleTimeZone(hours=utc_offset)
        newtime = timestamp.replace(minute=minutes).astimezone(local_timezone)

        timestring = Timestamp.to_string(newtime, format_string='%Y-%m-%d\n%H:%M {}'.format(
            timezone_label), include_tz=False)

        return timestring



    ## TODO Add arguments to control this
    clock_artist = clock.digital_clock(frame_time(0),
                                       my_format_time,
                                       (0.95, 0.85),
                                       ha='right',
                                       va='baseline',
                                       color='white',
                                       size=18,
                                       backgroundcolor='black',
                                       zorder=20)[0]

    if figure is None:
        figure = pyplot.gcf()

    print("Rendering to {}".format(filename))
    current_trajectory_batch = None
    with movie_writer.saving(figure, filename, dpi):

        for i in range(first_frame, first_frame+num_frames):

            current_time = frame_time(i)
            trail_start_time = frame_time(i) - trail_duration

            print("Rendering frame {}: current_time {}, trail_start_time {}".format(
                i,
                current_time.strftime("%Y-%m-%d %H:%M:%S"),
                trail_start_time.strftime("%Y-%m-%d %H:%M:%S")))

            current_trajectory_batch = list(annotated_trajectories)
#            print("Frame {}: trajectory batch contains {} items".format(i, len(current_trajectory_batch)))

#            if (i+1) % 10 == 0:
#                print("Rendering frame {}.  Batch extends to frame {}.".format(i, first_frame+num_frames-1))

            frame_data = render_trajectories_for_frame(
                frame_time=current_time,
                trail_start_time=trail_start_time,
                trajectories=current_trajectory_batch,
                basemap=basemap,
                axes=axes,
                render_args=local_trajectory_rendering_args,
                frame_number=i
                )

            if len(highlight_annotated_trajectories) > 0:
                frame_data += render_trajectories_for_frame(
                    frame_time=current_frame,
                    trail_start_time=trail_start_time,
                    trajectories=highlight_annotated_trajectories,
                    basemap=basemap,
                    axes=axes,
                    render_args=highlight_rendering_args,
                    frame_number=i
                )

            clock_artist.set_text(my_format_time(current_time))

            next_filename = 'test_frame_{}.png'.format(i)
            movie_writer.grab_frame(**local_savefig_kwargs)
            cleanup_frame(frame_data)

            current_time += frame_duration
            trail_start_time += frame_duration
Ejemplo n.º 33
0
 def format_time1(timestamp):
     return Timestamp.to_string(timestamp)
Ejemplo n.º 34
0
def dictionary_from_trajectory(trajectory):
    """Returns a dictionary constructed from the given trajectory
    Args:
       trajectory: the trajectory to convert into a dictonary representation
    """

    dictionary = {}
    dictionary['domain'] = trajectory.DOMAIN
    dictionary['object_id'] = trajectory[0].object_id

    # set trajectory properties
    dictionary['trajectory_properties'] = {}
    for (name, value) in trajectory.properties.items():
        if isinstance(value, datetime.datetime):
            dictionary['trajectory_properties'].update({
                name: {
                    'type': type(value).__name__,
                    'value': Timestamp.to_string(value, include_tz=False)
                }
            })
        else:
            # Python 2 has both 'int' and 'long' data types.  The
            # first is your system's ordinary integer; the second is
            # arbitrary-precision.  In Python 3, all integers are of
            # type 'int' and are of arbitrary precision.
            if sys.version_info[0] == 2 and type(value) is long:
                type_name = 'int'
            else:
                type_name = type(value).__name__
            dictionary['trajectory_properties'].update(
                {name: {
                    'type': type_name,
                    'value': value
                }})

    # initialize timestamps and coordinates
    dictionary['timestamps'] = []
    dictionary['coordinates'] = []

    # initialize point properties
    dictionary['point_properties'] = {}
    for (name, value) in trajectory[0].properties.items():
        # As above -- Python 2 has a 'long' data type that we will
        # call 'int'.
        if sys.version_info[0] == 2 and type(value) is long:
            type_name = 'int'
        else:
            type_name = type(value).__name__

        dictionary['point_properties'].update(
            {name: {
                'type': type_name,
                'values': []
            }})

    # set timestamps, coordinates and point_properties
    for i in range(len(trajectory)):
        dictionary['timestamps'].append(
            Timestamp.to_string(trajectory[i].timestamp, include_tz=False))
        dictionary['coordinates'].append(tuple(trajectory[i]))
        for (name, value) in trajectory[i].properties.items():
            if isinstance(value, datetime.datetime):
                dictionary['point_properties'][name]['values'].append(
                    Timestamp.to_string(value, include_tz=False))
            else:
                dictionary['point_properties'][name]['values'].append(value)

    return dictionary
def render_trajectory_movie(movie_writer,
                            map_projection,
                            trajectories,
                            num_frames,
                            trail_duration,
                            first_frame=0,
                            num_frames_overall=None,
                            figure=None,
                            dpi=100,
                            filename='movie.mp4',
                            start_time=None,
                            end_time=None,
                            savefig_kwargs=dict(),
                            trajectory_rendering_args=dict(),
                            frame_batch_size=100,
                            utc_offset=0,
                            timezone_label=None,
                            axes=None,
                            batch_id='0'):

    #    pdb.set_trace()

    if timezone_label is None:
        timezone_label = ''

    local_savefig_kwargs = dict(savefig_kwargs)
    local_trajectory_rendering_args = dict(trajectory_rendering_args)

    # Cull out trajectories that do not overlap the map.  We do not
    # clip them (at least not now) since that would affect measures
    # like progress along the path.
    try:
        map_bbox = map_projection.bbox
        trajectories_on_map = [
            traj for traj in trajectories
            if geomath.intersects(traj, map_bbox)
        ]
    except AttributeError:
        print(
            "INFO: Map does not contain a bbox attribute.  Trajectory culling will be skipped."
        )
        trajectories_on_map = list(trajectories)

    if len(trajectories_on_map) == 0:
        print(
            "ERROR: No trajectories intersect the map bounding box ({}).  Is the bounding box set correctly?"
        )
        return

    global ANNOTATED_TRAJECTORIES
    if not ANNOTATED_TRAJECTORIES:
        print("Annotating trajectories (should only happen once)")
        annotated_trajectories = list(
            annotate_trajectories(trajectories_on_map,
                                  **local_trajectory_rendering_args))
        ANNOTATED_TRAJECTORIES = annotated_trajectories
    else:
        print("Re-using trajectory annotations")
        annotated_trajectories = ANNOTATED_TRAJECTORIES

    print("Annotated trajectories retrieved.")

    if local_trajectory_rendering_args['trajectory_color_type'] == 'static':
        local_trajectory_rendering_args[
            'trajectory_colormap'] = example_trajectory_rendering.make_constant_colormap(
                local_trajectory_rendering_args['trajectory_color'])

    (data_start_time,
     data_end_time) = compute_trajectory_time_bounds(trajectories_on_map)
    if end_time is None:
        end_time = data_end_time
    else:
        end_time = Timestamp.from_any(end_time)
    if start_time is None:
        start_time = data_start_time
    else:
        start_time = Timestamp.from_any(start_time)

    print("INFO: Movie covers time span from {} to {}".format(
        start_time.strftime("%Y-%m-%d %H:%M:%S"),
        end_time.strftime("%Y-%m-%d %H:%M:%S")))
    print("INFO: Data set covers time span from {} to {}".format(
        data_start_time.strftime("%Y-%m-%d %H:%M:%S"),
        data_end_time.strftime("%Y-%m-%d %H:%M:%S")))

    if num_frames_overall is None:
        num_frames_overall = num_frames

        frame_duration_seconds = (
            end_time - start_time).total_seconds() / num_frames_overall
        frame_duration = datetime.timedelta(seconds=frame_duration_seconds)

    first_frame_time = start_time + trail_duration

    if (local_trajectory_rendering_args['trajectory_color_type'] == 'scalar'
            and local_trajectory_rendering_args.get('trajectory_color',
                                                    None) is not None):
        scalar_accessor = annotations.retrieve_feature_accessor(
            local_trajectory_rendering_args['trajectory_color'])
    else:
        scalar_accessor = None

    # We've handled these args ourselves - don't pass them on
    del local_trajectory_rendering_args['trajectory_color_type']
    del local_trajectory_rendering_args['trajectory_color']

    if scalar_accessor is not None:
        local_trajectory_rendering_args[
            'trajectory_scalar_accessor'] = scalar_accessor

    def frame_time(which_frame):
        return first_frame_time + which_frame * frame_duration

    def my_format_time(timestamp):
        minutes = timestamp.time().minute
        minutes = 15 * int(minutes / 15)
        local_timezone = SimpleTimeZone(hours=utc_offset)
        newtime = timestamp.replace(minute=minutes).astimezone(local_timezone)

        timestring = Timestamp.to_string(
            newtime,
            format_string='%Y-%m-%d\n%H:%M {}'.format(timezone_label),
            include_tz=False)

        return timestring

    ## TODO Add arguments to control this
    clock_artist = clock.digital_clock(frame_time(0),
                                       my_format_time, (0.95, 0.85),
                                       ha='right',
                                       va='baseline',
                                       color='white',
                                       size=18,
                                       backgroundcolor='black',
                                       zorder=20)[0]

    if figure is None:
        figure = pyplot.gcf()

    print("Rendering to {}".format(filename))
    current_trajectory_batch = None

    # Matplotlib's file animation writers save all of the frames for
    # the movie-in-progress to the current directory.  This is a bit
    # untidy; worse, it meanst hat multiple movies rendering in one
    # directory will stomp on one another's frames.  We use
    # frame_prefix to try to keep them apart.
    frame_prefix = "movie_chunk_{}".format(batch_id)
    #    with movie_writer.saving(figure, filename, dpi, frame_prefix=frame_prefix):
    with movie_writer.saving(figure, filename, dpi):

        for i in range(first_frame, first_frame + num_frames):

            current_time = frame_time(i)
            trail_start_time = frame_time(i) - trail_duration

            print("Rendering frame {}: current_time {}, trail_start_time {}".
                  format(i, current_time.strftime("%Y-%m-%d %H:%M:%S"),
                         trail_start_time.strftime("%Y-%m-%d %H:%M:%S")))

            current_trajectory_batch = list(trajectories_on_map)

            frame_data = render_trajectories_for_frame(
                frame_time=current_time,
                trail_start_time=trail_start_time,
                trajectories=current_trajectory_batch,
                basemap=map_projection,
                axes=axes,
                render_args=local_trajectory_rendering_args,
                frame_number=i)

            clock_artist.set_text(my_format_time(current_time))

            next_filename = 'test_frame_{}.png'.format(i)
            movie_writer.grab_frame(**local_savefig_kwargs)
            cleanup_frame(frame_data)

            current_time += frame_duration
            trail_start_time += frame_duration
Ejemplo n.º 36
0
 def format_time1(timestamp):
     return Timestamp.to_string(timestamp)
Ejemplo n.º 37
0
def test_point_type():
    print("Testing point type")

    error_count = 0

    surface_point = TrajectoryPoint()

    test_timestamp = Timestamp.from_any(
        datetime(year=1969, month=7, day=20, hour=20, minute=18))
    test_number = 12345
    test_string = 'this is a test'

    january_1_2014 = Timestamp.from_any(
        datetime(year=2014, month=1, day=1, hour=12, minute=34, second=56))

    surface_point.object_id = 'GreenChileExpress'
    surface_point.latitude = 35.1107
    surface_point.longitude = -106.6100
    surface_point.altitude = 10000
    surface_point.timestamp = january_1_2014
    surface_point.heading = 45
    surface_point.speed = 100
    surface_point.set_property('number', test_number)
    surface_point.set_property('string', test_string)
    surface_point.set_property('timestamp', test_timestamp)

    print("Dump of point contents: {}".format(point_to_string(surface_point)))

    surface_point_copy = surface_point
    if surface_point_copy != surface_point:
        sys.stderr.write('ERROR: Point is not equal to its immediate copy!\n')
        error_count += 1

    surface_point_copy.set_property('another_number', 23456)

    for (property_name, test_value) in [('number', test_number),
                                        ('string', test_string),
                                        ('timestamp', test_timestamp)]:

        if not surface_point.has_property(property_name):
            sys.stderr.write('ERROR: Point does not have property {}\n'.format(
                property_name))
            error_count += 1
        if surface_point.property(property_name) != test_value:
            sys.stderr.write(
                'ERROR: Point property {} does not have expected value {}\n'.
                format(property_name, test_value))
            error_count += 1

    picklebuf = StringIO()
    pickle.dump(surface_point, picklebuf)
    #    sys.stderr.write('Pickle buffer contents after pickling surface point: {}\n'.format(picklebuf.getvalue()))
    restorebuf = StringIO(picklebuf.getvalue())
    restored_point = pickle.load(restorebuf)

    if restored_point != surface_point:
        sys.stderr.write(
            'ERROR: Restored point is not the same as what we pickled!\n')
        sys.stderr.write('Original point: {}\n'.format(
            point_to_string(surface_point)))
        sys.stderr.write('Restored point: {}\n'.format(
            point_to_string(restored_point)))
        error_count += 1

    if (error_count == 0):
        print("Point type passes its Python tests.")

    return error_count
Ejemplo n.º 38
0
def add_timestamp_property(target, property_index, minute_of_year):

    property_name = 'timestamp_{}'.format(property_index)
    target.properties[property_name] = Timestamp.from_any(
        datetime_from_minute_of_year(minute_of_year))
def run_test():
    # Define three sets of points: ABQ to San Diego, San Diego to
    # Seattle, Denver to NYC.  ABQ->SAN->SEA should break into two
    # trajectories because of a timestamp break in San Diego.  The
    # flight to Denver will begin right when the flight to Seattle
    # ends so we expect to break that one based on the distance
    # threshold.

    print("Beginning run_test()")

    from tracktable.domain.terrestrial import TrajectoryPoint

    albuquerque = TrajectoryPoint( -106.5, 35.25 )
    albuquerque.timestamp = Timestamp.from_string('2010-01-01 12:00:00')
    albuquerque.object_id = 'flight1'

    san_diego1 = TrajectoryPoint( -117.16, 32.67 )
    san_diego1.timestamp = Timestamp.from_string('2010-01-01 15:00:00')
    san_diego1.object_id = 'flight1'

    san_diego2 = TrajectoryPoint( -117.16, 32.67 )
    san_diego2.timestamp = Timestamp.from_string('2010-01-01 16:00:00')
    san_diego2.object_id = 'flight1'

    seattle = TrajectoryPoint( -122.31, 47.60 )
    seattle.timestamp = Timestamp.from_string('2010-01-01 19:00:00')
    seattle.object_id = 'flight1'

    denver = TrajectoryPoint( -104.98, 39.79 )
    denver.timestamp = Timestamp.from_string('2010-01-01 19:01:00')
    denver.object_id = 'flight1'

    new_york = TrajectoryPoint( -74.02, 40.71 )
    new_york.timestamp = Timestamp.from_string('2010-01-02 00:00:00')
    new_york.object_id = 'flight1'

    # Now we want sequences of points for each flight.
    abq_to_sd = TrajectoryPointSource()
    abq_to_sd.start_point = albuquerque
    abq_to_sd.end_point = san_diego1
    abq_to_sd.num_points = 180

    sd_to_sea = TrajectoryPointSource()
    sd_to_sea.start_point = san_diego2
    sd_to_sea.end_point = seattle
    sd_to_sea.num_points = 360 # flying very slowly

    denver_to_nyc = TrajectoryPointSource()
    denver_to_nyc.start_point = denver
    denver_to_nyc.end_point = new_york
    denver_to_nyc.num_points = 600 # wow, very densely sampled

    print("Done creating point sources")

    all_points = list(itertools.chain( abq_to_sd.points(),
                                       sd_to_sea.points(),
                                       denver_to_nyc.points() ))

    trajectory_assembler = AssembleTrajectoryFromPoints()
    trajectory_assembler.input = all_points
    trajectory_assembler.separation_time = timedelta(minutes=30)
    trajectory_assembler.separation_distance = 100 
    trajectory_assembler_minimum_length = 10

    print("Done instantiating assembler")

    all_trajectories = list(trajectory_assembler.trajectories())
    print("Assembler statistics: {} points, {} valid trajectories, {} invalid trajectories".format(
        trajectory_assembler.valid_trajectory_count,
        trajectory_assembler.invalid_trajectory_count,
        trajectory_assembler.points_processed_count
        ))

    print("Done creating trajectories.  Found {}.".format(len(all_trajectories)))

    test_point_proximity = geomath.sanity_check_distance_less_than(1)
    def test_timestamp_proximity(time1, time2):
        return ( (time2 - time1).total_seconds() < 1 )

    error_count = 0
    if len(all_trajectories) != 3:
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected 3 trajectories but got {}\n'.format(len(all_trajectories)))
        error_count += 1

    if not test_point_proximity(all_trajectories[0][0], albuquerque):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected point 0 of first trajectory to be Albuquerque ({}) but it is instead {}\n'.format(albuquerque, str(all_trajectories[0][0])))
        error_count += 1

    if not test_point_proximity(all_trajectories[0][-1], san_diego1):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected last point of first trajectory to be San Diego ({}) but it is instead {}\n'.format(san_diego, str(all_trajectories[0][-1])))
        error_count += 1

    if not test_point_proximity(all_trajectories[1][0], san_diego2):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected point 0 of second trajectory to be San Diego ({}) but it is instead {}\n'.format(san_diego, str(all_trajectories[1][0])))
        error_count += 1

    if not test_point_proximity(all_trajectories[1][-1], seattle):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected last point of second trajectory to be Seattle ({}) but it is instead {}\n'.format(seattle, str(all_trajectories[1][-1])))
        error_count += 1

    if not test_point_proximity(all_trajectories[2][0], denver):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected first point of third trajectory to be Denver ({}) but it is instead {}\n'.format(denver, str(all_trajectories[2][0])))
        error_count += 1

    if not test_point_proximity(all_trajectories[2][-1], new_york):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected last point of third trajectory to be New York ({}) but it is instead {}\n'.format(new_york, str(all_trajectories[2][-1])))
        error_count += 1

    if not test_timestamp_proximity(all_trajectories[0][0].timestamp, albuquerque.timestamp):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected timestamp at beginning of trajectory 0 to be {} but it is instead {}\n'.format(albuquerque.timestamp, all_trajectories[0][0].timestamp))
        error_count += 1

    if not test_timestamp_proximity(all_trajectories[0][-1].timestamp, san_diego1.timestamp):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected timestamp at end of trajectory 0 to be {} but it is instead {}\n'.format(san_diego1.timestamp, all_trajectories[0][-1].timestamp))
        error_count += 1

    if not test_timestamp_proximity(all_trajectories[1][0].timestamp, san_diego2.timestamp):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected timestamp at beginning of trajectory 1 to be {} but it is instead {}\n'.format(san_diego2.timestamp, all_trajectories[1][0].timestamp))
        error_count += 1

    if not test_timestamp_proximity(all_trajectories[1][-1].timestamp, seattle.timestamp):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected end at beginning of trajectory 1 to be {} but it is instead {}\n'.format(seattle.timestamp, all_trajectories[1][-1].timestamp))
        error_count += 1

    if not test_timestamp_proximity(all_trajectories[2][0].timestamp, denver.timestamp):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected timestamp at beginning of trajectory 2 to be {} but it is instead {}\n'.format(denver.timestamp, all_trajectories[2][0].timestamp))
        error_count += 1

    if not test_timestamp_proximity(all_trajectories[2][-1].timestamp, new_york.timestamp):
        sys.stdout.write('ERROR: test_trajectory_assembly: Expected timestamp at end of trajectory 2 to be {} but it is instead {}\n'.format(new_york.timestamp, all_trajectories[2][-1].timestamp))
        error_count += 1

    print("Done checking proximities")

    return error_count