Single search bar accepts an address, Maidenhead grid square, or callsign; resolves it to lat/lon via Geocoder / Maidenhead / CallsignLocation (cheapest classification first), snaps to the HRRR grid via the existing ProfilesFile reader, and renders an SVG Skew-T-Log-P with isobars, skewed isotherms, dry/moist adiabats, and mixing-ratio lines. A button row picks between every available forecast hour (now → f18); default is the most recent analysis. Right pane lists derived stability and refractivity stats from SoundingParams.derive (PWAT, BL depth, K-index, lifted index, min dN/dh, ducting status + per-duct base/top/ΔM). Renderer is server-side SVG so the page works without JS and serializes into the LiveView payload as a single tag. Wind barbs are deliberately omitted — HRRR's persisted profile carries wind only at 10 m AGL.
46 lines
1.7 KiB
Elixir
46 lines
1.7 KiB
Elixir
defmodule MicrowavepropWeb.SkewtLocationResolverTest do
|
|
use Microwaveprop.DataCase, async: false
|
|
|
|
alias MicrowavepropWeb.SkewtLocationResolver
|
|
|
|
describe "classify/1" do
|
|
test "recognises 4/6/8-character Maidenhead grid squares" do
|
|
assert SkewtLocationResolver.classify("EM12") == :grid
|
|
assert SkewtLocationResolver.classify("EM12kp") == :grid
|
|
assert SkewtLocationResolver.classify("EM12kp37") == :grid
|
|
end
|
|
|
|
test "recognises typical US/foreign callsigns" do
|
|
assert SkewtLocationResolver.classify("W5ISP") == :callsign
|
|
assert SkewtLocationResolver.classify("KM5PO") == :callsign
|
|
assert SkewtLocationResolver.classify("VE3ABC") == :callsign
|
|
assert SkewtLocationResolver.classify("G0ABC") == :callsign
|
|
end
|
|
|
|
test "anything else is treated as an address" do
|
|
assert SkewtLocationResolver.classify("Dallas, TX") == :address
|
|
assert SkewtLocationResolver.classify("123 Main St, Plano TX") == :address
|
|
assert SkewtLocationResolver.classify("Eiffel Tower") == :address
|
|
end
|
|
|
|
test "is whitespace and case tolerant" do
|
|
assert SkewtLocationResolver.classify(" em12 ") == :grid
|
|
assert SkewtLocationResolver.classify("w5isp") == :callsign
|
|
end
|
|
end
|
|
|
|
describe "resolve/1 — grid square branch" do
|
|
test "returns lat/lon for a valid grid square" do
|
|
assert {:ok, %{lat: lat, lon: lon, label: "EM12KP", source: :grid}} =
|
|
SkewtLocationResolver.resolve("EM12kp")
|
|
|
|
assert_in_delta lat, 32.646, 0.01
|
|
assert_in_delta lon, -97.125, 0.01
|
|
end
|
|
|
|
test "round-trips a 4-char grid" do
|
|
assert {:ok, %{label: "EM12", source: :grid}} =
|
|
SkewtLocationResolver.resolve("EM12")
|
|
end
|
|
end
|
|
end
|