prop/lib/microwaveprop/radio/callsign_client.ex
Graham McIntire 95351a2358 Add /path calculator page
LiveView page for analyzing microwave propagation between two points.
Features:
- Source/destination input: callsign (via gridmap.org API) or Maidenhead grid
- Band selector for all 8 microwave bands (10-241 GHz)
- Leaflet map showing path line (reuses ContactMap hook)
- Terrain elevation cross-section (reuses ElevationProfile hook)
- Link summary: distance, bearing, terrain verdict
- Loss budget: FSPL + O2 + H2O + rain + diffraction
- Propagation score with 10-factor breakdown
- Current atmospheric conditions from path-integrated HRRR

New CallsignClient for gridmap.org location lookup.
Navigation links added to main navbar and map control panel.
2026-04-07 13:25:04 -05:00

37 lines
1.1 KiB
Elixir

defmodule Microwaveprop.Radio.CallsignClient do
@moduledoc "Looks up amateur radio callsign locations via gridmap.org."
@doc """
Fetch location for a callsign. Returns {:ok, %{callsign, gridsquare, lat, lon}} or {:error, reason}.
"""
def locate(callsign) do
url = "https://gridmap.org/locate/#{URI.encode(callsign)}"
case Req.get(url, req_options() ++ [receive_timeout: 10_000]) do
{:ok, %{status: 200, body: %{"latitude" => lat, "longitude" => lon} = body}} when is_number(lat) ->
{:ok,
%{
callsign: body["callsign"] || callsign,
gridsquare: body["gridsquare"],
lat: lat,
lon: lon
}}
{:ok, %{status: 200, body: _}} ->
{:error, "callsign not found"}
{:ok, %{status: 404}} ->
{:error, "callsign not found"}
{:ok, %{status: status}} ->
{:error, "gridmap.org HTTP #{status}"}
{:error, reason} ->
{:error, "gridmap.org failed: #{inspect(reason)}"}
end
end
defp req_options do
Application.get_env(:microwaveprop, :callsign_req_options, [])
end
end