From f89c3fa2bfe7d369866a1939a7c201200016cb38 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 12:27:19 -0600 Subject: [PATCH 01/23] Inital recode --- requirments.txt | 3 + satnogs.py | 67 +++-------------- satnogs_api_client.py | 171 ++++++++++++++++++------------------------ 3 files changed, 83 insertions(+), 158 deletions(-) create mode 100644 requirments.txt diff --git a/requirments.txt b/requirments.txt new file mode 100644 index 0000000..08420a8 --- /dev/null +++ b/requirments.txt @@ -0,0 +1,3 @@ +requests==2.21.0 +flask==1.0.2 +apscheduler==3.5.3 \ No newline at end of file diff --git a/satnogs.py b/satnogs.py index e60494d..9c3768e 100644 --- a/satnogs.py +++ b/satnogs.py @@ -3,15 +3,12 @@ import requests from flask import Flask , render_template,redirect,url_for import json from apscheduler.schedulers.background import BackgroundScheduler -import ephem from satnogs_api_client import fetch_satellites, DB_BASE_URL,fetch_tle_of_observation from satellite_tle import fetch_tles scheduler = BackgroundScheduler() app = Flask(__name__) -modes = {1: 'FM', 2: 'AFSK1k2', 5: 'SSTV', 6: 'CW', 7: 'FMN', 9: 'USB', 15: 'GFSK4k8', 17: 'AHRPT', 18: 'AFSK9k6', 19: 'AM', 20: 'LSB', 21: 'FSK1k2', 22: 'FSK9k6', 26: 'GFSK1k2', 27: 'GFSK2k4', 28: 'GFSK9k6', 29: 'GFSK19k2', 30: 'MSK1k2', 31: 'MSK2k4', 32: 'MSK4k8', 33: 'MSK9k6', 34: 'MSK19k2', 35: 'MSK38k4', 36: 'GMSK1k2', 37: 'GMSK2k4', 38: 'GMSK4k8', 39: 'GMSK9k6', 40: 'PSK31', 41: 'PSK63', 42: 'QPSK31', 43: 'QPSK63', 44: 'APT', 45: 'HRPT', 46: 'FSK4k8', 47: 'BPSK1k2', 48: 'GMSK19k2', 49: 'AFSK', 50: 'BPSK', 51: 'FSK19k2', 52: 'BPSK115k2', 53: 'LRPT', 54: 'BPSK9k6', 55: 'FFSK1k2', 56: 'FSK2k4', 57: 'DSTAR', 58: 'DUV', 59: 'CERTO', 60: 'BPSK400', 61: 'OFDM', 62: 'QPSK38k4'} - Passes = [] Stations = [] @@ -25,10 +22,7 @@ class Pass: satellite = None transmitter = None norad = 0 - - def __repr__(self): - return "\n: {}\n: {}\n: {}\n: {}\n {}\n: {}".format(self.id,self.start.strftime('%Y-%m-%dT%H:%M:%S%z'),self.end.strftime('%Y-%m-%dT%H:%M:%S%z'),self.ground_station,json.dumps(self.satellite,indent = 1),json.dumps(self.transmitter,indent=1)) - + def getActive(): @@ -68,10 +62,9 @@ def getActive(): temp.ground_station = x["ground_station"] temp.norad = str(x["norad_cat_id"]) try: - temp.satellite = requests.get("https://db.satnogs.org/api/satellites/"+str(x["norad_cat_id"])) .json() + temp.satellite = requests.get("https://db.satnogs.org/api/satellites/"+str(x["norad_cat_id"])).json() except: temp.satellite = {"name":""} - #temp.transmitter = requests.get("https://db.satnogs.org/api/transmitters/"+x["transmitter"]).json() Passes.append(temp) @@ -121,7 +114,7 @@ def updateStations(): def updateTLE(): print "Updating TLE" global TlEs - sats = fetch_satellites(url=DB_BASE_URL, max_satellites=None) + sats = fetch_satellites(None,DB_BASE_URL) satnogs_db_norad_ids = set(sat['norad_cat_id'] for sat in sats if sat['status'] != 're-entered') # Remove satellites with temporary norad ids temporary_norad_ids = set(filter(lambda norad_id: norad_id >= 99900, satnogs_db_norad_ids)) @@ -139,33 +132,11 @@ def updateTLE(): @app.route("/") def map_view(): - stations = [] - for x in Stations: - stations.append({'id':x['id'],'name':x['name'],'lat_lng':[x["lat"],x['lng']]}) - return render_template("map.html",stations = stations) - -@app.route('/occuringobservations') -def occuring_observations(): - obs = [] - for x in Passes: - obs.append(""+str(x.id)+"") - return json.dumps(obs) + return render_template("map.html") @app.route('/api/activestations') def api_active_stations(): - stations = [] - for x in Passes: - stations.append(x.ground_station) - return json.dumps(stations) - -@app.route('/api/onlinestations') -def api_online_stations(): - stations = [] - for x in Stations: - stations.append(x["id"]) - return json.dumps(stations) - - + return json.dumps(Stations) @app.route('/api/occuringobservations') def api_occuring_observations(): @@ -181,32 +152,12 @@ def api_occuring_sats(): if x.satellite['norad_cat_id'] not in TLEs.keys(): q = fetch_tle_of_observation(x.id) TLEs[ x.norad ] = [str(x.satellite["name"]),str(q[0]),str(q[1])] - satellite = ephem.readtle(TLEs[x.norad][0],TLEs[x.norad][1],TLEs[x.norad][2]) - now = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') - satellite.compute(now) - lat = satellite.sublat*57.295779514 - long = satellite.sublong*57.295779514 - if x.satellite['norad_cat_id'] == 25544: - obs[x.norad] = {"name":satellite.name,"lat_lng":[lat,long],"eclipsed":satellite.eclipsed,"image":"/static/ISS"} - else: - obs[x.norad] = {"name":satellite.name,"lat_lng":[lat,long],"eclipsed":satellite.eclipsed,"image":None} - return json.dumps(obs) + obs[x.id] = {"ground_station":x.ground_station,"start":x.start.isoformat(),"end":x.end.isoformat()} + return json.dumps([obs,TLEs]) -@app.route('/api/satstationpairs') -def api_sat_station_pairs(): - pairs = [] - for x in Passes: - pairs.append([x.ground_station,x.norad]) - return json.dumps(pairs) + -@app.route('/api/getsatloc/') -def get_sat_loc(norad): - satellite = ephem.readtle(TLEs[norad][0],TLEs[norad][1],TLEs[norad][2]) - now = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') - satellite.compute(now) - lat = satellite.sublat*57.295779514 - long = satellite.sublong*57.295779514 - return json.dumps([lat,long,satellite.eclipsed]) + updatePasses() updateStations() diff --git a/satnogs_api_client.py b/satnogs_api_client.py index 82b5e9e..59518af 100644 --- a/satnogs_api_client.py +++ b/satnogs_api_client.py @@ -1,6 +1,8 @@ -import requests +from __future__ import print_function import re +import requests + NETWORK_DEV_BASE_URL = 'https://network-dev.satnogs.org' NETWORK_BASE_URL = 'https://network.satnogs.org' @@ -8,92 +10,90 @@ DB_BASE_URL = 'https://db.satnogs.org' DB_DEV_BASE_URL = 'https://db-dev.satnogs.org' +def get_paginated_endpoint(url, max_entries=None): + r = requests.get(url=url) + r.raise_for_status() + + data = r.json() + + while 'next' in r.links and (not max_entries or len(data) < max_entries): + next_page_url = r.links['next']['url'] + + r = requests.get(url=next_page_url) + r.raise_for_status() + + data.extend(r.json()) + + return data + + def fetch_observation_data_from_id(norad_id, start, end, prod=True): - # Get all observations of the satellite with the given `norad_id` in the given timeframe + # Get all observations of the satellite + # with the given `norad_id` in the given timeframe # https://network.satnogs.org/api/observations/?satellite__norad_cat_id=25544&start=2018-06-10T00:00&end=2018-06-15T00:00 - query_str = '{}/api/observations/?satellite__norad_cat_id={}&start={}&end={}' + query_str = '{}/api/observations/' \ + '?satellite__norad_cat_id={}&start={}&end={}' url = query_str.format(NETWORK_BASE_URL if prod else NETWORK_DEV_BASE_URL, norad_id, start.isoformat(), end.isoformat()) - # print(url) - r = requests.get(url=url) + observations = get_paginated_endpoint(url) - if r.status_code != requests.codes.ok: - print("No observations found for {}, start: {}, end: {}.".format(norad_id, start_time, end_time)) - raise - - observations = r.json() - - next_page_available = ('Link' in r.headers.keys()) - - if next_page_available: - parts = r.headers['Link'].split(',') - for part in parts: - if part[-5:-1] == 'next': - next_page_url = part[1:-13] - - while next_page_available: - # print(next_page_url) - r = requests.get(url=next_page_url) - - observations.extend(r.json()) - - next_page_available = False - - if 'Link' in r.headers.keys(): - parts = r.headers['Link'].split(',') - for part in parts: - if part[-5:-1] == 'next': - next_page_url = part[1:-13] - next_page_available = True - - # Current prod is broken and can't filter on NORAD ID correctly, use client-side filtering instead - observations = list(filter(lambda o: o['norad_cat_id'] == norad_id, observations)) + # Current prod is broken and can't filter on NORAD ID correctly, + # use client-side filtering instead + observations = list(observation for observation in observations + if observation['norad_cat_id'] == norad_id) return observations def fetch_observation_data(observation_ids, prod=True): # Get station location from the observation via the observation_id - + observations = [] for observation_id in observation_ids: - r = requests.get(url='{}/api/observations/{}/'.format(NETWORK_BASE_URL if prod else NETWORK_DEV_BASE_URL, - observation_id)) - if r.status_code != requests.codes.ok: - print("Observation {} not found in network.".format(observation_id)) - continue + base_url = (NETWORK_BASE_URL if prod else NETWORK_DEV_BASE_URL) + r = requests.get(url='{}/api/observations/{}/'.format(base_url, + observation_id)) + r.raise_for_status() observations.append(r.json()) return observations + def fetch_ground_station_data(ground_station_ids, prod=True): # Fetch ground station metadata from network ground_stations = [] for ground_station_id in ground_station_ids: - r = requests.get(url='{}/api/stations/{}/'.format(NETWORK_BASE_URL if prod else NETWORK_DEV_BASE_URL, - ground_station_id)) - if r.status_code != requests.codes.ok: - print("Ground Station {} not found in db.".format(ground_station_id)) - raise - data = r.json() + # Skip frames from deleted groundstations, indidcated as ID 'None' + if str(ground_station_id) == 'None': + print("Skipping groundstation 'None'.") + continue + + base_url = (NETWORK_BASE_URL if prod else NETWORK_DEV_BASE_URL) + r = requests.get(url='{}/api/stations/{}/'.format(base_url, + ground_station_id)) + r.raise_for_status() + ground_stations.append(r.json()) return ground_stations + def fetch_satellite_data(norad_cat_id): # Fetch satellite metadata from network - r = requests.get(url='{}/api/satellites/{}/'.format(DB_BASE_URL, norad_cat_id)) - if r.status_code != requests.codes.ok: - print("ERROR: Satellite {} not found in network.".format(norad_cat_id)) + r = requests.get(url='{}/api/satellites/{}/'.format(DB_BASE_URL, + norad_cat_id)) + r.raise_for_status() return r.json() + def fetch_tle_of_observation(observation_id, prod=True): - url = '{}/observations/{}/'.format(NETWORK_BASE_URL if prod else NETWORK_DEV_BASE_URL, + base_url = (NETWORK_BASE_URL if prod else NETWORK_DEV_BASE_URL) + url = '{}/observations/{}/'.format(base_url, observation_id) r = requests.get(url=url) observation_page_html = r.text @@ -107,68 +107,39 @@ def fetch_tle_of_observation(observation_id, prod=True): return [obs_tle_2, obs_tle_3] -def fetch_telemetry(norad_id, max_frames, url): +def fetch_telemetry(norad_id, url): # http://db-dev.satnogs.org/api/telemetry/?satellite=43595 query_str = '{}/api/telemetry/?satellite={}' + url = query_str.format(url, norad_id) - try: - data = fetch_multi_page_api_endpoint(url, max_entries=max_frames) - except HTTPError: - print("No telemetry found for {}.".format(norad_id)) - raise + telemetry = get_paginated_endpoint(url) - return data + return telemetry -def fetch_satellites(max_satellites, url): +def fetch_transmitters(norad_id, url): + # http://db-dev.satnogs.org/api/transmitters/?satellite__norad_cat_id=25544 + + query_str = '{}/api/transmitters/?satellite__norad_cat_id={}' + + url = query_str.format(url, norad_id) + + transmitters = get_paginated_endpoint(url) + return transmitters + + +def fetch_satellites(max_entries, url): query_str = '{}/api/satellites/' url = query_str.format(url) - try: - data = fetch_multi_page_api_endpoint(url, max_entries=max_satellites) - except HTTPError: - print("An HTTPError occured.") - raise - - return data - -def fetch_multi_page_api_endpoint(url, max_entries): - # print(url) - r = requests.get(url=url) - r.raise_for_status() - - data = r.json() - - next_page_available = ('Link' in r.headers.keys()) - - if next_page_available and (not max_entries or len(data) < max_entries): - parts = r.headers['Link'].split(',') - for part in parts: - if part[-5:-1] == 'next': - next_page_url = part[1:-13] - - while next_page_available and (not max_entries or len(data) < max_entries): - # print(next_page_url) - r = requests.get(url=next_page_url) - - data.extend(r.json()) - - next_page_available = False - - if 'Link' in r.headers.keys(): - parts = r.headers['Link'].split(',') - for part in parts: - if part[-5:-1] == 'next': - next_page_url = part[1:-13] - next_page_available = True - - return data + satellites = get_paginated_endpoint(url, max_entries=max_entries) + return satellites def post_telemetry(norad_id, - source, + source, # Receiver Callsign lon, lat, timestamp, From 6f91791bf1c55e4c1a423a562b70e5d85edc01a6 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 12:28:17 -0600 Subject: [PATCH 02/23] Update stuff --- requirments.txt | 2 +- satnogs.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirments.txt b/requirments.txt index 08420a8..9d6c927 100644 --- a/requirments.txt +++ b/requirments.txt @@ -1,3 +1,3 @@ requests==2.21.0 flask==1.0.2 -apscheduler==3.5.3 \ No newline at end of file +apscheduler==3.5.3 diff --git a/satnogs.py b/satnogs.py index 9c3768e..3a681bb 100644 --- a/satnogs.py +++ b/satnogs.py @@ -163,4 +163,4 @@ updatePasses() updateStations() updateTLE() scheduler.start() -app.run(use_reloader=False,host = "0.0.0.0") \ No newline at end of file +app.run(use_reloader=False,host = "0.0.0.0",port=5001) \ No newline at end of file From 79054d0ece443f410f46bf7c6f861d4e47bc948a Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 12:29:10 -0600 Subject: [PATCH 03/23] Add missing dep --- satellite_tle/__init__.py | 2 ++ satellite_tle/__init__.pyc | Bin 0 -> 219 bytes satellite_tle/fetch_tle.py | 64 +++++++++++++++++++++++++++++++++ satellite_tle/fetch_tle.pyc | Bin 0 -> 2421 bytes satellite_tle/fetch_tles.py | 66 +++++++++++++++++++++++++++++++++++ satellite_tle/fetch_tles.pyc | Bin 0 -> 1642 bytes satellite_tle/sources.csv | 46 ++++++++++++++++++++++++ 7 files changed, 178 insertions(+) create mode 100644 satellite_tle/__init__.py create mode 100644 satellite_tle/__init__.pyc create mode 100644 satellite_tle/fetch_tle.py create mode 100644 satellite_tle/fetch_tle.pyc create mode 100644 satellite_tle/fetch_tles.py create mode 100644 satellite_tle/fetch_tles.pyc create mode 100644 satellite_tle/sources.csv diff --git a/satellite_tle/__init__.py b/satellite_tle/__init__.py new file mode 100644 index 0000000..42d10af --- /dev/null +++ b/satellite_tle/__init__.py @@ -0,0 +1,2 @@ +from .fetch_tle import * # noqa +from .fetch_tles import * # noqa diff --git a/satellite_tle/__init__.pyc b/satellite_tle/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e69939c5aa25f32c9d5a8cd56366d54ac709098f GIT binary patch literal 219 zcmYk0&kDjY4945-q66^ Nx_el~PcZ(G$uGl5F6KcM~2tPPF&itStPFVF1Ed}h{_zn2z%ocwtd(ezcp_cJ_3 zqlxkHC?z^{eV@YZraSd& zFe=l>Yj#w?n4q7R!3C^aJInHmEZE=O31-HL7&{Mvu}+gA>@Q&r(W=ayk8-P{fhrBp zePvlY&n4MOr^)^hALfP5EPH0}+Reb?|b3r`LJe z=^T8&6TWE6x+)+db`r%x=X%ix8T};HcEQQ(O=Yq8GQW_YJ7Yv6%x+?Zq%qIYYj1TA zj4n+#8YFL$?zT2(HZQt+%4YeA*;Z!oJXdAh{Q!V&U)yNFD6ALn>@vihXv@Ri)N$-F z^9dTN)%|5}(W~RV=q=%ST{qGTzr_A3X=h15PF`$Dp&!| z0ssJia0;ZEohdG$>A~q7T_I+5I`iROLbQJJC?lrnW|;?#*M5D4q%+q&)daIIDy-9V@FY{s0*5GZwRA=i> zrb-O>dy&QZa;GdIG3i5C5G$*K1l->I8f&ci|N5LHvw?FCtS!t|t95a4u^zD|%bKEm z*h27dx|YOiP<-3|Zod%_oDEx6k-}2)>5C$JX?&UHlMh;wh@%_wM=+y-&S) z2RXZkt!(p--_bb89p0`QUZF~&4hp>7I@E=EUaHY$pUWL+54MjFX;P;#*a!7Mp5gw5 z;4_p&U=7^A;KXRmlBdDEBRe37i)Nj`HIirCpeLLQsHqs&S?BpvdW{u#37EfdQUP=u z^)Ss_jjM_SsZ)ikKnc{q1ZsR1fNuH_l9T#2R$~*+`UFec{V=F+EHdd#Zlf;`c zu{n`itkRT;?in<+?S_h6UvlSfOl&VY(^(u;g#=7`x^LQ!_ z7P`w$kQaXbklB=Lkc}f55nRQzVaTbm?9WTNUiR*I zE8auA>)wJd`5rRRa{lykm`ZkwZ{#mRadv{+XL1}%Dv{@u#_z4?`Y0m;5afB*mh literal 0 HcmV?d00001 diff --git a/satellite_tle/fetch_tles.py b/satellite_tle/fetch_tles.py new file mode 100644 index 0000000..916b757 --- /dev/null +++ b/satellite_tle/fetch_tles.py @@ -0,0 +1,66 @@ +from __future__ import print_function + +from sgp4.earth_gravity import wgs72 +from sgp4.io import twoline2rv + +from . import get_tle_sources, fetch_tles_from_url, fetch_tle_from_celestrak + + +def fetch_tles(requested_norad_ids): + ''' + Returns the most recent TLEs found for the requested satellites + available via Celestrak, CalPoly and AMSAT. + ''' + + # List of 2-tuples of the form (source, tle) + # source is a human-readable string + # tle is a 3-tuple of strings + tles = dict() + + def update_tles(source, tle): + if norad_id not in requested_norad_ids: + # Satellite not requested, + # skip. + return + + if norad_id not in tles.keys(): + # Satellite requested and first occurence in the downloaded data, + # store new TLE. + #print('Found {}'.format(norad_id)) + tles[norad_id] = source, tle + return + + # There are multiple TLEs for this satellite available. + # Parse and compare epoch of both TLEs and choose the most recent one. + current_sat = twoline2rv(tles[norad_id][1][1], tles[norad_id][1][2], wgs72) + new_sat = twoline2rv(tle[1], tle[2], wgs72) + if new_sat.epoch > current_sat.epoch: + # Found a more recent TLE than the current one, + # store the new TLE. + + tles[norad_id] = source, tle + + # Fetch TLE sets from well-known TLE sources + sources = get_tle_sources() + + for source, url in sources: + #print('Fetch from {}'.format(url)) + new_tles = fetch_tles_from_url(url=url) + + for norad_id, tle in new_tles.items(): + update_tles(source, tle) + + # Try fetching missing sats from another Celestrak endoint + missing_norad_ids = set(requested_norad_ids) - set(tles.keys()) + + for norad_id in missing_norad_ids: + try: + #print('Fetching {} from Celestrak (satcat):'.format(norad_id), end='') + tle = fetch_tle_from_celestrak(norad_id) + #print(' ok, ', end='') + update_tles('Celestrak (satcat)', tle) + except LookupError: + #print(' failed.') + continue + + return tles diff --git a/satellite_tle/fetch_tles.pyc b/satellite_tle/fetch_tles.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2303c02c33230dca94bdfd73eef946333dfcf4f GIT binary patch literal 1642 zcmb_c-EJF26#iy*ZO3Us-GoXBDroO82<4(eAXOEjO>);(Xk7>xSF7#r*xq`7oSE4q zmh7t_(!K&WAn_{PbHOcd!2`fKv#nE!+pczJ=lsl>Ip6utc>io~{_)$NKPGtnNcw*b z0rLY*QhEh)pb!`e2$m&siNeFsYh(|(kD`TPi)0^Z3waww2g44E4GcF>bTRCbt&N|6 z;U>}!2K^0+p8ZQtU(n3HN5foarH#gQnb@o<8-0uP=M(eg-A3GG-}5TZN_AJCWxTZS zvF;`f6J;ZttH@NfPL#2`q#G-nOj&E9v95}!*16q#Ti>V?MIKhivxGzP+1m6`f-ry6 z!~&PVD~T)MO5jRj>@hGu11kY5*t(Lqc#NgQ(X(TWBvu|)KCEQGmOgoiRSOp%W7)zB zj~5(0+h@O5w6u+-z|zCAjY|n}`W;SA4{&0AyrkH)15G4ew0Iebd#esE9%9*{82329 z;zQUrUOHnFEL{gXIsFB`?O?VE{TGA~B-8sneJ2!j(Dx}pv!G!!peIze)};yTR0Tz4 zY@k)5N*g?VbZmlgRhKD^+L^UFtqC=i1}3&D&oirxixHp2Ssp*nRdANY!QmThKMM}y z{F^FY1TjT<@Obdx>4Ec4m~(s#{&pGk-)TbWQ1-J9bdPyBV3|O0rC{wBSb}jIOV*S1 zK6_Cy8fl;Ev98hNlbDZaK({Mz?{(#_ zyeap^ZSRiU7M|Rax5T!*A)oY_4wlzObRkklswfJ1nPuF~Wd8YqinX0a6CIyrcG0km xIpb_u<+w-J7Ui@?*})m|?boEuRyTWR$ujEqiz=;i^%e8pu%ah>q9^Zo{{axwZZ7}; literal 0 HcmV?d00001 diff --git a/satellite_tle/sources.csv b/satellite_tle/sources.csv new file mode 100644 index 0000000..2752a80 --- /dev/null +++ b/satellite_tle/sources.csv @@ -0,0 +1,46 @@ +'CalPoly','http://mstl.atl.calpoly.edu/~ops/keps/kepler.txt' +'AMSAT','https://www.amsat.org/amsat/ftp/keps/current/nasabare.txt' +'Celestrak (tle-new)','https://www.celestrak.com/NORAD/elements/tle-new.txt' +'Celestrak (stations)','https://www.celestrak.com/NORAD/elements/stations.txt' +'Celestrak (visual)','https://www.celestrak.com/NORAD/elements/visual.txt' +'Celestrak (1999-025)','https://www.celestrak.com/NORAD/elements/1999-025.txt' +'Celestrak (iridium-33-debris)','https://www.celestrak.com/NORAD/elements/iridium-33-debris.txt' +'Celestrak (cosmos-2251-debris)','https://www.celestrak.com/NORAD/elements/cosmos-2251-debris.txt' +'Celestrak (2012-044)','https://www.celestrak.com/NORAD/elements/2012-044.txt' +'Celestrak (weather)','https://www.celestrak.com/NORAD/elements/weather.txt' +'Celestrak (noaa)','https://www.celestrak.com/NORAD/elements/noaa.txt' +'Celestrak (goes)','https://www.celestrak.com/NORAD/elements/goes.txt' +'Celestrak (resource)','https://www.celestrak.com/NORAD/elements/resource.txt' +'Celestrak (sarsat)','https://www.celestrak.com/NORAD/elements/sarsat.txt' +'Celestrak (dmc)','https://www.celestrak.com/NORAD/elements/dmc.txt' +'Celestrak (tdrss)','https://www.celestrak.com/NORAD/elements/tdrss.txt' +'Celestrak (argos)','https://www.celestrak.com/NORAD/elements/argos.txt' +'Celestrak (planet)','https://www.celestrak.com/NORAD/elements/planet.txt' +'Celestrak (spire)','https://www.celestrak.com/NORAD/elements/spire.txt' +'Celestrak (geo)','https://www.celestrak.com/NORAD/elements/geo.txt' +'Celestrak (intelsat)','https://www.celestrak.com/NORAD/elements/intelsat.txt' +'Celestrak (ses)','https://www.celestrak.com/NORAD/elements/ses.txt' +'Celestrak (iridium)','https://www.celestrak.com/NORAD/elements/iridium.txt' +'Celestrak (iridium-NEXT)','https://www.celestrak.com/NORAD/elements/iridium-NEXT.txt' +'Celestrak (orbcomm)','https://www.celestrak.com/NORAD/elements/orbcomm.txt' +'Celestrak (globalstar)','https://www.celestrak.com/NORAD/elements/globalstar.txt' +'Celestrak (amateur)','https://www.celestrak.com/NORAD/elements/amateur.txt' +'Celestrak (other-comm)','https://www.celestrak.com/NORAD/elements/other-comm.txt' +'Celestrak (gorizont)','https://www.celestrak.com/NORAD/elements/gorizont.txt' +'Celestrak (raduga)','https://www.celestrak.com/NORAD/elements/raduga.txt' +'Celestrak (molniya)','https://www.celestrak.com/NORAD/elements/molniya.txt' +'Celestrak (gps-ops)','https://www.celestrak.com/NORAD/elements/gps-ops.txt' +'Celestrak (glo-ops)','https://www.celestrak.com/NORAD/elements/glo-ops.txt' +'Celestrak (galileo)','https://www.celestrak.com/NORAD/elements/galileo.txt' +'Celestrak (beidou)','https://www.celestrak.com/NORAD/elements/beidou.txt' +'Celestrak (sbas)','https://www.celestrak.com/NORAD/elements/sbas.txt' +'Celestrak (nnss)','https://www.celestrak.com/NORAD/elements/nnss.txt' +'Celestrak (musson)','https://www.celestrak.com/NORAD/elements/musson.txt' +'Celestrak (science)','https://www.celestrak.com/NORAD/elements/science.txt' +'Celestrak (geodetic)','https://www.celestrak.com/NORAD/elements/geodetic.txt' +'Celestrak (engineering)','https://www.celestrak.com/NORAD/elements/engineering.txt' +'Celestrak (education)','https://www.celestrak.com/NORAD/elements/education.txt' +'Celestrak (military)','https://www.celestrak.com/NORAD/elements/military.txt' +'Celestrak (radar)','https://www.celestrak.com/NORAD/elements/radar.txt' +'Celestrak (cubesat)','https://www.celestrak.com/NORAD/elements/cubesat.txt' +'Celestrak (other)','https://www.celestrak.com/NORAD/elements/other.txt' From 662689e014e4b41ceccb1dc2dae46bad971542e8 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 12:49:23 -0600 Subject: [PATCH 04/23] Backend mostly done --- satnogs.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/satnogs.py b/satnogs.py index 3a681bb..4592cc1 100644 --- a/satnogs.py +++ b/satnogs.py @@ -136,6 +136,9 @@ def map_view(): @app.route('/api/activestations') def api_active_stations(): + sations = [] + for x in Stations: + sations.append([x["name"],x["lat"],x["lng"]]) return json.dumps(Stations) @app.route('/api/occuringobservations') @@ -148,12 +151,14 @@ def api_occuring_observations(): @app.route('/api/occuringsats') def api_occuring_sats(): obs = {} + tle = {} for x in Passes: if x.satellite['norad_cat_id'] not in TLEs.keys(): q = fetch_tle_of_observation(x.id) TLEs[ x.norad ] = [str(x.satellite["name"]),str(q[0]),str(q[1])] - obs[x.id] = {"ground_station":x.ground_station,"start":x.start.isoformat(),"end":x.end.isoformat()} - return json.dumps([obs,TLEs]) + tle[x.norad] = TLEs[x.norad] + obs[x.id] = {"ground_station":x.ground_station,"start":x.start.isoformat(),"end":x.end.isoformat(),"sat":x.norad} + return json.dumps([obs,tle]) From 0aefbba3446b763a92edfcc608a5b684f70680b1 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 18:33:36 -0600 Subject: [PATCH 05/23] Finishing work on backend --- satnogs.py | 6 +- static/ISS-dark.png | Bin 6812 -> 0 bytes static/ISS-light.png | Bin 8058 -> 0 bytes static/Leaflet.Geodesic.js | 495 ------------------------------ static/light-satellite-marker.png | Bin 2598 -> 0 bytes static/satellite-marker.png | Bin 2531 -> 0 bytes templates/map.html | 146 +-------- 7 files changed, 17 insertions(+), 630 deletions(-) delete mode 100644 static/ISS-dark.png delete mode 100644 static/ISS-light.png delete mode 100644 static/Leaflet.Geodesic.js delete mode 100644 static/light-satellite-marker.png delete mode 100644 static/satellite-marker.png diff --git a/satnogs.py b/satnogs.py index 4592cc1..be4e47b 100644 --- a/satnogs.py +++ b/satnogs.py @@ -157,7 +157,11 @@ def api_occuring_sats(): q = fetch_tle_of_observation(x.id) TLEs[ x.norad ] = [str(x.satellite["name"]),str(q[0]),str(q[1])] tle[x.norad] = TLEs[x.norad] - obs[x.id] = {"ground_station":x.ground_station,"start":x.start.isoformat(),"end":x.end.isoformat(),"sat":x.norad} + if not x.norad in obs.keys(): + obs[x.norad] = [] + obs[x.norad].append({"ground_station":x.ground_station,"start":x.start.isoformat(),"end":x.end.isoformat()}) + + return json.dumps([obs,tle]) diff --git a/static/ISS-dark.png b/static/ISS-dark.png deleted file mode 100644 index 0780e25993b9e97a0e673925291495760080df6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6812 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 diff --git a/static/Leaflet.Geodesic.js b/static/Leaflet.Geodesic.js deleted file mode 100644 index 278815d..0000000 --- a/static/Leaflet.Geodesic.js +++ /dev/null @@ -1,495 +0,0 @@ -"use strict"; - -// This file is part of Leaflet.Geodesic. -// Copyright (C) 2017 Henry Thasler -// based on code by Chris Veness Copyright (C) 2014 https://github.com/chrisveness/geodesy -// -// Leaflet.Geodesic is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Leaflet.Geodesic is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Leaflet.Geodesic. If not, see . - - -/** Extend Number object with method to convert numeric degrees to radians */ -if (typeof Number.prototype.toRadians === "undefined") { - Number.prototype.toRadians = function() { - return this * Math.PI / 180; - }; -} - -/** Extend Number object with method to convert radians to numeric (signed) degrees */ -if (typeof Number.prototype.toDegrees === "undefined") { - Number.prototype.toDegrees = function() { - return this * 180 / Math.PI; - }; -} - -var INTERSECT_LNG = 179.999; // Lng used for intersection and wrap around on map edges - -L.Geodesic = L.Polyline.extend({ - options: { - color: "blue", - steps: 10, - dash: 1, - wrap: true - }, - - initialize: function(latlngs, options) { - this.options = this._merge_options(this.options, options); - this.options.dash = Math.max(1e-3, Math.min(1, parseFloat(this.options.dash) || 1)); - this.datum = {}; - this.datum.ellipsoid = { - a: 6378137, - b: 6356752.3142, - f: 1 / 298.257223563 - }; // WGS-84 - this._latlngs = this._generate_Geodesic(latlngs); - L.Polyline.prototype.initialize.call(this, this._latlngs, this.options); - }, - - setLatLngs: function(latlngs) { - this._latlngs = this._generate_Geodesic(latlngs); - L.Polyline.prototype.setLatLngs.call(this, this._latlngs); - }, - - /** - * Calculates some statistic values of current geodesic multipolyline - * @returns (Object} Object with several properties (e.g. overall distance) - */ - getStats: function() { - let obj = { - distance: 0, - points: 0, - polygons: this._latlngs.length - }, poly, points; - - for (poly = 0; poly < this._latlngs.length; poly++) { - obj.points += this._latlngs[poly].length; - for (points = 0; points < (this._latlngs[poly].length - 1); points++) { - obj.distance += this._vincenty_inverse(this._latlngs[poly][points], - this._latlngs[poly][points + 1]).distance; - } - } - return obj; - }, - - - /** - * Creates geodesic lines from geoJson. Replaces all current features of this instance. - * Supports LineString, MultiLineString and Polygon - * @param {Object} geojson - geosjon as object. - */ - geoJson: function(geojson) { - - let normalized = L.GeoJSON.asFeature(geojson); - let features = normalized.type === "FeatureCollection" ? normalized.features : [ - normalized - ]; - this._latlngs = []; - for (let feature of features) { - let geometry = feature.type === "Feature" ? feature.geometry : - feature, - coords = geometry.coordinates; - - switch (geometry.type) { - case "LineString": - this._latlngs.push(this._generate_Geodesic([L.GeoJSON.coordsToLatLngs( - coords, 0)])); - break; - case "MultiLineString": - case "Polygon": - this._latlngs.push(this._generate_Geodesic(L.GeoJSON.coordsToLatLngs( - coords, 1))); - break; - case "Point": - case "MultiPoint": - console.log("Dude, points can't be drawn as geodesic lines..."); - break; - default: - console.log("Drawing " + geometry.type + - " as a geodesic is not supported. Skipping..."); - } - } - L.Polyline.prototype.setLatLngs.call(this, this._latlngs); - }, - - /** - * Creates a great circle. Replaces all current lines. - * @param {Object} center - geographic position - * @param {number} radius - radius of the circle in metres - */ - createCircle: function(center, radius) { - let polylineIndex = 0; - let prev = { - lat: 0, - lng: 0, - brg: 0 - }; - let step; - - this._latlngs = []; - this._latlngs[polylineIndex] = []; - - let direct = this._vincenty_direct(L.latLng(center), 0, radius, this.options - .wrap); - prev = L.latLng(direct.lat, direct.lng); - this._latlngs[polylineIndex].push(prev); - for (step = 1; step <= this.options.steps;) { - direct = this._vincenty_direct(L.latLng(center), 360 / this.options - .steps * step, radius, this.options.wrap); - let gp = L.latLng(direct.lat, direct.lng); - if (Math.abs(gp.lng - prev.lng) > 180) { - let inverse = this._vincenty_inverse(prev, gp); - let sec = this._intersection(prev, inverse.initialBearing, { - lat: -89, - lng: ((gp.lng - prev.lng) > 0) ? -INTERSECT_LNG : INTERSECT_LNG - }, 0); - if (sec) { - this._latlngs[polylineIndex].push(L.latLng(sec.lat, sec.lng)); - polylineIndex++; - this._latlngs[polylineIndex] = []; - prev = L.latLng(sec.lat, -sec.lng); - this._latlngs[polylineIndex].push(prev); - } else { - polylineIndex++; - this._latlngs[polylineIndex] = []; - this._latlngs[polylineIndex].push(gp); - prev = gp; - step++; - } - } else { - this._latlngs[polylineIndex].push(gp); - prev = gp; - step++; - } - } - - L.Polyline.prototype.setLatLngs.call(this, this._latlngs); - }, - - /** - * Creates a geodesic Polyline from given coordinates - * Note: dashed lines are under work - * @param {Object} latlngs - One or more polylines as an array. See Leaflet doc about Polyline - * @returns (Object} An array of arrays of geographical points. - */ - _generate_Geodesic: function(latlngs) { - let _geo = [], _geocnt = 0; - - for (let poly = 0; poly < latlngs.length; poly++) { - _geo[_geocnt] = []; - let prev = L.latLng(latlngs[poly][0]); - for (let points = 0; points < (latlngs[poly].length - 1); points++) { - // use prev, so that wrapping behaves correctly - let pointA = prev; - let pointB = L.latLng(latlngs[poly][points + 1]); - if (pointA.equals(pointB)) { - continue; - } - let inverse = this._vincenty_inverse(pointA, pointB); - _geo[_geocnt].push(prev); - for (let s = 1; s <= this.options.steps;) { - let distance = inverse.distance / this.options.steps; - // dashed lines don't go the full distance between the points - let dist_mult = s - 1 + this.options.dash; - let direct = this._vincenty_direct(pointA, inverse.initialBearing, distance*dist_mult, this.options.wrap); - let gp = L.latLng(direct.lat, direct.lng); - if (Math.abs(gp.lng - prev.lng) > 180) { - let sec = this._intersection(pointA, inverse.initialBearing, { - lat: -89, - lng: ((gp.lng - prev.lng) > 0) ? -INTERSECT_LNG : INTERSECT_LNG - }, 0); - if (sec) { - _geo[_geocnt].push(L.latLng(sec.lat, sec.lng)); - _geocnt++; - _geo[_geocnt] = []; - prev = L.latLng(sec.lat, -sec.lng); - _geo[_geocnt].push(prev); - } else { - _geocnt++; - _geo[_geocnt] = []; - _geo[_geocnt].push(gp); - prev = gp; - s++; - } - } else { - _geo[_geocnt].push(gp); - // Dashed lines start a new line - if (this.options.dash < 1){ - _geocnt++; - // go full distance this time, to get starting point for next line - let direct_full = this._vincenty_direct(pointA, inverse.initialBearing, distance*s, this.options.wrap); - _geo[_geocnt] = []; - prev = L.latLng(direct_full.lat, direct_full.lng); - _geo[_geocnt].push(prev); - } - else prev = gp; - s++; - } - } - } - _geocnt++; - } - return _geo; - }, - - /** - * Vincenty direct calculation. - * based on the work of Chris Veness (https://github.com/chrisveness/geodesy) - * - * @private - * @param {number} initialBearing - Initial bearing in degrees from north. - * @param {number} distance - Distance along bearing in metres. - * @returns (Object} Object including point (destination point), finalBearing. - */ - - _vincenty_direct: function(p1, initialBearing, distance, wrap) { - var φ1 = p1.lat.toRadians(), - λ1 = p1.lng.toRadians(); - var α1 = initialBearing.toRadians(); - var s = distance; - - var a = this.datum.ellipsoid.a, - b = this.datum.ellipsoid.b, - f = this.datum.ellipsoid.f; - - var sinα1 = Math.sin(α1); - var cosα1 = Math.cos(α1); - - var tanU1 = (1 - f) * Math.tan(φ1), - cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), - sinU1 = tanU1 * cosU1; - var σ1 = Math.atan2(tanU1, cosα1); - var sinα = cosU1 * sinα1; - var cosSqα = 1 - sinα * sinα; - var uSq = cosSqα * (a * a - b * b) / (b * b); - var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * - uSq))); - var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))); - - var σ = s / (b * A), - σʹ, iterations = 0; - var sinσ, cosσ; - var cos2σM; - do { - cos2σM = Math.cos(2 * σ1 + σ); - sinσ = Math.sin(σ); - cosσ = Math.cos(σ); - var Δσ = B * sinσ * (cos2σM + B / 4 * (cosσ * (-1 + 2 * cos2σM * - cos2σM) - - B / 6 * cos2σM * (-3 + 4 * sinσ * sinσ) * (-3 + 4 * cos2σM * - cos2σM))); - σʹ = σ; - σ = s / (b * A) + Δσ; - } while (Math.abs(σ - σʹ) > 1e-12 && ++iterations); - - var x = sinU1 * sinσ - cosU1 * cosσ * cosα1; - var φ2 = Math.atan2(sinU1 * cosσ + cosU1 * sinσ * cosα1, (1 - f) * - Math.sqrt(sinα * sinα + x * x)); - var λ = Math.atan2(sinσ * sinα1, cosU1 * cosσ - sinU1 * sinσ * cosα1); - var C = f / 16 * cosSqα * (4 + f * (4 - 3 * cosSqα)); - var L = λ - (1 - C) * f * sinα * - (σ + C * sinσ * (cos2σM + C * cosσ * (-1 + 2 * cos2σM * cos2σM))); - - var λ2; - if (wrap) { - λ2 = (λ1 + L + 3 * Math.PI) % (2 * Math.PI) - Math.PI; // normalise to -180...+180 - } else { - λ2 = (λ1 + L); // do not normalize - } - - var revAz = Math.atan2(sinα, -x); - - return { - lat: φ2.toDegrees(), - lng: λ2.toDegrees(), - finalBearing: revAz.toDegrees() - }; - }, - - /** - * Vincenty inverse calculation. - * based on the work of Chris Veness (https://github.com/chrisveness/geodesy) - * - * @private - * @param {LatLng} p1 - Latitude/longitude of start point. - * @param {LatLng} p2 - Latitude/longitude of destination point. - * @returns {Object} Object including distance, initialBearing, finalBearing. - * @throws {Error} If formula failed to converge. - */ - _vincenty_inverse: function(p1, p2) { - var φ1 = p1.lat.toRadians(), - λ1 = p1.lng.toRadians(); - var φ2 = p2.lat.toRadians(), - λ2 = p2.lng.toRadians(); - - var a = this.datum.ellipsoid.a, - b = this.datum.ellipsoid.b, - f = this.datum.ellipsoid.f; - - var L = λ2 - λ1; - var tanU1 = (1 - f) * Math.tan(φ1), - cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), - sinU1 = tanU1 * cosU1; - var tanU2 = (1 - f) * Math.tan(φ2), - cosU2 = 1 / Math.sqrt((1 + tanU2 * tanU2)), - sinU2 = tanU2 * cosU2; - - var λ = L, - λʹ, iterations = 0; - var cosSqα, sinσ, cos2σM, cosσ, σ, sinλ, cosλ; - do { - sinλ = Math.sin(λ); - cosλ = Math.cos(λ); - var sinSqσ = (cosU2 * sinλ) * (cosU2 * sinλ) + (cosU1 * sinU2 - - sinU1 * cosU2 * cosλ) * (cosU1 * sinU2 - sinU1 * cosU2 * cosλ); - sinσ = Math.sqrt(sinSqσ); - if (sinσ == 0) return 0; // co-incident points - cosσ = sinU1 * sinU2 + cosU1 * cosU2 * cosλ; - σ = Math.atan2(sinσ, cosσ); - var sinα = cosU1 * cosU2 * sinλ / sinσ; - cosSqα = 1 - sinα * sinα; - cos2σM = cosσ - 2 * sinU1 * sinU2 / cosSqα; - if (isNaN(cos2σM)) cos2σM = 0; // equatorial line: cosSqα=0 (§6) - var C = f / 16 * cosSqα * (4 + f * (4 - 3 * cosSqα)); - λʹ = λ; - λ = L + (1 - C) * f * sinα * (σ + C * sinσ * (cos2σM + C * cosσ * (- - 1 + 2 * cos2σM * cos2σM))); - } while (Math.abs(λ - λʹ) > 1e-12 && ++iterations < 100); - if (iterations >= 100) { - console.log("Formula failed to converge. Altering target position."); - return this._vincenty_inverse(p1, { - lat: p2.lat, - lng: p2.lng - 0.01 - }); - // throw new Error('Formula failed to converge'); - } - - var uSq = cosSqα * (a * a - b * b) / (b * b); - var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * - uSq))); - var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))); - var Δσ = B * sinσ * (cos2σM + B / 4 * (cosσ * (-1 + 2 * cos2σM * - cos2σM) - - B / 6 * cos2σM * (-3 + 4 * sinσ * sinσ) * (-3 + 4 * cos2σM * - cos2σM))); - - var s = b * A * (σ - Δσ); - - var fwdAz = Math.atan2(cosU2 * sinλ, cosU1 * sinU2 - sinU1 * cosU2 * - cosλ); - var revAz = Math.atan2(cosU1 * sinλ, -sinU1 * cosU2 + cosU1 * sinU2 * - cosλ); - - s = Number(s.toFixed(3)); // round to 1mm precision - return { - distance: s, - initialBearing: fwdAz.toDegrees(), - finalBearing: revAz.toDegrees() - }; - }, - - - /** - * Returns the point of intersection of two paths defined by point and bearing. - * based on the work of Chris Veness (https://github.com/chrisveness/geodesy) - * - * @param {LatLon} p1 - First point. - * @param {number} brng1 - Initial bearing from first point. - * @param {LatLon} p2 - Second point. - * @param {number} brng2 - Initial bearing from second point. - * @returns {Object} containing lat/lng information of intersection. - * - * @example - * var p1 = LatLon(51.8853, 0.2545), brng1 = 108.55; - * var p2 = LatLon(49.0034, 2.5735), brng2 = 32.44; - * var pInt = LatLon.intersection(p1, brng1, p2, brng2); // pInt.toString(): 50.9078°N, 4.5084°E - */ - _intersection: function(p1, brng1, p2, brng2) { - // see http://williams.best.vwh.net/avform.htm#Intersection - - var φ1 = p1.lat.toRadians(), - λ1 = p1.lng.toRadians(); - var φ2 = p2.lat.toRadians(), - λ2 = p2.lng.toRadians(); - var θ13 = Number(brng1).toRadians(), - θ23 = Number(brng2).toRadians(); - var Δφ = φ2 - φ1, - Δλ = λ2 - λ1; - - var δ12 = 2 * Math.asin(Math.sqrt(Math.sin(Δφ / 2) * Math.sin(Δφ / 2) + - Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / - 2))); - if (δ12 == 0) return null; - - // initial/final bearings between points - var θ1 = Math.acos((Math.sin(φ2) - Math.sin(φ1) * Math.cos(δ12)) / - (Math.sin(δ12) * Math.cos(φ1))); - if (isNaN(θ1)) θ1 = 0; // protect against rounding - var θ2 = Math.acos((Math.sin(φ1) - Math.sin(φ2) * Math.cos(δ12)) / - (Math.sin(δ12) * Math.cos(φ2))); - var θ12, θ21; - if (Math.sin(λ2 - λ1) > 0) { - θ12 = θ1; - θ21 = 2 * Math.PI - θ2; - } else { - θ12 = 2 * Math.PI - θ1; - θ21 = θ2; - } - - var α1 = (θ13 - θ12 + Math.PI) % (2 * Math.PI) - Math.PI; // angle 2-1-3 - var α2 = (θ21 - θ23 + Math.PI) % (2 * Math.PI) - Math.PI; // angle 1-2-3 - - if (Math.sin(α1) == 0 && Math.sin(α2) == 0) return null; // infinite intersections - if (Math.sin(α1) * Math.sin(α2) < 0) return null; // ambiguous intersection - - //α1 = Math.abs(α1); - //α2 = Math.abs(α2); - // ... Ed Williams takes abs of α1/α2, but seems to break calculation? - - var α3 = Math.acos(-Math.cos(α1) * Math.cos(α2) + - Math.sin(α1) * Math.sin(α2) * Math.cos(δ12)); - var δ13 = Math.atan2(Math.sin(δ12) * Math.sin(α1) * Math.sin(α2), - Math.cos(α2) + Math.cos(α1) * Math.cos(α3)); - var φ3 = Math.asin(Math.sin(φ1) * Math.cos(δ13) + - Math.cos(φ1) * Math.sin(δ13) * Math.cos(θ13)); - var Δλ13 = Math.atan2(Math.sin(θ13) * Math.sin(δ13) * Math.cos(φ1), - Math.cos(δ13) - Math.sin(φ1) * Math.sin(φ3)); - var λ3 = λ1 + Δλ13; - λ3 = (λ3 + 3 * Math.PI) % (2 * Math.PI) - Math.PI; // normalise to -180..+180º - - return { - lat: φ3.toDegrees(), - lng: λ3.toDegrees() - }; - }, - - /** - * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1 - * @param obj1 - * @param obj2 - * @returns obj3 a new object based on obj1 and obj2 - */ - _merge_options: function(obj1, obj2) { - let obj3 = {}; - for (let attrname in obj1) { - obj3[attrname] = obj1[attrname]; - } - for (let attrname in obj2) { - obj3[attrname] = obj2[attrname]; - } - return obj3; - } -}); - -L.geodesic = function(latlngs, options) { - return new L.Geodesic(latlngs, options); -}; diff --git a/static/light-satellite-marker.png b/static/light-satellite-marker.png deleted file mode 100644 index af17f1bf8929891e63a2c12839e56ad31bc7db94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2598 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 IM6N<$f+(cjz5oCK diff --git a/static/satellite-marker.png b/static/satellite-marker.png deleted file mode 100644 index 697846db9c6696cd2e1ec1d930abbdf2fc1831d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2531 zcmV<92^{u`P)0Htk2LX{yQK|2)! zNtKy~9~m5e4c0OssPP95P5i@=D47A^3Bk_4jC;Bo*YkhhwgQVhydRsn4FJWzV`?24;tFN zmm4Glp9H*2Iyn!LnH*290(U3divV9?AWjvB)Q@4sn}L6lO3o*7BS(O1zz0Yr$CLk% zKElQ%<^vsMH*&lTyACrsemMf%99nON2{VCRxRVnFYVeU$TwE+gMMXCKSAmKU`!g(9 ziCbpvA2|mADJdzD^XJdYsZ*z9>eQ*W=dPnx&v9XPD%Z#~#nQ+rEiIJ`7cPj1$jOr@ zWx|9B#%Jfwoh$kI`2zfwF&@AlC72vY=23Iz%#n*1FN%oBv17-iprF7=&XOfdq_eYA zjvP56kw`>jPLU7%lyq|LOMd?dAoJ$UlS`K_iHOM2qerdeR903>S67#ah_tk{ z_`mybxZTPvrU0*yPEHFT^XJc(%a<>Uh{&Nsha@jA&q&VFrAzzCX=-ZHzi(%ZpPB!eAd40) zk}FrPh=|Dk{rj!KeEIU_($mu;A|iYC?8&q$t`4_LxyL?|v81!J(-ccmq^71uu3ft( zi9|wn?b_v%Q~et#3cXi3!alU=(%jr^?d+;mtNO{=v15m8(kZ~V!tPiu&({SKEEbcE8#h|@%FE09 z1AJ?1tGD{Kp-x?fjQfG*sPidX?l2oD_sLrfI#V>A1pzjLs)+)~`t|Gk$=R@BgH^Ah zqQVs5b4CuN-p**U==?x)?287S3Qeacz-Aus5|&PH-MUrc@wmidF==RMu#!_%Rb|Sg zb4m`tYd)h7TXY`Roco$V=T1W>f@(GMP(`tnXSQwICh>S&dV70i_3G7Da{T#_FIn`+ z$wy`8)7>Zt#@~E~4_kCvH3xrW(76d!IrQt5XRzJu*KcTOkVGOO(P&g^Yiq6KtX#RW zf63pyd$)<4BgxNxO%ATw{KjYeMT^dZnv-WOdar7FJ2TiW08V@QGiJD?Y0=_6~#2EvTayzuq!~UcIIh14krsp*20p9EAOA2l!HMsuRqW5LZ;NLM%$NidKFY0u|1rbz%KdQAMP7FeAs4M^L%iIpD2X z_yWLJwZ`tZ=$+N{Ov^pMrwtAs%+jZcs9eS$`-VzR7XyJktNTbbT7%D9^z`$s1W;zs zD*#Rz9Nm|VQ%T$dTx5V8P}`V3L;E&zDj6WhA4;6BK^LHkOa2B-uMSKmHS-qKS-A;s z1Kuz={5aW7H&Ddrg|97!wq42bq$L|C^lbUCMX%9dsKKIJfqCbC26$IC&N=$*mjk3u zE1NvvYV0oU!5C_PrDG!SS55Z~;5JLU%TNiZ?pO?US!%Ycg9hXQPa4`jK=8=%OD|CE zYVc|8;gc4$ns3GK=_m}aCQ5_u&Io=iIMuKZt{di7m(!ovFA9teBZ_4ByPifTIu9`%GcM7Inn~sZ>ri(24*E2)r}v=KHWeOcpvJfzP`sB zEI|N^aC<$=M2;s;Ig)90*lf|goz#oup8Os~U?vo!rqU0Sjt_+(P)V*HA6?1uBx8;= zne^JuH3ses>L|mU^K@WO0c@CpT2bGJISF;aLk3?2xQzNi!JMx6C1X;159ybl{)M?< z59(Jjy|*F2&v4(c<^mDY7ldrc@#G_!41Lb<&^govO%sYxMKY7I7^8O=9+mR!{&oNgu(ol%6 zZtRn@sQs1=w-fw6nV>eDFQAT*>VP?9zfW_;u#n^7O{CV0{PX%f8J?|S;KG!P#84aJ z3k+`eZ$csIn{1mr#UM{Yih=Wn2Co9!9Gw%sJ9CWI1wl%)&g~ z1oevetqyIJpz2C5l9{Yr5(L3H(vZpVa5HKXYcld0D)_n9-l`gifyExZseLE zFy}})BgaENsyJ`^HU5bDdmclGylE`aJm2h002ovPDHLkV1m}K(SZN} diff --git a/templates/map.html b/templates/map.html index 404b2bd..3e7dfea 100644 --- a/templates/map.html +++ b/templates/map.html @@ -8,7 +8,7 @@ - + @@ -73,145 +73,23 @@ var active_station = L.icon({ accessToken: 'pk.eyJ1IjoiY2hpYmlsbCIsImEiOiJjamxsNHBuZG4wdG1uM3FwYTN5c2ZubmxrIn0.ghkx6AngBzUiZQWBAWKziQ' }).addTo(mymap); -stationList = {} -{% for x in stations %} - marker = L.marker({{x["lat_lng"]}},{icon: station,zIndexOffset:-1000}).addTo(mymap); - marker.bindPopup("Name: {{x['name']}}") - stationList[{{x['id']}}] = marker + //Ground Stations + // marker = L.marker({{x["lat_lng"]}},{icon: station,zIndexOffset:-1000}).addTo(mymap); + //marker.bindPopup("Name: {{x['name']}}") -{%endfor%} + //Sats + //marker = L.marker(data[key]["lat_lng"],{icon: sat,zIndexOffset:1000}).addTo(mymap); + //marker.bindPopup("Name: "+data[key]["name"]+"
Norad: "+key+"
Eclipsed?: "+data[key]["eclipsed"]); + //sats[key] = marker; - - - -var sats = {} - -var links = {} - - - $.get("/api/occuringsats", function(data, status){ - data = JSON.parse(data) - Object.keys(data).forEach(function(key){ - sat = light_sat - if(data[key]["eclipsed"]){ - sat = dark_sat - } - if(data[key]["image"] != null){ - image = data[key]["image"] - if(data[key]["eclipsed"]){ - image = image + "-dark.png" - }else{ - image = image + "-light.png" - } - sat = L.icon({ - iconUrl: image, - iconSize: [40, 40], - iconAnchor: [20, 20], - popupAnchor: [0, 0], - - }); - } - marker = L.marker(data[key]["lat_lng"],{icon: sat,zIndexOffset:1000}).addTo(mymap); - marker.bindPopup("Name: "+data[key]["name"]+"
Norad: "+key+"
Eclipsed?: "+data[key]["eclipsed"]); - sats[key] = marker; - }); - }); - -$.get("/api/satstationpairs", function(data, status){ - data = JSON.parse(data) - data.forEach(function(entry){ - firstpolyline = new L.Polyline([[stationList[entry[0]]._latlng.lat,stationList[entry[0]]._latlng.lng],[sats[entry[1]]._latlng.lat,sats[entry[1]]._latlng.lng]], {color: '#'+entry[1].toString(16).repeat(2).substr(0,6),weight: 3,opacity: 1,smoothFactor: 1}); + //lines + // firstpolyline = new L.Polyline([[stationList[entry[0]]._latlng.lat,stationList[entry[0]]._latlng.lng],[sats[entry[1]]._latlng.lat,sats[entry[1]]._latlng.lng]], {color: '#'+entry[1].toString(16).repeat(2).substr(0,6),weight: 3,opacity: 1,smoothFactor: 1}); - firstpolyline.addTo(mymap) - - links[entry[0]] = firstpolyline - stationList[entry[0]].setIcon(active_station) - stationList[entry[0]].setZIndexOffset(500) - - }); - }); + // firstpolyline.addTo(mymap) + -setInterval(function(){ - - Object.keys(links).forEach(function(key){ - links[key].setStyle({opacity:0}) - links[key].removeFrom(mymap) - - }) - - links = {} - - - - - $.get("/api/occuringsats", function(data, status){ - data = JSON.parse(data) - Object.keys(sats).forEach(function(key){ - sats[key].removeFrom(mymap) - delete sats[key] - }) - - Object.keys(data).forEach(function(key){ - sat = light_sat - if(data[key]["eclipsed"]){ - sat = dark_sat - } - if(data[key]["image"] != null){ - image = data[key]["image"] - if(data[key]["eclipsed"]){ - image = image + "-dark.png" - }else{ - image = image + "-light.png" - } - - sat = L.icon({ - iconUrl: image, - iconSize: [40, 40], - iconAnchor: [20, 20], - popupAnchor: [0, 0], - - }); - } - marker = L.marker(data[key]["lat_lng"],{icon: sat,zIndexOffset:1000}).addTo(mymap); - marker.bindPopup("Name: "+data[key]["name"]+"
Norad: "+key+"
Eclipsed?: "+data[key]["eclipsed"]); - sats[key] = marker; - }); - - - }); - - $.get("/api/satstationpairs", function(data, status){ - data = JSON.parse(data) - var usedStations = [] - Object.keys(stationList).forEach(function(key){ - stationList[key].setIcon(station) - stationList[key].setZIndexOffset(-1000) - - }) - data.forEach(function(entry){ - firstpolyline = new L.Polyline([[stationList[entry[0]]._latlng.lat,stationList[entry[0]]._latlng.lng],[sats[entry[1]]._latlng.lat,sats[entry[1]]._latlng.lng]], {color: '#'+entry[1].toString(16).repeat(2).substr(0,6),weight:3,opacity:1,smoothFactor: 1}); - - firstpolyline.addTo(mymap) - links[entry[0]] = firstpolyline - stationList[entry[0]].setIcon(active_station) - stationList[entry[0]].setZIndexOffset(500) - }); - - }); - console.log(links) - - }, 20000); - - var t = L.terminator(); -t.addTo(mymap); -setInterval(function(){updateTerminator(t)}, 500); -function updateTerminator(t) { - var t2 = L.terminator(); - t.setLatLngs(t2.getLatLngs()); - t.redraw(); -} From cdea8a1991c8d8dc9aa9d45801c1acb94949d607 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 18:36:19 -0600 Subject: [PATCH 06/23] . --- satnogs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/satnogs.py b/satnogs.py index be4e47b..b45e4d0 100644 --- a/satnogs.py +++ b/satnogs.py @@ -121,6 +121,7 @@ def updateTLE(): satnogs_db_norad_ids = satnogs_db_norad_ids - temporary_norad_ids # Fetch TLEs for the satellites of interest + print satnogs_db_norad_ids tles = fetch_tles(satnogs_db_norad_ids) TLEs = {} for norad_id, (source, tle) in tles.items(): From 47187c0ae1bbf4b233a4499b3411238b3da4ac7a Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 18:39:31 -0600 Subject: [PATCH 07/23] Add another dep. --- requirments.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirments.txt b/requirments.txt index 9d6c927..1a226d3 100644 --- a/requirments.txt +++ b/requirments.txt @@ -1,3 +1,4 @@ requests==2.21.0 flask==1.0.2 apscheduler==3.5.3 +satellitetle==0.5.1 \ No newline at end of file From f23e70e497be5aa48b992383039139c9510ad33e Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 18:44:34 -0600 Subject: [PATCH 08/23] Remove local dep --- satellite_tle/__init__.py | 2 -- satellite_tle/__init__.pyc | Bin 219 -> 0 bytes satellite_tle/fetch_tle.py | 64 --------------------------------- satellite_tle/fetch_tle.pyc | Bin 2421 -> 0 bytes satellite_tle/fetch_tles.py | 66 ----------------------------------- satellite_tle/fetch_tles.pyc | Bin 1642 -> 0 bytes satellite_tle/sources.csv | 46 ------------------------ 7 files changed, 178 deletions(-) delete mode 100644 satellite_tle/__init__.py delete mode 100644 satellite_tle/__init__.pyc delete mode 100644 satellite_tle/fetch_tle.py delete mode 100644 satellite_tle/fetch_tle.pyc delete mode 100644 satellite_tle/fetch_tles.py delete mode 100644 satellite_tle/fetch_tles.pyc delete mode 100644 satellite_tle/sources.csv diff --git a/satellite_tle/__init__.py b/satellite_tle/__init__.py deleted file mode 100644 index 42d10af..0000000 --- a/satellite_tle/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .fetch_tle import * # noqa -from .fetch_tles import * # noqa diff --git a/satellite_tle/__init__.pyc b/satellite_tle/__init__.pyc deleted file mode 100644 index e69939c5aa25f32c9d5a8cd56366d54ac709098f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 219 zcmYk0&kDjY4945-q66^ Nx_el~PcZ(G$uGl5F6KcM~2tPPF&itStPFVF1Ed}h{_zn2z%ocwtd(ezcp_cJ_3 zqlxkHC?z^{eV@YZraSd& zFe=l>Yj#w?n4q7R!3C^aJInHmEZE=O31-HL7&{Mvu}+gA>@Q&r(W=ayk8-P{fhrBp zePvlY&n4MOr^)^hALfP5EPH0}+Reb?|b3r`LJe z=^T8&6TWE6x+)+db`r%x=X%ix8T};HcEQQ(O=Yq8GQW_YJ7Yv6%x+?Zq%qIYYj1TA zj4n+#8YFL$?zT2(HZQt+%4YeA*;Z!oJXdAh{Q!V&U)yNFD6ALn>@vihXv@Ri)N$-F z^9dTN)%|5}(W~RV=q=%ST{qGTzr_A3X=h15PF`$Dp&!| z0ssJia0;ZEohdG$>A~q7T_I+5I`iROLbQJJC?lrnW|;?#*M5D4q%+q&)daIIDy-9V@FY{s0*5GZwRA=i> zrb-O>dy&QZa;GdIG3i5C5G$*K1l->I8f&ci|N5LHvw?FCtS!t|t95a4u^zD|%bKEm z*h27dx|YOiP<-3|Zod%_oDEx6k-}2)>5C$JX?&UHlMh;wh@%_wM=+y-&S) z2RXZkt!(p--_bb89p0`QUZF~&4hp>7I@E=EUaHY$pUWL+54MjFX;P;#*a!7Mp5gw5 z;4_p&U=7^A;KXRmlBdDEBRe37i)Nj`HIirCpeLLQsHqs&S?BpvdW{u#37EfdQUP=u z^)Ss_jjM_SsZ)ikKnc{q1ZsR1fNuH_l9T#2R$~*+`UFec{V=F+EHdd#Zlf;`c zu{n`itkRT;?in<+?S_h6UvlSfOl&VY(^(u;g#=7`x^LQ!_ z7P`w$kQaXbklB=Lkc}f55nRQzVaTbm?9WTNUiR*I zE8auA>)wJd`5rRRa{lykm`ZkwZ{#mRadv{+XL1}%Dv{@u#_z4?`Y0m;5afB*mh diff --git a/satellite_tle/fetch_tles.py b/satellite_tle/fetch_tles.py deleted file mode 100644 index 916b757..0000000 --- a/satellite_tle/fetch_tles.py +++ /dev/null @@ -1,66 +0,0 @@ -from __future__ import print_function - -from sgp4.earth_gravity import wgs72 -from sgp4.io import twoline2rv - -from . import get_tle_sources, fetch_tles_from_url, fetch_tle_from_celestrak - - -def fetch_tles(requested_norad_ids): - ''' - Returns the most recent TLEs found for the requested satellites - available via Celestrak, CalPoly and AMSAT. - ''' - - # List of 2-tuples of the form (source, tle) - # source is a human-readable string - # tle is a 3-tuple of strings - tles = dict() - - def update_tles(source, tle): - if norad_id not in requested_norad_ids: - # Satellite not requested, - # skip. - return - - if norad_id not in tles.keys(): - # Satellite requested and first occurence in the downloaded data, - # store new TLE. - #print('Found {}'.format(norad_id)) - tles[norad_id] = source, tle - return - - # There are multiple TLEs for this satellite available. - # Parse and compare epoch of both TLEs and choose the most recent one. - current_sat = twoline2rv(tles[norad_id][1][1], tles[norad_id][1][2], wgs72) - new_sat = twoline2rv(tle[1], tle[2], wgs72) - if new_sat.epoch > current_sat.epoch: - # Found a more recent TLE than the current one, - # store the new TLE. - - tles[norad_id] = source, tle - - # Fetch TLE sets from well-known TLE sources - sources = get_tle_sources() - - for source, url in sources: - #print('Fetch from {}'.format(url)) - new_tles = fetch_tles_from_url(url=url) - - for norad_id, tle in new_tles.items(): - update_tles(source, tle) - - # Try fetching missing sats from another Celestrak endoint - missing_norad_ids = set(requested_norad_ids) - set(tles.keys()) - - for norad_id in missing_norad_ids: - try: - #print('Fetching {} from Celestrak (satcat):'.format(norad_id), end='') - tle = fetch_tle_from_celestrak(norad_id) - #print(' ok, ', end='') - update_tles('Celestrak (satcat)', tle) - except LookupError: - #print(' failed.') - continue - - return tles diff --git a/satellite_tle/fetch_tles.pyc b/satellite_tle/fetch_tles.pyc deleted file mode 100644 index b2303c02c33230dca94bdfd73eef946333dfcf4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1642 zcmb_c-EJF26#iy*ZO3Us-GoXBDroO82<4(eAXOEjO>);(Xk7>xSF7#r*xq`7oSE4q zmh7t_(!K&WAn_{PbHOcd!2`fKv#nE!+pczJ=lsl>Ip6utc>io~{_)$NKPGtnNcw*b z0rLY*QhEh)pb!`e2$m&siNeFsYh(|(kD`TPi)0^Z3waww2g44E4GcF>bTRCbt&N|6 z;U>}!2K^0+p8ZQtU(n3HN5foarH#gQnb@o<8-0uP=M(eg-A3GG-}5TZN_AJCWxTZS zvF;`f6J;ZttH@NfPL#2`q#G-nOj&E9v95}!*16q#Ti>V?MIKhivxGzP+1m6`f-ry6 z!~&PVD~T)MO5jRj>@hGu11kY5*t(Lqc#NgQ(X(TWBvu|)KCEQGmOgoiRSOp%W7)zB zj~5(0+h@O5w6u+-z|zCAjY|n}`W;SA4{&0AyrkH)15G4ew0Iebd#esE9%9*{82329 z;zQUrUOHnFEL{gXIsFB`?O?VE{TGA~B-8sneJ2!j(Dx}pv!G!!peIze)};yTR0Tz4 zY@k)5N*g?VbZmlgRhKD^+L^UFtqC=i1}3&D&oirxixHp2Ssp*nRdANY!QmThKMM}y z{F^FY1TjT<@Obdx>4Ec4m~(s#{&pGk-)TbWQ1-J9bdPyBV3|O0rC{wBSb}jIOV*S1 zK6_Cy8fl;Ev98hNlbDZaK({Mz?{(#_ zyeap^ZSRiU7M|Rax5T!*A)oY_4wlzObRkklswfJ1nPuF~Wd8YqinX0a6CIyrcG0km xIpb_u<+w-J7Ui@?*})m|?boEuRyTWR$ujEqiz=;i^%e8pu%ah>q9^Zo{{axwZZ7}; diff --git a/satellite_tle/sources.csv b/satellite_tle/sources.csv deleted file mode 100644 index 2752a80..0000000 --- a/satellite_tle/sources.csv +++ /dev/null @@ -1,46 +0,0 @@ -'CalPoly','http://mstl.atl.calpoly.edu/~ops/keps/kepler.txt' -'AMSAT','https://www.amsat.org/amsat/ftp/keps/current/nasabare.txt' -'Celestrak (tle-new)','https://www.celestrak.com/NORAD/elements/tle-new.txt' -'Celestrak (stations)','https://www.celestrak.com/NORAD/elements/stations.txt' -'Celestrak (visual)','https://www.celestrak.com/NORAD/elements/visual.txt' -'Celestrak (1999-025)','https://www.celestrak.com/NORAD/elements/1999-025.txt' -'Celestrak (iridium-33-debris)','https://www.celestrak.com/NORAD/elements/iridium-33-debris.txt' -'Celestrak (cosmos-2251-debris)','https://www.celestrak.com/NORAD/elements/cosmos-2251-debris.txt' -'Celestrak (2012-044)','https://www.celestrak.com/NORAD/elements/2012-044.txt' -'Celestrak (weather)','https://www.celestrak.com/NORAD/elements/weather.txt' -'Celestrak (noaa)','https://www.celestrak.com/NORAD/elements/noaa.txt' -'Celestrak (goes)','https://www.celestrak.com/NORAD/elements/goes.txt' -'Celestrak (resource)','https://www.celestrak.com/NORAD/elements/resource.txt' -'Celestrak (sarsat)','https://www.celestrak.com/NORAD/elements/sarsat.txt' -'Celestrak (dmc)','https://www.celestrak.com/NORAD/elements/dmc.txt' -'Celestrak (tdrss)','https://www.celestrak.com/NORAD/elements/tdrss.txt' -'Celestrak (argos)','https://www.celestrak.com/NORAD/elements/argos.txt' -'Celestrak (planet)','https://www.celestrak.com/NORAD/elements/planet.txt' -'Celestrak (spire)','https://www.celestrak.com/NORAD/elements/spire.txt' -'Celestrak (geo)','https://www.celestrak.com/NORAD/elements/geo.txt' -'Celestrak (intelsat)','https://www.celestrak.com/NORAD/elements/intelsat.txt' -'Celestrak (ses)','https://www.celestrak.com/NORAD/elements/ses.txt' -'Celestrak (iridium)','https://www.celestrak.com/NORAD/elements/iridium.txt' -'Celestrak (iridium-NEXT)','https://www.celestrak.com/NORAD/elements/iridium-NEXT.txt' -'Celestrak (orbcomm)','https://www.celestrak.com/NORAD/elements/orbcomm.txt' -'Celestrak (globalstar)','https://www.celestrak.com/NORAD/elements/globalstar.txt' -'Celestrak (amateur)','https://www.celestrak.com/NORAD/elements/amateur.txt' -'Celestrak (other-comm)','https://www.celestrak.com/NORAD/elements/other-comm.txt' -'Celestrak (gorizont)','https://www.celestrak.com/NORAD/elements/gorizont.txt' -'Celestrak (raduga)','https://www.celestrak.com/NORAD/elements/raduga.txt' -'Celestrak (molniya)','https://www.celestrak.com/NORAD/elements/molniya.txt' -'Celestrak (gps-ops)','https://www.celestrak.com/NORAD/elements/gps-ops.txt' -'Celestrak (glo-ops)','https://www.celestrak.com/NORAD/elements/glo-ops.txt' -'Celestrak (galileo)','https://www.celestrak.com/NORAD/elements/galileo.txt' -'Celestrak (beidou)','https://www.celestrak.com/NORAD/elements/beidou.txt' -'Celestrak (sbas)','https://www.celestrak.com/NORAD/elements/sbas.txt' -'Celestrak (nnss)','https://www.celestrak.com/NORAD/elements/nnss.txt' -'Celestrak (musson)','https://www.celestrak.com/NORAD/elements/musson.txt' -'Celestrak (science)','https://www.celestrak.com/NORAD/elements/science.txt' -'Celestrak (geodetic)','https://www.celestrak.com/NORAD/elements/geodetic.txt' -'Celestrak (engineering)','https://www.celestrak.com/NORAD/elements/engineering.txt' -'Celestrak (education)','https://www.celestrak.com/NORAD/elements/education.txt' -'Celestrak (military)','https://www.celestrak.com/NORAD/elements/military.txt' -'Celestrak (radar)','https://www.celestrak.com/NORAD/elements/radar.txt' -'Celestrak (cubesat)','https://www.celestrak.com/NORAD/elements/cubesat.txt' -'Celestrak (other)','https://www.celestrak.com/NORAD/elements/other.txt' From f2df83c42e6e5dc1bde2526e9fc5c26f8a087ea2 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 20:30:14 -0600 Subject: [PATCH 09/23] Make backend better for use with web workers --- satnogs.py | 21 +++++++++------------ static/Worker.js | 16 ++++++++++++++++ templates/map.html | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 static/Worker.js diff --git a/satnogs.py b/satnogs.py index b45e4d0..ce672c6 100644 --- a/satnogs.py +++ b/satnogs.py @@ -135,35 +135,32 @@ def updateTLE(): def map_view(): return render_template("map.html") -@app.route('/api/activestations') +@app.route('/api/active_stations') def api_active_stations(): sations = [] for x in Stations: sations.append([x["name"],x["lat"],x["lng"]]) return json.dumps(Stations) -@app.route('/api/occuringobservations') -def api_occuring_observations(): +@app.route('/api/stations_from_sat/') +def api_occuring_observations(norad): obs = [] for x in Passes: - obs.append(x.id) + if x.norad == norad: + obs.append(x.ground_station) + return json.dumps(obs) -@app.route('/api/occuringsats') +@app.route('/api/occuring_sats') def api_occuring_sats(): - obs = {} tle = {} for x in Passes: if x.satellite['norad_cat_id'] not in TLEs.keys(): q = fetch_tle_of_observation(x.id) TLEs[ x.norad ] = [str(x.satellite["name"]),str(q[0]),str(q[1])] tle[x.norad] = TLEs[x.norad] - if not x.norad in obs.keys(): - obs[x.norad] = [] - obs[x.norad].append({"ground_station":x.ground_station,"start":x.start.isoformat(),"end":x.end.isoformat()}) - - - return json.dumps([obs,tle]) + + return json.dumps(tle) diff --git a/static/Worker.js b/static/Worker.js new file mode 100644 index 0000000..d86248a --- /dev/null +++ b/static/Worker.js @@ -0,0 +1,16 @@ +importScripts("https://bundle.run/satellite.js@3.0.0") + +norad = 0 +passes = [] +TLE = [] + +onmessage = function(e) { + if(e[0] == 1){ + norad = e[1] + TLE = e[2] + passes = e[3] + } + var workerResult = 'Result: ' + (e.data[0] * e.data[1]); + console.log('Posting message back to main script'); + postMessage(workerResult); +} \ No newline at end of file diff --git a/templates/map.html b/templates/map.html index 3e7dfea..46347c5 100644 --- a/templates/map.html +++ b/templates/map.html @@ -7,8 +7,7 @@ crossorigin=""> - - + @@ -74,6 +73,40 @@ var active_station = L.icon({ }).addTo(mymap); +function UpdateMap(e) { + var satPos = e[0] + var links = e[1] +} + + $.get("/api/activestations", function(data, status){ + data = JSON.parse(data) + Object.keys(data).forEach(function(key){ + sat = light_sat + if(data[key]["eclipsed"]){ + sat = dark_sat + } + if(data[key]["image"] != null){ + image = data[key]["image"] + if(data[key]["eclipsed"]){ + image = image + "-dark.png" + }else{ + image = image + "-light.png" + } + + sat = L.icon({ + iconUrl: image, + iconSize: [40, 40], + iconAnchor: [20, 20], + popupAnchor: [0, 0], + + }); + } + marker = L.marker(data[key]["lat_lng"],{icon: sat,zIndexOffset:1000}).addTo(mymap); + marker.bindPopup("Name: "+data[key]["name"]+"
Norad: "+key+"
Eclipsed?: "+data[key]["eclipsed"]); + sats[key] = marker; + }); + }); + //Ground Stations // marker = L.marker({{x["lat_lng"]}},{icon: station,zIndexOffset:-1000}).addTo(mymap); //marker.bindPopup("Name: {{x['name']}}") From b3ec27be74215f7d4533f667bf384e81e062c165 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 20:41:43 -0600 Subject: [PATCH 10/23] Finalizing the back end --- satnogs.py | 8 ++++---- templates/map.html | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/satnogs.py b/satnogs.py index ce672c6..71cd656 100644 --- a/satnogs.py +++ b/satnogs.py @@ -135,14 +135,14 @@ def updateTLE(): def map_view(): return render_template("map.html") -@app.route('/api/active_stations') +@app.route('/active_stations') def api_active_stations(): sations = [] for x in Stations: sations.append([x["name"],x["lat"],x["lng"]]) - return json.dumps(Stations) + return json.dumps(sations) -@app.route('/api/stations_from_sat/') +@app.route('/stations_from_sat/') def api_occuring_observations(norad): obs = [] for x in Passes: @@ -151,7 +151,7 @@ def api_occuring_observations(norad): return json.dumps(obs) -@app.route('/api/occuring_sats') +@app.route('/occuring_sats') def api_occuring_sats(): tle = {} for x in Passes: diff --git a/templates/map.html b/templates/map.html index 46347c5..e8487c0 100644 --- a/templates/map.html +++ b/templates/map.html @@ -78,7 +78,7 @@ function UpdateMap(e) { var links = e[1] } - $.get("/api/activestations", function(data, status){ + $.get("/activestations", function(data, status){ data = JSON.parse(data) Object.keys(data).forEach(function(key){ sat = light_sat From ec8d2eeca03af7bc1e83a55243733930c1a61702 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 20:42:36 -0600 Subject: [PATCH 11/23] . --- satnogs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/satnogs.py b/satnogs.py index 71cd656..17a05ab 100644 --- a/satnogs.py +++ b/satnogs.py @@ -142,7 +142,7 @@ def api_active_stations(): sations.append([x["name"],x["lat"],x["lng"]]) return json.dumps(sations) -@app.route('/stations_from_sat/') +@app.route('/stations_from_sat/') def api_occuring_observations(norad): obs = [] for x in Passes: From 94762a8e1afbbc539583b26cfda2fd3a115f2922 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 21:09:46 -0600 Subject: [PATCH 12/23] Inital map objects --- satnogs.py | 2 +- templates/map.html | 40 +++++++++------------------------------- 2 files changed, 10 insertions(+), 32 deletions(-) diff --git a/satnogs.py b/satnogs.py index 17a05ab..35e9f01 100644 --- a/satnogs.py +++ b/satnogs.py @@ -139,7 +139,7 @@ def map_view(): def api_active_stations(): sations = [] for x in Stations: - sations.append([x["name"],x["lat"],x["lng"]]) + sations.append([x["name"],[x["lat"],x["lng"]]]) return json.dumps(sations) @app.route('/stations_from_sat/') diff --git a/templates/map.html b/templates/map.html index e8487c0..12eb36d 100644 --- a/templates/map.html +++ b/templates/map.html @@ -73,6 +73,8 @@ var active_station = L.icon({ }).addTo(mymap); +Stations = [] + function UpdateMap(e) { var satPos = e[0] var links = e[1] @@ -80,38 +82,14 @@ function UpdateMap(e) { $.get("/activestations", function(data, status){ data = JSON.parse(data) - Object.keys(data).forEach(function(key){ - sat = light_sat - if(data[key]["eclipsed"]){ - sat = dark_sat - } - if(data[key]["image"] != null){ - image = data[key]["image"] - if(data[key]["eclipsed"]){ - image = image + "-dark.png" - }else{ - image = image + "-light.png" - } + Object.keys(data).forEach(function(x){ + marker = L.marker([1],{icon: station,zIndexOffset:-1000}).addTo(mymap); + marker.bindPopup("Name: "+x[2]+"") + + }); + }); + - sat = L.icon({ - iconUrl: image, - iconSize: [40, 40], - iconAnchor: [20, 20], - popupAnchor: [0, 0], - - }); - } - marker = L.marker(data[key]["lat_lng"],{icon: sat,zIndexOffset:1000}).addTo(mymap); - marker.bindPopup("Name: "+data[key]["name"]+"
Norad: "+key+"
Eclipsed?: "+data[key]["eclipsed"]); - sats[key] = marker; - }); - }); - - //Ground Stations - // marker = L.marker({{x["lat_lng"]}},{icon: station,zIndexOffset:-1000}).addTo(mymap); - //marker.bindPopup("Name: {{x['name']}}") - - //Sats //marker = L.marker(data[key]["lat_lng"],{icon: sat,zIndexOffset:1000}).addTo(mymap); //marker.bindPopup("Name: "+data[key]["name"]+"
Norad: "+key+"
Eclipsed?: "+data[key]["eclipsed"]); //sats[key] = marker; From 7003b7ab9926b8c7cc14fdb5e0d42bcbfa4b7803 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 21:13:31 -0600 Subject: [PATCH 13/23] Fix inital objects --- templates/map.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/map.html b/templates/map.html index 12eb36d..df0e588 100644 --- a/templates/map.html +++ b/templates/map.html @@ -80,7 +80,7 @@ function UpdateMap(e) { var links = e[1] } - $.get("/activestations", function(data, status){ + $.get("/active_stations", function(data, status){ data = JSON.parse(data) Object.keys(data).forEach(function(x){ marker = L.marker([1],{icon: station,zIndexOffset:-1000}).addTo(mymap); From 04ba084a5af912078e7df0f26b560a0037cde773 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 21:19:15 -0600 Subject: [PATCH 14/23] Stupid little errors --- templates/map.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/map.html b/templates/map.html index df0e588..47e403b 100644 --- a/templates/map.html +++ b/templates/map.html @@ -83,7 +83,7 @@ function UpdateMap(e) { $.get("/active_stations", function(data, status){ data = JSON.parse(data) Object.keys(data).forEach(function(x){ - marker = L.marker([1],{icon: station,zIndexOffset:-1000}).addTo(mymap); + marker = L.marker(x[1],{icon: station,zIndexOffset:-1000}).addTo(mymap); marker.bindPopup("Name: "+x[2]+"") }); From 739fd839e75fe18c1902f1423d9b0258046d0e23 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Tue, 18 Dec 2018 21:21:58 -0600 Subject: [PATCH 15/23] Stupid little error --- satnogs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/satnogs.py b/satnogs.py index 35e9f01..62399cb 100644 --- a/satnogs.py +++ b/satnogs.py @@ -139,7 +139,7 @@ def map_view(): def api_active_stations(): sations = [] for x in Stations: - sations.append([x["name"],[x["lat"],x["lng"]]]) + sations.append([x["name"],{"lat":x["lat"],"lng":x["lng"]}]) return json.dumps(sations) @app.route('/stations_from_sat/') From 87ceb972dae14d302930083fc0b681e7a4ca5df8 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Wed, 19 Dec 2018 15:25:38 -0600 Subject: [PATCH 16/23] Front-end mostly working. Some small bugs. --- satnogs.py | 23 ++++++++-------- static/Worker.js | 52 +++++++++++++++++++++++++++--------- static/satellite.js | 1 + templates/map.html | 65 ++++++++++++++++++++++++++++++++++++++------- 4 files changed, 109 insertions(+), 32 deletions(-) create mode 100644 static/satellite.js diff --git a/satnogs.py b/satnogs.py index 62399cb..d128593 100644 --- a/satnogs.py +++ b/satnogs.py @@ -11,6 +11,7 @@ app = Flask(__name__) Passes = [] +Occuring_sats = {} Stations = [] TLEs = {} @@ -101,9 +102,16 @@ def GetGroundStations(): @scheduler.scheduled_job('interval',minutes=3) def updatePasses(): global Passes + global Occuring_sats print "Updating Passes" Passes = getActive() - + Occuring_sats = {} + for x in Passes: + if x.satellite['norad_cat_id'] not in TLEs.keys(): + q = fetch_tle_of_observation(x.id) + TLEs[ x.norad ] = [str(x.satellite["name"]),str(q[0]),str(q[1])] + Occuring_sats[x.norad] = TLEs[x.norad] + @scheduler.scheduled_job('interval',hours=1) def updateStations(): global Stations @@ -121,7 +129,7 @@ def updateTLE(): satnogs_db_norad_ids = satnogs_db_norad_ids - temporary_norad_ids # Fetch TLEs for the satellites of interest - print satnogs_db_norad_ids + tles = fetch_tles(satnogs_db_norad_ids) TLEs = {} for norad_id, (source, tle) in tles.items(): @@ -139,7 +147,7 @@ def map_view(): def api_active_stations(): sations = [] for x in Stations: - sations.append([x["name"],{"lat":x["lat"],"lng":x["lng"]}]) + sations.append({'id':x['id'],'name':x['name'],'lat_lng':[x["lat"],x['lng']]}) return json.dumps(sations) @app.route('/stations_from_sat/') @@ -153,14 +161,7 @@ def api_occuring_observations(norad): @app.route('/occuring_sats') def api_occuring_sats(): - tle = {} - for x in Passes: - if x.satellite['norad_cat_id'] not in TLEs.keys(): - q = fetch_tle_of_observation(x.id) - TLEs[ x.norad ] = [str(x.satellite["name"]),str(q[0]),str(q[1])] - tle[x.norad] = TLEs[x.norad] - - return json.dumps(tle) + return json.dumps(Occuring_sats) diff --git a/static/Worker.js b/static/Worker.js index d86248a..e02410c 100644 --- a/static/Worker.js +++ b/static/Worker.js @@ -1,16 +1,44 @@ -importScripts("https://bundle.run/satellite.js@3.0.0") +self.importScripts("satellite.js"); -norad = 0 -passes = [] +norad = "" +groundStations = [] TLE = [] onmessage = function(e) { - if(e[0] == 1){ - norad = e[1] - TLE = e[2] - passes = e[3] - } - var workerResult = 'Result: ' + (e.data[0] * e.data[1]); - console.log('Posting message back to main script'); - postMessage(workerResult); -} \ No newline at end of file + norad = e.data[0] + TLE = e.data[1] + getStations() +} + +setInterval(function(){ + getStations() +}, 20000); + +setInterval(function(){ + var satrec = self.satellite_js.twoline2satrec(TLE[1],TLE[2]); + var gmst = self.satellite_js.gstime(new Date()); + var positionAndVelocity = self.satellite_js.propagate(satrec, new Date()); + var positionEci = positionAndVelocity.position + var positionGd = self.satellite_js.eciToGeodetic(positionEci, gmst) + var longitude = positionGd.longitude + var latitude = positionGd.latitude + + postMessage([norad,TLE[0],[degress(latitude),degress(longitude)],groundStations]) + + +}, 500); + +function getStations(){ +var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + groundStations = JSON.parse(this.responseText); + } + }; + xhttp.open("GET", "/stations_from_sat/"+norad, true); + xhttp.send(); +} + +function degress (radians) { + return radians * 180 / Math.PI; +}; \ No newline at end of file diff --git a/static/satellite.js b/static/satellite.js new file mode 100644 index 0000000..e294cab --- /dev/null +++ b/static/satellite.js @@ -0,0 +1 @@ +!function(o,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(o.satellite_js={})}(this,function(o){"use strict";var Ho=Math.PI,Yo=2*Ho,m=Ho/180,t=180/Ho,s=398600.5,Ao=6378.137,Bo=60/Math.sqrt(Ao*Ao*Ao/s),p=1/Bo,Co=.00108262998905,e=-253215306e-14,Uo=-161098761e-14,Do=e/Co,Jo=2/3,a=Object.freeze({pi:Ho,twoPi:Yo,deg2rad:m,rad2deg:t,minutesPerDay:1440,mu:s,earthRadius:Ao,xke:Bo,tumin:p,j2:Co,j3:e,j4:Uo,j3oj2:Do,x2o3:Jo});function l(o,t){for(var s=[31,o%4==0?29:28,31,30,31,30,31,31,30,31,30,31],e=Math.floor(t),a=1,n=0;n+s[a-1]Ho&&(so - +test = null var light_sat = L.icon({ iconUrl: 'static/satellite-marker-light.png', iconSize: [40, 40], @@ -71,24 +71,71 @@ var active_station = L.icon({ id: 'mapbox.streets', accessToken: 'pk.eyJ1IjoiY2hpYmlsbCIsImEiOiJjamxsNHBuZG4wdG1uM3FwYTN5c2ZubmxrIn0.ghkx6AngBzUiZQWBAWKziQ' }).addTo(mymap); +var t = L.terminator(); +t.addTo(mymap); +setInterval(function(){updateTerminator(t)}, 500); +function updateTerminator(t) { + var t2 = L.terminator(); + t.setLatLngs(t2.getLatLngs()); + t.redraw(); +} +Stations = {} +Workers = {} +Lines = {} +Sats = {} -Stations = [] - +dataS = null function UpdateMap(e) { - var satPos = e[0] - var links = e[1] + var norad = e.data[0] + var name = e.data[1] + var satPos = e.data[2] + if (norad in Sats){ + + }else{ + Sats[norad] = L.marker(satPos,{icon: dark_sat,zIndexOffset:1000}).addTo(mymap); + Sats[norad].bindPopup("Name: "+name+"
Norad: "+norad+""); + Lines[norad] = {} + e.data[3].forEach(function(x){ + Lines[norad][x] = new L.Polyline([[Stations[x]._latlng.lat,Stations[x]._latlng.lng],[satPos[0],satPos[1]]], {color: '#'+norad.toString(16).repeat(2).substr(0,6),weight: 3,opacity: 1,smoothFactor: 1}); + Lines[norad][x].addTo(mymap) + }); + } + Sats[norad]._latlng = {"lat":satPos[0],"lng":satPos[1]} + Sats[norad].update() + Object.keys(Lines[norad]).forEach(function(x){ + if (x in e){ + Lines[norad][x]._latlngs[1]= {"lat":satPos[0],"lng":satPos[1]} + Lines[norad][x].update() + }else{ + Lines[norad][x].removeFrom(mymap) + delete Lines[norad][x] + } + }) + + + } $.get("/active_stations", function(data, status){ data = JSON.parse(data) - Object.keys(data).forEach(function(x){ - marker = L.marker(x[1],{icon: station,zIndexOffset:-1000}).addTo(mymap); - marker.bindPopup("Name: "+x[2]+"") - + dataS = data + data.forEach(function(x){ + + marker = L.marker(x["lat_lng"],{icon: station,zIndexOffset:-1000}).addTo(mymap); + marker.bindPopup("Name: "+x['name']+"") + Stations[x["id"]] = marker }); }); + $.get("/occuring_sats", function(data, status){ + data = JSON.parse(data) + Object.keys(data).forEach(function(x){ + worker = new Worker('/static/Worker.js'); + worker.onmessage = UpdateMap + worker.postMessage([x,data[x]]); + }); + }); //marker = L.marker(data[key]["lat_lng"],{icon: sat,zIndexOffset:1000}).addTo(mymap); //marker.bindPopup("Name: "+data[key]["name"]+"
Norad: "+key+"
Eclipsed?: "+data[key]["eclipsed"]); From 2578c9acd79c06e493b210488deaecc4d46b7906 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Wed, 19 Dec 2018 15:28:57 -0600 Subject: [PATCH 17/23] Fix error preventing lines from displaying --- satnogs_api_client.pyc | Bin 0 -> 5049 bytes templates/map.html | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 satnogs_api_client.pyc diff --git a/satnogs_api_client.pyc b/satnogs_api_client.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91a2e0bcb2f30ce869fb71493d419f57f5680b25 GIT binary patch literal 5049 zcmcIo(QX^Z6}_{RC{d<@977$=iFJ*lw=eIDv9Rs?#%4W?7iold)KvpEiU}y zgSEY`RDS_}e=bJsKVc;JXQVGOFtTgJ@H&uwAiIH%!LG?}O%k*-lFZ2NtR%CtTbHCR zyK|hJ%*j`{xgqI-B=c%tQ@f#dQ|$${7bUqSUy1B4X=hVAuS>G1oy(Fesc}P+>uRh> ziY=CP+D-1Y)4G8}XaB}u%fNC=Xoh8$yXat)cU@NG9s4@^4xJm?yX|(Ky5AM$@jFTS z#fFVtUi9onQTFVs7w4QA|Mt{)vVUgiJ7Y$QC&cD$>vLV?V#2=B|z&teECWi-VyC?i#E?{4~ONnPGW$mbyw3 zW5q>W@)*%D?xhh9)Fyu0_oF*9-KohsOD`>>5n1!Gj+%`7?TB|{q z9-?!6kP+a0Tp$Jr!O4sq2?JHWB6y;_CN7XaqsLSsp2Ygg85z$Cp7&&yQ61MA;XjES z040HZja%xnjR8M~iz-g`BW(73+{S~ni+yY<~jFYGvyC_RO zd_MjWLR2~$cs%@c>1)E2F@KK`eFFxN`T46dR)i%YYdH3CAZ3k*|I|Ez1Q;BGx49;o z={-6=I6B5=<0p>cojRW<>-^-tEYVvoEtIx_rSJ7pKxSBOwQ*q?rn=Nji||tn04iS@(kK*BQ9oDo@eV9fJ69VKD2;xFszt3PHK$X{X z6{+$*1&e{KQO*EjgepNSVIWc$1F3=23^uQUY+MK=W6)7Hbc#H+#M{nsHXLSoZ@pI* zqdZ{(frPEU$q8?6_@Fa>RnV((+h)KQ(61Z=nUr;!{Qo-yLT)-0d@|N=t;q{}g9twU zj=(rOW*tk8vwfH!exHk86%y94xJSadjmh1I7_`KS1ONlmlBuIrNCc~9BJXs)GWQM) z#NSsSBxOJ!vJ~;8RLuudK|;e+rSv?*L9**K9H)842ZY!=$2%4O?FSPLRUUf(6RjbA zd}W@a7&YDkaz$CGw! z#eyj0u!OxgEYq!b*IOHJzjbfF+`8kfHhV37{qB0kw4(N%^^9FDCZs9Cs8UXZ zQ<>^ectHnP`l)={G%mY`N;krBs4NWExsHmaQbE%f`QQkasU!Om?$8bTx2h6 zAQ^WLQTp*fm>;=*8r?Z__1;ye>?_#LBZM0k2h+Lnw-~d85bM4MK4?L*mEfki=@G;1 zGC>TF2YgiJyrQQIqcHq9Tz@{ki?0@^p8AZrit(_pPBSX&pplLE zJ{!J)(eTG;ycDZCe8@X^8&2YXV;635;(az0X??U|{H$NZiHF8j6);pTo;;eU)L+r# zrFCw>%vGO-;JUemZ;P7i2#W~+k>f@s-eN;sN%#&MK9#TVIWK%0jaF(XGNxbF!XI*! zTdU_jDMxAeU3UF|&0B0py^z&(_)|7NWAg! Date: Wed, 19 Dec 2018 15:53:09 -0600 Subject: [PATCH 18/23] Try and get lines working. Also make sats disapper once done --- templates/map.html | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/templates/map.html b/templates/map.html index 08397dd..56f5ce2 100644 --- a/templates/map.html +++ b/templates/map.html @@ -104,12 +104,12 @@ function UpdateMap(e) { Sats[norad]._latlng = {"lat":satPos[0],"lng":satPos[1]} Sats[norad].update() Object.keys(Lines[norad]).forEach(function(x){ - if (x in .data[3]){ + if (e.data[3].includes(x)){ Lines[norad][x]._latlngs[1]= {"lat":satPos[0],"lng":satPos[1]} Lines[norad][x].update() }else{ - Lines[norad][x].removeFrom(mymap) - delete Lines[norad][x] + + } }) @@ -134,21 +134,41 @@ function UpdateMap(e) { worker = new Worker('/static/Worker.js'); worker.onmessage = UpdateMap worker.postMessage([x,data[x]]); + Workers[x] =worker }); }); - //marker = L.marker(data[key]["lat_lng"],{icon: sat,zIndexOffset:1000}).addTo(mymap); - //marker.bindPopup("Name: "+data[key]["name"]+"
Norad: "+key+"
Eclipsed?: "+data[key]["eclipsed"]); - //sats[key] = marker; - - - //lines - // firstpolyline = new L.Polyline([[stationList[entry[0]]._latlng.lat,stationList[entry[0]]._latlng.lng],[sats[entry[1]]._latlng.lat,sats[entry[1]]._latlng.lng]], {color: '#'+entry[1].toString(16).repeat(2).substr(0,6),weight: 3,opacity: 1,smoothFactor: 1}); - - // firstpolyline.addTo(mymap) + +setInterval(function(){ +$.get("/occuring_sats", function(data, status){ + data = JSON.parse(data) + Object.keys(data).forEach(function(x){ + if (x in Workers){ + }else{ + worker = new Worker('/static/Worker.js'); + worker.onmessage = UpdateMap + worker.postMessage([x,data[x]]); + Workers[x] =worker + } + }); + Object.keys(Workers).forEach(function(x){ + if (Object.keys(data).includes(x)){ + }else{ + Workers[x].terminate() + delete Workers[x] + UpdateMap({"data":[x,"",[0,0],[]]}) + Sats[x].removeFrom(mymap) + delete Sats[x] + delete Lines[x] + + } + }) + }); +}, 20000); + From 81dd4525880b1ddee169199f473353e0e12b77c1 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Wed, 19 Dec 2018 16:15:59 -0600 Subject: [PATCH 19/23] Works mostly some weird errors now and then with the lines. --- satnogs_api_client.pyc | Bin 5049 -> 0 bytes templates/map.html | 13 ++++++------- 2 files changed, 6 insertions(+), 7 deletions(-) delete mode 100644 satnogs_api_client.pyc diff --git a/satnogs_api_client.pyc b/satnogs_api_client.pyc deleted file mode 100644 index 91a2e0bcb2f30ce869fb71493d419f57f5680b25..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5049 zcmcIo(QX^Z6}_{RC{d<@977$=iFJ*lw=eIDv9Rs?#%4W?7iold)KvpEiU}y zgSEY`RDS_}e=bJsKVc;JXQVGOFtTgJ@H&uwAiIH%!LG?}O%k*-lFZ2NtR%CtTbHCR zyK|hJ%*j`{xgqI-B=c%tQ@f#dQ|$${7bUqSUy1B4X=hVAuS>G1oy(Fesc}P+>uRh> ziY=CP+D-1Y)4G8}XaB}u%fNC=Xoh8$yXat)cU@NG9s4@^4xJm?yX|(Ky5AM$@jFTS z#fFVtUi9onQTFVs7w4QA|Mt{)vVUgiJ7Y$QC&cD$>vLV?V#2=B|z&teECWi-VyC?i#E?{4~ONnPGW$mbyw3 zW5q>W@)*%D?xhh9)Fyu0_oF*9-KohsOD`>>5n1!Gj+%`7?TB|{q z9-?!6kP+a0Tp$Jr!O4sq2?JHWB6y;_CN7XaqsLSsp2Ygg85z$Cp7&&yQ61MA;XjES z040HZja%xnjR8M~iz-g`BW(73+{S~ni+yY<~jFYGvyC_RO zd_MjWLR2~$cs%@c>1)E2F@KK`eFFxN`T46dR)i%YYdH3CAZ3k*|I|Ez1Q;BGx49;o z={-6=I6B5=<0p>cojRW<>-^-tEYVvoEtIx_rSJ7pKxSBOwQ*q?rn=Nji||tn04iS@(kK*BQ9oDo@eV9fJ69VKD2;xFszt3PHK$X{X z6{+$*1&e{KQO*EjgepNSVIWc$1F3=23^uQUY+MK=W6)7Hbc#H+#M{nsHXLSoZ@pI* zqdZ{(frPEU$q8?6_@Fa>RnV((+h)KQ(61Z=nUr;!{Qo-yLT)-0d@|N=t;q{}g9twU zj=(rOW*tk8vwfH!exHk86%y94xJSadjmh1I7_`KS1ONlmlBuIrNCc~9BJXs)GWQM) z#NSsSBxOJ!vJ~;8RLuudK|;e+rSv?*L9**K9H)842ZY!=$2%4O?FSPLRUUf(6RjbA zd}W@a7&YDkaz$CGw! z#eyj0u!OxgEYq!b*IOHJzjbfF+`8kfHhV37{qB0kw4(N%^^9FDCZs9Cs8UXZ zQ<>^ectHnP`l)={G%mY`N;krBs4NWExsHmaQbE%f`QQkasU!Om?$8bTx2h6 zAQ^WLQTp*fm>;=*8r?Z__1;ye>?_#LBZM0k2h+Lnw-~d85bM4MK4?L*mEfki=@G;1 zGC>TF2YgiJyrQQIqcHq9Tz@{ki?0@^p8AZrit(_pPBSX&pplLE zJ{!J)(eTG;ycDZCe8@X^8&2YXV;635;(az0X??U|{H$NZiHF8j6);pTo;;eU)L+r# zrFCw>%vGO-;JUemZ;P7i2#W~+k>f@s-eN;sN%#&MK9#TVIWK%0jaF(XGNxbF!XI*! zTdU_jDMxAeU3UF|&0B0py^z&(_)|7NWAg!Name: "+name+"
Norad: "+norad+""); @@ -101,15 +102,13 @@ function UpdateMap(e) { Lines[norad][x].addTo(mymap) }); } - Sats[norad]._latlng = {"lat":satPos[0],"lng":satPos[1]} - Sats[norad].update() + Object.keys(Lines[norad]).forEach(function(x){ - if (e.data[3].includes(x)){ + if (e.data[3].includes(Number(x))){ Lines[norad][x]._latlngs[1]= {"lat":satPos[0],"lng":satPos[1]} - Lines[norad][x].update() }else{ - - + Lines[norad][x].removeFrom(mymap) + delete Lines[norad][x] } }) From c5e531facba84ff287d41d141e4f3de3d6c8c02a Mon Sep 17 00:00:00 2001 From: wgaylord Date: Sat, 22 Dec 2018 01:33:23 -0600 Subject: [PATCH 20/23] Added new transmitter information! --- satnogs.py | 29 ++++++++++++++++++++++++++--- satnogs_api_client.pyc | Bin 0 -> 5049 bytes static/Worker.js | 6 +++++- templates/map.html | 39 ++++++++++++++++++++++++++++----------- 4 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 satnogs_api_client.pyc diff --git a/satnogs.py b/satnogs.py index d128593..a35d1b0 100644 --- a/satnogs.py +++ b/satnogs.py @@ -2,6 +2,7 @@ from datetime import datetime , timedelta import requests from flask import Flask , render_template,redirect,url_for import json +import random from apscheduler.schedulers.background import BackgroundScheduler from satnogs_api_client import fetch_satellites, DB_BASE_URL,fetch_tle_of_observation from satellite_tle import fetch_tles @@ -14,6 +15,7 @@ Passes = [] Occuring_sats = {} Stations = [] TLEs = {} +Transmitters = {} class Pass: id = 0 @@ -61,6 +63,7 @@ def getActive(): temp.start = datetime.strptime(x["start"],'%Y-%m-%dT%H:%M:%Sz') temp.end = datetime.strptime(x["end"],'%Y-%m-%dT%H:%M:%Sz') temp.ground_station = x["ground_station"] + temp.transmitter = x["transmitter"] temp.norad = str(x["norad_cat_id"]) try: temp.satellite = requests.get("https://db.satnogs.org/api/satellites/"+str(x["norad_cat_id"])).json() @@ -98,6 +101,18 @@ def GetGroundStations(): return stations +@scheduler.scheduled_job('interval',days=5) +def updateTransmitters(): + global Transmitters + print "Updating Transmitters" + temp = requests.get("https://db.satnogs.org/api/transmitters/").json() + for x in temp: + if str(x["norad_cat_id"]) in Transmitters.keys(): + Transmitters[str(x["norad_cat_id"])][x["uuid"]] = [x["description"],"#"+str("%06x" % random.randint(0, 0xFFFFFF))] + else: + Transmitters[str(x["norad_cat_id"])]={} + Transmitters[str(x["norad_cat_id"])][x["uuid"]] = [x["description"],"#"+str("%06x" % random.randint(0, 0xFFFFFF))] + #print Transmitters @scheduler.scheduled_job('interval',minutes=3) def updatePasses(): @@ -153,11 +168,18 @@ def api_active_stations(): @app.route('/stations_from_sat/') def api_occuring_observations(norad): obs = [] + trans = [] for x in Passes: if x.norad == norad: - obs.append(x.ground_station) - - return json.dumps(obs) + obs.append([x.ground_station,Transmitters[norad][x.transmitter][1]]) + trans.append(x.transmitter) + #print Transmitters[norad].values() + + transList = [] + for x in set(trans): + transList.append(Transmitters[norad][x]) + #print transList,norad + return json.dumps([obs,transList]) @app.route('/occuring_sats') def api_occuring_sats(): @@ -170,5 +192,6 @@ def api_occuring_sats(): updatePasses() updateStations() updateTLE() +updateTransmitters() scheduler.start() app.run(use_reloader=False,host = "0.0.0.0",port=5001) \ No newline at end of file diff --git a/satnogs_api_client.pyc b/satnogs_api_client.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91a2e0bcb2f30ce869fb71493d419f57f5680b25 GIT binary patch literal 5049 zcmcIo(QX^Z6}_{RC{d<@977$=iFJ*lw=eIDv9Rs?#%4W?7iold)KvpEiU}y zgSEY`RDS_}e=bJsKVc;JXQVGOFtTgJ@H&uwAiIH%!LG?}O%k*-lFZ2NtR%CtTbHCR zyK|hJ%*j`{xgqI-B=c%tQ@f#dQ|$${7bUqSUy1B4X=hVAuS>G1oy(Fesc}P+>uRh> ziY=CP+D-1Y)4G8}XaB}u%fNC=Xoh8$yXat)cU@NG9s4@^4xJm?yX|(Ky5AM$@jFTS z#fFVtUi9onQTFVs7w4QA|Mt{)vVUgiJ7Y$QC&cD$>vLV?V#2=B|z&teECWi-VyC?i#E?{4~ONnPGW$mbyw3 zW5q>W@)*%D?xhh9)Fyu0_oF*9-KohsOD`>>5n1!Gj+%`7?TB|{q z9-?!6kP+a0Tp$Jr!O4sq2?JHWB6y;_CN7XaqsLSsp2Ygg85z$Cp7&&yQ61MA;XjES z040HZja%xnjR8M~iz-g`BW(73+{S~ni+yY<~jFYGvyC_RO zd_MjWLR2~$cs%@c>1)E2F@KK`eFFxN`T46dR)i%YYdH3CAZ3k*|I|Ez1Q;BGx49;o z={-6=I6B5=<0p>cojRW<>-^-tEYVvoEtIx_rSJ7pKxSBOwQ*q?rn=Nji||tn04iS@(kK*BQ9oDo@eV9fJ69VKD2;xFszt3PHK$X{X z6{+$*1&e{KQO*EjgepNSVIWc$1F3=23^uQUY+MK=W6)7Hbc#H+#M{nsHXLSoZ@pI* zqdZ{(frPEU$q8?6_@Fa>RnV((+h)KQ(61Z=nUr;!{Qo-yLT)-0d@|N=t;q{}g9twU zj=(rOW*tk8vwfH!exHk86%y94xJSadjmh1I7_`KS1ONlmlBuIrNCc~9BJXs)GWQM) z#NSsSBxOJ!vJ~;8RLuudK|;e+rSv?*L9**K9H)842ZY!=$2%4O?FSPLRUUf(6RjbA zd}W@a7&YDkaz$CGw! z#eyj0u!OxgEYq!b*IOHJzjbfF+`8kfHhV37{qB0kw4(N%^^9FDCZs9Cs8UXZ zQ<>^ectHnP`l)={G%mY`N;krBs4NWExsHmaQbE%f`QQkasU!Om?$8bTx2h6 zAQ^WLQTp*fm>;=*8r?Z__1;ye>?_#LBZM0k2h+Lnw-~d85bM4MK4?L*mEfki=@G;1 zGC>TF2YgiJyrQQIqcHq9Tz@{ki?0@^p8AZrit(_pPBSX&pplLE zJ{!J)(eTG;ycDZCe8@X^8&2YXV;635;(az0X??U|{H$NZiHF8j6);pTo;;eU)L+r# zrFCw>%vGO-;JUemZ;P7i2#W~+k>f@s-eN;sN%#&MK9#TVIWK%0jaF(XGNxbF!XI*! zTdU_jDMxAeU3UF|&0B0py^z&(_)|7NWAg!Name: "+name+"

