feat: polish & windviz & deploy
This commit is contained in:
parent
81b8e763bd
commit
465ad00f7b
78 changed files with 20622 additions and 2154 deletions
98
examples/wind-demo/index.html
Normal file
98
examples/wind-demo/index.html
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>stratoflights-predictor — wind layer demo</title>
|
||||
|
||||
<!-- Leaflet -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<!-- leaflet-velocity: consumes the wind-js-server JSON this API emits -->
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet-velocity@1.7.0/dist/leaflet-velocity.css" />
|
||||
<script src="https://unpkg.com/leaflet-velocity@1.7.0/dist/leaflet-velocity.js"></script>
|
||||
|
||||
<style>
|
||||
html, body, #map { height: 100%; margin: 0; }
|
||||
#controls {
|
||||
position: absolute; z-index: 1000; top: 10px; right: 10px;
|
||||
background: #fff; padding: 8px 10px; border-radius: 6px;
|
||||
font: 13px sans-serif; box-shadow: 0 1px 4px rgba(0,0,0,.3);
|
||||
}
|
||||
#controls label { display: block; margin: 4px 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<div id="controls">
|
||||
<strong>Wind layer</strong>
|
||||
<label>Altitude (m):
|
||||
<input id="altitude" type="number" value="10000" step="1000" style="width:80px">
|
||||
</label>
|
||||
<label>Step (deg):
|
||||
<input id="step" type="number" value="2" step="0.5" min="0.25" style="width:60px">
|
||||
</label>
|
||||
<button id="reload">Reload</button>
|
||||
<div id="status"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Base URL of the predictor API. Same-origin by default.
|
||||
const API = "";
|
||||
|
||||
const map = L.map("map").setView([30, 0], 2);
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
attribution: "© OpenStreetMap",
|
||||
}).addTo(map);
|
||||
|
||||
let velocityLayer = null;
|
||||
|
||||
// fetchWindField pulls the leaflet-velocity-compatible grid from the API.
|
||||
//
|
||||
// The endpoint returns a two-element array [uComponent, vComponent], each
|
||||
// with a {header, data} object — exactly the gfs.json / wind-js-server
|
||||
// shape leaflet-velocity and wind-layer expect.
|
||||
async function fetchWindField({ altitude, step, time, bbox } = {}) {
|
||||
const q = new URLSearchParams();
|
||||
if (altitude != null) q.set("altitude", altitude);
|
||||
if (step != null) q.set("step", step);
|
||||
if (time) q.set("time", time);
|
||||
if (bbox) {
|
||||
q.set("min_lat", bbox.minLat); q.set("max_lat", bbox.maxLat);
|
||||
q.set("min_lng", bbox.minLng); q.set("max_lng", bbox.maxLng);
|
||||
}
|
||||
const res = await fetch(`${API}/api/v1/wind/field?` + q.toString());
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function reload() {
|
||||
const status = document.getElementById("status");
|
||||
const altitude = Number(document.getElementById("altitude").value);
|
||||
const step = Number(document.getElementById("step").value);
|
||||
status.textContent = "loading…";
|
||||
try {
|
||||
const data = await fetchWindField({ altitude, step });
|
||||
if (velocityLayer) map.removeLayer(velocityLayer);
|
||||
velocityLayer = L.velocityLayer({
|
||||
displayValues: true,
|
||||
displayOptions: {
|
||||
velocityType: "Wind",
|
||||
displayPosition: "bottomleft",
|
||||
displayEmptyString: "No wind data",
|
||||
},
|
||||
data,
|
||||
maxVelocity: 60,
|
||||
}).addTo(map);
|
||||
status.textContent = `loaded ${data[0].header.nx}×${data[0].header.ny} grid`;
|
||||
} catch (err) {
|
||||
status.textContent = "error: " + err.message;
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("reload").addEventListener("click", reload);
|
||||
reload();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue