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 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 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 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_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 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 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 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 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 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