diff --git a/assets/js/hooks/info_map.js b/assets/js/hooks/info_map.js index c40ea31..285877d 100644 --- a/assets/js/hooks/info_map.js +++ b/assets/js/hooks/info_map.js @@ -11,7 +11,9 @@ export const InfoMap = { const symbolHtml = this.el.dataset.symbolHtml; // Validate coordinates + const callsign = this.el.dataset.callsign; if (isNaN(lat) || isNaN(lon)) { + console.warn(`InfoMap: Invalid coordinates lat=${lat}, lon=${lon} for ${callsign} during update`); return; } @@ -61,7 +63,7 @@ export const InfoMap = { // Validate coordinates if (isNaN(lat) || isNaN(lon)) { - console.error("Invalid coordinates for InfoMap"); + console.warn(`InfoMap: Invalid coordinates lat=${lat}, lon=${lon} for ${callsign}`); return; } diff --git a/config/config.exs b/config/config.exs index e705f8e..250d640 100644 --- a/config/config.exs +++ b/config/config.exs @@ -37,6 +37,11 @@ config :aprsme, :cleanup_scheduler, # 6 hours in milliseconds interval: 6 * 60 * 60 * 1000 +# Configure position tracking sensitivity +config :aprsme, :position_tracking, + # Position change threshold in degrees (~100 meters at equator) + change_threshold: 0.001 + config :aprsme, ecto_repos: [Aprsme.Repo] diff --git a/lib/aprsme_web/live/info_live/show.ex b/lib/aprsme_web/live/info_live/show.ex index 03ff870..ff08797 100644 --- a/lib/aprsme_web/live/info_live/show.ex +++ b/lib/aprsme_web/live/info_live/show.ex @@ -101,16 +101,32 @@ defmodule AprsmeWeb.InfoLive.Show do defp position_changed?(current_packet, new_packet) do # Compare lat/lon to see if position actually changed - current_lat = to_float(current_packet.lat) - current_lon = to_float(current_packet.lon) - new_lat = to_float(new_packet.lat) - new_lon = to_float(new_packet.lon) + current_lat = to_float_safe(current_packet.lat) + current_lon = to_float_safe(current_packet.lon) + new_lat = to_float_safe(new_packet.lat) + new_lon = to_float_safe(new_packet.lon) - # Consider position changed if coordinates differ by more than ~100 meters (0.001 degrees) - lat_diff = abs(current_lat - new_lat) - lon_diff = abs(current_lon - new_lon) + # If any coordinate is invalid, consider it a change + case {current_lat, current_lon, new_lat, new_lon} do + {nil, _, _, _} -> + true - lat_diff > 0.001 or lon_diff > 0.001 + {_, nil, _, _} -> + true + + {_, _, nil, _} -> + true + + {_, _, _, nil} -> + true + + {curr_lat, curr_lon, new_lat, new_lon} -> + # Consider position changed if coordinates differ by more than the configured threshold + threshold = Application.get_env(:aprsme, :position_tracking, [])[:change_threshold] || 0.001 + lat_diff = abs(curr_lat - new_lat) + lon_diff = abs(curr_lon - new_lon) + lat_diff > threshold or lon_diff > threshold + end end # Expose for testing @@ -186,6 +202,10 @@ defmodule AprsmeWeb.InfoLive.Show do r * c end + # Safe float conversion that preserves nil for invalid coordinates + defp to_float_safe(value), do: EncodingUtils.to_float(value) + + # Legacy float conversion that defaults to 0.0 for backward compatibility defp to_float(value), do: EncodingUtils.to_float(value) || 0.0 defp format_timestamp_for_display(packet) do diff --git a/test/aprsme_web/live/info_live/position_change_test.exs b/test/aprsme_web/live/info_live/position_change_test.exs index c8b7db8..29d6cce 100644 --- a/test/aprsme_web/live/info_live/position_change_test.exs +++ b/test/aprsme_web/live/info_live/position_change_test.exs @@ -43,5 +43,30 @@ defmodule AprsmeWeb.InfoLive.PositionChangeTest do new_packet = %{lat: Decimal.new("40.7200"), lon: Decimal.new("-74.0060")} assert Show.position_changed_for_test(current_packet, new_packet) end + + test "handles coordinates at equator/prime meridian (0.0 is valid)" do + current_packet = %{lat: 0.0, lon: 0.0} + # Small change from valid 0.0 + new_packet = %{lat: 0.0005, lon: 0.0} + refute Show.position_changed_for_test(current_packet, new_packet) + end + + test "detects change when coordinates become invalid (nil)" do + current_packet = %{lat: 40.7128, lon: -74.0060} + new_packet = %{lat: nil, lon: -74.0060} + assert Show.position_changed_for_test(current_packet, new_packet) + end + + test "detects change when coordinates become valid from invalid" do + current_packet = %{lat: nil, lon: -74.0060} + new_packet = %{lat: 40.7128, lon: -74.0060} + assert Show.position_changed_for_test(current_packet, new_packet) + end + + test "handles both coordinates being invalid" do + current_packet = %{lat: nil, lon: nil} + new_packet = %{lat: nil, lon: nil} + assert Show.position_changed_for_test(current_packet, new_packet) + end end end