Skip to content

Commit

Permalink
Fix pressure bug, add pressure altitudes, default to normalized, remo…
Browse files Browse the repository at this point in the history
…ve interpolated (#162)
  • Loading branch information
aeharding authored Jan 6, 2025
1 parent a7d5085 commit df9a893
Show file tree
Hide file tree
Showing 11 changed files with 28 additions and 81 deletions.
4 changes: 2 additions & 2 deletions src/features/rap/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default function Table({
);

switch (altitudeLevels) {
case AltitudeLevels.Default:
case AltitudeLevels.Raw:
return filteredPressures;
case AltitudeLevels.Normalized:
return NORMALIZED_PRESSURE_MB.map((pressure) =>
Expand All @@ -103,7 +103,7 @@ export default function Table({
}

switch (altitudeLevels) {
case AltitudeLevels.Default:
case AltitudeLevels.Raw:
return windsAloftHour.altitudes
.slice(0, rows)
.filter((datum) => !hiddenAltitude(datum));
Expand Down
2 changes: 1 addition & 1 deletion src/features/rap/extra/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default function Settings() {
<Radio
label={t("Altitude levels")}
tip={t("Altitude levels tip")}
options={[AltitudeLevels.Default, AltitudeLevels.Normalized]}
options={[AltitudeLevels.Normalized, AltitudeLevels.Raw]}
value={altitudeLevels}
onChange={(value) => dispatch(setAltitudeLevels(value))}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/features/rap/extra/settings/settingEnums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export enum AltitudeType {
}

export enum AltitudeLevels {
Default = "Default",
Normalized = "Normalized",
Raw = "Raw",
}

// CSS scroll-snap-stop
Expand Down
2 changes: 1 addition & 1 deletion src/features/user/locationHash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function getAltitudeLevels() {
const value = locationHashMap.get(
ALTITUDE_LEVELS_STORAGE_KEY,
) as AltitudeLevels;
if (value !== AltitudeLevels.Default && value !== AltitudeLevels.Normalized)
if (value !== AltitudeLevels.Raw && value !== AltitudeLevels.Normalized)
return undefined;
return value;
}
Expand Down
4 changes: 2 additions & 2 deletions src/features/user/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ export function getAltitudeLevels(): AltitudeLevels {

if (
typeof savedValue !== "string" ||
(savedValue !== AltitudeLevels.Default &&
(savedValue !== AltitudeLevels.Raw &&
savedValue !== AltitudeLevels.Normalized)
)
return AltitudeLevels.Default;
return AltitudeLevels.Normalized;

return savedValue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"Hush G-AIRMETs": "G-AIRMETs stummschalten",
"Hush G-Airmets tip": "Wenn aktiviert, lösen neue G-AIRMETs keinen Hinweis für ungelesene Benachrichtigungen aus und werden am Ende der Liste der Benachrichtigungen angezeigt. Dies kann nützlich sein, wenn Sie G-AIRMETs als zu laut empfinden. [Nur USA]",
"Localization in progress": "Die Lokalisierung läuft. Um zu helfen, senden Sie bitte eine E-Mail an [email protected]",
"Default": "Standard",
"Raw": "Roh",
"Normalized": "Normalisiert",
"Advanced features": "Erweiterte Funktionen",
"Advanced features tip": "EXPERIMENTELL. Aktuelle Funktionen umfassen: <ul><li>Symbol zur Darstellung der Temperaturabnahme (Schwellenwerte für DALR, MALR und Temperaturinversion).</li><li>Indikator für gesättigte relative Luftfeuchtigkeit.</li><li>Auf Temperaturzelle tippen, um Temperaturdetails anzuzeigen.</li></ul> Feedback willkommen - [email protected]",
Expand Down
2 changes: 1 addition & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"Hush G-AIRMETs": "Hush G-AIRMETs",
"Hush G-Airmets tip": "If turned on, new G-AIRMETs will not trigger the unread alert notifications banner, and they will be pushed to the bottom of the alerts list. This can be useful if you find G-AIRMETs too noisy. [US-only]",
"Localization in progress": "Localization is in progress. To help, please email [email protected]",
"Default": "Default",
"Raw": "Raw",
"Normalized": "Normalized",
"Advanced features": "Advanced features",
"Advanced features tip": "EXPERIMENTAL. Current features include: <ul><li>Icon to represent lapse rate (thresholds for DALR, MALR, and temperature inversion).</li><li>Relative humidity saturation indicator.</li><li>Tap temperature cell to open temperature details tooltip.</li></ul> Feedback welcome — [email protected]",
Expand Down
2 changes: 1 addition & 1 deletion src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"Hush G-AIRMETs": "Silenciar G-AIRMETs",
"Hush G-Airmets tip": "Si está activado, los nuevos G-AIRMETs no activarán el banner de notificaciones de alertas no leídas y se mostrarán al final de la lista de alertas. Esto puede ser útil si encuentras los G-AIRMETs demasiado ruidosos. [Solo EE. UU.]",
"Localization in progress": "La localización está en curso. Para ayudar, envía un correo electrónico a [email protected]",
"Default": "Predeterminado",
"Raw": "Crudo",
"Normalized": "Normalizado",
"Advanced features": "Funciones avanzadas",
"Advanced features tip": "EXPERIMENTAL. Las características actuales incluyen: <ul><li>Icono para representar la tasa de enfriamiento (umbrales para DALR, MALR e inversión de temperatura).</li><li>Indicador de saturación de humedad relativa.</li><li>Toca la celda de temperatura para abrir detalles de temperatura.</li></ul> Comentarios bienvenidos - [email protected]",
Expand Down
2 changes: 1 addition & 1 deletion src/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"Hush G-AIRMETs": "Réduire les G-AIRMETs",
"Hush G-Airmets tip": "Si activée, les nouveaux G-AIRMETs ne déclencheront pas la bannière de notifications des alertes non lues, et ils seront poussés en bas de la liste des alertes. Ceci peut être utile si vous trouvez les G-AIRMETs trop bruyants. [Uniquement aux États-Unis]",
"Localization in progress": "La localisation est en cours. Pour aider, veuillez envoyer un e-mail à [email protected]",
"Default": "Par défaut",
"Raw": "Brut",
"Normalized": "Normalisé",
"Advanced features": "Fonctionnalités avancées",
"Advanced features tip": "EXPÉRIMENTAL. Les fonctionnalités actuelles comprennent : <ul><li>Icône pour représenter le gradient de température (seuils pour DALR, MALR et inversion de température).</li><li>Indicateur de saturation de l'humidité relative.</li><li>Appuyez sur la cellule de température pour ouvrir les détails de température.</li></ul> Vos commentaires sont les bienvenus - [email protected]",
Expand Down
2 changes: 1 addition & 1 deletion src/locales/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"Hush G-AIRMETs": "Geluidsdemping G-AIRMET's",
"Hush G-Airmets tip": "Als dit is ingeschakeld, zullen nieuwe G-AIRMET's de meldingsbanner voor ongelezen meldingen niet activeren en worden ze onderaan de lijst met meldingen weergegeven. Dit kan handig zijn als je de G-AIRMET's te storend vindt. [Alleen in de VS]",
"Localization in progress": "Lokalisatie is in uitvoering. Stuur alstublieft een e-mail naar [email protected] om te helpen.",
"Default": "Standaard",
"Raw": "Ruw",
"Normalized": "Gestandaardiseerd",
"Advanced features": "Geavanceerde functies",
"Advanced features tip": "EXPERIMENTEEL. Huidige functies omvatten: <ul><li>Pictogram om de temperatuurdaling aan te geven (drempels voor DALR, MALR en temperatuurinversie).</li><li>Indicator voor verzadiging van de relatieve luchtvochtigheid.</li><li>Tik op de temperatuurcel om temperatuurdetails weer te geven.</li></ul> Feedback is welkom - [email protected]",
Expand Down
85 changes: 16 additions & 69 deletions src/services/openMeteo.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import axios from "axios";
import { WindsAloftAltitude, WindsAloftReport } from "../models/WindsAloft";
import {
convertToInterpolatorWithHeight,
interpolateWindVectors,
} from "../helpers/interpolate";
import { WindsAloftReport } from "../models/WindsAloft";
import { notEmpty } from "../helpers/array";
import zipObject from "lodash/zipObject";
import * as velitherm from "velitherm";
Expand All @@ -15,7 +11,8 @@ const FORECAST_DAYS_WINDS_ALOFT = 2;
* in hPa
*/
const PRESSURE_ALTITUDES = [
1000, 975, 950, 925, 900, 850, 800, 700, 600, 500, 400, 300, 250,
1000, 975, 950, 925, 900, 875, 850, 825, 800, 775, 750, 725, 700, 650, 600,
550, 500, 450, 400, 300, 250,
] as const;

const PRESSURE_ALTITUDE_METRICS = [
Expand Down Expand Up @@ -118,11 +115,12 @@ export async function getWindsAloft(
windsAloft: WindsAloftReport;
elevationInM: number;
}> {
const aloft = await getOpenMeteoWindsAloft(latitude, longitude);
const response = await getOpenMeteoWindsAloft(latitude, longitude);
const windsAloft = convertOpenMeteoToWindsAloft(response);

return {
windsAloft: interpolate(convertOpenMeteoToWindsAloft(aloft)),
elevationInM: aloft.elevation,
windsAloft,
elevationInM: response.elevation,
};
}

Expand All @@ -146,62 +144,6 @@ function convertOpenMeteoToWeather(
};
}

function interpolate(report: WindsAloftReport): WindsAloftReport {
const lowestAltitudeMsl =
(report.elevationInM ?? 0) + Math.max(...AGL_ALTITUDES);

return {
...report,
hours: report.hours.map((hour) => ({
...hour,
altitudes: (() => {
const ditheredAltitudes: WindsAloftAltitude[] = [];

for (let i = 0; i < hour.altitudes.length; i++) {
ditheredAltitudes.push(hour.altitudes[i]);

if (!hour.altitudes[i + 1]) continue;
if (hour.altitudes[i].altitudeInM <= lowestAltitudeMsl) continue;

const middleAltitude =
(hour.altitudes[i].altitudeInM +
hour.altitudes[i + 1].altitudeInM) /
2;

const { height, speed, direction } = interpolateWindVectors(
convertToInterpolatorWithHeight(hour.altitudes[i]),
convertToInterpolatorWithHeight(hour.altitudes[i + 1]),
middleAltitude,
);

const temperatureInC = Math.round(
(hour.altitudes[i].temperatureInC +
hour.altitudes[i + 1].temperatureInC) /
2,
);

ditheredAltitudes.push({
windSpeedInKph: Math.round(speed * 10) / 10,
windDirectionInDeg: Math.round(direction),
altitudeInM: Math.round(height),
temperatureInC,
dewpointInC: Math.round(
(hour.altitudes[i].dewpointInC +
hour.altitudes[i + 1].dewpointInC) /
2,
),
pressure: Math.round(
(hour.altitudes[i].pressure + hour.altitudes[i + 1].pressure) / 2,
),
});
}

return ditheredAltitudes;
})(),
})),
};
}

async function getOpenMeteoWindsAloft(
latitude: number,
longitude: number,
Expand Down Expand Up @@ -300,6 +242,7 @@ function convertOpenMeteoToWindsAloft(
openMeteoResponse.hourly[`temperature_${agl}m`][index],
dewpointInC: velitherm.dewPoint(
calculateRelativeHumidity(
openMeteoResponse.elevation,
agl,
openMeteoResponse.hourly[`surface_pressure`][index],
openMeteoResponse.hourly[`temperature_${agl}m`][index],
Expand All @@ -309,8 +252,11 @@ function convertOpenMeteoToWindsAloft(
),
pressure: Math.round(
velitherm.pressureFromAltitude(
agl,
openMeteoResponse.elevation + agl,
openMeteoResponse.hourly["pressure_msl"][index],
(openMeteoResponse.hourly[`temperature_${agl}m`][index] +
openMeteoResponse.hourly[`temperature_2m`][index]) /
2,
),
),
})),
Expand Down Expand Up @@ -354,20 +300,21 @@ function generateWeatherParams(): HourlyWeatherParams[] {
}

function calculateRelativeHumidity(
altitude: number,
elevation: number,
agl: number,
basePressure: number,
baseTemperature: number,
baseRH: number,
): number {
// Calculate the pressure at the given altitude
const pressure = velitherm.pressureFromAltitude(
altitude,
elevation + agl,
basePressure,
baseTemperature,
);

// Calculate the temperature at the given altitude
const temperature = baseTemperature - altitude * velitherm.gamma;
const temperature = baseTemperature - agl * velitherm.gamma;

// Calculate the specific humidity at the given temperature and pressure
const specificHumidity = velitherm.specificHumidity(
Expand Down

0 comments on commit df9a893

Please sign in to comment.