Only send visible map scores based on viewport bounds
The JS hook sends map bounds on load and on pan/zoom. The server queries only scores within those bounds, dramatically reducing the payload for band switches and map updates. At zoom 7 (DFW area) this sends ~2k scores instead of ~95k.
This commit is contained in:
parent
321133c3cb
commit
97d4bd9372
3 changed files with 47 additions and 16 deletions
|
|
@ -23,13 +23,14 @@ export const PropagationMap = {
|
|||
{ min: 0, r: 255, g: 79, b: 79 } // NEGLIGIBLE - red
|
||||
]
|
||||
|
||||
const initialScores = JSON.parse(this.el.dataset.scores || "[]")
|
||||
this.renderScores(initialScores)
|
||||
|
||||
this.handleEvent("update_scores", ({ scores }) => {
|
||||
this.renderScores(scores)
|
||||
})
|
||||
|
||||
// Send bounds to server on load and on pan/zoom
|
||||
this.sendBounds()
|
||||
this.map.on("moveend", () => this.sendBounds())
|
||||
|
||||
// Legend
|
||||
const legend = L.control({ position: "bottomright" })
|
||||
legend.onAdd = () => {
|
||||
|
|
@ -166,6 +167,16 @@ export const PropagationMap = {
|
|||
return { r: last.r, g: last.g, b: last.b }
|
||||
},
|
||||
|
||||
sendBounds() {
|
||||
const b = this.map.getBounds()
|
||||
this.pushEvent("map_bounds", {
|
||||
south: b.getSouth(),
|
||||
north: b.getNorth(),
|
||||
west: b.getWest(),
|
||||
east: b.getEast()
|
||||
})
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
if (this.map) this.map.remove()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ defmodule Microwaveprop.Propagation do
|
|||
{:ok, total}
|
||||
end
|
||||
|
||||
@doc "Get the latest scores for a band."
|
||||
def latest_scores(band_mhz) do
|
||||
@doc "Get the latest scores for a band, optionally within a bounding box."
|
||||
def latest_scores(band_mhz, bounds \\ nil) do
|
||||
latest_time_query =
|
||||
from(gs in GridScore,
|
||||
where: gs.band_mhz == ^band_mhz,
|
||||
|
|
@ -101,15 +101,23 @@ defmodule Microwaveprop.Propagation do
|
|||
[]
|
||||
|
||||
latest_time ->
|
||||
Repo.all(
|
||||
from(gs in GridScore,
|
||||
where: gs.band_mhz == ^band_mhz and gs.valid_time == ^latest_time,
|
||||
select: %{lat: gs.lat, lon: gs.lon, score: gs.score}
|
||||
)
|
||||
from(gs in GridScore,
|
||||
where: gs.band_mhz == ^band_mhz and gs.valid_time == ^latest_time,
|
||||
select: %{lat: gs.lat, lon: gs.lon, score: gs.score}
|
||||
)
|
||||
|> maybe_filter_bounds(bounds)
|
||||
|> Repo.all()
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_filter_bounds(query, nil), do: query
|
||||
|
||||
defp maybe_filter_bounds(query, %{"south" => s, "north" => n, "west" => w, "east" => e}) do
|
||||
from(gs in query,
|
||||
where: gs.lat >= ^s and gs.lat <= ^n and gs.lon >= ^w and gs.lon <= ^e
|
||||
)
|
||||
end
|
||||
|
||||
@doc "Get the latest valid_time across all scores."
|
||||
def latest_valid_time do
|
||||
Repo.one(from(gs in GridScore, select: max(gs.valid_time)))
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ defmodule MicrowavepropWeb.MapLive do
|
|||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
bands = BandConfig.all_bands()
|
||||
scores = Propagation.latest_scores(@default_band)
|
||||
valid_time = Propagation.latest_valid_time()
|
||||
|
||||
if connected?(socket) do
|
||||
|
|
@ -22,15 +21,16 @@ defmodule MicrowavepropWeb.MapLive do
|
|||
page_title: "Propagation Map",
|
||||
bands: bands,
|
||||
selected_band: @default_band,
|
||||
scores: scores,
|
||||
valid_time: valid_time
|
||||
scores: [],
|
||||
valid_time: valid_time,
|
||||
bounds: nil
|
||||
)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("select_band", %{"value" => band_str}, socket) do
|
||||
band = String.to_integer(band_str)
|
||||
scores = Propagation.latest_scores(band)
|
||||
scores = Propagation.latest_scores(band, socket.assigns.bounds)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|
|
@ -41,9 +41,21 @@ defmodule MicrowavepropWeb.MapLive do
|
|||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event("map_bounds", bounds, socket) do
|
||||
scores = Propagation.latest_scores(socket.assigns.selected_band, bounds)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:bounds, bounds)
|
||||
|> assign(:scores, scores)
|
||||
|> push_event("update_scores", %{scores: scores})
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info({:propagation_updated, valid_time}, socket) do
|
||||
scores = Propagation.latest_scores(socket.assigns.selected_band)
|
||||
scores = Propagation.latest_scores(socket.assigns.selected_band, socket.assigns.bounds)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|
|
@ -70,7 +82,7 @@ defmodule MicrowavepropWeb.MapLive do
|
|||
id="propagation-map"
|
||||
phx-hook="PropagationMap"
|
||||
phx-update="ignore"
|
||||
data-scores={Jason.encode!(@scores)}
|
||||
data-scores="[]"
|
||||
class="absolute inset-0 z-0"
|
||||
>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue