import tkinter import tkintermapview import requests import skydome import math import imageio from PIL import Image, ImageTk #api altitude endpoint URL="https://api.open-elevation.com/api/v1/lookup" def get_api_params(coords): return {"locations":"{},{}".format(coords[0],coords[1])} # create tkinter window root_tk = tkinter.Tk() # set other tile server (standard is OpenStreetMap) # map_widget.set_tile_server("https://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}&s=Ga", max_zoom=22) # google normal # map_widget.set_tile_server("https://mt0.google.com/vt/lyrs=s&hl=en&x={x}&y={y}&z={z}&s=Ga", max_zoom=22) # google satellite def printer(): print("button") environment_tk = tkinter.Tk() class EnvButton(tkinter.Button): def __init__(self,*args,**kwargs): tkinter.Button.__init__(self, *args, **kwargs) self.default_bg_color = self.cget('bg') self['activebackground'] = 'cadetblue2' def switch(self): print(self.cget('bg')) if self.cget('bg') == self.default_bg_color: self['bg'] = 'cadetblue1' else: self['bg'] = self.default_bg_color class renderedImageZoom: def __init__(self,root,image_window,aerosol_window): self.root = root self.root.geometry(f"{1000}x{700}") self.root.title("map_view_simple_example.py") self.temperature = 5 self.pressure = 720 self.set_sun(90) self.fisheye = False self.curr_env = 0 self.zoom_factor = 1 self.env_list = ["cont_clean","cont_avr","cont_poll","urban","desert","mar_clean","mar_poll","mar_tro","arctic","antarctic"] self.aerosol_window = aerosol_window # create map widget self.map_widget = tkintermapview.TkinterMapView(self.root, width=1000, height=700, corner_radius=0) self.map_widget.pack(fill="both", expand=True) self.map_widget.add_right_click_menu_command(label="Set as observer location", command=self.add_marker_event, pass_coords=True) self.map_widget.add_right_click_menu_command(label="get altitude", command=self.get_altitude, pass_coords=True) self.image_window = image_window self.image_window.title("Simulated Sunset") self.image_window.config(width=256,height=256) #image = skydome.renderFromCamera(coords) self.canvas = tkinter.Canvas(self.image_window,bg="white") self.canvas.pack(fill=tkinter.BOTH,expand=True) self.environment_window_filler() def environment_window_filler(self): self.aerosol_window.title("options selector") environemnt_info_text = tkinter.Label(self.aerosol_window, text="Please choose in which environment the sunset is occuring") environemnt_info_text.grid(column=0,row=0,columnspan=2,pady=20,padx=10) #Continental Clean - 26e-6 g = 0.709 #Continental Average - 75e-6 g = 0.703 #Continental Polluted - 175e-6 g = 0.698 # #Urban - 353e-6 g = 0.689 # #Desert - 145e-6 g = 0.729 # #Maritime Clean - 90e-6 g = 0.772 #Maritime Polluted - 115e-6 g = 0.756 #Maritime Tropic - 43e-6 g = 0.774 # #Arctic - 23e-6 g = 0.721 # #Antarctic - 11e-6 g = 0.784 # button_list = [buton_cont_clean,buton_cont_avr,buton_cont_poll,buton_urban,buton_desert,buton_mar_clean,buton_mar_poll,button_mar_tro,button_arctic,buton_antarctic] def set_active(index): if index != self.curr_env: button_list[index].switch() button_list[self.curr_env].switch() self.curr_env = index buton_cont_clean = EnvButton(self.aerosol_window,text="Continental Clean",command=lambda: [self.env_setter(26e-6,0.709),set_active(0)]); buton_cont_clean.grid(column=0,row=1,padx=10,pady=5) buton_cont_clean['bg'] = 'cadetblue1' self.env_setter(26e-6,0.709) buton_cont_avr = EnvButton(self.aerosol_window,text="Continental Average ",command=lambda: [self.env_setter(75e-6,0.793),set_active(1)]); buton_cont_avr.grid(column=0,row=2,padx=10,pady=5) buton_cont_poll = EnvButton(self.aerosol_window,text="Continental Polluted ",command=lambda:[ self.env_setter(175e-6,0.698),set_active(2)]); buton_cont_poll.grid(column=0,row=3,padx=10,pady=5) buton_urban = EnvButton(self.aerosol_window,text="Urban ",command=lambda: [self.env_setter(353e-6,0.689),set_active(3)]); buton_urban.grid(column=0,row=4,padx=10,pady=5) buton_desert = EnvButton(self.aerosol_window,text="Desert ",command=lambda: [self.env_setter(145e-6,0.729),set_active(4)]); buton_desert.grid(column=0,row=5,padx=10,pady=5) buton_mar_clean = EnvButton(self.aerosol_window,text="Maritime Clean ",command=lambda: [self.env_setter(90e-6,0.772),set_active(5)]); buton_mar_clean.grid(column=1,row=1,padx=10,pady=5) buton_mar_poll = EnvButton(self.aerosol_window,text="Maritime Polluted ",command=lambda: [self.env_setter(115e-6,0.756),set_active(6)]); buton_mar_poll.grid(column=1,row=2,padx=10,pady=5) buton_mar_tro = EnvButton(self.aerosol_window,text="Maritime Tropic ",command=lambda: [self.env_setter(43e-6,0.774),set_active(7)]); buton_mar_tro.grid(column=1,row=3,padx=10,pady=5) buton_arctic = EnvButton(self.aerosol_window,text="Arctic ",command=lambda: [self.env_setter(23e-6,0.721),set_active(8)]); buton_arctic.grid(column=1,row=4,padx=10,pady=5) buton_antarctic = EnvButton(self.aerosol_window,text="Antarctic ",command=lambda:[ self.env_setter(11e-6,0.784),set_active(9)]); buton_antarctic.grid(column=1,row=5,padx=10,pady=5) button_list = [buton_cont_clean,buton_cont_avr,buton_cont_poll,buton_urban,buton_desert,buton_mar_clean,buton_mar_poll,buton_mar_tro,buton_arctic,buton_antarctic] environemnt_info_text = tkinter.Label(self.aerosol_window, text="Please enter the temperature and pressure (in C, and mmHg)") environemnt_info_text.grid(column=0,row=6,columnspan=2,pady=20,padx=10) def t_update(value,label): self.set_temp(value) label.config(text=str(sorted([-270,int(value),100]))) t_frame = tkinter.Frame(self.aerosol_window) text_t = tkinter.Text(t_frame,height=1,width=10) submit_t_button = tkinter.Button(t_frame,text="set temperature", command=lambda: [self.set_temp(text_t.get("1.0","end-1c")),t_label.config(text=str(sorted([-270,int(text_t.get("1.0","end-1c")),100])[1])+" C")]) #submit_t_button = tkinter.Button(t_frame,text="set temperature",command=lambda: [print("what"),t_label.config(text="bruh")]) t_label = tkinter.Label(t_frame,text="5 C") text_t.pack(side=tkinter.LEFT) t_label.pack(side=tkinter.RIGHT) submit_t_button.pack(side=tkinter.RIGHT) t_frame.grid(column=0,row=7,columnspan=2,padx=20) p_frame = tkinter.Frame(self.aerosol_window) text_p = tkinter.Text(p_frame,height=1,width=10) submit_p_button = tkinter.Button(p_frame,text="set pressure",command=lambda: [self.set_press(text_p.get("1.0","end-1c")), p_label.config(text=str(sorted([400,int(text_p.get("1.0","end-1c")),900])[1]) +" mmHg")]) p_label = tkinter.Label(p_frame,text="720 mmHg") text_p.pack(side=tkinter.LEFT) p_label.pack(side=tkinter.RIGHT) submit_p_button.pack(side=tkinter.RIGHT) p_frame.grid(column=0,row=8,columnspan=2,padx=20) s_frame = tkinter.Frame(self.aerosol_window) text_s = tkinter.Text(s_frame,height=1,width=10) submit_s_button = tkinter.Button(s_frame,text="set direction of the sun",command=lambda: [self.set_sun(text_s.get("1.0","end-1c")), sun_dir_label.config(text=str(sorted([0,int(text_s.get("1.0","end-1c")),90])[1])+" degrees")]) sun_dir_label = tkinter.Label(s_frame,text="90 degrees") text_s.pack(side=tkinter.LEFT) sun_dir_label.pack(side=tkinter.RIGHT) submit_s_button.pack(side=tkinter.RIGHT) s_frame.grid(column=0,row=9,columnspan=2,padx=20) testing_info_text = tkinter.Label(self.aerosol_window, text="Change y heights between which average redness and blueness will be calculated") testing_info_text.grid(column=0,row=10,columnspan=2,pady=20,padx=10) r_frame = tkinter.Frame(self.aerosol_window) text_r_l = tkinter.Text(r_frame,height=1,width=10) text_r_u = tkinter.Text(r_frame,height=1,width=10) submit_r_button = tkinter.Button(r_frame,text="calculate_average_red",command=lambda: average_r_label.config( text=self.get_image_average("red",int(text_r_l.get("1.0","end-1c")),int(text_r_u.get("1.0","end-1c"))))) average_r_label = tkinter.Label(r_frame,text="no average yet") text_r_l.pack(side=tkinter.LEFT) text_r_u.pack(side=tkinter.LEFT) average_r_label.pack(side=tkinter.RIGHT) submit_r_button.pack(side=tkinter.RIGHT) r_frame.grid(column=0,row=11,columnspan=2,padx=20) b_frame = tkinter.Frame(self.aerosol_window) text_b_l = tkinter.Text(b_frame,height=1,width=10) text_b_u = tkinter.Text(b_frame,height=1,width=10) submit_b_button = tkinter.Button(b_frame,text="calculate_average_blue",command=lambda: average_b_label.config( text=self.get_image_average("blue",int(text_b_l.get("1.0","end-1c")),int(text_b_u.get("1.0","end-1c"))))) average_b_label = tkinter.Label(b_frame,text="no average yet") text_b_l.pack(side=tkinter.LEFT) text_b_u.pack(side=tkinter.LEFT) average_b_label.pack(side=tkinter.RIGHT) submit_b_button.pack(side=tkinter.RIGHT) b_frame.grid(column=0,row=12,columnspan=2,padx=20) #self.img = Image.fromarray(image,mode="RGB") #self.tk_image = ImageTk.PhotoImage(width=256,height=256,image=self.img) #img = ImageTk.PhotoImage(Image.open("highpress_camera.png")) def cam_toggle(): if cam_fish_toggle.config('text')[-1] == "cam view": cam_fish_toggle.config(text="fisheye") self.fisheye = True else: cam_fish_toggle.config(text="cam view") self.fisheye = False #self.canvas.create_image(0,0, anchor="center", image=self.tk_image) zoom_in_button = tkinter.Button(self.image_window, text="Zoom In", command=self.zoom_in) zoom_out_button = tkinter.Button(self.image_window, text="Zoom Out", command=self.zoom_out) render_button = tkinter.Button(self.image_window,text="render",command=self.render) cam_fish_toggle = tkinter.Button(self.image_window,text="cam view", command=cam_toggle) save_button = tkinter.Button(self.image_window,text="Save image",command=self.save_image) zoom_in_button.pack(side=tkinter.LEFT) zoom_out_button.pack(side=tkinter.LEFT) save_button.pack(side=tkinter.LEFT) render_button.pack(side=tkinter.RIGHT) cam_fish_toggle.pack(side=tkinter.RIGHT) self.canvas.bind("",self.zoom_in) self.canvas.bind("", self.zoom_out) def set_temp(self,temp): if temp is None: self.temperature = 0 elif int(temp) < -270 or int(temp) > 100: print("temperature unrealistic, resetting to 0 degrees") self.temperature = 0 else: self.temperature = int(temp) print("temperature set at ",temp) def set_sun(self,angle): if angle is None: angle_degrees:cython.int = 90 # Sun direction in degrees (0 to 90, noon to sunset) elif int(angle) > 90 or int(angle) < 0: angle_degrees:cython.int = 90 # Sun direction in degrees (0 to 90, noon to sunset) else: angle_degrees:cython.int = int(angle) # Sun direction in degrees (0 to 90, noon to sunset) angle_radians:cython.double = math.radians(angle_degrees) # Convert to radians sunDir:skydome.Vec3 = skydome.Vec3(0, math.cos(angle_radians), -math.sin(angle_radians)) self.sunDir = sunDir def set_press(self,press): if press is None: self.pressure = 720 elif int(press) < 400 or int(press) > 900: pressure = sorted([400,int(press),900])[1] print("pressure unrealistic, resetting to clamped value {}".format(pressure)) self.pressure = pressure else: self.pressure = int(press) def get_image_average(self,color,low, high): if color == "blue": slice = self.image[:][low:high] blue = 0 for line in slice: blue += sum([p[2]/(p[0]+p[1]+p[2]) for p in line]) blue = blue / (100*(high-low)) return "{} is the pixel average".format(blue) else: slice = self.image[:][low:high] red = 0 for line in slice: for pixel in line: if sum(pixel) == 0: print(pixel) red += 0 else: print(pixel) red += pixel[0]/sum(pixel) red = red / (100*(high-low)) return "{} is the pixel average".format(red) def env_setter(self,environment_constant,g): self.betaM = skydome.Vec3(environment_constant,environment_constant,environment_constant) self.g = g def render(self): #adding button to switch between if self.fisheye: self.image = skydome.renderSkydome(self.coords,self.betaM,self.g,self.altitude,self.temperature,self.pressure,self.sunDir) else: self.image = skydome.renderFromCamera(self.coords,self.betaM,self.g,self.altitude,self.temperature,self.pressure,self.sunDir) self.img = Image.fromarray(self.image,mode="RGB") #self.tk_image = ImageTk.PhotoImage(width=256,height=256,image=self.img) #img = ImageTk.PhotoImage(Image.open("highpress_camera.png")) #self.canvas.create_image(0,0, anchor="nw", image=self.tk_image) self.img = self.img.resize((int(self.img.width * self.zoom_factor), int(self.img.height * self.zoom_factor))) self.tk_image = ImageTk.PhotoImage(self.img) self.canvas.delete("all") self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image) def save_image(self): imageio.imwrite("./sunset_t{}_p{}_env_{}_alt{}_ang{}_{}.png".format(self.temperature,self.pressure,self.env_list[self.curr_env],self.altitude ,math.degrees(math.acos(self.sunDir.v[1])), "cam" if not self.fisheye else "fisheye"), self.img) def zoom_in(self, event=None): # Increase the image size by a factor (e.g., 1.2) self.zoom_factor = self.zoom_factor *1.2 self.img = self.img.resize((int(self.img.width * 1.2), int(self.img.height * 1.2))) self.tk_image = ImageTk.PhotoImage(self.img) self.canvas.delete("all") self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image) def zoom_out(self, event=None): self.zoom_factor = self.zoom_factor*0.8 # Decrease the image size by a factor (e.g., 0.8) self.img = self.img.resize((int(self.img.width * 0.8), int(self.img.height * 0.8)))#,resampling) self.tk_image = ImageTk.PhotoImage(self.img) self.canvas.delete("all") self.canvas.create_image(0, 0, anchor="nw", image=self.tk_image) # def show_image(self,coords): # self.coords = coords #image_shower = renderedImageZoom(image_window,coords) # self.image_window.mainloop() def add_marker_event(self,coords): self.coords = coords print("marker added to {}".format(self.coords)) self.map_widget.delete_all_marker() new_marker = self.map_widget.set_marker(self.coords[0], self.coords[1], text="sunset observer") self.get_altitude(coords) def marker_click(self,marker): print(f"marker clicked - text: {marker.text} position: {marker.position}") def get_altitude(self,coords): self.coords = coords print("getting altitude for {}\n".format(self.coords)) params = get_api_params(self.coords) r = requests.get(URL,params) data = r.json() print(data['results'][0]['elevation']) self.altitude = data['results'][0]['elevation'] image_window = tkinter.Toplevel() #image_shower = renderedImageZoom(image_window,coords) image_shower = renderedImageZoom(root_tk,image_window,environment_tk) root_tk.mainloop()