Vertical 'Height above clutter' slider on the left of the map now matches cnHeat's experience: pick an SM install height, the heatmap re-renders to show only the coverage achievable from that height. Backend - New JSONB height_tiers column on coverages keyed by string metres → relative PNG path. - CoverageWorker runs compute_pixels once per tier in [1.83, 3.05, 4.57, 6.10, 9.14, 12.19] m (~6/10/15/20/30/40 ft) by varying receiver_height_m on a copied struct. Each tier writes its own raster + PNG via Raster.write/4 with a per-height filename suffix; the default 3.05 m tier also populates the legacy raster_path / png_path so existing show pages keep working. Frontend - Vertical range slider (writing-mode: vertical-lr) anchored centre-left. Step picks one of HEIGHT_TIERS_FT; label updates to '6 ft'..'40 ft'. - pngForCoverage/2 picks the closest available tier from the payload's height_tiers map, falling back to the original png for coverages not yet recomputed. - On slider change the JS swaps each L.imageOverlay's URL via setUrl, drops the cached pixel data, and re-decodes so the RSSI filter still applies. coverage_hooks chunk: 20 KB → 22 KB.
12 lines
400 B
Elixir
12 lines
400 B
Elixir
defmodule Towerops.Repo.Migrations.AddHeightTiersToCoverages do
|
|
use Ecto.Migration
|
|
|
|
def change do
|
|
alter table(:coverages) do
|
|
# Map of receiver-height-in-metres → relative PNG path written
|
|
# by the worker. Empty for coverages that haven't been recomputed
|
|
# since the multi-height pipeline shipped.
|
|
add :height_tiers, :map, default: %{}, null: false
|
|
end
|
|
end
|
|
end
|