Remove dead code: round_coordinate non-float heads, unreachable get_nearby_stations branch, redundant pattern-match guards

This commit is contained in:
Graham McIntire 2026-05-08 17:49:23 -05:00
parent 0caf7e4fda
commit 001af22286
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59
3 changed files with 49 additions and 117 deletions

View file

@ -657,22 +657,11 @@ defmodule Aprsme.Packet do
defp process_weather_data(attrs, weather_data) do
case weather_data do
weather when is_binary(weather) ->
process_binary_weather_data(attrs, weather)
weather when is_map(weather) ->
process_map_weather_data(attrs, weather)
_ ->
attrs
weather when is_map(weather) -> process_map_weather_data(attrs, weather)
_ -> attrs
end
end
defp process_binary_weather_data(attrs, _weather) do
# If you have a weather parsing function, call it here
attrs
end
defp process_map_weather_data(attrs, weather) do
weather = Map.drop(weather, [:raw_weather_data, "raw_weather_data"])
@ -791,21 +780,12 @@ defmodule Aprsme.Packet do
)
end
# Extract altitude from APRS comment field (e.g., "/A=000680" means 680 feet)
defp extract_altitude_from_comment(nil), do: nil
# Extract altitude from APRS comment field (e.g., "/A=000680" means 680 feet).
# The regex captures exactly six digits, so Integer.parse always succeeds.
defp extract_altitude_from_comment(comment) when is_binary(comment) do
case Regex.run(~r/\/A=(\d{6})/, comment) do
[_, altitude_str] ->
# Convert string to integer (altitude in feet)
case Integer.parse(altitude_str) do
# Convert to float
{altitude, _} -> altitude * 1.0
_ -> nil
end
_ ->
nil
[_, altitude_str] -> String.to_integer(altitude_str) * 1.0
_ -> nil
end
end
@ -831,30 +811,18 @@ defmodule Aprsme.Packet do
defp extract_phg_from_comment(_), do: nil
# The PHG regex captures single digits 0-9, so Integer.parse always
# succeeds and the value is always in 0..9. No fallback clauses needed.
# PHG power calculation: power = n^2 watts
defp calculate_phg_power(n) when is_binary(n) do
case Integer.parse(n) do
{num, _} -> num * num
_ -> 0
end
end
defp calculate_phg_power(<<n>>) when n in ?0..?9, do: (n - ?0) * (n - ?0)
# PHG height calculation: height = 10 * 2^n feet
defp calculate_phg_height(n) when is_binary(n) do
case Integer.parse(n) do
{num, _} -> 10 * trunc(:math.pow(2, num))
_ -> 10
end
end
defp calculate_phg_height(<<n>>) when n in ?0..?9, do: 10 * trunc(:math.pow(2, n - ?0))
# PHG directivity: 0-8 = directional (n * 45 degrees), 9 = omni (360 degrees)
defp calculate_phg_directivity(n) when is_binary(n) do
case Integer.parse(n) do
{9, _} -> 360
{num, _} when num >= 0 and num <= 8 -> num * 45
_ -> 0
end
end
defp calculate_phg_directivity(<<?9>>), do: 360
defp calculate_phg_directivity(<<n>>) when n in ?0..?8, do: (n - ?0) * 45
# Normalize format field from atom to string
defp normalize_format_field(nil), do: nil

View file

