fix: handle both string and atom keys in packet map accessors
CoordinateUtils, Clustering, DataBuilder, HistoricalLoader, PacketHandler, PacketUtils, and Index now support both string-keyed and atom-keyed packet maps via Map.get/3 nested fallback pattern.
This commit is contained in:
parent
2e101870d7
commit
d63cdf4cda
7 changed files with 21 additions and 19 deletions
|
|
@ -69,8 +69,8 @@ defmodule Aprsme.Packets.Clustering do
|
||||||
# Filter packets with valid lat/lon coordinates
|
# Filter packets with valid lat/lon coordinates
|
||||||
defp filter_valid_coordinates(packets) do
|
defp filter_valid_coordinates(packets) do
|
||||||
Enum.filter(packets, fn packet ->
|
Enum.filter(packets, fn packet ->
|
||||||
lat = decimal_to_float(Map.get(packet, :lat))
|
lat = decimal_to_float(Map.get(packet, :lat, Map.get(packet, "lat")))
|
||||||
lon = decimal_to_float(Map.get(packet, :lon))
|
lon = decimal_to_float(Map.get(packet, :lon, Map.get(packet, "lon")))
|
||||||
|
|
||||||
not is_nil(lat) and not is_nil(lon) and
|
not is_nil(lat) and not is_nil(lon) and
|
||||||
lat >= -90 and lat <= 90 and
|
lat >= -90 and lat <= 90 and
|
||||||
|
|
@ -96,8 +96,8 @@ defmodule Aprsme.Packets.Clustering do
|
||||||
defp perform_clustering(packets, radius) do
|
defp perform_clustering(packets, radius) do
|
||||||
packets
|
packets
|
||||||
|> Enum.reduce(%{}, fn packet, clusters ->
|
|> Enum.reduce(%{}, fn packet, clusters ->
|
||||||
lat = decimal_to_float(Map.get(packet, :lat))
|
lat = decimal_to_float(Map.get(packet, :lat, Map.get(packet, "lat")))
|
||||||
lon = decimal_to_float(Map.get(packet, :lon))
|
lon = decimal_to_float(Map.get(packet, :lon, Map.get(packet, "lon")))
|
||||||
|
|
||||||
# Find cluster key by rounding to grid
|
# Find cluster key by rounding to grid
|
||||||
cluster_lat = Float.round(lat / radius) * radius
|
cluster_lat = Float.round(lat / radius) * radius
|
||||||
|
|
|
||||||
|
|
@ -585,7 +585,7 @@ defmodule AprsmeWeb.MapLive.DataBuilder do
|
||||||
# Helper to get packet ID
|
# Helper to get packet ID
|
||||||
@spec get_packet_id(map()) :: any()
|
@spec get_packet_id(map()) :: any()
|
||||||
defp get_packet_id(packet) do
|
defp get_packet_id(packet) do
|
||||||
Map.get(packet, :id)
|
Map.get(packet, :id, Map.get(packet, "id"))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helper to get packet received_at datetime
|
# Helper to get packet received_at datetime
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ defmodule AprsmeWeb.MapLive.HistoricalLoader do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Increment generation to invalidate any in-flight loads
|
# Increment generation to invalidate any in-flight loads
|
||||||
new_generation = socket.assigns.loading_generation + 1
|
new_generation = Map.get(socket.assigns, :loading_generation, 0) + 1
|
||||||
|
|
||||||
# Cancel any pending batch tasks
|
# Cancel any pending batch tasks
|
||||||
socket = cancel_pending_loads(socket)
|
socket = cancel_pending_loads(socket)
|
||||||
|
|
@ -99,7 +99,7 @@ defmodule AprsmeWeb.MapLive.HistoricalLoader do
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_historical_batch(socket, batch_offset, generation) do
|
def load_historical_batch(socket, batch_offset, generation) do
|
||||||
if generation == socket.assigns.loading_generation do
|
if generation == Map.get(socket.assigns, :loading_generation, 0) do
|
||||||
do_load_historical_batch(socket, batch_offset)
|
do_load_historical_batch(socket, batch_offset)
|
||||||
else
|
else
|
||||||
# Stale request, skip
|
# Stale request, skip
|
||||||
|
|
@ -330,7 +330,7 @@ defmodule AprsmeWeb.MapLive.HistoricalLoader do
|
||||||
|
|
||||||
defp maybe_schedule_next_batch(socket, batch_offset, false) do
|
defp maybe_schedule_next_batch(socket, batch_offset, false) do
|
||||||
next_batch = batch_offset + 1
|
next_batch = batch_offset + 1
|
||||||
generation = socket.assigns.loading_generation
|
generation = Map.get(socket.assigns, :loading_generation, 0)
|
||||||
timer_ref = Process.send_after(self(), {:load_historical_batch, next_batch, generation}, 50)
|
timer_ref = Process.send_after(self(), {:load_historical_batch, next_batch, generation}, 50)
|
||||||
|
|
||||||
assign(socket, :pending_batch_tasks, [timer_ref | socket.assigns.pending_batch_tasks])
|
assign(socket, :pending_batch_tasks, [timer_ref | socket.assigns.pending_batch_tasks])
|
||||||
|
|
|
||||||
|
|
@ -351,13 +351,15 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
|
|
||||||
def handle_info({:load_historical_batch, batch_offset}, socket) do
|
def handle_info({:load_historical_batch, batch_offset}, socket) do
|
||||||
# For backward compatibility with old messages
|
# For backward compatibility with old messages
|
||||||
socket = HistoricalLoader.load_historical_batch(socket, batch_offset, socket.assigns.loading_generation)
|
socket =
|
||||||
|
HistoricalLoader.load_historical_batch(socket, batch_offset, Map.get(socket.assigns, :loading_generation, 0))
|
||||||
|
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_info({:load_historical_batch, batch_offset, generation}, socket) do
|
def handle_info({:load_historical_batch, batch_offset, generation}, socket) do
|
||||||
# Only process if generation matches current loading generation
|
# Only process if generation matches current loading generation
|
||||||
if generation == socket.assigns.loading_generation do
|
if generation == Map.get(socket.assigns, :loading_generation, 0) do
|
||||||
socket = HistoricalLoader.load_historical_batch(socket, batch_offset, generation)
|
socket = HistoricalLoader.load_historical_batch(socket, batch_offset, generation)
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
else
|
else
|
||||||
|
|
@ -368,7 +370,7 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
|
|
||||||
def handle_info({:historical_loading_timeout, generation}, socket) do
|
def handle_info({:historical_loading_timeout, generation}, socket) do
|
||||||
# Only process if generation matches current loading generation and we're still loading
|
# Only process if generation matches current loading generation and we're still loading
|
||||||
if generation == socket.assigns.loading_generation && socket.assigns.historical_loading do
|
if generation == Map.get(socket.assigns, :loading_generation, 0) && socket.assigns.historical_loading do
|
||||||
Logger.warning("Historical loading timeout reached, forcing completion")
|
Logger.warning("Historical loading timeout reached, forcing completion")
|
||||||
|
|
||||||
socket =
|
socket =
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ defmodule AprsmeWeb.Live.Shared.CoordinateUtils do
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_coordinates(packet) do
|
def get_coordinates(packet) do
|
||||||
lat = Map.get(packet, :lat)
|
lat = Map.get(packet, :lat, Map.get(packet, "lat"))
|
||||||
lon = Map.get(packet, :lon)
|
lon = Map.get(packet, :lon, Map.get(packet, "lon"))
|
||||||
data_extended = Map.get(packet, :data_extended)
|
data_extended = Map.get(packet, :data_extended, Map.get(packet, "data_extended"))
|
||||||
{lat, lon, data_extended}
|
{lat, lon, data_extended}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -64,8 +64,8 @@ defmodule AprsmeWeb.Live.Shared.CoordinateUtils do
|
||||||
"""
|
"""
|
||||||
@spec has_position_data?(map()) :: boolean()
|
@spec has_position_data?(map()) :: boolean()
|
||||||
def has_position_data?(packet) do
|
def has_position_data?(packet) do
|
||||||
lat = Map.get(packet, :lat)
|
lat = Map.get(packet, :lat, Map.get(packet, "lat"))
|
||||||
lon = Map.get(packet, :lon)
|
lon = Map.get(packet, :lon, Map.get(packet, "lon"))
|
||||||
|
|
||||||
has_direct_coordinates?(lat, lon) or has_position_in_data_extended?(packet)
|
has_direct_coordinates?(lat, lon) or has_position_in_data_extended?(packet)
|
||||||
end
|
end
|
||||||
|
|
@ -130,7 +130,7 @@ defmodule AprsmeWeb.Live.Shared.CoordinateUtils do
|
||||||
defp has_direct_coordinates?(_, _), do: false
|
defp has_direct_coordinates?(_, _), do: false
|
||||||
|
|
||||||
defp has_position_in_data_extended?(packet) do
|
defp has_position_in_data_extended?(packet) do
|
||||||
data_extended = Map.get(packet, :data_extended)
|
data_extended = Map.get(packet, :data_extended, Map.get(packet, "data_extended"))
|
||||||
has_position_in_data_extended_case?(data_extended)
|
has_position_in_data_extended_case?(data_extended)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ defmodule AprsmeWeb.Live.SharedPacketHandler do
|
||||||
Checks if packet sender matches the given callsign.
|
Checks if packet sender matches the given callsign.
|
||||||
"""
|
"""
|
||||||
def packet_matches_callsign?(packet, callsign) do
|
def packet_matches_callsign?(packet, callsign) do
|
||||||
packet_sender = Map.get(packet, :sender, "")
|
packet_sender = Map.get(packet, "sender", Map.get(packet, :sender, ""))
|
||||||
Callsign.matches?(packet_sender, callsign)
|
Callsign.matches?(packet_sender, callsign)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ defmodule AprsmeWeb.Live.Shared.PacketUtils do
|
||||||
case Map.get(packet, to_string(field)) do
|
case Map.get(packet, to_string(field)) do
|
||||||
nil ->
|
nil ->
|
||||||
de =
|
de =
|
||||||
Map.get(packet, :data_extended) || %{}
|
Map.get(packet, :data_extended, Map.get(packet, "data_extended")) || %{}
|
||||||
|
|
||||||
Map.get(de, field) || Map.get(de, to_string(field)) || default
|
Map.get(de, field) || Map.get(de, to_string(field)) || default
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue