Never download SRTM tiles during page load, only in Oban workers
- Srtm.lookup no longer auto-downloads by default, requires download: true - TerrainProfileWorker passes download: true for background tile fetch - Contact detail page enqueues TerrainProfileWorker if profile missing - Page load gracefully handles missing tiles via API fallback or nil
This commit is contained in:
parent
ebd22ce156
commit
fd00de7bc6
5 changed files with 33 additions and 13 deletions
|
|
@ -7,16 +7,16 @@ defmodule Microwaveprop.Terrain.ElevationClient do
|
||||||
|
|
||||||
@batch_size 100
|
@batch_size 100
|
||||||
|
|
||||||
@spec fetch_elevation_profile(float(), float(), float(), float(), pos_integer()) ::
|
@spec fetch_elevation_profile(float(), float(), float(), float(), pos_integer(), keyword()) ::
|
||||||
{:ok, list(map())} | {:error, String.t()}
|
{:ok, list(map())} | {:error, String.t()}
|
||||||
def fetch_elevation_profile(lat1, lon1, lat2, lon2, n \\ 64) do
|
def fetch_elevation_profile(lat1, lon1, lat2, lon2, n \\ 64, opts \\ []) do
|
||||||
case srtm_tiles_dir() do
|
case srtm_tiles_dir() do
|
||||||
nil ->
|
nil ->
|
||||||
Logger.debug("SRTM tiles_dir not configured, using API")
|
Logger.debug("SRTM tiles_dir not configured, using API")
|
||||||
fetch_elevation_profile_api(lat1, lon1, lat2, lon2, n)
|
fetch_elevation_profile_api(lat1, lon1, lat2, lon2, n)
|
||||||
|
|
||||||
tiles_dir ->
|
tiles_dir ->
|
||||||
case Srtm.fetch_elevation_profile(lat1, lon1, lat2, lon2, tiles_dir, n) do
|
case Srtm.fetch_elevation_profile(lat1, lon1, lat2, lon2, tiles_dir, n, opts) do
|
||||||
{:ok, _profile} = ok ->
|
{:ok, _profile} = ok ->
|
||||||
Logger.info("Elevation profile served from SRTM tiles")
|
Logger.info("Elevation profile served from SRTM tiles")
|
||||||
ok
|
ok
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,9 @@ defmodule Microwaveprop.Terrain.Srtm do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec lookup(float(), float(), String.t()) ::
|
@spec lookup(float(), float(), String.t(), keyword()) ::
|
||||||
{:ok, integer()} | {:error, :no_tile} | {:error, :void}
|
{:ok, integer()} | {:error, :no_tile} | {:error, :void}
|
||||||
def lookup(lat, lon, tiles_dir) do
|
def lookup(lat, lon, tiles_dir, opts \\ []) do
|
||||||
path = Path.join(tiles_dir, tile_filename(lat, lon))
|
path = Path.join(tiles_dir, tile_filename(lat, lon))
|
||||||
|
|
||||||
case :file.open(path, [:read, :binary, :raw]) do
|
case :file.open(path, [:read, :binary, :raw]) do
|
||||||
|
|
@ -61,9 +61,9 @@ defmodule Microwaveprop.Terrain.Srtm do
|
||||||
read_elevation(fd, lat, lon)
|
read_elevation(fd, lat, lon)
|
||||||
|
|
||||||
{:error, :enoent} ->
|
{:error, :enoent} ->
|
||||||
if File.dir?(tiles_dir) do
|
if opts[:download] && File.dir?(tiles_dir) do
|
||||||
case download_tile(lat, lon, tiles_dir) do
|
case download_tile(lat, lon, tiles_dir) do
|
||||||
{:ok, _path} ->
|
{:ok, _} ->
|
||||||
case :file.open(path, [:read, :binary, :raw]) do
|
case :file.open(path, [:read, :binary, :raw]) do
|
||||||
{:ok, fd} -> read_elevation(fd, lat, lon)
|
{:ok, fd} -> read_elevation(fd, lat, lon)
|
||||||
{:error, _} -> {:error, :no_tile}
|
{:error, _} -> {:error, :no_tile}
|
||||||
|
|
@ -78,15 +78,15 @@ defmodule Microwaveprop.Terrain.Srtm do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec fetch_elevation_profile(float(), float(), float(), float(), String.t(), pos_integer()) ::
|
@spec fetch_elevation_profile(float(), float(), float(), float(), String.t(), pos_integer(), keyword()) ::
|
||||||
{:ok, list(map())} | {:error, term()}
|
{:ok, list(map())} | {:error, term()}
|
||||||
def fetch_elevation_profile(lat1, lon1, lat2, lon2, tiles_dir, n \\ 64) do
|
def fetch_elevation_profile(lat1, lon1, lat2, lon2, tiles_dir, n \\ 64, opts \\ []) do
|
||||||
pts = sample_path(lat1, lon1, lat2, lon2, n)
|
pts = sample_path(lat1, lon1, lat2, lon2, n)
|
||||||
dist_km = haversine_km(lat1, lon1, lat2, lon2)
|
dist_km = haversine_km(lat1, lon1, lat2, lon2)
|
||||||
|
|
||||||
results =
|
results =
|
||||||
Enum.reduce_while(pts, {:ok, []}, fn pt, {:ok, acc} ->
|
Enum.reduce_while(pts, {:ok, []}, fn pt, {:ok, acc} ->
|
||||||
case lookup(pt.lat, pt.lon, tiles_dir) do
|
case lookup(pt.lat, pt.lon, tiles_dir, opts) do
|
||||||
{:ok, elev} ->
|
{:ok, elev} ->
|
||||||
entry = %{
|
entry = %{
|
||||||
lat: pt.lat,
|
lat: pt.lat,
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ defmodule Microwaveprop.Workers.TerrainProfileWorker do
|
||||||
# Look up HRRR refractivity gradient for dynamic k-factor
|
# Look up HRRR refractivity gradient for dynamic k-factor
|
||||||
k = lookup_k_factor(contact)
|
k = lookup_k_factor(contact)
|
||||||
|
|
||||||
case ElevationClient.fetch_elevation_profile(lat1, lon1, lat2, lon2) do
|
case ElevationClient.fetch_elevation_profile(lat1, lon1, lat2, lon2, 64, download: true) do
|
||||||
{:ok, profile} ->
|
{:ok, profile} ->
|
||||||
analysis = TerrainAnalysis.analyse(profile, dist_km, freq_ghz, k_factor: k)
|
analysis = TerrainAnalysis.analyse(profile, dist_km, freq_ghz, k_factor: k)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
||||||
alias Microwaveprop.Weather
|
alias Microwaveprop.Weather
|
||||||
# alias Microwaveprop.Weather.HrrrClient
|
# alias Microwaveprop.Weather.HrrrClient
|
||||||
# alias Microwaveprop.Workers.HrrrFetchWorker
|
# alias Microwaveprop.Workers.HrrrFetchWorker
|
||||||
|
alias Microwaveprop.Workers.TerrainProfileWorker
|
||||||
|
|
||||||
@earth_radius_m 6_371_000.0
|
@earth_radius_m 6_371_000.0
|
||||||
|
|
||||||
|
|
@ -26,6 +27,7 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
||||||
hrrr = List.first(hrrr_path)
|
hrrr = List.first(hrrr_path)
|
||||||
{hrrr, hrrr_status} = maybe_enqueue_hrrr(hrrr, contact)
|
{hrrr, hrrr_status} = maybe_enqueue_hrrr(hrrr, contact)
|
||||||
terrain = Terrain.get_terrain_profile(contact.id)
|
terrain = Terrain.get_terrain_profile(contact.id)
|
||||||
|
maybe_enqueue_terrain(terrain, contact)
|
||||||
elevation_profile = compute_elevation_profile(contact, hrrr_path, weather.soundings)
|
elevation_profile = compute_elevation_profile(contact, hrrr_path, weather.soundings)
|
||||||
propagation_analysis = build_propagation_analysis(contact, hrrr, terrain, elevation_profile, weather.soundings)
|
propagation_analysis = build_propagation_analysis(contact, hrrr, terrain, elevation_profile, weather.soundings)
|
||||||
|
|
||||||
|
|
@ -175,6 +177,16 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp maybe_enqueue_terrain(terrain, _contact) when not is_nil(terrain), do: :ok
|
||||||
|
|
||||||
|
defp maybe_enqueue_terrain(nil, contact) do
|
||||||
|
if contact.pos1 && contact.pos2 do
|
||||||
|
Oban.insert(TerrainProfileWorker.new(%{"qso_id" => contact.id}))
|
||||||
|
end
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
defp maybe_enqueue_hrrr(hrrr, _contact) when not is_nil(hrrr), do: {hrrr, :loaded}
|
defp maybe_enqueue_hrrr(hrrr, _contact) when not is_nil(hrrr), do: {hrrr, :loaded}
|
||||||
|
|
||||||
# TODO: Re-enable auto HRRR backfill on page view when appropriate
|
# TODO: Re-enable auto HRRR backfill on page view when appropriate
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,15 @@ defmodule Microwaveprop.Terrain.SrtmTest do
|
||||||
Plug.Conn.send_resp(conn, 200, gzipped)
|
Plug.Conn.send_resp(conn, 200, gzipped)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert {:ok, @test_elevation} = Srtm.lookup(32.0, -97.0, tmp_dir)
|
assert {:ok, @test_elevation} = Srtm.lookup(32.0, -97.0, tmp_dir, download: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns {:error, :no_tile} without download opt" do
|
||||||
|
tmp_dir = Path.join(System.tmp_dir!(), "srtm_test_#{System.unique_integer([:positive])}")
|
||||||
|
File.mkdir_p!(tmp_dir)
|
||||||
|
on_exit(fn -> File.rm_rf!(tmp_dir) end)
|
||||||
|
|
||||||
|
assert {:error, :no_tile} = Srtm.lookup(32.0, -97.0, tmp_dir)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns {:error, :no_tile} when download fails" do
|
test "returns {:error, :no_tile} when download fails" do
|
||||||
|
|
@ -112,7 +120,7 @@ defmodule Microwaveprop.Terrain.SrtmTest do
|
||||||
end)
|
end)
|
||||||
|
|
||||||
capture_log(fn ->
|
capture_log(fn ->
|
||||||
assert {:error, :no_tile} = Srtm.lookup(80.0, 0.0, tmp_dir)
|
assert {:error, :no_tile} = Srtm.lookup(80.0, 0.0, tmp_dir, download: true)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue