Fetch elevation data along the path between two stations via the Open-Meteo Elevation API (with Open-Topo-Data fallback), compute Fresnel zone clearance, earth bulge, and knife-edge diffraction loss, and store the results per QSO. - terrain_profiles table with migration and TerrainProfile schema - ElevationClient with batched API calls and fallback - TerrainAnalysis with Fresnel/diffraction physics (ITU-R P.526-15) - TerrainProfileWorker on Oban :terrain queue - QsoWeatherEnqueueWorker enqueues terrain jobs automatically - QSO show page displays verdict badge and collapsible elevation table - Reorder show page: terrain, soundings, solar, HRRR, surface obs - Fix Dockerfile wgrib2 build (add cmake dependency)
28 lines
630 B
Elixir
28 lines
630 B
Elixir
defmodule Microwaveprop.Terrain do
|
|
@moduledoc false
|
|
|
|
import Ecto.Query
|
|
|
|
alias Microwaveprop.Repo
|
|
alias Microwaveprop.Terrain.TerrainProfile
|
|
|
|
def upsert_terrain_profile(attrs) do
|
|
%TerrainProfile{}
|
|
|> TerrainProfile.changeset(attrs)
|
|
|> Repo.insert(
|
|
on_conflict: {:replace_all_except, [:id, :qso_id, :inserted_at]},
|
|
conflict_target: [:qso_id],
|
|
returning: true
|
|
)
|
|
end
|
|
|
|
def get_terrain_profile(qso_id) do
|
|
Repo.get_by(TerrainProfile, qso_id: qso_id)
|
|
end
|
|
|
|
def has_terrain_profile?(qso_id) do
|
|
TerrainProfile
|
|
|> where([t], t.qso_id == ^qso_id)
|
|
|> Repo.exists?()
|
|
end
|
|
end
|