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
|
{ 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.handleEvent("update_scores", ({ scores }) => {
|
||||||
this.renderScores(scores)
|
this.renderScores(scores)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Send bounds to server on load and on pan/zoom
|
||||||
|
this.sendBounds()
|
||||||
|
this.map.on("moveend", () => this.sendBounds())
|
||||||
|
|
||||||
// Legend
|
// Legend
|
||||||
const legend = L.control({ position: "bottomright" })
|
const legend = L.control({ position: "bottomright" })
|
||||||
legend.onAdd = () => {
|
legend.onAdd = () => {
|
||||||
|
|
@ -166,6 +167,16 @@ export const PropagationMap = {
|
||||||
return { r: last.r, g: last.g, b: last.b }
|
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() {
|
destroyed() {
|
||||||
if (this.map) this.map.remove()
|
if (this.map) this.map.remove()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,8 +88,8 @@ defmodule Microwaveprop.Propagation do
|
||||||
{:ok, total}
|
{:ok, total}
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Get the latest scores for a band."
|
@doc "Get the latest scores for a band, optionally within a bounding box."
|
||||||
def latest_scores(band_mhz) do
|
def latest_scores(band_mhz, bounds \\ nil) do
|
||||||
latest_time_query =
|
latest_time_query =
|
||||||
from(gs in GridScore,
|
from(gs in GridScore,
|
||||||
where: gs.band_mhz == ^band_mhz,
|
where: gs.band_mhz == ^band_mhz,
|
||||||
|
|
@ -101,15 +101,23 @@ defmodule Microwaveprop.Propagation do
|
||||||
[]
|
[]
|
||||||
|
|
||||||
latest_time ->
|
latest_time ->
|
||||||
Repo.all(
|
from(gs in GridScore,
|
||||||
from(gs in GridScore,
|
where: gs.band_mhz == ^band_mhz and gs.valid_time == ^latest_time,
|
||||||
where: gs.band_mhz == ^band_mhz and gs.valid_time == ^latest_time,
|
select: %{lat: gs.lat, lon: gs.lon, score: gs.score}
|
||||||
select: %{lat: gs.lat, lon: gs.lon, score: gs.score}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|> maybe_filter_bounds(bounds)
|
||||||
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
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."
|
@doc "Get the latest valid_time across all scores."
|
||||||
def latest_valid_time do
|
def latest_valid_time do
|
||||||
Repo.one(from(gs in GridScore, select: max(gs.valid_time)))
|
Repo.one(from(gs in GridScore, select: max(gs.valid_time)))
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ defmodule MicrowavepropWeb.MapLive do
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, _session, socket) do
|
||||||
bands = BandConfig.all_bands()
|
bands = BandConfig.all_bands()
|
||||||
scores = Propagation.latest_scores(@default_band)
|
|
||||||
valid_time = Propagation.latest_valid_time()
|
valid_time = Propagation.latest_valid_time()
|
||||||
|
|
||||||
if connected?(socket) do
|
if connected?(socket) do
|
||||||
|
|
@ -22,15 +21,16 @@ defmodule MicrowavepropWeb.MapLive do
|
||||||
page_title: "Propagation Map",
|
page_title: "Propagation Map",
|
||||||
bands: bands,
|
bands: bands,
|
||||||
selected_band: @default_band,
|
selected_band: @default_band,
|
||||||
scores: scores,
|
scores: [],
|
||||||
valid_time: valid_time
|
valid_time: valid_time,
|
||||||
|
bounds: nil
|
||||||
)}
|
)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("select_band", %{"value" => band_str}, socket) do
|
def handle_event("select_band", %{"value" => band_str}, socket) do
|
||||||
band = String.to_integer(band_str)
|
band = String.to_integer(band_str)
|
||||||
scores = Propagation.latest_scores(band)
|
scores = Propagation.latest_scores(band, socket.assigns.bounds)
|
||||||
|
|
||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
|
|
@ -41,9 +41,21 @@ defmodule MicrowavepropWeb.MapLive do
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
end
|
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
|
@impl true
|
||||||
def handle_info({:propagation_updated, valid_time}, socket) do
|
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 =
|
||||||
socket
|
socket
|
||||||
|
|
@ -70,7 +82,7 @@ defmodule MicrowavepropWeb.MapLive do
|
||||||
id="propagation-map"
|
id="propagation-map"
|
||||||
phx-hook="PropagationMap"
|
phx-hook="PropagationMap"
|
||||||
phx-update="ignore"
|
phx-update="ignore"
|
||||||
data-scores={Jason.encode!(@scores)}
|
data-scores="[]"
|
||||||
class="absolute inset-0 z-0"
|
class="absolute inset-0 z-0"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue