diff --git a/lib/towerops/workers/coverage_worker.ex b/lib/towerops/workers/coverage_worker.ex index af6d17e3..4ea05dd4 100644 --- a/lib/towerops/workers/coverage_worker.ex +++ b/lib/towerops/workers/coverage_worker.ex @@ -140,18 +140,11 @@ defmodule Towerops.Workers.CoverageWorker do fn r -> row_lat = max_lat - (r + 0.5) * cell_lat + tx = {{lat, lon}, tx_z, tx_height} + for c <- 0..(ncols - 1) do pixel_lon = min_lon + (c + 0.5) * cell_lon - - compute_pixel( - coverage, - antenna, - {lat, lon}, - tx_z, - {row_lat, pixel_lon}, - grid, - eirp - ) + compute_pixel(coverage, antenna, tx, {row_lat, pixel_lon}, grid, eirp) end end, ordered: true, @@ -173,7 +166,7 @@ defmodule Towerops.Workers.CoverageWorker do }} end - defp compute_pixel(coverage, antenna, tx_latlon, tx_z, rx_latlon, grid, eirp) do + defp compute_pixel(coverage, antenna, {tx_latlon, _tx_z, _tx_height} = tx, rx_latlon, grid, eirp) do distance_m = Profile.great_circle_distance_m(tx_latlon, rx_latlon) cond do @@ -184,15 +177,14 @@ defmodule Towerops.Workers.CoverageWorker do :nan true -> - do_compute_pixel(coverage, antenna, tx_latlon, tx_z, rx_latlon, grid, eirp, distance_m) + do_compute_pixel(coverage, antenna, tx, rx_latlon, grid, eirp, distance_m) end end defp do_compute_pixel( coverage, antenna, - {tx_lat, tx_lon} = tx_latlon, - tx_z, + {{tx_lat, tx_lon} = tx_latlon, tx_z, tx_height}, {rx_lat, rx_lon} = rx_latlon, grid, eirp, @@ -202,10 +194,10 @@ defmodule Towerops.Workers.CoverageWorker do samples = max(3, min(@profile_samples, ceil(distance_m / coverage.cell_size_m) + 2)) profile = Profile.sample(grid, tx_latlon, rx_latlon, samples) - # Replace TX endpoint with the absolute Z (so diffraction sees the correct - # antenna height). The receiver height is added inside Propagation. + # Replace TX endpoint with the ground elevation under the antenna (so the + # path loss model sees the correct antenna height above terrain). [_old_first | rest] = profile - profile = [tx_z - (coverage.height_agl_m + (coverage.height_above_rooftop_m || 0.0)) | rest] + profile = [tx_z - tx_height | rest] # 2. Antenna pattern attenuation at this bearing/elevation. bearing_offset = bearing_offset_deg(tx_lat, tx_lon, rx_lat, rx_lon, coverage.azimuth_deg) @@ -218,7 +210,7 @@ defmodule Towerops.Workers.CoverageWorker do distance_m, coverage.frequency_mhz * 1.0, profile, - coverage.height_agl_m + (coverage.height_above_rooftop_m || 0.0), + tx_height, coverage.receiver_height_m || 3.0 ) diff --git a/lib/towerops_web/live/coverage_live/show.ex b/lib/towerops_web/live/coverage_live/show.ex index 2257099e..3ec470b6 100644 --- a/lib/towerops_web/live/coverage_live/show.ex +++ b/lib/towerops_web/live/coverage_live/show.ex @@ -61,7 +61,9 @@ defmodule ToweropsWeb.CoverageLive.Show do @impl true def handle_info({:coverage_status, _status, _extra}, socket) do coverage = - Coverages.get_coverage!(socket.assigns.organization.id, socket.assigns.coverage.id) + socket.assigns.organization.id + |> Coverages.get_coverage!(socket.assigns.coverage.id) + |> Towerops.Repo.preload(:device) eirp = Coverage.eirp_dbm( diff --git a/lib/towerops_web/live/coverage_live/show.html.heex b/lib/towerops_web/live/coverage_live/show.html.heex index 35d3270b..88552356 100644 --- a/lib/towerops_web/live/coverage_live/show.html.heex +++ b/lib/towerops_web/live/coverage_live/show.html.heex @@ -199,7 +199,8 @@ /> <.param_row :if={ - @coverage.device_id and Ecto.assoc_loaded?(@coverage.device) and @coverage.device + not is_nil(@coverage.device_id) and Ecto.assoc_loaded?(@coverage.device) and + not is_nil(@coverage.device) } label={t("Device")} value={@coverage.device.name || @coverage.device.ip_address}