@ -100,18 +100,10 @@ defmodule Aprsme.Packets do
end
defp normalize_packet_attrs(packet_data) do
case_result =
case packet_data do
%Packet{} = packet ->
packet
|> Map.from_struct()
|> Map.delete(:__meta__)
%{} ->
packet_data
end
case_result
# store_packet's rescue branch indexes packet_data[:sender], which only works
# on plain maps — Packet structs would raise. So normalize_packet_attrs only
# ever sees a plain map here.
packet_data
|> Aprsme.EncodingUtils.sanitize_packet()
|> normalize_data_type()
end
@ -147,9 +139,7 @@ defmodule Aprsme.Packets do
defp normalize_to_map(%{__struct__: _} = struct), do: Map.from_struct(struct)
defp normalize_to_map(map) when is_map(map), do: map
# Safe decimal conversion with pattern matching
defp to_decimal_safe(nil), do: {:error, :nil_value}
# Callers guard with `when not is_nil(value)`, so we never see nil here.
defp to_decimal_safe(value) do
case Aprsme.EncodingUtils.to_decimal(value) do
nil -> {:error, :conversion_failed}
@ -166,15 +156,14 @@ defmodule Aprsme.Packets do
extract_coordinate(ext_map, :longitude)
end
# Unified coordinate extraction with pattern matching
defp extract_coordinate(%{} = map, coord_type) when coord_type in [:latitude, :longitude] do
# Callers always pass a map (patch_lat_lon_from_data_extended pattern-matches
# %{data_extended: %{} = ext} before calling, then wraps via normalize_to_map).
defp extract_coordinate(map, coord_type) when coord_type in [:latitude, :longitude] do
coord_string = Atom.to_string(coord_type)
find_coordinate_value(map, coord_type) || find_coordinate_value(map, coord_string)
end
defp extract_coordinate(_, _), do: nil
# Pattern matching for direct coordinate access
defp find_coordinate_value(%{latitude: lat}, :latitude) when not is_nil(lat), do: lat
defp find_coordinate_value(%{longitude: lon}, :longitude) when not is_nil(lon), do: lon
@ -200,20 +189,10 @@ defmodule Aprsme.Packets do
|> Map.put(:lon, round_coordinate(lon))
end
# Moved out as a separate function to avoid recreating on each call
# extract_position runs values through EncodingUtils.to_float, so by the
# time round_coordinate sees them they're either float or nil.
defp round_coordinate(nil), do: nil
defp round_coordinate(%Decimal{} = d), do: Decimal.round(d, 6)
defp round_coordinate(n) when is_float(n), do: Float.round(n, 6)
defp round_coordinate(n) when is_integer(n), do: n * 1.0
defp round_coordinate(n) when is_binary(n) do
case Float.parse(n) do
{f, _} -> Float.round(f, 6)
:error -> nil
end
end
defp round_coordinate(_), do: nil
# Pattern matching for SSID normalization
defp normalize_ssid(%{ssid: nil} = attrs), do: attrs
@ -474,8 +453,7 @@ defmodule Aprsme.Packets do
case Repo.one(query) do
nil -> 0
count when is_integer(count) -> count
_ -> 0
count -> count
end
rescue
_ -> 0
@ -575,27 +553,21 @@ defmodule Aprsme.Packets do
@impl true
@spec get_nearby_stations(float(), float(), String.t() | nil, map()) :: [struct()]
def get_nearby_stations(lat, lon, exclude_callsign \\ nil, opts \\ %{}) do
# Use KNN (K-nearest neighbors) query for better performance
results = PreparedQueries.get_nearby_stations_knn(lat, lon, exclude_callsign, opts)
# Convert results back to Packet structs if needed
Enum.map(results, fn result ->
# If result is already a Packet struct, return it
if is_struct(result, Packet) do
result
else
# Otherwise, create a minimal Packet struct from the map
%Packet{
sender: result.callsign,
base_callsign: result.base_callsign,
lat: result.lat,
lon: result.lon,
received_at: result.received_at,
symbol_table_id: result.symbol_table_id,
symbol_code: result.symbol_code,
comment: result.comment
}
end
# PreparedQueries returns plain maps from a select clause; wrap each in a
# minimal Packet struct so callers get the shape they expect.
lat
|> PreparedQueries.get_nearby_stations_knn(lon, exclude_callsign, opts)
|> Enum.map(fn result ->
%Packet{
sender: result.callsign,
base_callsign: result.base_callsign,
lat: result.lat,
lon: result.lon,
received_at: result.received_at,
symbol_table_id: result.symbol_table_id,
symbol_code: result.symbol_code,
comment: result.comment
}
end)
end

View file

@ -66,10 +66,12 @@ defmodule AprsmeWeb.MapLive.Index do
# Handle callsign tracking - check path params first, then query params
tracked_callsign =
case Map.get(params, "callsign", Map.get(params, "call", "")) do
"" -> ""
nil -> ""
callsign -> callsign |> String.trim() |> String.upcase()
case Map.get(params, "callsign") || Map.get(params, "call") do
callsign when is_binary(callsign) and callsign != "" ->
callsign |> String.trim() |> String.upcase()
_ ->
""
end
{final_map_center, final_map_zoom} =
@ -1114,20 +1116,10 @@ defmodule AprsmeWeb.MapLive.Index do
defp update_display_for_batch(socket, []), do: socket
defp update_display_for_batch(socket, marker_data_list) do
tracked_callsign = socket.assigns.tracked_callsign || ""
if socket.assigns.map_zoom <= 8 do
# If tracking a callsign, send trail line instead of heat map
if tracked_callsign == "" do
DisplayManager.send_heat_map_for_current_bounds(socket)
else
DisplayManager.send_trail_line_for_tracked_callsign(socket)
end
else
send_marker_batch(socket, marker_data_list)
end
end
# PacketProcessor.build_marker_data returns nil when zoom <= 8, so by the time
# marker_data_list is non-empty here, zoom is always > 8. Heat-map / trail-line
# rendering for low-zoom packet batches happens inside the per-packet handler.
defp update_display_for_batch(socket, marker_data_list), do: send_marker_batch(socket, marker_data_list)
defp send_marker_batch(socket, marker_data_list) do
reversed = Enum.reverse(marker_data_list)