Show IEMRE gridded reanalysis data on contact detail page
This commit is contained in:
parent
da490f7c59
commit
383c18e50a
1 changed files with 62 additions and 0 deletions
|
|
@ -38,6 +38,7 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
|||
terrain = Terrain.get_terrain_profile(contact.id)
|
||||
contact = maybe_enqueue_terrain(terrain, contact)
|
||||
contact = maybe_enqueue_weather(weather, contact)
|
||||
iemre = load_iemre(contact)
|
||||
elevation_profile = compute_elevation_profile(contact, hrrr_path, weather.soundings)
|
||||
propagation_analysis = build_propagation_analysis(contact, hrrr, terrain, elevation_profile, weather.soundings)
|
||||
data_sources = build_data_sources(hrrr, hrrr_path, terrain, weather, elevation_profile)
|
||||
|
|
@ -50,6 +51,7 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
|||
soundings: weather.soundings,
|
||||
solar: solar,
|
||||
hrrr: hrrr,
|
||||
iemre: iemre,
|
||||
terrain: terrain,
|
||||
elevation_profile: elevation_profile,
|
||||
propagation_analysis: propagation_analysis,
|
||||
|
|
@ -254,6 +256,18 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
|||
defp sounding_sort_key("lifted_index"), do: &(&1.lifted_index || 0)
|
||||
defp sounding_sort_key(_), do: fn s -> s.station.name || s.station.station_code end
|
||||
|
||||
defp load_iemre(contact) do
|
||||
case Weather.iemre_for_contact(contact) do
|
||||
%{hourly: hourly} = obs when is_list(hourly) and hourly != [] ->
|
||||
qso_hour = contact.qso_timestamp.hour
|
||||
nearest = Enum.min_by(hourly, fn h -> abs((h["utc_hour"] || 0) - qso_hour) end)
|
||||
%{observation: obs, nearest_hour: nearest}
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
defp load_weather(contact) do
|
||||
lat1 = contact.pos1 && contact.pos1["lat"]
|
||||
lon1 = contact.pos1 && (contact.pos1["lon"] || contact.pos1["lng"])
|
||||
|
|
@ -799,6 +813,47 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
|||
|
||||
<div class="divider" />
|
||||
|
||||
<h2 class="text-base font-semibold mb-2">IEMRE Gridded Reanalysis</h2>
|
||||
<%= if @iemre do %>
|
||||
<% h = @iemre.nearest_hour %>
|
||||
<% obs = @iemre.observation %>
|
||||
<div class="text-xs opacity-60 mb-2">
|
||||
Grid point: {format_number(obs.lat)}°, {format_number(obs.lon)}° — {obs.date} hour {h[
|
||||
"utc_hour"
|
||||
] || "—"} UTC
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-x-6 gap-y-1 text-sm">
|
||||
<div><span class="font-semibold">Temp:</span> {format_number(h["air_temp_f"])}°F</div>
|
||||
<div><span class="font-semibold">Dewpoint:</span> {format_number(h["dew_point_f"])}°F</div>
|
||||
<div><span class="font-semibold">Sky Cover:</span> {format_number(h["skyc_%"])}%</div>
|
||||
<div>
|
||||
<span class="font-semibold">Wind:</span>
|
||||
{format_number(wind_speed_from_components(h["uwnd_mps"], h["vwnd_mps"]))} kts
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-semibold">Precip:</span> {format_number(h["hourly_precip_in"])}"
|
||||
</div>
|
||||
<div :if={h["soil4t_f"]}>
|
||||
<span class="font-semibold">Soil Temp:</span> {format_number(h["soil4t_f"])}°F
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="text-sm text-base-content/50 italic">
|
||||
<%= case @contact.iemre_status do %>
|
||||
<% :queued -> %>
|
||||
<span class="flex items-center gap-2">
|
||||
<span class="loading loading-spinner loading-sm"></span> Fetching IEMRE data
|
||||
</span>
|
||||
<% :unavailable -> %>
|
||||
IEMRE data unavailable for this contact.
|
||||
<% _ -> %>
|
||||
No IEMRE data available.
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="divider" />
|
||||
|
||||
<h2 class="text-base font-semibold mb-2">Surface Observations</h2>
|
||||
<%= if @surface_observations == [] do %>
|
||||
<div class="text-sm text-base-content/50 italic">
|
||||
|
|
@ -931,6 +986,13 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
|||
defp format_number(n) when is_float(n), do: :erlang.float_to_binary(n, decimals: 1)
|
||||
defp format_number(n), do: to_string(n)
|
||||
|
||||
defp wind_speed_from_components(u, v) when is_number(u) and is_number(v) do
|
||||
mps = :math.sqrt(u * u + v * v)
|
||||
Float.round(mps * 1.944, 1)
|
||||
end
|
||||
|
||||
defp wind_speed_from_components(_, _), do: nil
|
||||
|
||||
defp format_dist(km) do
|
||||
mi = km * 0.621371
|
||||
"#{:erlang.float_to_binary(mi, decimals: 1)} mi (#{:erlang.float_to_binary(km, decimals: 1)} km)"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue