prop/test/microwaveprop/rover/path_terrain_test.exs
Graham McIntire 40cbb40cb1
feat(rover): score per-station terrain clearance from SRTM path samples
For each (rover cell, fixed station) pair, sample SRTM along the
great-circle path and add a per-link dB bonus proportional to the
rover's elevation above the highest intermediate terrain. Rover spots
on hilltops with clear sight to multiple stations now rise to the top.

Also vendor Leaflet's layers control PNGs and copy them under
priv/static/assets/css/images/ on build so /rover stops 404'ing on
layers-2x.png.
2026-04-25 17:29:29 -05:00

58 lines
1.8 KiB
Elixir

defmodule Microwaveprop.Rover.PathTerrainTest do
use ExUnit.Case, async: true
alias Microwaveprop.Rover.PathTerrain
describe "clearance_map/2" do
test "returns positive clearance when rover sits well above intermediate terrain" do
cells = [%{lat: 33.0, lon: -96.0}]
stations = [%{lat: 33.5, lon: -96.5}]
# Rover at 800 m, intermediate path tops out at 200 m → 600 m clearance.
lookup = fn _pts ->
%{}
|> Map.put({33.0, -96.0}, 800)
|> Map.merge(intermediate_elevs(cells, stations, 200))
end
result = PathTerrain.clearance_map(cells, stations, elev_lookup: lookup)
assert result[{{33.0, -96.0}, {33.5, -96.5}}] == 600
end
test "returns negative clearance when rover is below path obstruction" do
cells = [%{lat: 33.0, lon: -96.0}]
stations = [%{lat: 33.5, lon: -96.5}]
lookup = fn _pts ->
%{}
|> Map.put({33.0, -96.0}, 100)
|> Map.merge(intermediate_elevs(cells, stations, 500))
end
result = PathTerrain.clearance_map(cells, stations, elev_lookup: lookup)
assert result[{{33.0, -96.0}, {33.5, -96.5}}] == -400
end
test "returns nil when rover cell has no SRTM coverage" do
cells = [%{lat: 33.0, lon: -96.0}]
stations = [%{lat: 33.5, lon: -96.5}]
lookup = fn _pts -> %{} end
result = PathTerrain.clearance_map(cells, stations, elev_lookup: lookup)
assert result[{{33.0, -96.0}, {33.5, -96.5}}] == nil
end
end
defp intermediate_elevs(cells, stations, elev) do
for cell <- cells, station <- stations, i <- 1..12, into: %{} do
f = i / 13
lat = cell.lat + f * (station.lat - cell.lat)
lon = cell.lon + f * (station.lon - cell.lon)
{{lat, lon}, elev}
end
end
end