Add routes

This commit is contained in:
ThePetrovich 2025-04-05 22:44:34 +08:00
parent 55295b84aa
commit afc45cc9cc
10 changed files with 241 additions and 21 deletions

58
src/lib/telemetry.ts Normal file
View file

@ -0,0 +1,58 @@
import { writable } from "svelte/store"
import type { LatLngExpression } from "leaflet";
import L from "leaflet";
interface TelemetryPoint {
altitude: number;
datetime: string;
latitude: number;
longitude: number;
payload: string;
}
interface ParsedTelemetry {
flight_path: [number, number, number][];
launch: {
latlng: LatLngExpression;
datetime: Date;
};
datapoints: TelemetryPoint[];
}
export const latestTelemetry = writable({
metadata: {
complete_datetime: "",
start_datetime: ""
},
telemetry: [
{
altitude: 0.0,
datetime: "",
latitude: 0.0,
longitude: 0.0,
payload: ""
}
]
});
export const latestTelemetryParsed = writable({} as ParsedTelemetry);
export function parseTelemetry(telemetry: TelemetryPoint[]): ParsedTelemetry {
const flight_path: [number, number, number][] = telemetry.map((point) => [
point.latitude,
point.longitude,
point.altitude
]);
const launch = {
latlng: L.latLng(telemetry[0].latitude, telemetry[0].longitude),
datetime: new Date(telemetry[0].datetime)
};
return {
flight_path,
launch,
datapoints: telemetry
};
}

View file

@ -1,26 +1,7 @@
<script> <script>
import Map from './map.svelte';
import ControlPanel from './ControlPanel.svelte';
import Navbar from './Navbar.svelte'; import Navbar from './Navbar.svelte';
// import BurstCalculator from './BurstCalculator.svelte';
let coordinates = {
lat: '56.3576',
lng: '39.8666'
}
function handlePositionUpdate(event) {
coordinates.lat = event.detail.lat;
coordinates.lng = event.detail.lng;
}
</script> </script>
<main> <main>
<Navbar /> <Navbar />
<Map bind:coordinates>
<ControlPanel
{coordinates}
on:updatePosition={handlePositionUpdate}
/>
</Map>
</main> </main>

View file

@ -21,10 +21,10 @@
<div class="collapse navbar-collapse" id="navbarNav"> <div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto mb-2 mb-lg-0"> <ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link nav-full-height {window.location.pathname === '/' ? 'active' : ''}" href="/">Прогнозирование</a> <a class="nav-link nav-full-height {window.location.pathname === '/predict' ? 'active' : ''}" href="/predict">Прогнозирование</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link nav-full-height {window.location.pathname === '/page2' ? 'active' : ''}" href="/page2">Слежение</a> <a class="nav-link nav-full-height {window.location.pathname === '/track' ? 'active' : ''}" href="/track">Слежение</a>
</li> </li>
</ul> </ul>
<ul class="navbar-nav"> <ul class="navbar-nav">

View file

