Add initial plotting

This commit is contained in:
ThePetrovich 2025-04-05 14:43:23 +08:00
parent 2db5d14202
commit 55295b84aa
10 changed files with 362 additions and 436 deletions

198
src/lib/prediction.ts Normal file
View file

@ -0,0 +1,198 @@
import { writable } from "svelte/store"
import type { LatLngExpression } from "leaflet";
import L from "leaflet";
interface TrajectoryPoint {
altitude: number;
datetime: string;
latitude: number;
longitude: number;
}
interface PredictionStage {
stage: string;
trajectory: TrajectoryPoint[];
}
interface ParsedPrediction {
flight_path: [number, number, number][];
launch: {
latlng: LatLngExpression;
datetime: Date;
};
burst: {
latlng: LatLngExpression;
datetime: Date;
};
landing: {
latlng: LatLngExpression;
datetime: Date;
};
profile: string;
flight_time: number;
}
export const latestPrediction = writable({
metadata: {
complete_datetime: "",
start_datetime: ""
},
prediction: [
{
stage: "",
trajectory: [
{
altitude: 0.0,
datetime: "",
latitude: 0.0,
longitude: 0.0
}
]
}
]
});
export const latestPredictionParsed = writable({} as ParsedPrediction);
function getLatestDataset() {
const now = new Date();
const hours = now.getUTCHours();
const minutes = now.getUTCMinutes();
const seconds = now.getUTCSeconds();
// Round down to the nearest 6-hour interval
const roundedHours = Math.floor(hours / 6) * 6;
const roundedDate = new Date(now);
roundedDate.setUTCHours(roundedHours, 0, 0, 0);
// Subtract 6 hours to account for the lag
roundedDate.setUTCHours(roundedDate.getUTCHours() - 6);
return roundedDate.toISOString();
}
function formatLaunchDateTime(dateObj: string | Date, timeStr: string): string {
// Ensure date is a Date object
const date = new Date(dateObj);
// Extract date components
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
// Format time (ensure it has seconds)
let formattedTime = timeStr;
if (timeStr.split(':').length === 2) {
formattedTime += ':00'; // Add seconds if missing
}
// Combine into ISO string
const isoString = new Date(`${year}-${month}-${day}T${formattedTime}Z`).toISOString();
return isoString;
}
export const getForecast = async (flightParameters: Record<string, any>, startDate: string, startTime: string): Promise<void> => {
const launch_datetime = formatLaunchDateTime(startDate, startTime);
// Create request object
flightParameters.dataset = getLatestDataset();
flightParameters.launch_datetime = launch_datetime;
console.log("Sending request:", flightParameters);
try {
// Example POST request - replace with your actual API endpoint
const response = await fetch('http://127.0.0.1:8000/api/predictions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(flightParameters)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log("Forecast response:", data);
latestPrediction.set(data.result);
latestPredictionParsed.set(parsePrediction(data.result.prediction));
alert("Forecast request successful!");
// Handle the response data as needed
} catch (error) {
console.error("Error sending forecast request:", error);
alert("Error getting forecast: " + error);
}
};
export function parsePrediction(prediction: PredictionStage[]): ParsedPrediction {
const flight_path: [number, number, number][] = [];
const launch: { latlng: LatLngExpression; datetime: Date } = {} as any;
const burst: { latlng: LatLngExpression; datetime: Date } = {} as any;
const landing: { latlng: LatLngExpression; datetime: Date } = {} as any;
const ascent = prediction[0].trajectory;
const descent = prediction[1].trajectory;
// Add the ascent track to the flight path array.
ascent.forEach((item) => {
let lon = item.longitude;
if (lon > 180.0) {
lon -= 360.0;
}
flight_path.push([item.latitude, lon, item.altitude]);
});
// Add the descent track to the flight path array.
descent.forEach((item) => {
let lon = item.longitude;
if (lon > 180.0) {
lon -= 360.0;
}
flight_path.push([item.latitude, lon, item.altitude]);
});
// Populate the launch, burst, and landing points
const launchObj = ascent[0];
let lon = launchObj.longitude;
if (lon > 180.0) {
lon -= 360.0;
}
launch.latlng = L.latLng([launchObj.latitude, lon, launchObj.altitude]);
launch.datetime = new Date(launchObj.datetime);
const burstObj = descent[0];
lon = burstObj.longitude;
if (lon > 180.0) {
lon -= 360.0;
}
burst.latlng = L.latLng([burstObj.latitude, lon, burstObj.altitude]);
burst.datetime = new Date(burstObj.datetime);
const landingObj = descent[descent.length - 1];
lon = landingObj.longitude;
if (lon > 180.0) {
lon -= 360.0;
}
landing.latlng = L.latLng([landingObj.latitude, lon, landingObj.altitude]);
landing.datetime = new Date(landingObj.datetime);
const profile = prediction[1].stage === "descent" ? "standard_profile" : "float_profile";
const flight_time = (new Date(landing.datetime).getTime() - new Date(launch.datetime).getTime()) / 1000;
return {
flight_path,
launch,
burst,
landing,
profile,
flight_time,
};
}