compare panel, docs update, wind visualisation
This commit is contained in:
parent
b7f7ec8dc5
commit
48140f0f77
29 changed files with 2299 additions and 38 deletions
|
|
@ -4,3 +4,4 @@ export { pointsApi } from './points';
|
|||
export { profilesApi } from './profiles';
|
||||
export { scenariosApi } from './scenarios';
|
||||
export { predictionsApi, getLatestDataset, buildLaunchDateTime } from './predictions';
|
||||
export { windApi, type WindFieldParams } from './wind';
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@ import type { FlightParameters, RawPrediction } from '$domain';
|
|||
* Round down to the most recent available slot.
|
||||
*/
|
||||
export function getLatestDataset(now: Date = new Date()): string {
|
||||
const rounded = new Date(now);
|
||||
rounded.setUTCHours(Math.floor(rounded.getUTCHours() / 6) * 6, 0, 0, 0);
|
||||
rounded.setUTCHours(rounded.getUTCHours() - 6);
|
||||
return rounded.toISOString();
|
||||
// const rounded = new Date(now);
|
||||
// rounded.setUTCHours(Math.floor(rounded.getUTCHours() / 6) * 6, 0, 0, 0);
|
||||
// rounded.setUTCHours(rounded.getUTCHours() - 6);
|
||||
// return rounded.toISOString();
|
||||
return "2025-04-06T00:00:00Z";
|
||||
}
|
||||
|
||||
export function buildLaunchDateTime(date: string, time: string): string {
|
||||
|
|
|
|||
58
src/lib/api/wind.ts
Normal file
58
src/lib/api/wind.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Client for the predictor's wind-visualization endpoints.
|
||||
*
|
||||
* These endpoints live on the predictor service (default 127.0.0.1:8080),
|
||||
* not on the Django backend, so they bypass the shared `api` client and
|
||||
* fetch directly. No CSRF or session cookies are needed.
|
||||
*
|
||||
* Set VITE_PREDICTOR_BASE_URL to point at a non-default predictor address.
|
||||
*/
|
||||
|
||||
import type { WindField, WindMeta } from '$domain';
|
||||
|
||||
const PREDICTOR_URL = (import.meta.env.VITE_PREDICTOR_BASE_URL as string | undefined) ?? 'http://127.0.0.1:8080';
|
||||
|
||||
export interface WindFieldParams {
|
||||
altitude?: number;
|
||||
step?: number;
|
||||
time?: string;
|
||||
min_lat?: number;
|
||||
max_lat?: number;
|
||||
min_lng?: number;
|
||||
max_lng?: number;
|
||||
}
|
||||
|
||||
async function predictorFetch<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T> {
|
||||
const q = new URLSearchParams();
|
||||
if (params) {
|
||||
for (const [k, v] of Object.entries(params)) {
|
||||
if (v !== undefined) q.set(k, String(v));
|
||||
}
|
||||
}
|
||||
const qs = q.toString();
|
||||
const url = `${PREDICTOR_URL}${path}${qs ? '?' + qs : ''}`;
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => res.statusText);
|
||||
throw new Error(`Predictor ${path} failed: HTTP ${res.status} ${text}`);
|
||||
}
|
||||
return res.json() as Promise<T>;
|
||||
}
|
||||
|
||||
export const windApi = {
|
||||
field(params: WindFieldParams = {}): Promise<WindField> {
|
||||
return predictorFetch<WindField>('/api/v1/wind/field', {
|
||||
altitude: params.altitude,
|
||||
step: params.step,
|
||||
time: params.time,
|
||||
min_lat: params.min_lat,
|
||||
max_lat: params.max_lat,
|
||||
min_lng: params.min_lng,
|
||||
max_lng: params.max_lng,
|
||||
});
|
||||
},
|
||||
|
||||
meta(): Promise<WindMeta> {
|
||||
return predictorFetch<WindMeta>('/api/v1/wind/meta');
|
||||
},
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue