v1.02 - Location Saving
This commit is contained in:
+15
-8
@@ -40,15 +40,22 @@ export function UTCIForecast() {
|
||||
// Each useState() pairs a value with a setter. Calling the setter
|
||||
// re-renders the page with the new value.
|
||||
|
||||
// The location we're forecasting for. Change the values below to set
|
||||
// a different starting location for new visitors.
|
||||
const [location, setLocation] = useState({
|
||||
name: 'Pangbourne, Berkshire',
|
||||
lat: 51.4839,
|
||||
lon: -1.0725,
|
||||
country: 'GB',
|
||||
// The location we're forecasting for. Restored from localStorage if the
|
||||
// user has visited before, otherwise defaults to Pangbourne, Berkshire.
|
||||
const [location, setLocation] = useState(() => {
|
||||
try {
|
||||
const saved = localStorage.getItem('sunscope_last_location');
|
||||
if (saved) return JSON.parse(saved);
|
||||
} catch (e) { /* ignore */ }
|
||||
return { name: 'Pangbourne, Berkshire', lat: 51.4839, lon: -1.0725, country: 'GB' };
|
||||
});
|
||||
|
||||
// Wrapper that persists the location before updating state.
|
||||
const setLocationAndSave = (loc) => {
|
||||
try { localStorage.setItem('sunscope_last_location', JSON.stringify(loc)); } catch (e) { /* ignore */ }
|
||||
setLocation(loc);
|
||||
};
|
||||
|
||||
const [forecast, setForecast] = useState(null); // raw Open-Meteo response
|
||||
const [loading, setLoading] = useState(false); // true while fetching
|
||||
const [error, setError] = useState(null); // fetch error message
|
||||
@@ -750,7 +757,7 @@ export function UTCIForecast() {
|
||||
key=${`${r.id}-${r.latitude}`}
|
||||
class="utci-result"
|
||||
onClick=${() => {
|
||||
setLocation({
|
||||
setLocationAndSave({
|
||||
name: `${r.name}${r.admin1 ? ', ' + r.admin1 : ''}`,
|
||||
lat: r.latitude,
|
||||
lon: r.longitude,
|
||||
|
||||
@@ -308,6 +308,30 @@ export function calcVehicleInteriorTemp(Ta, globalRad, solElev, vehicleType = 'c
|
||||
return Math.max(Ta, Math.min(Ti, 90));
|
||||
}
|
||||
|
||||
// ── FUTURE FEATURE: Vehicle-at-speed thermal model ────────────────────────────
|
||||
// Idea: extend calcVehicleInteriorTemp (or add a companion function) to model
|
||||
// cabin temperature for a vehicle travelling at speed, not just parked.
|
||||
//
|
||||
// Key physics differences from the static model:
|
||||
// • Forced convection over the shell scales with vehicle speed (v²), so
|
||||
// hOut rises significantly — shell cools much faster than when parked.
|
||||
// • Above ~30 mph the vehicle's own forward motion dominates airflow, so
|
||||
// ambient wind direction becomes largely irrelevant (simplifies the model).
|
||||
// • Speed classes to model: urban (~20 mph), dual carriageway (~50 mph),
|
||||
// motorway (~70 mph) — each with a derived hOut multiplier.
|
||||
// • Windows-open behaviour changes completely at speed: at 70 mph open
|
||||
// windows create high-velocity through-flow, dramatically cutting cabin
|
||||
// temp vs. the sealed-car case (but much less pleasant than AC!).
|
||||
// • Roof and bonnet solar gain stays the same; side-glass gain is unchanged.
|
||||
// • AC-off vs AC-on would be the primary user toggle alongside speed class.
|
||||
//
|
||||
// Suggested signature:
|
||||
// calcVehicleInteriorTempAtSpeed(Ta, globalRad, solElev, vehicleType, speedMph, windowsOpen)
|
||||
//
|
||||
// This would be a useful companion output column (e.g. "Vehicle (moving)")
|
||||
// for road-trip planning, dog-in-car safety at a rest stop vs. motorway, etc.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
// Vapour pressure (Magnus → hPa)
|
||||
export function vaporPressureHpa(Ta, RH) {
|
||||
const es = 6.105 * Math.exp((17.27 * Ta) / (237.7 + Ta));
|
||||
|
||||
Reference in New Issue
Block a user