Norad: "+norad+""); Lines[norad] = {} - e.data[3].forEach(function(x){ - Lines[norad][x] = new L.Polyline([[Stations[x]._latlng.lat,Stations[x]._latlng.lng],[satPos[0],satPos[1]]], {color: '#'+norad.toString(16).repeat(2).substr(0,6),weight: 3,opacity: 1,smoothFactor: 1}); - Lines[norad][x].addTo(mymap) - }); + + + } + + popupText = "Name: "+name+"
Norad: "+norad+"
Station Count: "+e.data[3].length+"
" - Object.keys(Lines[norad]).forEach(function(x){ - if (e.data[3].includes(Number(x))){ - Lines[norad][x]._latlngs[1]= {"lat":satPos[0],"lng":satPos[1]} + e.data[4].forEach(function(x){ + //console.log(x + " "+norad) + popupText = popupText + '
'+x[0]+"

" + }) + Sats[norad].bindPopup(popupText) + Sats[norad]._popup.setContent(popupText) + + temp = [] + e.data[3].forEach(function(x){ + temp.push(x[0]) + }) + + e.data[3].forEach(function(x){ + if (Object.keys(Lines[norad]).includes(Number(x[0]))){ + Object.keys(Lines[norad]).forEach(function(y){ + if (temp.includes(Number(y))){ + Lines[norad][y]._latlngs[1]= {"lat":satPos[0],"lng":satPos[1]} }else{ - Lines[norad][x].removeFrom(mymap) - delete Lines[norad][x] + Lines[norad][x[0]].removeFrom(mymap) + delete Lines[norad][x[0]] } + + })}else{Lines[norad][x[0]] = new L.Polyline([[Stations[x[0]]._latlng.lat,Stations[x[0]]._latlng.lng],[satPos[0],satPos[1]]], {color: x[1],weight: 3,opacity: 1,smoothFactor: 1}); + Lines[norad][x[0]].addTo(mymap)}; }) From ef9ca1e336ad6801d94c8c3c62ffcccc8f9158ff Mon Sep 17 00:00:00 2001 From: wgaylord Date: Sat, 22 Dec 2018 01:39:50 -0600 Subject: [PATCH 21/23] Possibly fix lines --- templates/map.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/map.html b/templates/map.html index dc32f03..d2910bf 100644 --- a/templates/map.html +++ b/templates/map.html @@ -121,8 +121,8 @@ function UpdateMap(e) { if (temp.includes(Number(y))){ Lines[norad][y]._latlngs[1]= {"lat":satPos[0],"lng":satPos[1]} }else{ - Lines[norad][x[0]].removeFrom(mymap) - delete Lines[norad][x[0]] + Lines[norad][y].removeFrom(mymap) + delete Lines[norad][y] } })}else{Lines[norad][x[0]] = new L.Polyline([[Stations[x[0]]._latlng.lat,Stations[x[0]]._latlng.lng],[satPos[0],satPos[1]]], {color: x[1],weight: 3,opacity: 1,smoothFactor: 1}); From 7d918adff0beb712738f918ef96a53e81aec0206 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Sat, 22 Dec 2018 02:09:23 -0600 Subject: [PATCH 22/23] Fixed lines --- templates/map.html | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/templates/map.html b/templates/map.html index d2910bf..2ba5f59 100644 --- a/templates/map.html +++ b/templates/map.html @@ -13,6 +13,12 @@
@@ -105,7 +111,7 @@ function UpdateMap(e) { e.data[4].forEach(function(x){ //console.log(x + " "+norad) - popupText = popupText + '
'+x[0]+"

" + popupText = popupText + '
'+x[0]+"
" }) Sats[norad].bindPopup(popupText) Sats[norad]._popup.setContent(popupText) @@ -116,20 +122,22 @@ function UpdateMap(e) { }) e.data[3].forEach(function(x){ - if (Object.keys(Lines[norad]).includes(Number(x[0]))){ + if (Object.keys(Lines[norad]).includes(String(x[0]))){ Object.keys(Lines[norad]).forEach(function(y){ - if (temp.includes(Number(y))){ - Lines[norad][y]._latlngs[1]= {"lat":satPos[0],"lng":satPos[1]} - }else{ - Lines[norad][y].removeFrom(mymap) - delete Lines[norad][y] - } + Lines[norad][y]._latlngs[1]= {"lat":satPos[0],"lng":satPos[1]} })}else{Lines[norad][x[0]] = new L.Polyline([[Stations[x[0]]._latlng.lat,Stations[x[0]]._latlng.lng],[satPos[0],satPos[1]]], {color: x[1],weight: 3,opacity: 1,smoothFactor: 1}); Lines[norad][x[0]].addTo(mymap)}; }) - - + Object.keys(Lines[norad]).forEach(function(x){ + if (temp.includes(Number(x))){ + + }else{ + Lines[norad][x].removeFrom(mymap) + delete Lines[norad][x] + } + }) + } @@ -173,7 +181,7 @@ $.get("/occuring_sats", function(data, status){ }else{ Workers[x].terminate() delete Workers[x] - UpdateMap({"data":[x,"",[0,0],[]]}) + UpdateMap({"data":[x,"",[0,0],[],[]]}) Sats[x].removeFrom(mymap) delete Sats[x] delete Lines[x] From 7f2667417f4a0acd41c0f1386f3ddc361f4e0cc1 Mon Sep 17 00:00:00 2001 From: wgaylord Date: Sat, 22 Dec 2018 02:21:30 -0600 Subject: [PATCH 23/23] Fix color problem --- templates/map.html | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/templates/map.html b/templates/map.html index 2ba5f59..3b9b0ab 100644 --- a/templates/map.html +++ b/templates/map.html @@ -14,11 +14,7 @@