@ -0,0 +1,74 @@
<script>
import { onMount } from 'svelte';
//import { telemetryStore } from '../lib/telemetry.ts'; // Import your telemetry store
let telemetry = {};
let isCollapsed = false;
// Subscribe to the telemetry store
//const unsubscribe = telemetryStore.subscribe((data) => {
// telemetry = data;
//});
telemetry = {
latitude: 56.3576,
longitude: 39.8666,
altitude: 1000
};
// onMount(() => {
// return () => {
// unsubscribe(); // Cleanup subscription on component destroy
// };
// });
</script>
<div class="card shadow-lg position-absolute bottom-0 end-0 m-3" style="width: 23rem; max-height: 80vh; overflow-y: auto; z-index: 1000;">
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
<h6 class="card-title mb-0">Последние данные телеметрии</h6>
<button class="btn btn-sm btn-primary" on:click={() => (isCollapsed = !isCollapsed)}>
{#if isCollapsed}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-left-fill" viewBox="0 0 16 16">
<path d="m3.86 8.753 5.482 4.796c.646.566 1.658.106 1.658-.753V3.204a1 1 0 0 0-1.659-.753l-5.48 4.796a1 1 0 0 0 0 1.506z"/>
</svg>
{:else}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-down" viewBox="0 0 16 16">
<path d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/>
</svg>
{/if}
</button>
</div>
{#if !isCollapsed}
<div class="card-body">
<div class="mb-2">
<label class="form-label small">Широта:</label>
<div class="input-group input-group-sm">
<input type="text" class="form-control" value={telemetry.latitude || 'N/A'} readonly>
</div>
</div>
<div class="mb-2">
<label class="form-label small">Долгота:</label>
<div class="input-group input-group-sm">
<input type="text" class="form-control" value={telemetry.longitude || 'N/A'} readonly>
</div>
</div>
<div class="mb-2">
<label class="form-label small">Высота (м):</label>
<div class="input-group input-group-sm">
<input type="text" class="form-control" value={telemetry.altitude || 'N/A'} readonly>
</div>
</div>
</div>
{/if}
</div>
<style>
.card {
transition: all 0.3s ease;
}
.card-header {
cursor: pointer;
}
</style>

View file

@ -5,6 +5,7 @@
import { distHaversine } from '../lib/mathutil.ts'; import { distHaversine } from '../lib/mathutil.ts';
import { latestPredictionParsed } from '../lib/prediction.ts'; import { latestPredictionParsed } from '../lib/prediction.ts';
import { latestTelemetryParsed } from '../lib/telemetry.ts';
/** /**
* @type {L.Map} * @type {L.Map}
@ -147,6 +148,65 @@
map.setView(launch.latlng, 8); map.setView(launch.latlng, 8);
}; };
const plotTelemetryTrack = (telemetry) => {
console.log("Telemetry data parsed, creating map plot...");
// Clear existing map items
if (marker) {
map.eachLayer((layer) => {
if (layer instanceof L.Marker || layer instanceof L.Polyline) {
map.removeLayer(layer);
}
});
}
// Create custom icons for telemetry markers
const telemetryIcon = L.icon({
iconUrl: 'marker-sm-red.png',
iconSize: [10, 10],
iconAnchor: [5, 5],
});
const launchIcon = L.icon({
iconUrl: 'target-blue.png',
iconSize: [10, 10],
iconAnchor: [5, 5],
});
// Add markers to the map
const launchMarker = L.marker(telemetry.launch.latlng, {
title: `Launch (${telemetry.launch.latlng.lat.toFixed(4)}, ${telemetry.launch.latlng.lng.toFixed(4)}) at ${telemetry.launch.datetime.toUTCString()}`,
icon: launchIcon,
}).addTo(map);
// interface TelemetryPoint {
// altitude: number;
// datetime: string;
// latitude: number;
// longitude: number;
// payload: string;
// }
// Add telemetry markers to the map
telemetry.datapoints.forEach((point) => {
const telemetryMarker = L.marker([point.latitude, point.longitude], {
title: `Telemetry (${point.latitude.toFixed(4)}, ${point.longitude.toFixed(4)}) at ${point.datetime}`,
icon: telemetryIcon,
}).addTo(map)
.bindPopup(() => {
return `
<b>Telemetry Point</b><br>, Lat: ${point.latitude.toFixed(6)}<br>, Lon: ${point.longitude.toFixed(6)}<br>
`;
});
});
// Add flight path polyline
const pathPolyline = L.polyline(telemetry.flight_path, {
weight: 3,
color: "#000000",
}).addTo(map);
};
</script> </script>
<div class="map-container"> <div class="map-container">

View file

@ -0,0 +1,26 @@
<script>
import Map from '../map.svelte';
import ControlPanel from '../ControlPanel.svelte';
import Navbar from '../Navbar.svelte';
// import BurstCalculator from './BurstCalculator.svelte';
let coordinates = {
lat: '56.3576',
lng: '39.8666'
}
function handlePositionUpdate(event) {
coordinates.lat = event.detail.lat;
coordinates.lng = event.detail.lng;
}
</script>
<main>
<Navbar />
<Map bind:coordinates>
<ControlPanel
{coordinates}
on:updatePosition={handlePositionUpdate}
/>
</Map>
</main>

View file

@ -0,0 +1 @@
export const ssr =false;

View file

@ -0,0 +1,19 @@
<script>
import Map from '../map.svelte';
import TelemetryPanel from '../TelemetryPanel.svelte';
import Navbar from '../Navbar.svelte';
// import BurstCalculator from './BurstCalculator.svelte';
let coordinates = {
lat: '56.3576',
lng: '39.8666'
}
</script>
<main>
<Navbar />
<Map bind:coordinates>
<TelemetryPanel
/>
</Map>
</main>

View file

@ -0,0 +1 @@
export const ssr =false;

BIN
static/marker-sm-red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B