defmodule MicrowavepropWeb.WeatherMapLive do @moduledoc false use MicrowavepropWeb, :live_view alias Microwaveprop.Weather @initial_bounds %{ "south" => 29.5, "north" => 36.3, "west" => -101.5, "east" => -92.5 } @layers [ %{id: "refractivity_gradient", label: "Refractivity Gradient", unit: "N/km"}, %{id: "bl_height", label: "Boundary Layer", unit: "m"}, %{id: "dewpoint_depression", label: "Dewpoint Depression", unit: "°C"}, %{id: "pwat", label: "Precipitable Water", unit: "mm"}, %{id: "temperature", label: "Temperature", unit: "°C"}, %{id: "ducting", label: "Ducting Detected", unit: ""} ] @impl true def mount(_params, _session, socket) do if connected?(socket) do Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "weather:updated") end data = Weather.latest_weather_grid(@initial_bounds) valid_time = if data != [], do: hd(data).valid_time {:ok, assign(socket, page_title: "Weather Map", layers: @layers, selected_layer: "refractivity_gradient", initial_data_json: Jason.encode!(data), valid_time: valid_time, bounds: @initial_bounds )} end @impl true def handle_event("select_layer", %{"layer" => layer_id}, socket) do {:noreply, assign(socket, :selected_layer, layer_id)} end def handle_event("map_bounds", bounds, socket) do data = Weather.latest_weather_grid(bounds) socket = socket |> assign(:bounds, bounds) |> push_event("update_weather", %{data: data}) {:noreply, socket} end def handle_event("point_detail", %{"lat" => lat, "lon" => lon}, socket) do detail = if socket.assigns.valid_time do Weather.weather_point_detail(lat, lon, socket.assigns.valid_time) end payload = detail || %{} {:noreply, push_event(socket, "point_detail", payload)} end @impl true def handle_info({:weather_updated, _valid_time}, socket) do data = Weather.latest_weather_grid(socket.assigns.bounds) valid_time = if data != [], do: hd(data).valid_time socket = socket |> assign(:valid_time, valid_time) |> push_event("update_weather", %{data: data}) {:noreply, socket} end @impl true def render(assigns) do ~H"""
<%!-- Full-page map --%>
<%!-- Top-left control panel --%>
Weather
<%= if @valid_time do %> {Calendar.strftime(@valid_time, "%Y-%m-%d %H:%M UTC")} <% else %> No data available <% end %>
<%!-- Layer pill buttons --%>
<%!-- Links --%>
<.link navigate="/map" class="btn btn-xs btn-ghost justify-start gap-1.5"> <.icon name="hero-signal" class="size-3.5" /> Propagation Map
<%!-- Point detail panel --%>
""" end end