components

This commit is contained in:
Vasilisk9812 2025-04-04 22:57:35 +09:00
parent c88469c1d4
commit 0f130c640c
6 changed files with 847 additions and 221 deletions

View file

@ -0,0 +1,291 @@
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
let startPoint = 'Custom';
let startHeight = 0;
let startTime = '13:13';
let startDate = new Date(2025, 2, 24);
let ascentRate = 5;
let burstAltitude = 30000;
let flightProfile = 'Normal';
let descentRate = 5;
let forecastMode = 'Single';
let inputLat = '56.3576';
let inputLng = '39.8666';
function formatLaunchDateTime(date, time) {
// Parse the date
const d = new Date(date);
const year = d.getUTCFullYear();
const month = String(d.getUTCMonth() + 1).padStart(2, '0');
const day = String(d.getUTCDate()).padStart(2, '0');
// Parse the time (add seconds if missing)
const [hours, minutes, seconds = '00'] = time.split(':');
const formattedTime = `${hours.padStart(2, '0')}:${minutes.padStart(2, '0')}:${seconds.padStart(2, '0')}`;
return new Date(`${year}-${month}-${day}T${formattedTime}Z`).toISOString();
}
const launch_datetime = formatLaunchDateTime(startDate, startTime);
const getForecast = async () => {
// Create request object
const request = {
ascent_rate: parseFloat(ascentRate),
burst_altitude: parseFloat(burstAltitude),
dataset: new Date().toISOString(), // Current time as dataset timestamp
descent_rate: parseFloat(descentRate),
format: "json",
launch_altitude: parseFloat(startHeight),
launch_datetime,
launch_latitude: parseFloat(inputLat),
launch_longitude: parseFloat(inputLng),
profile: flightProfile === 'Normal' ? 'standard_profile' : 'custom_profile',
version: 2
};
console.log("Sending request:", request);
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(request)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log("Forecast response:", data);
alert("Forecast request successful!");
// Handle the response data as needed
} catch (error) {
console.error("Error sending forecast request:", error);
alert("Error getting forecast: " + error.message);
}
};
// Helper function to format date as YYYY-MM-DD
const formatDateForAPI = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
function handleUpdatePosition() {
dispatch('updatePosition', {
lat: inputLat,
lng: inputLng
});
}
</script>
<div class="control-panel">
<div class="control-header">Launch Point</div>
<div class="control-row">
<span>Start Point:</span>
<select bind:value={startPoint}>
<option>Custom</option>
<option>Preset 1</option>
<option>Preset 2</option>
</select>
</div>
<div class="control-row">
<span>Latitude/Longitude:</span>
<div class="coordinate-inputs">
<input type="text" bind:value={inputLat} placeholder="Latitude">
<p>/</p>
<input type="text" bind:value={inputLng} placeholder="Longitude">
<button on:click={handleUpdatePosition} class="update-button"></button>
</div>
</div>
<div class="control-row">
<button class="map-button" on:click={() => {
inputLat = mouseLat;
inputLng = mouseLng;
updateMapPosition();
}}>Specify on map (click location)</button>
</div>
<div class="control-row">
<span>Launch Height (m):</span>
<input type="number" bind:value={startHeight}>
</div>
<div class="control-row">
<span>Launch Time (UTC):</span>
<input type="time" bind:value={startTime}>
</div>
<div class="control-row">
<span>Launch Date:</span>
<input type="date" bind:value={startDate}>
</div>
<div class="control-row">
<span>Ascent Rate (m/s):</span>
<input type="number" bind:value={ascentRate}>
</div>
<div class="control-row">
<span>Burst/Drift Altitude (m):</span>
<input type="number" bind:value={burstAltitude}>
</div>
<div class="control-row">
<span>Flight Profile:</span>
<select bind:value={flightProfile}>
<option>Normal</option>
<option>Drift</option>
<option>Reversible (on the rise)</option>
<option>Custom</option>
</select>
</div>
<div class="control-row buttons">
<button on:click={toggleBurstCalculator}>Open Burst Calculator</button>
<button>Set Custom Flight Profile</button>
<button>Show Last Altitude Graph</button>
</div>
<div class="control-row">
<span>Descent Rate (m/s):</span>
<input type="number" bind:value={descentRate}>
</div>
<div class="control-row">
<span>Forecast Mode (help):</span>
<div class="radio-group">
<label>
<input type="radio" bind:group={forecastMode} value="Single"> Single
</label>
<label>
<input type="radio" bind:group={forecastMode} value="Multiple"> Multiple
</label>
</div>
</div>
<div class="control-row">
<button class="primary-button" on:click={getForecast}>Get Forecast</button>
<button>Save Point</button>
</div>
</div>
<style>
.control-panel {
position: absolute;
bottom: 20px;
right: 20px;
background: rgba(255, 255, 255, 0.9);
padding: 15px;
border-radius: 5px;
font-family: Arial, sans-serif;
font-size: 14px;
z-index: 1000;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
width: 320px;
max-height: 80vh;
overflow-y: auto;
}
.control-header {
font-weight: bold;
margin-bottom: 10px;
font-size: 16px;
border-bottom: 1px solid #ddd;
padding-bottom: 5px;
}
.control-row {
margin-bottom: 8px;
display: flex;
align-items: center;
}
.control-row span {
width: 160px;
display: inline-block;
}
.control-row input[type="number"],
.control-row input[type="date"],
.control-row input[type="time"],
.control-row select {
width: 120px;
padding: 3px;
}
.coordinate-inputs {
display: flex;
align-items: center;
gap: 5px;
}
.coordinate-inputs input {
width: 70px !important;
padding: 3px;
}
.update-button {
padding: 3px 8px;
background: #4CAF50;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
margin-left: 5px;
}
.map-button {
width: 100%;
padding: 5px;
background: #f0f0f0;
border: 1px solid #ccc;
border-radius: 3px;
cursor: pointer;
}
.buttons {
flex-direction: column;
gap: 5px;
margin-top: 10px;
}
.buttons button {
width: 100%;
padding: 5px;
margin-bottom: 5px;
background: #f0f0f0;
border: 1px solid #ccc;
border-radius: 3px;
cursor: pointer;
}
.primary-button {
background: #4CAF50 !important;
color: white;
border: 1px solid #3e8e41 !important;
}
.radio-group {
display: flex;
gap: 10px;
}
.radio-group label {
display: flex;
align-items: center;
gap: 5px;
}
</style>