from manimlib import * import inspect import sys import os sys.path.append(os.path.abspath("../script_generator")) from Event import * from math import inf,sqrt,pi,log,tan,radians zoom = 10 def get_coord(station_event): return(station_event.link) def dist(p,q): return(sqrt((p[0]-q[0])**2+(p[1]-q[1])**2)) def shortify(name): splitted = name.split() f = splitted[0] if(f=="halte" or f=="station" or f=="stopplaats"): return(' '.join(splitted[1:])) return(' '.join(splitted)) #def coord_to_pos(coord): # return((coord[1]*100,coord[0]*100,0)) def coord_to_pos(coord): lat = radians(coord[0]) long= radians(coord[1]) x=25.6/(pi*2)*2**zoom*(long+pi) y=-25.6/(pi*2)*2**zoom*(pi-log(tan(pi/4+lat/2))) return((x,y,0)) #def degree_to_real_coord(lat,long,zoom): # x=256/(m.pi*2)*2**zoom*(long+m.pi) # y=256/(m.pi*2)*2**zoom*(m.pi-m.log(m.tan(m.pi/4+lat/2))) # return(x,y) class Animator(Scene): def construct(self): self.drawn_stations = {} self.camera.frame.set_width(40) script_tree = ET.parse("../script_generator/Events.xml") events_element = script_tree.getroot() i=0 for event_element in events_element: event = Event.fromXML(event_element) surface_text = Text(event.date) surface_text.fix_in_frame() surface_text.to_edge(UP) self.add(surface_text) if isinstance(event,StationEvent): self.play(self.camera.frame.animate.move_to(coord_to_pos(event.coordinates))) self.draw_station(event) if(isinstance(event,LineSegmentEvent)): self.draw_segment(event) self.remove(surface_text) def draw_station(self,station_event): if(station_event.coordinates==None): print(f"{station_event.name} has no coordinates") return pos = coord_to_pos(station_event.coordinates) p = Circle(color=BLACK,fill_opacity=1,radius=0.1).move_to(pos) short_name = shortify(station_event.name) text = Text(short_name,font_size=40).set_color(BLUE).move_to((pos[0]+0.4,pos[1]+0.4,0)) if(station_event.opening_or_closure=="opening"): self.drawn_stations[station_event.name]=(p,text,\ station_event.vertex_indices) self.play(ShowCreation(p),ShowCreation(text)) elif(station_event.opening_or_closure=="closure"): (p,text,_) = self.drawn_stations.pop(station_event.name) self.remove(p) self.remove(text) self.play(Uncreate(p),Uncreate(text)) def draw_path(self,coords,start_index,end_index,station_event): corners = coords[start_index:end_index] vmob = VMobject(stroke_color=RED) vmob.set_points_as_corners(list(map(coord_to_pos,corners))) if station_event == None: self.play(ShowCreation(vmob)) else: self.play(ShowCreation(vmob),self.camera.frame.animate.move_to(coord_to_pos(station_event.coordinates))) if(station_event!=None): self.draw_station(station_event) def draw_segment(self,event): gpx_tree = ET.parse(f"../data/gpx/{event.gpx_file_path}") gpx_element = gpx_tree.getroot() trk_element = gpx_element[1] trkseg_element = trk_element[1] coords = [] line_number = int(event.gpx_file_path[:-4]) for trkpt_element in trkseg_element: coords.append((float(trkpt_element.attrib["lat"]),float(trkpt_element.attrib["lon"]))) self.play(self.camera.frame.animate.move_to(coord_to_pos(event.start_coord))) #prev_coord = event.start_station_link i=0 drawn_last_segment = False if(event.station_events!=[]): if(event.start_name in self.drawn_stations.keys()): (_,_,start_indices) = self.drawn_stations[event.start_name] start_index= start_indices[line_number] self.draw_path(coords,start_index,event.station_events[0].vertex_indices[line_number],event.station_events[0]) else: self.draw_station(event.station_events[0]) else: (_,_,start_indices) = self.drawn_stations[event.start_name] (_,_,end_indices) = self.drawn_stations[event.end_name] start_index= start_indices[line_number] end_index= end_indices[line_number] self.draw_path(coords,start_index,end_index,None) drawn_last_segment =True prev_station = None first = True for station_event in event.station_events: print(f"in segment_stations loop: {station_event.name}") if(first): prev_station = station_event first = False continue reached_segment = False self.draw_path(coords,prev_station.vertex_indices[line_number],station_event.vertex_indices[line_number],station_event) prev_coord=station_event.coordinates i+=1 if(not drawn_last_segment and event.end_name in self.drawn_stations.keys()): (_,_,end_indices) = self.drawn_stations[event.end_name] end_index = end_indices[line_number] self.draw_path(coords,event.station_events[-1].vertex_indices[line_number],end_index,None)