1
import requests
import os
from pyorbital.orbital import Orbital
from datetime import datetime
import numpy as np
import plotly.graph_objects as go
from tqdm import tqdm
import dash, math
from dash.dependencies import Input, Output
from PIL import Image
import logging, time

logging.getLogger('werkzeug').setLevel(logging.ERROR)


def LOGIN():
  username = os.getenv("username")
  password = os.getenv("password")
  session = requests.Session()
  login_url = 'https://www.space-track.org/ajaxauth/login'
  login_data = {'identity': username, 'password': password}
  session.post(login_url, data=login_data)

  query_url = 'https://www.space-track.org/basicspacedata/query/class/gp/object_type/payload'
  response = session.get(query_url)
  return (response.json())


def SETUP(satellite_data):
  Locations = []
  print("INITIALISING...")
  COLOURS = {}
  for satellite in tqdm(satellite_data):
    try:
      if satellite["CENTER_NAME"] == "EARTH":
        name = satellite['OBJECT_NAME']
        line1 = satellite['TLE_LINE1']
        line2 = satellite['TLE_LINE2']
        sat = Orbital(name, line1=line1, line2=line2)
        if satellite["DECAY_DATE"] == None:
          color = name.split("-")[0]
          if color not in COLOURS.keys():
            Colour = list(np.random.choice(range(256), size=3))
            while Colour in COLOURS.values():
              Colour = list(np.random.choice(range(256), size=3))
            COLOURS.update({color: Colour})
          elif color in COLOURS.keys():
            Colour = COLOURS[color]
          if name not in Locations:
            Locations.append([sat, name, Colour])
    except Exception as e:
      None
  return (Locations)


def NOW(Locations):
  now = {}
  timez = datetime.utcnow()
  print("GETTING LOCATIONS...")
  for satellite in tqdm(Locations):
    try:
      lat, lon, alt = satellite[0].get_lonlatalt(timez)
      now.update({
        satellite[1]: {
          "lat": lon,
          "lon": lat,
          "alt": alt,
          "color": satellite[2]
        }
      })
    except:
      None
  return (now)


def sphere(size, texture):
  N_lat = int(texture.shape[0])
  N_lon = int(texture.shape[1])
  theta = np.linspace(0, 2 * np.pi, N_lat)
  phi = np.linspace(0, np.pi, N_lon)

  x0 = size * np.outer(np.cos(theta), np.sin(phi))
  y0 = size * np.outer(np.sin(theta), np.sin(phi))
  z0 = size * np.outer(np.ones(N_lat), np.cos(phi))

  return x0, y0, z0


texture = np.asarray(Image.open('earth.jpg')).T
colorscale = [[0.0, 'rgb(30, 59, 117)'], [0.1, 'rgb(46, 68, 21)'],
              [0.2, 'rgb(74, 96, 28)'], [0.3, 'rgb(115,141,90)'],
              [0.4, 'rgb(122, 126, 75)'], [0.6, 'rgb(122, 126, 75)'],
              [0.7, 'rgb(141,115,96)'], [0.8, 'rgb(223, 197, 170)'],
              [0.9, 'rgb(237,214,183)'], [1.0, 'rgb(255, 255, 255)']]

r_earth = 6378.137
print("STARTING...")
DATA = SETUP(LOGIN())
LOADING = False
colors = {'background': '#111111', 'text': '#7FDBFF'}


def convert_to_cartesian(latitude, longitude, altitude):
  latitude_radians = math.radians(latitude)
  longitude_radians = math.radians(longitude)
  b = 6356.752
  f = (r_earth - b) / r_earth
  e_sq = f * (2 - f)
  N = r_earth / math.sqrt(1 - e_sq * math.sin(latitude_radians)**2)
  X = (N + altitude) * math.cos(latitude_radians) * math.cos(longitude_radians)
  Y = (N + altitude) * math.cos(latitude_radians) * math.sin(longitude_radians)
  Z = ((1 - e_sq) * N + altitude) * math.sin(latitude_radians)

  return X, Y, Z


app = dash.Dash(__name__)

