base sys done. shift to vs code
This commit is contained in:
3
.env
Normal file
3
.env
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
POSTGRES_DB=spacecom
|
||||||
|
POSTGRES_USER=spacecom
|
||||||
|
POSTGRES_PASSWORD=spacecom
|
||||||
8
backend/Dockerfile
Normal file
8
backend/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN pip install fastapi uvicorn
|
||||||
|
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
BIN
backend/app/__pycache__/main.cpython-311.pyc
Normal file
BIN
backend/app/__pycache__/main.cpython-311.pyc
Normal file
Binary file not shown.
65
backend/app/main.py
Normal file
65
backend/app/main.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# backend/main.py
|
||||||
|
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=[
|
||||||
|
"http://aegis.sbln.bxl.skynav.cloud:8080"
|
||||||
|
],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/czml/test")
|
||||||
|
def get_dummy_czml():
|
||||||
|
czml = [
|
||||||
|
{
|
||||||
|
"id": "document",
|
||||||
|
"name": "Dummy orbit test",
|
||||||
|
"version": "1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "sat1",
|
||||||
|
"name": "TestSat-001",
|
||||||
|
"availability": "2025-06-29T00:00:00Z/2025-06-29T00:04:00Z",
|
||||||
|
"position": {
|
||||||
|
"interpolationAlgorithm": "LAGRANGE",
|
||||||
|
"interpolationDegree": 5,
|
||||||
|
"referenceFrame": "INERTIAL",
|
||||||
|
"epoch": "2025-06-29T00:00:00Z",
|
||||||
|
"cartesian": [
|
||||||
|
0, 7000000, 0, 0,
|
||||||
|
60, 7050000, 20000, 0,
|
||||||
|
120, 7100000, 40000, 0,
|
||||||
|
180, 7150000, 60000, 0,
|
||||||
|
240, 7200000, 80000, 0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"point": {
|
||||||
|
"pixelSize": 10,
|
||||||
|
"color": {
|
||||||
|
"rgba": [0, 255, 255, 255]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"text": "TestSat-001",
|
||||||
|
"font": "12pt sans-serif",
|
||||||
|
"style": "FILL",
|
||||||
|
"outlineWidth": 2,
|
||||||
|
"verticalOrigin": "BOTTOM",
|
||||||
|
"pixelOffset": {
|
||||||
|
"cartesian2": [0, -20]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
return JSONResponse(content=czml)
|
||||||
44
db/schema.sql
Normal file
44
db/schema.sql
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
-- Enable extensions
|
||||||
|
CREATE EXTENSION IF NOT EXISTS postgis;
|
||||||
|
CREATE EXTENSION IF NOT EXISTS timescaledb;
|
||||||
|
|
||||||
|
-- Main object catalog (replaces 'satellites')
|
||||||
|
CREATE TABLE objects (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
norad_id INT UNIQUE NOT NULL,
|
||||||
|
intl_designator TEXT,
|
||||||
|
launch_date DATE,
|
||||||
|
orbit_type TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE orbits (
|
||||||
|
object_id INT REFERENCES objects(id),
|
||||||
|
ts TIMESTAMPTZ NOT NULL,
|
||||||
|
position GEOGRAPHY(POINT, 4326),
|
||||||
|
altitude_km DOUBLE PRECISION,
|
||||||
|
velocity_kms DOUBLE PRECISION,
|
||||||
|
PRIMARY KEY (object_id, ts)
|
||||||
|
);
|
||||||
|
SELECT create_hypertable('orbits', 'ts', if_not_exists => TRUE);
|
||||||
|
|
||||||
|
-- Conjunction Data Messages / alerts
|
||||||
|
CREATE TABLE conjunctions (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
primary_object INT REFERENCES objects(id),
|
||||||
|
secondary_object INT,
|
||||||
|
tca TIMESTAMPTZ, -- Time of Closest Approach
|
||||||
|
miss_distance_km DOUBLE PRECISION,
|
||||||
|
risk_level TEXT,
|
||||||
|
poc DOUBLE PRECISION -- Probability of Collision
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Re-entry prediction windows and footprints
|
||||||
|
CREATE TABLE reentry_predictions (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
object_id INT REFERENCES objects(id),
|
||||||
|
window_start TIMESTAMPTZ,
|
||||||
|
window_end TIMESTAMPTZ,
|
||||||
|
footprint GEOGRAPHY(POLYGON, 4326),
|
||||||
|
notes TEXT
|
||||||
|
);
|
||||||
43
docker-compose.yml
Normal file
43
docker-compose.yml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
frontend:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: spacecom-frontend
|
||||||
|
volumes:
|
||||||
|
- ./frontend/public:/usr/share/nginx/html:ro
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
backend:
|
||||||
|
build: ./backend
|
||||||
|
container_name: spacecom-backend
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
environment:
|
||||||
|
- DB_URL=postgresql://spacecom:spacecom@db:5432/spacecom
|
||||||
|
volumes:
|
||||||
|
- ./backend:/app
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: timescaledev/timescaledb-ha:pg17
|
||||||
|
container_name: spacecom-db
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: spacecom
|
||||||
|
POSTGRES_USER: spacecom
|
||||||
|
POSTGRES_PASSWORD: uCV4@YUCuR9kX.MQaxp2
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
- ./db/schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
56
frontend/public/app.js
Normal file
56
frontend/public/app.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// app.js
|
||||||
|
import { API_BASE_URL } from "./config.js";
|
||||||
|
|
||||||
|
console.log('🔥 app.js loaded');
|
||||||
|
|
||||||
|
// Optional: set Ion token (if using Ion)
|
||||||
|
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkZjk0MDM3OC1kZDE1LTRhMjItODg3NC1iMjUzNmI1NzUwMjgiLCJpZCI6MzE2ODE3LCJpYXQiOjE3NTEyMzM5OTh9.UDLPRYrMOcLAjuCWAZa2f159W0bULWSMNv3iiQcAAP8';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Create empty viewer with no base layer
|
||||||
|
const viewer = new Cesium.Viewer("cesiumContainer", {
|
||||||
|
imageryProvider: false,
|
||||||
|
baseLayerPicker: false,
|
||||||
|
terrainProvider: new Cesium.EllipsoidTerrainProvider()
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('✅ Viewer created:', viewer);
|
||||||
|
|
||||||
|
// Create OSM imagery layer
|
||||||
|
const osmLayer = new Cesium.ImageryLayer(
|
||||||
|
new Cesium.UrlTemplateImageryProvider({
|
||||||
|
url: "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
||||||
|
credit: "© OpenStreetMap contributors"
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add imagery layer manually
|
||||||
|
viewer.imageryLayers.add(osmLayer);
|
||||||
|
|
||||||
|
console.log('✅ OSM Layer Added:', osmLayer);
|
||||||
|
console.log('✅ Imagery Layers:', viewer.imageryLayers.length);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Load CZML from FastAPI endpoint
|
||||||
|
fetch(`${API_BASE_URL}/czml/test`)
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(czmlData => {
|
||||||
|
// Load the CZML data into a Cesium data source
|
||||||
|
const czmlSource = new Cesium.CzmlDataSource();
|
||||||
|
czmlSource.load(czmlData).then(() => {
|
||||||
|
viewer.dataSources.add(czmlSource);
|
||||||
|
viewer.zoomTo(czmlSource);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error("Failed to load CZML:", error);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
2
frontend/public/config.js
Normal file
2
frontend/public/config.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
// config.js
|
||||||
|
export const API_BASE_URL = "http://aegis.sbln.bxl.skynav.cloud:8000";
|
||||||
69
frontend/public/index.html
Normal file
69
frontend/public/index.html
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>SkyNav SpaceCom</title>
|
||||||
|
|
||||||
|
<!-- CesiumJS -->
|
||||||
|
<script src="https://cesium.com/downloads/cesiumjs/releases/1.110/Build/Cesium/Cesium.js"></script>
|
||||||
|
<link href="https://cesium.com/downloads/cesiumjs/releases/1.110/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Google Font (Montserrat) -->
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
font-family: 'Montserrat', sans-serif;
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#branding {
|
||||||
|
height: 6em;
|
||||||
|
background: linear-gradient(to right, #1e124f, #2e1a6d); /* SkyNav deep purple gradient */
|
||||||
|
color: #fff;
|
||||||
|
padding: 1em;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 2px solid #352f66;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#branding h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#branding p {
|
||||||
|
margin: 0.3em 0 0;
|
||||||
|
font-size: 1em;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cesiumContainer {
|
||||||
|
position: absolute;
|
||||||
|
top: 8em;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header id="branding">
|
||||||
|
<h1>🛰️ SkyNav SpaceCom</h1>
|
||||||
|
<p>Real-Time Orbit & Re-entry Monitoring Platform</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div id="cesiumContainer"></div>
|
||||||
|
<script type="module" src="app.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2
worker/fetch.py
Normal file
2
worker/fetch.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Placeholder for TLE or CDM ingestion logic
|
||||||
|
print("Worker fetch script ready. Implement data polling here.")
|
||||||
Reference in New Issue
Block a user