fix packet storing exception

This commit is contained in:
Graham McIntire 2025-06-16 13:33:38 -05:00
parent 7db7156729
commit 20ed933a52
No known key found for this signature in database
4 changed files with 40 additions and 15 deletions

View file

@ -117,7 +117,15 @@ defmodule Aprs.DbTest do
IO.puts("Fetching #{limit} most recent packets...")
try do
packets = Repo.all(from(p in Packet, where: p.has_position == true, order_by: [desc: p.received_at], limit: ^limit))
packets =
Repo.all(
from(p in Packet,
where: p.has_position == true,
order_by: [desc: p.received_at],
limit: ^limit,
select: %{p | lat: fragment("ST_Y(?)", p.location), lon: fragment("ST_X(?)", p.location)}
)
)
IO.puts("Found #{length(packets)} recent packets")

View file

@ -4,7 +4,6 @@ defmodule Aprs.Packets do
"""
import Ecto.Query, warn: false
# import Geo.PostGIS
alias Aprs.Packet
alias Aprs.Repo
@ -149,6 +148,7 @@ defmodule Aprs.Packets do
|> filter_by_callsign(opts)
|> filter_by_map_bounds(opts)
|> limit_results(opts)
|> select_with_virtual_coordinates()
Repo.all(query)
end
@ -169,6 +169,12 @@ defmodule Aprs.Packets do
Repo.one(query)
end
# Adds a select clause to populate virtual lat/lon fields from PostGIS geometry.
defp select_with_virtual_coordinates(query) do
from p in query,
select: %{p | lat: fragment("ST_Y(?)", p.location), lon: fragment("ST_X(?)", p.location)}
end
# Query building helpers
# Handle both start_time and end_time
defp filter_by_time(query, %{start_time: start_time, end_time: end_time}) do
@ -267,10 +273,14 @@ defmodule Aprs.Packets do
defp filter_by_map_bounds(query, %{bounds: [min_lon, min_lat, max_lon, max_lat]})
when not is_nil(min_lon) and not is_nil(min_lat) and not is_nil(max_lon) and not is_nil(max_lat) do
# Create a bounding box polygon for PostGIS spatial query
bbox_wkt =
"POLYGON((#{min_lon} #{min_lat}, #{max_lon} #{min_lat}, #{max_lon} #{max_lat}, #{min_lon} #{max_lat}, #{min_lon} #{min_lat}))"
from p in query,
where: p.has_position == true,
where: p.lat >= ^min_lat and p.lat <= ^max_lat,
where: p.lon >= ^min_lon and p.lon <= ^max_lon
where: not is_nil(p.location),
where: fragment("ST_Within(?, ST_GeomFromText(?, 4326))", p.location, ^bbox_wkt)
end
defp filter_by_map_bounds(query, _), do: query
@ -358,6 +368,7 @@ defmodule Aprs.Packets do
|> where([p], p.received_at >= ^one_hour_ago)
|> order_by([p], asc: p.received_at)
|> limit(500)
|> select_with_virtual_coordinates()
|> Repo.all()
end

View file

@ -390,16 +390,19 @@ defmodule AprsWeb.MapLive.Enhanced do
defp fetch_packets_in_bounds(bounds, limit) do
cutoff_time = DateTime.add(DateTime.utc_now(), -@packet_retention_minutes * 60, :second)
# Create a bounding box polygon for PostGIS spatial query
bbox_wkt =
"POLYGON((#{bounds["west"]} #{bounds["south"]}, #{bounds["east"]} #{bounds["south"]}, #{bounds["east"]} #{bounds["north"]}, #{bounds["west"]} #{bounds["north"]}, #{bounds["west"]} #{bounds["south"]}))"
Repo.all(
from(p in Packet,
where: p.has_position == true,
where: p.received_at >= ^cutoff_time,
where: p.lat >= ^bounds["south"],
where: p.lat <= ^bounds["north"],
where: p.lon >= ^bounds["west"],
where: p.lon <= ^bounds["east"],
where: not is_nil(p.location),
where: fragment("ST_Within(?, ST_GeomFromText(?, 4326))", p.location, ^bbox_wkt),
order_by: [desc: p.received_at],
limit: ^limit
limit: ^limit,
select: %{p | lat: fragment("ST_Y(?)", p.location), lon: fragment("ST_X(?)", p.location)}
)
)
end
@ -561,17 +564,20 @@ defmodule AprsWeb.MapLive.Enhanced do
end
defp fetch_historical_packets(bounds, start_time, end_time) do
# Create a bounding box polygon for PostGIS spatial query
bbox_wkt =
"POLYGON((#{bounds["west"]} #{bounds["south"]}, #{bounds["east"]} #{bounds["south"]}, #{bounds["east"]} #{bounds["north"]}, #{bounds["west"]} #{bounds["north"]}, #{bounds["west"]} #{bounds["south"]}))"
Repo.all(
from(p in Packet,
where: p.has_position == true,
where: p.received_at >= ^start_time,
where: p.received_at <= ^end_time,
where: p.lat >= ^bounds["south"],
where: p.lat <= ^bounds["north"],
where: p.lon >= ^bounds["west"],
where: p.lon <= ^bounds["east"],
where: not is_nil(p.location),
where: fragment("ST_Within(?, ST_GeomFromText(?, 4326))", p.location, ^bbox_wkt),
order_by: [asc: p.received_at],
limit: 1000
limit: 1000,
select: %{p | lat: fragment("ST_Y(?)", p.location), lon: fragment("ST_X(?)", p.location)}
)
)
end

View file

@ -60,7 +60,7 @@ defmodule AprsWeb.MapLive.Index do
Endpoint.subscribe("aprs_messages")
# Only do IP geolocation in non-test environments
if Mix.env() != :test do
if Application.get_env(:aprs, :disable_aprs_connection, false) != true do
IO.puts("Socket is connected, attempting to get IP location")
# Get IP-based location on initial load
IO.puts("Connect info: #{inspect(socket.private[:connect_info])}")