class ISSScreen(Screen): def __init__(self, **kwargs): super(ISSScreen, self).__init__(**kwargs) # Set the path for the folder self.path = os.path.dirname(os.path.abspath(__file__)) # Set the path for local images self.imagefolder = os.path.join(self.path, "images") # Ephem calculates the position using the Two Line Element data # We need to make sure we have up to date info tle = self.get_TLE() # Create an iss object from which we can get positional data self.iss = ephem.readtle(*tle) # Run the calculations self.iss.compute() # Get positon of iss and place a marker there lat, lon = self.get_loc() self.marker = MapMarker(lat=lat, lon=lon) # Create a value to check when we last drew ISS path self.last_path_update = 0 # Create the path icon self.path_icon = os.path.join(self.imagefolder, "dot.png") # Create the world map self.map = MapView(id="mpv", lat=0, lon=0, zoom=1, scale=1.5) x, y = self.map.get_window_xy_from(0, 0, 1) self.map.scale_at(1.2, x, y) # Add the ISS marker to the map and draw the map on the screen self.map.add_widget(self.marker) self.add_widget(self.map) # Add a new layer for the path self.mmlayer = MarkerMapLayer() self.draw_iss_path() self.timer = None def on_enter(self): self.timer = Clock.schedule_interval(self.update, 1) def on_leave(self): Clock.unschedule(self.timer) def utcnow(self): return (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds() def draw_iss_path(self): # Path is drawn every 5 mins if self.utcnow() - self.last_path_update > 30: try: self.map.remove_layer(self.mmlayer) except: pass self.mmlayer = MarkerMapLayer() # Create markers showing the ISS's position every 5 mins for i in range(20): lat, lon = self.get_loc(datetime.now() + timedelta(0, i * 300)) self.mmlayer.add_widget( MapMarker(lat=lat, lon=lon, source=self.path_icon)) # Update the flag so we know when next update should be run self.last_path_update = self.utcnow() # Add the layer and call the reposition function otherwise the # markers don't show otherwise! self.map.add_layer(self.mmlayer) self.mmlayer.reposition() def get_TLE(self): # Set some flags need_update = False # Set our data source and the name of the object we're tracking source = "http://www.celestrak.com/NORAD/elements/stations.txt" ISS = "ISS (ZARYA)" # Get the current time utc_now = self.utcnow() # Set the name of our file to store data data = os.path.join(self.path, "iss_tle.json") # Try loading old data try: with open(data, "r") as savefile: saved = json.load(savefile) # If we can't create a dummy dict except IOError: saved = {"updated": 0} # If old data is more than an hour hold, let's check for an update if utc_now - saved["updated"] > 3600: need_update = True # If we don't have any TLE data then we need an update if not saved.get("tle"): need_update = True if need_update: # Load the TLE data raw = requests.get(source).text # Split the data into a neat list all_sats = [sat.strip() for sat in raw.split("\n")] # Find the ISS and grab the whole TLE (three lines) iss_index = all_sats.index(ISS) iss_tle = all_sats[iss_index:iss_index + 3] # Prepare a dict to save our data new_tle = {"updated": utc_now, "tle": iss_tle} # Save it with open(data, "w") as savefile: json.dump(new_tle, savefile, indent=4) # ephem needs strings not unicode return [str(x) for x in iss_tle] else: # return the saved data (as strings) return [str(x) for x in saved["tle"]] def update(self, *args): # Update the ISS with newest TLE self.iss = ephem.readtle(*self.get_TLE()) # Get the position and update marker lat, lon = self.get_loc() self.marker.lat = lat self.marker.lon = lon self.map.remove_widget(self.marker) self.map.add_widget(self.marker) # Check if the path needs redrawing self.draw_iss_path() def get_loc(self, dt=None): # We can get the location for a specific time as well if dt is None: self.iss.compute() else: self.iss.compute(dt) # Convert the ephem data into something that the map can use lat = float(self.iss.sublat / ephem.degree) lon = float(self.iss.sublong / ephem.degree) return lat, lon
class Main(App): height = 720 width = (height/16) * 9 Window.size = (width,height) def build(self): self.itu_lat = 55.6593807 self.itu_lon = 12.5910774 self.obs_dic = None self.old_time = 0.0 self.weatherbox = AnchorLayout(anchor_x = 'center', anchor_y = 'bottom') self.Layout = RelativeLayout() self.mapview = MapView(zoom=11, lat=self.itu_lat, lon=self.itu_lon) mapview = self.mapview self.Layout.add_widget(mapview) # add map layer self.jsonmap = GeoJsonMapLayer(source='5_mile_airport.json') self.mapview.add_layer(self.jsonmap) self.overlay = AnchorLayout(anchor_x='right', anchor_y='top') lowerLeft = AnchorLayout(anchor_x='left', anchor_y='bottom') self.lowerLeftStack = StackLayout(orientation='lr-bt',size_hint=(0.15,0.15)) lowerLeft.add_widget(self.lowerLeftStack) btnre = Button(background_normal='refocus_normal.png', background_down='refocus_down.png', size_hint = (2,1)) btnre.bind(on_press=self.resetloc) btnnf = ToggleButton(background_normal='nofly_normal.png', background_down='nofly_down.png',size_hint = (2,1)) btnnf.bind(on_press=self.nofly) self.lowerLeftStack.add_widget(btnre) self.lowerLeftStack.add_widget(btnnf) btn = ToggleButton(background_normal='Settings B.png', background_down="Settings G.png") btn.bind(on_press= self.show_dropdown) self.settings = StackLayout(size_hint=(0.2,0.2)) self.settings.add_widget(btn) self.overlay.add_widget(self.settings) self.Layout.add_widget(lowerLeft) self.Layout.add_widget(self.overlay) marker = MapMarker(anchor_x = 0.5, anchor_y = 0.5, lat=self.itu_lat, lon=self.itu_lon) self.mapview.add_marker(marker) return self.Layout def resetloc(self,instance): self.mapview.center_on(self.itu_lat,self.itu_lon) def nofly(self,instance): if instance.state == 'down': self.mapview.remove_layer(self.jsonmap) else: self.mapview.add_layer(self.jsonmap) def show_dropdown(self,instance): if instance.state == 'down': size = (1,0.5) btn1 = ToggleButton(text='Weather', size_hint = size) btn2 = Button(text='Level',size_hint = size) btn3 = Button(text='Nearby\nusers', size_hint = size) btn1.bind(on_press = self.show_weather_data) self.settings.add_widget(btn1) self.settings.add_widget(btn2) self.settings.add_widget(btn3) else: for child in self.settings.children[:]: if child.text != "": self.settings.remove_widget(child) def show_weather_data(self,instance): weatherbox = self.weatherbox if instance.state == 'down': layout = BoxLayout(orientation='vertical', size_hint = (0.2,0.1) ) clat = self.mapview.lat clon = self.mapview.lon ctime = time.time() if(self.obs_dic == None or ctime > (self.old_time + 0.5)): self.old_time = ctime self.obs_dic = api.loc_weather(clat,clon) weList = self.obs_dic['weather'] we = weList[0] wi = self.obs_dic['wind'] l1 = Label(text = 'Current weather: ' + we['main'], color = (0.,0.,0.,1)) main = self.obs_dic['main'] k = main['temp'] #Conversion from imperial to metric temp = k-273.15 l2 = Label(text = 'temp: ' + str(temp) + ' ' + u'\u00B0' + 'C', color = (0.,0.,0.,1)) hu = main['humidity'] l3 = Label(text = 'humidity: ' + str(hu) + '%', color = (0.,0.,0.,1)) pre = main['pressure'] l4 = Label(text = 'pressure' + str(pre) + ' hPa', color = (0.,0.,0.,1)) wispeed = wi['speed'] widir = wi['deg'] l5 = Label(text = 'wind speed: ' + str(wispeed) + 'm/s', color = (0.,0.,0.,1)) l6 = Label(text = 'wind direction '+ str(widir) + u'\u00B0', color = (0.,0.,0.,1)) Tdp = temp - ((100-hu)/5) l7 = Label(text = 'dew point: ' + str(Tdp) + ' ' + u'\u00B0' + 'C', color = (0.,0.,0.,1)) layout.add_widget(l1) layout.add_widget(l2) layout.add_widget(l3) layout.add_widget(l4) layout.add_widget(l5) layout.add_widget(l6) layout.add_widget(l7) weatherbox.add_widget(layout) weatherbox.add_widget self.Layout.add_widget(weatherbox) else: for c in self.weatherbox.children[:]: for child in c.children[:]: c.remove_widget(child) self.weatherbox.remove_widget(c) self.overlay.remove_widget(weatherbox)
class ISSScreen(Screen): def __init__(self, **kwargs): super(ISSScreen, self).__init__(**kwargs) # Set the path for the folder self.path = os.path.dirname(os.path.abspath(__file__)) # Set the path for local images self.imagefolder = os.path.join(self.path, "images") # Ephem calculates the position using the Two Line Element data # We need to make sure we have up to date info tle = self.get_TLE() # Create an iss object from which we can get positional data self.iss = ephem.readtle(*tle) # Run the calculations self.iss.compute() # Get positon of iss and place a marker there lat, lon = self.get_loc() self.marker = MapMarker(lat=lat, lon=lon) # Create a value to check when we last drew ISS path self.last_path_update = 0 # Create the path icon self.path_icon = os.path.join(self.imagefolder, "dot.png") # Create the world map self.map = MapView(id="mpv",lat=0, lon=0, zoom=1, scale=1.5) x, y = self.map.get_window_xy_from(0,0,1) self.map.scale_at(1.2, x, y) # Add the ISS marker to the map and draw the map on the screen self.map.add_widget(self.marker) self.add_widget(self.map) # Add a new layer for the path self.mmlayer = MarkerMapLayer() self.draw_iss_path() self.timer = None def on_enter(self): self.timer = Clock.schedule_interval(self.update, 1) def on_leave(self): Clock.unschedule(self.timer) def utcnow(self): return (datetime.utcnow() - datetime(1970,1,1)).total_seconds() def draw_iss_path(self): # Path is drawn every 5 mins if self.utcnow() - self.last_path_update > 30: try: self.map.remove_layer(self.mmlayer) except: pass self.mmlayer = MarkerMapLayer() # Create markers showing the ISS's position every 5 mins for i in range(20): lat, lon = self.get_loc(datetime.now() + timedelta(0, i * 300)) self.mmlayer.add_widget(MapMarker(lat=lat, lon=lon, source=self.path_icon)) # Update the flag so we know when next update should be run self.last_path_update = self.utcnow() # Add the layer and call the reposition function otherwise the # markers don't show otherwise! self.map.add_layer(self.mmlayer) self.mmlayer.reposition() def get_TLE(self): # Set some flags need_update = False # Set our data source and the name of the object we're tracking source = "http://www.celestrak.com/NORAD/elements/stations.txt" ISS = "ISS (ZARYA)" # Get the current time utc_now = self.utcnow() # Set the name of our file to store data data = os.path.join(self.path, "iss_tle.json") # Try loading old data try: with open(data, "r") as savefile: saved = json.load(savefile) # If we can't create a dummy dict except IOError: saved = {"updated": 0} # If old data is more than an hour hold, let's check for an update if utc_now - saved["updated"] > 3600: need_update = True # If we don't have any TLE data then we need an update if not saved.get("tle"): need_update = True if need_update: # Load the TLE data raw = requests.get(source).text # Split the data into a neat list all_sats = [sat.strip() for sat in raw.split("\n")] # Find the ISS and grab the whole TLE (three lines) iss_index = all_sats.index(ISS) iss_tle = all_sats[iss_index:iss_index + 3] # Prepare a dict to save our data new_tle = {"updated": utc_now, "tle": iss_tle} # Save it with open(data, "w") as savefile: json.dump(new_tle, savefile, indent=4) # ephem needs strings not unicode return [str(x) for x in iss_tle] else: # return the saved data (as strings) return [str(x) for x in saved["tle"]] def update(self, *args): # Update the ISS with newest TLE self.iss = ephem.readtle(*self.get_TLE()) # Get the position and update marker lat, lon = self.get_loc() self.marker.lat = lat self.marker.lon = lon self.map.remove_widget(self.marker) self.map.add_widget(self.marker) # Check if the path needs redrawing self.draw_iss_path() def get_loc(self, dt=None): # We can get the location for a specific time as well if dt is None: self.iss.compute() else: self.iss.compute(dt) # Convert the ephem data into something that the map can use lat = float(self.iss.sublat / ephem.degree) lon = float(self.iss.sublong / ephem.degree) return lat, lon