Add rotating earth view
commit
23929fdf6c
55
satnogs.py
55
satnogs.py
|
@ -6,7 +6,8 @@ import json
|
||||||
from collections import defaultdict, Counter
|
from collections import defaultdict, Counter
|
||||||
import random
|
import random
|
||||||
from apscheduler.schedulers.background import BackgroundScheduler
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
from satnogs_api_client import fetch_satellites, DB_BASE_URL,fetch_tle_of_observation ,get_paginated_endpoint
|
from satnogs_api_client import fetch_satellites
|
||||||
|
from satnogs_api_client import DB_BASE_URL, get_paginated_endpoint
|
||||||
from satellite_tle import fetch_tles
|
from satellite_tle import fetch_tles
|
||||||
from skyfield.api import EarthSatellite, utc, load
|
from skyfield.api import EarthSatellite, utc, load
|
||||||
|
|
||||||
|
@ -29,21 +30,19 @@ StationsPasses = defaultdict(list)
|
||||||
SatDescrip = defaultdict(str)
|
SatDescrip = defaultdict(str)
|
||||||
CZML = []
|
CZML = []
|
||||||
|
|
||||||
|
|
||||||
def getFuture():
|
def getFuture():
|
||||||
print "Getting future Passes"
|
print "Getting future Passes"
|
||||||
global Sats
|
global Sats
|
||||||
global TLEs
|
global TLEs
|
||||||
|
|
||||||
observations = defaultdict(dict)
|
observations = defaultdict(dict)
|
||||||
|
|
||||||
start = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S%z')
|
start = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S%z')
|
||||||
end = (datetime.utcnow() + timedelta(hours=4,minutes=30)).strftime('%Y-%m-%dT%H:%M:%S%z')
|
end = (datetime.utcnow() + timedelta(hours=4, minutes=30))
|
||||||
|
end = end.strftime('%Y-%m-%dT%H:%M:%S%z')
|
||||||
passes = get_paginated_endpoint("https://network.satnogs.org/api/jobs/")
|
passes = get_paginated_endpoint("https://network.satnogs.org/api/jobs/")
|
||||||
obs = get_paginated_endpoint("https://network.satnogs.org/api/observations/?end="+end+"&format=json&start="+start)
|
obs = get_paginated_endpoint("https://network.satnogs.org/api/observations/?end="+end+"&format=json&start="+start)
|
||||||
for x in tqdm(obs):
|
for x in tqdm(obs):
|
||||||
observations[x["id"]] = x
|
observations[x["id"]] = x
|
||||||
ground_stations = {}
|
|
||||||
Sats = defaultdict(list)
|
Sats = defaultdict(list)
|
||||||
for x in tqdm(passes):
|
for x in tqdm(passes):
|
||||||
if x["id"] in observations:
|
if x["id"] in observations:
|
||||||
|
@ -62,15 +61,9 @@ def getFuture():
|
||||||
print str(len(Sats))+" Future passes found."
|
print str(len(Sats))+" Future passes found."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def GetGroundStations():
|
def GetGroundStations():
|
||||||
print "Getting Ground Stations"
|
print "Getting Ground Stations"
|
||||||
|
|
||||||
stations = get_paginated_endpoint("https://network.satnogs.org/api/stations/")
|
stations = get_paginated_endpoint("https://network.satnogs.org/api/stations/")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return stations
|
return stations
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,7 +85,6 @@ def updateTLE():
|
||||||
print('\nTLEs for {} of {} requested satellites found ({} satellites with temporary norad ids skipped).'.format(len(tles), len(satnogs_db_norad_ids), len(temporary_norad_ids)))
|
print('\nTLEs for {} of {} requested satellites found ({} satellites with temporary norad ids skipped).'.format(len(tles), len(satnogs_db_norad_ids), len(temporary_norad_ids)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job('interval', days=5)
|
@scheduler.scheduled_job('interval', days=5)
|
||||||
def updateTransmitters():
|
def updateTransmitters():
|
||||||
global Transmitters
|
global Transmitters
|
||||||
|
@ -105,16 +97,19 @@ def updateTransmitters():
|
||||||
for y in Transmitters[x].keys():
|
for y in Transmitters[x].keys():
|
||||||
SatDescrip[x] += '<div class="trans" style="background-color:#'+str("%02x" % Transmitters[x][y][1][0])+str("%02x" % Transmitters[x][y][1][1])+str("%02x" % Transmitters[x][y][1][2])+'";>'+Transmitters[x][y][0]+'</div>'
|
SatDescrip[x] += '<div class="trans" style="background-color:#'+str("%02x" % Transmitters[x][y][1][0])+str("%02x" % Transmitters[x][y][1][1])+str("%02x" % Transmitters[x][y][1][2])+'";>'+Transmitters[x][y][0]+'</div>'
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job('interval', hours=1)
|
@scheduler.scheduled_job('interval', hours=1)
|
||||||
def updatePasses():
|
def updatePasses():
|
||||||
getFuture()
|
getFuture()
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job('interval', hours=1)
|
@scheduler.scheduled_job('interval', hours=1)
|
||||||
def updateStations():
|
def updateStations():
|
||||||
global Stations
|
global Stations
|
||||||
print "Updating Stations"
|
print "Updating Stations"
|
||||||
Stations = GetGroundStations()
|
Stations = GetGroundStations()
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job('interval', minutes=30)
|
@scheduler.scheduled_job('interval', minutes=30)
|
||||||
def updateCZML():
|
def updateCZML():
|
||||||
global CZML
|
global CZML
|
||||||
|
@ -128,8 +123,6 @@ def updateCZML():
|
||||||
doc["clock"]["step"] = "SYSTEM_CLOCK"
|
doc["clock"]["step"] = "SYSTEM_CLOCK"
|
||||||
CZML.append(doc)
|
CZML.append(doc)
|
||||||
|
|
||||||
StationList = {}
|
|
||||||
|
|
||||||
for x in tqdm(Stations):
|
for x in tqdm(Stations):
|
||||||
color = [0, 230, 64, 255]
|
color = [0, 230, 64, 255]
|
||||||
if x["status"] == "Testing":
|
if x["status"] == "Testing":
|
||||||
|
@ -155,19 +148,12 @@ def updateCZML():
|
||||||
station["description"] += x["qthlocator"] + "</b><br></b>Description: </b>" + x["description"]
|
station["description"] += x["qthlocator"] + "</b><br></b>Description: </b>" + x["description"]
|
||||||
CZML.append(station)
|
CZML.append(station)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for x in tqdm(Sats.keys()):
|
for x in tqdm(Sats.keys()):
|
||||||
for y in Sats[x]:
|
for y in Sats[x]:
|
||||||
sat = {}
|
sat = {}
|
||||||
sat["id"] = str(y["id"])
|
sat["id"] = str(y["id"])
|
||||||
sat["name"] = TLEs[x][0]
|
sat["name"] = TLEs[x][0]
|
||||||
sat["show"] = True
|
sat["show"] = True
|
||||||
#sat["point"] = {}
|
|
||||||
#sat["point"]["color"] = {}
|
|
||||||
#sat["point"]["color"]["rgba"] = [255,0,0,255]
|
|
||||||
#sat["point"]["pixelSize"]=8.0
|
|
||||||
sat["billboard"] = {"image": "static/sat.png", "scale": 0.50}
|
sat["billboard"] = {"image": "static/sat.png", "scale": 0.50}
|
||||||
sat["position"] = {}
|
sat["position"] = {}
|
||||||
sat["position"]["cartographicDegrees"] = []
|
sat["position"]["cartographicDegrees"] = []
|
||||||
|
@ -176,7 +162,6 @@ def updateCZML():
|
||||||
satObj = EarthSatellite(TLEs[x][1], TLEs[x][2], TLEs[x][0])
|
satObj = EarthSatellite(TLEs[x][1], TLEs[x][2], TLEs[x][0])
|
||||||
time = 0
|
time = 0
|
||||||
while temp <= y["end"] + timedelta(minutes=1):
|
while temp <= y["end"] + timedelta(minutes=1):
|
||||||
|
|
||||||
subpoint = satObj.at(ts.utc(temp)).subpoint()
|
subpoint = satObj.at(ts.utc(temp)).subpoint()
|
||||||
lat = subpoint.latitude.degrees
|
lat = subpoint.latitude.degrees
|
||||||
lng = subpoint.longitude.degrees
|
lng = subpoint.longitude.degrees
|
||||||
|
@ -186,10 +171,8 @@ def updateCZML():
|
||||||
temp = temp + timedelta(minutes=1)
|
temp = temp + timedelta(minutes=1)
|
||||||
sat["position"]["interpolationAlgorithm"] = "LAGRANGE"
|
sat["position"]["interpolationAlgorithm"] = "LAGRANGE"
|
||||||
sat["position"]["interpolationDegree"] = 5
|
sat["position"]["interpolationDegree"] = 5
|
||||||
# sat["position"]["referenceFrame"] = "INERTIAL"
|
|
||||||
sat["position"]["epoch"] = (y["start"].isoformat()+"Z").replace("+00:00", "")
|
sat["position"]["epoch"] = (y["start"].isoformat()+"Z").replace("+00:00", "")
|
||||||
sat["path"] = {"show": {"interval": (y["start"].isoformat()+"Z").replace("+00:00", "") + "/" + ((y["end"] + timedelta(minutes=1)).isoformat()+"Z").replace("+00:00", ""), "boolean": True}, "width": 2, "material": {"solidColor": {"color": {"rgba": [0, 255, 0, 255]}}}, "leadTime": 100000, "trailTime": 100000}
|
sat["path"] = {"show": {"interval": (y["start"].isoformat()+"Z").replace("+00:00", "") + "/" + ((y["end"] + timedelta(minutes=1)).isoformat()+"Z").replace("+00:00", ""), "boolean": True}, "width": 2, "material": {"solidColor": {"color": {"rgba": [0, 255, 0, 255]}}}, "leadTime": 100000, "trailTime": 100000}
|
||||||
|
|
||||||
CZML.append(sat)
|
CZML.append(sat)
|
||||||
for x in tqdm(Sats.keys()):
|
for x in tqdm(Sats.keys()):
|
||||||
for y in Sats[x]:
|
for y in Sats[x]:
|
||||||
|
@ -199,7 +182,6 @@ def updateCZML():
|
||||||
CZML.append(sat)
|
CZML.append(sat)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
|
|
||||||
|
@ -218,16 +200,16 @@ def index_station(station_id):
|
||||||
Usage.update(request.headers.get("CF-IPCountry"))
|
Usage.update(request.headers.get("CF-IPCountry"))
|
||||||
return render_template("index.html",url="/czml/"+str(station_id))
|
return render_template("index.html",url="/czml/"+str(station_id))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/future_sats')
|
@app.route('/future_sats')
|
||||||
def api_future_sats():
|
def api_future_sats():
|
||||||
return json.dumps(Sats)
|
return json.dumps(Sats)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/czml")
|
@app.route("/czml")
|
||||||
def api_czml():
|
def api_czml():
|
||||||
return json.dumps(CZML)
|
return json.dumps(CZML)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/broken")
|
@app.route("/broken")
|
||||||
def api_broken():
|
def api_broken():
|
||||||
output = defaultdict(list)
|
output = defaultdict(list)
|
||||||
|
@ -235,11 +217,6 @@ def api_broken():
|
||||||
output[x]=list(broken[x])
|
output[x]=list(broken[x])
|
||||||
return json.dumps(output)
|
return json.dumps(output)
|
||||||
|
|
||||||
@app.route("/usage")
|
|
||||||
def usage():
|
|
||||||
return json.dumps(Usage)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/czml/<int:station_id>")
|
@app.route("/czml/<int:station_id>")
|
||||||
def api_station(station_id):
|
def api_station(station_id):
|
||||||
czml = []
|
czml = []
|
||||||
|
@ -253,7 +230,6 @@ def api_station(station_id):
|
||||||
doc["clock"]["step"] = "SYSTEM_CLOCK"
|
doc["clock"]["step"] = "SYSTEM_CLOCK"
|
||||||
czml.append(doc)
|
czml.append(doc)
|
||||||
|
|
||||||
|
|
||||||
for x in Stations:
|
for x in Stations:
|
||||||
if x["id"] == station_id:
|
if x["id"] == station_id:
|
||||||
color = [0, 230, 64, 255]
|
color = [0, 230, 64, 255]
|
||||||
|
@ -261,7 +237,6 @@ def api_station(station_id):
|
||||||
color = [248, 148, 6, 255]
|
color = [248, 148, 6, 255]
|
||||||
if x["status"] == "Offline":
|
if x["status"] == "Offline":
|
||||||
color = [255, 0, 0, 50]
|
color = [255, 0, 0, 50]
|
||||||
|
|
||||||
station = {}
|
station = {}
|
||||||
station["id"] = str(x["id"])
|
station["id"] = str(x["id"])
|
||||||
station["name"] = x["name"]
|
station["name"] = x["name"]
|
||||||
|
@ -281,7 +256,6 @@ def api_station(station_id):
|
||||||
czml.append(station)
|
czml.append(station)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
for y in StationsPasses[station_id]:
|
for y in StationsPasses[station_id]:
|
||||||
sat = {}
|
sat = {}
|
||||||
sat["id"] = str(y["id"])
|
sat["id"] = str(y["id"])
|
||||||
|
@ -291,7 +265,6 @@ def api_station(station_id):
|
||||||
sat["point"]["color"] = {}
|
sat["point"]["color"] = {}
|
||||||
sat["point"]["color"]["rgba"] = [255, 0, 0, 255]
|
sat["point"]["color"]["rgba"] = [255, 0, 0, 255]
|
||||||
sat["point"]["pixelSize"] = 8.0
|
sat["point"]["pixelSize"] = 8.0
|
||||||
#sat["billboard"] = {"image":"static/sat.png","scale":0.50}
|
|
||||||
sat["position"] = {}
|
sat["position"] = {}
|
||||||
sat["position"]["cartographicDegrees"] = []
|
sat["position"]["cartographicDegrees"] = []
|
||||||
sat["description"] = SatDescrip[y["norad"]]
|
sat["description"] = SatDescrip[y["norad"]]
|
||||||
|
@ -299,7 +272,6 @@ def api_station(station_id):
|
||||||
satObj = EarthSatellite(TLEs[y["norad"]][1], TLEs[y["norad"]][2], TLEs[y["norad"]][0])
|
satObj = EarthSatellite(TLEs[y["norad"]][1], TLEs[y["norad"]][2], TLEs[y["norad"]][0])
|
||||||
time = 0
|
time = 0
|
||||||
while temp <= y["end"]+timedelta(minutes=1):
|
while temp <= y["end"]+timedelta(minutes=1):
|
||||||
|
|
||||||
subpoint = satObj.at(ts.utc(temp)).subpoint()
|
subpoint = satObj.at(ts.utc(temp)).subpoint()
|
||||||
lat = subpoint.latitude.degrees
|
lat = subpoint.latitude.degrees
|
||||||
lng = subpoint.longitude.degrees
|
lng = subpoint.longitude.degrees
|
||||||
|
@ -311,25 +283,18 @@ def api_station(station_id):
|
||||||
sat["position"]["interpolationDegree"] = 5
|
sat["position"]["interpolationDegree"] = 5
|
||||||
sat["position"]["epoch"] = (y["start"].isoformat() + "Z").replace("+00:00", "")
|
sat["position"]["epoch"] = (y["start"].isoformat() + "Z").replace("+00:00", "")
|
||||||
sat["path"] = {"show": {"interval": (y["start"].isoformat()+"Z").replace("+00:00", "") + "/" + ((y["end"] + timedelta(minutes=1)).isoformat() + "Z").replace("+00:00", ""), "boolean": True}, "width": 2, "material": {"solidColor": {"color": {"rgba": [0, 255, 0, 255]}}}, "leadTime": 100000, "trailTime": 100000}
|
sat["path"] = {"show": {"interval": (y["start"].isoformat()+"Z").replace("+00:00", "") + "/" + ((y["end"] + timedelta(minutes=1)).isoformat() + "Z").replace("+00:00", ""), "boolean": True}, "width": 2, "material": {"solidColor": {"color": {"rgba": [0, 255, 0, 255]}}}, "leadTime": 100000, "trailTime": 100000}
|
||||||
|
|
||||||
czml.append(sat)
|
czml.append(sat)
|
||||||
|
|
||||||
for y in StationsPasses[station_id]:
|
for y in StationsPasses[station_id]:
|
||||||
sat = {}
|
sat = {}
|
||||||
sat["id"] = str(y["id"])+"Link"
|
sat["id"] = str(y["id"])+"Link"
|
||||||
sat["polyline"] = {"show": {"interval": (y["start"].isoformat()+"Z").replace("+00:00", "") + "/" + ((y["end"] + timedelta(minutes=1)).isoformat()+"Z").replace("+00:00", ""), "boolean": True}, "width": 2, "material": {"solidColor": {"color": {"rgba": y["transmitter"][1]}}}, "followSurface": False, "positions": {"references": [str(y["id"]) + "#position", str(station_id) + "#position"]}}
|
sat["polyline"] = {"show": {"interval": (y["start"].isoformat()+"Z").replace("+00:00", "") + "/" + ((y["end"] + timedelta(minutes=1)).isoformat()+"Z").replace("+00:00", ""), "boolean": True}, "width": 2, "material": {"solidColor": {"color": {"rgba": y["transmitter"][1]}}}, "followSurface": False, "positions": {"references": [str(y["id"]) + "#position", str(station_id) + "#position"]}}
|
||||||
czml.append(sat)
|
czml.append(sat)
|
||||||
|
|
||||||
return json.dumps(czml)
|
return json.dumps(czml)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#updatePasses()
|
|
||||||
updateStations()
|
updateStations()
|
||||||
updateTransmitters()
|
updateTransmitters()
|
||||||
getFuture()
|
getFuture()
|
||||||
updateCZML()
|
updateCZML()
|
||||||
#updateTLE()
|
|
||||||
#updatePasses()
|
|
||||||
scheduler.start()
|
scheduler.start()
|
||||||
app.run(use_reloader=False, host="0.0.0.0", port=5001)
|
app.run(use_reloader=False, host="0.0.0.0", port=5001)
|
||||||
|
|
Loading…
Reference in New Issue