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 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))
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
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
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))
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 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
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 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 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
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)
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
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))
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
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
def format_time1(timestamp): return Timestamp.to_string(timestamp)
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
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
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