app.layout = dash.html.Div(children=[
  dash.html.H1(children='Satellite Tracker'),
  dash.html.Div(children='''
        Real-time tracking of all satellites from space-track.org
    '''),
  dash.dcc.Graph(id='my-graph',
                 animate=True,
                 style={
                   'height': '100vh',
                   'scene': {
                     'xaxis': {
                       'visible': False,
                       'showgrid': False
                     },
                     'yaxis': {
                       'visible': False,
                       'showgrid': False
                     },
                     'zaxis': {
                       'visible': False,
                       'showgrid': False
                     }
                   },
                   'textAlign': 'center',
                   'color': colors['text'],
                   'backgroundColor': colors['background']
                 }),
  dash.dcc.Interval(id='interval-component', interval=5 * 1000)
])

@app.callback(Output('my-graph', 'figure'),
              [Input('interval-component', 'n_intervals')])
def update_graph(n):
  print(n)
  global LOADING
  if LOADING:
    return dash.no_update
  LOADING = True
  now = NOW(DATA)
  now = {k: now[k] for k in list(now)[:10]}
  All = []
  x, y, z = sphere(r_earth, texture)
  All.append(
    go.Surface(x=x,
               y=y,
               z=z,
               surfacecolor=texture,
               colorscale=colorscale,
               hoverinfo="skip"))
  X, Y, Z, COLORS = [], [], [], []
  for name, loc in tqdm(now.items()):
    x, y, z = convert_to_cartesian(loc['lat'], loc['lon'], loc['alt'])
    if 10000 > x > -10000 and 10000 > y > -10000 and 10000 > z > -10000:
      X.append(-x)
      Y.append(-y)
      Z.append(z)
      COLORS.append(loc["color"])
  camera = dict(up=dict(x=0, y=0, z=1),
                center=dict(x=0, y=0, z=0),
                eye=dict(x=-2, y=-2, z=0.1))
  layout = go.Layout(xaxis=dict(showticklabels=False,
                                showgrid=False,
                                zeroline=False),
                     yaxis=dict(showticklabels=False,
                                showgrid=False,
                                zeroline=False),
                     showlegend=False,
                     scene=dict(xaxis=dict(visible=False, showgrid=False),
                                yaxis=dict(visible=False, showgrid=False),
                                zaxis=dict(visible=False, showgrid=False),
                                bgcolor=colors['background'],
                                camera=camera))
  Sat = go.Scatter3d(x=X,
                 y=Y,
                 z=Z,
                 mode='markers',
                 name=name,
                 marker=dict(size=1,
                             color=COLORS,
                             colorscale='Viridis',
                             opacity=1))
  All.append(Sat)
    
  AKA = go.Figure(data=All, layout=layout)
  LOADING = False
  #{'data': All, 'layout': layout}
  return AKA

if __name__ == '__main__':
  app.run_server(host="0.0.0.0", debug=False)

I have tried everything I know but it doesn’t seem to want to update. If you change n_intervals it updates once it then stops. The actual code updates but it’s just relaying that information to the dash website. All the functions work I thought it was the app.callback part but I spend hours debugging it and I don’t think it is that. I think maybe it’s the way I layered my app? Any help is greatly appreciated, I have used all my power trying to get it to update, my brain has literally melted.

This code is a Python script that retrieves location data of different satellites orbiting the Earth and displays them on a 3D globe. It requires the requests, os, pyorbital, datetime, numpy, plotly.graph_objects, tqdm, dash, PIL libraries.

The LOGIN() function authenticates the user with the Space-Track website by providing the username and password. Then it sends a GET request to retrieve satellite data in JSON format.

The SETUP() function processes the satellite data obtained from LOGIN() and extracts the names and orbital parameters of the active satellites that are currently orbiting the Earth. It uses the pyorbital library to calculate the position of each satellite.

The NOW() function retrieves the current position of the satellites by calling get_lonlatalt() method of the pyorbital library. It returns a dictionary containing the latitude, longitude, altitude, and color of each satellite.

The sphere() function returns the coordinates of the points on a sphere of a given size.

The convert_to_cartesian() function converts the latitude, longitude, and altitude of a satellite to Cartesian coordinates.

The code initializes a Dash app and defines an update_graph() function that updates the 3D globe with the current location of the satellites. The update_graph() function calls the NOW() function to get the current position of the satellites and then updates the 3D globe with the new data. It uses the plotly.graph_objects library to plot the 3D globe and the dash library to create the web application.

Ok so after ages of debugging the code does update but the graph doesn’t change. Still need help though.

0 Answers0