format
This commit is contained in:
parent
514d1b66d5
commit
ef95f597b0
6 changed files with 180 additions and 142 deletions
|
|
@ -1,13 +1,13 @@
|
||||||
defmodule AprsmeWeb.AprsSymbol do
|
defmodule AprsmeWeb.AprsSymbol do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Shared library for APRS symbol handling and rendering.
|
Shared library for APRS symbol handling and rendering.
|
||||||
|
|
||||||
This module provides centralized functions for:
|
This module provides centralized functions for:
|
||||||
- Symbol table and code normalization
|
- Symbol table and code normalization
|
||||||
- Sprite file mapping
|
- Sprite file mapping
|
||||||
- Symbol positioning calculations
|
- Symbol positioning calculations
|
||||||
- HTML generation for symbols
|
- HTML generation for symbols
|
||||||
|
|
||||||
All APRS symbol logic should use this module to ensure consistency
|
All APRS symbol logic should use this module to ensure consistency
|
||||||
across the application.
|
across the application.
|
||||||
"""
|
"""
|
||||||
|
|
@ -15,9 +15,9 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
@doc """
|
@doc """
|
||||||
Gets sprite information for a given symbol table and code.
|
Gets sprite information for a given symbol table and code.
|
||||||
Returns a map with sprite_file, background_position, and background_size.
|
Returns a map with sprite_file, background_position, and background_size.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> AprsmeWeb.AprsSymbol.get_sprite_info("/", "_")
|
iex> AprsmeWeb.AprsSymbol.get_sprite_info("/", "_")
|
||||||
%{
|
%{
|
||||||
sprite_file: "/aprs-symbols/aprs-symbols-128-0@2x.png",
|
sprite_file: "/aprs-symbols/aprs-symbols-128-0@2x.png",
|
||||||
|
|
@ -34,21 +34,22 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
# Normal symbol table processing
|
# Normal symbol table processing
|
||||||
symbol_table = normalize_symbol_table(symbol_table)
|
symbol_table = normalize_symbol_table(symbol_table)
|
||||||
symbol_code = normalize_symbol_code(symbol_code)
|
symbol_code = normalize_symbol_code(symbol_code)
|
||||||
|
|
||||||
# Map symbol table to sprite file ID
|
# Map symbol table to sprite file ID
|
||||||
table_id = get_table_id(symbol_table)
|
table_id = get_table_id(symbol_table)
|
||||||
|
|
||||||
sprite_file = "/aprs-symbols/aprs-symbols-128-#{table_id}@2x.png"
|
sprite_file = "/aprs-symbols/aprs-symbols-128-#{table_id}@2x.png"
|
||||||
|
|
||||||
# Get symbol position using ASCII-based calculation
|
# Get symbol position using ASCII-based calculation
|
||||||
symbol_code_ord = symbol_code
|
symbol_code_ord =
|
||||||
|> String.to_charlist()
|
symbol_code
|
||||||
|> List.first()
|
|> String.to_charlist()
|
||||||
|> (fn c -> if is_integer(c), do: c, else: 63 end).()
|
|> List.first()
|
||||||
|
|> then(fn c -> if is_integer(c), do: c, else: 63 end)
|
||||||
|
|
||||||
index = symbol_code_ord - 33
|
index = symbol_code_ord - 33
|
||||||
safe_index = max(0, min(index, 93))
|
safe_index = max(0, min(index, 93))
|
||||||
|
|
||||||
# Calculate positioning for 16-column grid
|
# Calculate positioning for 16-column grid
|
||||||
column = rem(safe_index, 16)
|
column = rem(safe_index, 16)
|
||||||
row = div(safe_index, 16)
|
row = div(safe_index, 16)
|
||||||
|
|
@ -72,16 +73,17 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
# Check which table to use based on the symbol code
|
# Check which table to use based on the symbol code
|
||||||
table_id = get_overlay_base_table_id(base_symbol_code)
|
table_id = get_overlay_base_table_id(base_symbol_code)
|
||||||
sprite_file = "/aprs-symbols/aprs-symbols-128-#{table_id}@2x.png"
|
sprite_file = "/aprs-symbols/aprs-symbols-128-#{table_id}@2x.png"
|
||||||
|
|
||||||
# Get position of the base symbol in the appropriate table
|
# Get position of the base symbol in the appropriate table
|
||||||
base_symbol_ord = base_symbol_code
|
base_symbol_ord =
|
||||||
|> String.to_charlist()
|
base_symbol_code
|
||||||
|> List.first()
|
|> String.to_charlist()
|
||||||
|> (fn c -> if is_integer(c), do: c, else: 63 end).()
|
|> List.first()
|
||||||
|
|> then(fn c -> if is_integer(c), do: c, else: 63 end)
|
||||||
|
|
||||||
index = base_symbol_ord - 33
|
index = base_symbol_ord - 33
|
||||||
safe_index = max(0, min(index, 93))
|
safe_index = max(0, min(index, 93))
|
||||||
|
|
||||||
# Calculate positioning for 16-column grid
|
# Calculate positioning for 16-column grid
|
||||||
column = rem(safe_index, 16)
|
column = rem(safe_index, 16)
|
||||||
row = div(safe_index, 16)
|
row = div(safe_index, 16)
|
||||||
|
|
@ -104,15 +106,21 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
# Most overlay symbols are in the alternate table (1)
|
# Most overlay symbols are in the alternate table (1)
|
||||||
case base_symbol_code do
|
case base_symbol_code do
|
||||||
# Digipeater symbols are often in the alternate table (1) and have colored backgrounds
|
# Digipeater symbols are often in the alternate table (1) and have colored backgrounds
|
||||||
"#" -> "1" # Digipeater - green star background
|
# Digipeater - green star background
|
||||||
"a" -> "1" # Diamond shape - APRS overlay symbol (alternate table)
|
"#" -> "1"
|
||||||
"A" -> "1" # Square shape - APRS overlay symbol (alternate table)
|
# Diamond shape - APRS overlay symbol (alternate table)
|
||||||
"&" -> "1" # Diamond shape - alternate table
|
"a" -> "1"
|
||||||
">" -> "1" # Arrow symbols
|
# Square shape - APRS overlay symbol (alternate table)
|
||||||
|
"A" -> "1"
|
||||||
|
# Diamond shape - alternate table
|
||||||
|
"&" -> "1"
|
||||||
|
# Arrow symbols
|
||||||
|
">" -> "1"
|
||||||
"<" -> "1"
|
"<" -> "1"
|
||||||
"^" -> "1"
|
"^" -> "1"
|
||||||
"v" -> "1"
|
"v" -> "1"
|
||||||
"i" -> "1" # Black square background - alternate table
|
# Black square background - alternate table
|
||||||
|
"i" -> "1"
|
||||||
# Most other symbols that can be overlaid are in the alternate table
|
# Most other symbols that can be overlaid are in the alternate table
|
||||||
_ -> "1"
|
_ -> "1"
|
||||||
end
|
end
|
||||||
|
|
@ -125,16 +133,17 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
def get_overlay_character_sprite_info(overlay_char) do
|
def get_overlay_character_sprite_info(overlay_char) do
|
||||||
# Use overlay table (table 2) for the overlay character
|
# Use overlay table (table 2) for the overlay character
|
||||||
sprite_file = "/aprs-symbols/aprs-symbols-128-2@2x.png"
|
sprite_file = "/aprs-symbols/aprs-symbols-128-2@2x.png"
|
||||||
|
|
||||||
# Get position of the overlay character in the overlay table
|
# Get position of the overlay character in the overlay table
|
||||||
overlay_char_ord = overlay_char
|
overlay_char_ord =
|
||||||
|> String.to_charlist()
|
overlay_char
|
||||||
|> List.first()
|
|> String.to_charlist()
|
||||||
|> (fn c -> if is_integer(c), do: c, else: 63 end).()
|
|> List.first()
|
||||||
|
|> then(fn c -> if is_integer(c), do: c, else: 63 end)
|
||||||
|
|
||||||
index = overlay_char_ord - 33
|
index = overlay_char_ord - 33
|
||||||
safe_index = max(0, min(index, 93))
|
safe_index = max(0, min(index, 93))
|
||||||
|
|
||||||
# Calculate positioning for 16-column grid
|
# Calculate positioning for 16-column grid
|
||||||
column = rem(safe_index, 16)
|
column = rem(safe_index, 16)
|
||||||
row = div(safe_index, 16)
|
row = div(safe_index, 16)
|
||||||
|
|
@ -150,9 +159,9 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Normalizes a symbol table identifier.
|
Normalizes a symbol table identifier.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> AprsmeWeb.AprsSymbol.normalize_symbol_table("/")
|
iex> AprsmeWeb.AprsSymbol.normalize_symbol_table("/")
|
||||||
"/"
|
"/"
|
||||||
|
|
||||||
|
|
@ -172,9 +181,9 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Normalizes a symbol code.
|
Normalizes a symbol code.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> AprsmeWeb.AprsSymbol.normalize_symbol_code("_")
|
iex> AprsmeWeb.AprsSymbol.normalize_symbol_code("_")
|
||||||
"_"
|
"_"
|
||||||
|
|
||||||
|
|
@ -190,9 +199,9 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Maps a symbol table to its sprite file ID.
|
Maps a symbol table to its sprite file ID.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> AprsmeWeb.AprsSymbol.get_table_id("/")
|
iex> AprsmeWeb.AprsSymbol.get_table_id("/")
|
||||||
"0"
|
"0"
|
||||||
|
|
||||||
|
|
@ -204,59 +213,64 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
"""
|
"""
|
||||||
def get_table_id(symbol_table) do
|
def get_table_id(symbol_table) do
|
||||||
case symbol_table do
|
case symbol_table do
|
||||||
"/" -> "0" # Primary table
|
# Primary table
|
||||||
"\\" -> "1" # Alternate table
|
"/" -> "0"
|
||||||
"]" -> "2" # Overlay table (A-Z, 0-9)
|
# Alternate table
|
||||||
_ -> "0" # Default to primary table
|
"\\" -> "1"
|
||||||
|
# Overlay table (A-Z, 0-9)
|
||||||
|
"]" -> "2"
|
||||||
|
# Default to primary table
|
||||||
|
_ -> "0"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Renders an APRS symbol as HTML for use in Leaflet markers.
|
Renders an APRS symbol as HTML for use in Leaflet markers.
|
||||||
Returns HTML string that can be used as marker content.
|
Returns HTML string that can be used as marker content.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> AprsmeWeb.AprsSymbol.render_marker_html("/", "_", "W1AW")
|
iex> AprsmeWeb.AprsSymbol.render_marker_html("/", "_", "W1AW")
|
||||||
"<div style=\"position: relative; width: 32px; height: 32px; display: flex; align-items: center;\">..."
|
"<div style=\"position: relative; width: 32px; height: 32px; display: flex; align-items: center;\">..."
|
||||||
"""
|
"""
|
||||||
def render_marker_html(symbol_table, symbol_code, callsign \\ nil, size \\ 32) do
|
def render_marker_html(symbol_table, symbol_code, callsign \\ nil, size \\ 32) do
|
||||||
sprite_info = get_sprite_info(symbol_table, symbol_code)
|
sprite_info = get_sprite_info(symbol_table, symbol_code)
|
||||||
|
|
||||||
# Check if this is an overlay symbol
|
# Check if this is an overlay symbol
|
||||||
is_overlay = symbol_table && String.match?(symbol_table, ~r/^[A-Z0-9]$/)
|
is_overlay = symbol_table && String.match?(symbol_table, ~r/^[A-Z0-9]$/)
|
||||||
|
|
||||||
symbol_html = if is_overlay do
|
symbol_html =
|
||||||
# For overlay symbols, we need both the base symbol background and the overlay character
|
if is_overlay do
|
||||||
overlay_sprite_info = get_overlay_character_sprite_info(symbol_table)
|
# For overlay symbols, we need both the base symbol background and the overlay character
|
||||||
|
overlay_sprite_info = get_overlay_character_sprite_info(symbol_table)
|
||||||
"""
|
|
||||||
<div style="
|
"""
|
||||||
position: relative;
|
<div style="
|
||||||
width: #{size}px;
|
position: relative;
|
||||||
height: #{size}px;
|
width: #{size}px;
|
||||||
background-image: url(#{overlay_sprite_info.sprite_file}), url(#{sprite_info.sprite_file});
|
height: #{size}px;
|
||||||
background-position: #{overlay_sprite_info.background_position}, #{sprite_info.background_position};
|
background-image: url(#{overlay_sprite_info.sprite_file}), url(#{sprite_info.sprite_file});
|
||||||
background-size: #{overlay_sprite_info.background_size}, #{sprite_info.background_size};
|
background-position: #{overlay_sprite_info.background_position}, #{sprite_info.background_position};
|
||||||
background-repeat: no-repeat, no-repeat;
|
background-size: #{overlay_sprite_info.background_size}, #{sprite_info.background_size};
|
||||||
image-rendering: pixelated;
|
background-repeat: no-repeat, no-repeat;
|
||||||
" title="#{symbol_table}#{symbol_code}">
|
image-rendering: pixelated;
|
||||||
</div>
|
" title="#{symbol_table}#{symbol_code}">
|
||||||
"""
|
</div>
|
||||||
else
|
"""
|
||||||
"""
|
else
|
||||||
<div style="
|
"""
|
||||||
width: #{size}px;
|
<div style="
|
||||||
height: #{size}px;
|
width: #{size}px;
|
||||||
background-image: url(#{sprite_info.sprite_file});
|
height: #{size}px;
|
||||||
background-position: #{sprite_info.background_position};
|
background-image: url(#{sprite_info.sprite_file});
|
||||||
background-size: #{sprite_info.background_size};
|
background-position: #{sprite_info.background_position};
|
||||||
background-repeat: no-repeat;
|
background-size: #{sprite_info.background_size};
|
||||||
image-rendering: pixelated;
|
background-repeat: no-repeat;
|
||||||
" title="#{symbol_table}#{symbol_code}"></div>
|
image-rendering: pixelated;
|
||||||
"""
|
" title="#{symbol_table}#{symbol_code}"></div>
|
||||||
end
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
if callsign do
|
if callsign do
|
||||||
"""
|
"""
|
||||||
<div style="position: relative; width: #{size}px; height: #{size}px; display: flex; align-items: center;">
|
<div style="position: relative; width: #{size}px; height: #{size}px; display: flex; align-items: center;">
|
||||||
|
|
@ -289,23 +303,23 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
@doc """
|
@doc """
|
||||||
Renders an APRS symbol as a style string for use in templates.
|
Renders an APRS symbol as a style string for use in templates.
|
||||||
Returns a CSS style string that can be used directly in HTML.
|
Returns a CSS style string that can be used directly in HTML.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> AprsmeWeb.AprsSymbol.render_style("/", "_", 32)
|
iex> AprsmeWeb.AprsSymbol.render_style("/", "_", 32)
|
||||||
"width: 32px; height: 32px; background-image: url(/aprs-symbols/aprs-symbols-128-0@2x.png); ..."
|
"width: 32px; height: 32px; background-image: url(/aprs-symbols/aprs-symbols-128-0@2x.png); ..."
|
||||||
"""
|
"""
|
||||||
def render_style(symbol_table, symbol_code, size \\ 32) do
|
def render_style(symbol_table, symbol_code, size \\ 32) do
|
||||||
sprite_info = get_sprite_info(symbol_table, symbol_code)
|
sprite_info = get_sprite_info(symbol_table, symbol_code)
|
||||||
|
|
||||||
"width: #{size}px; height: #{size}px; background-image: url(#{sprite_info.sprite_file}); background-position: #{sprite_info.background_position}; background-size: #{sprite_info.background_size}; background-repeat: no-repeat; image-rendering: pixelated; opacity: 1.0; display: inline-block; vertical-align: middle; margin-bottom: -6px;"
|
"width: #{size}px; height: #{size}px; background-image: url(#{sprite_info.sprite_file}); background-position: #{sprite_info.background_position}; background-size: #{sprite_info.background_size}; background-repeat: no-repeat; image-rendering: pixelated; opacity: 1.0; display: inline-block; vertical-align: middle; margin-bottom: -6px;"
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Extracts symbol information from a packet with fallbacks.
|
Extracts symbol information from a packet with fallbacks.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> AprsmeWeb.AprsSymbol.extract_from_packet(%{symbol_table_id: "/", symbol_code: "_"})
|
iex> AprsmeWeb.AprsSymbol.extract_from_packet(%{symbol_table_id: "/", symbol_code: "_"})
|
||||||
{"/", "_"}
|
{"/", "_"}
|
||||||
|
|
||||||
|
|
@ -315,7 +329,7 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
def extract_from_packet(packet) do
|
def extract_from_packet(packet) do
|
||||||
symbol_table_id = get_packet_field(packet, :symbol_table_id, "/")
|
symbol_table_id = get_packet_field(packet, :symbol_table_id, "/")
|
||||||
symbol_code = get_packet_field(packet, :symbol_code, ">")
|
symbol_code = get_packet_field(packet, :symbol_code, ">")
|
||||||
|
|
||||||
{symbol_table_id, symbol_code}
|
{symbol_table_id, symbol_code}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -329,4 +343,4 @@ defmodule AprsmeWeb.AprsSymbol do
|
||||||
Map.get(data_extended, to_string(field)) ||
|
Map.get(data_extended, to_string(field)) ||
|
||||||
default
|
default
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,6 @@ defmodule AprsmeWeb.SymbolRenderer do
|
||||||
AprsmeWeb.AprsSymbol.get_sprite_info(symbol_table, symbol_code)
|
AprsmeWeb.AprsSymbol.get_sprite_info(symbol_table, symbol_code)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Renders an APRS symbol for use in Leaflet markers.
|
Renders an APRS symbol for use in Leaflet markers.
|
||||||
Returns HTML string that can be used as marker content.
|
Returns HTML string that can be used as marker content.
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ defmodule AprsmeWeb.InfoLive.Show do
|
||||||
use Gettext, backend: AprsmeWeb.Gettext
|
use Gettext, backend: AprsmeWeb.Gettext
|
||||||
|
|
||||||
alias Aprsme.Packets
|
alias Aprsme.Packets
|
||||||
alias AprsmeWeb.MapLive.PacketUtils
|
|
||||||
alias AprsmeWeb.AprsSymbol
|
alias AprsmeWeb.AprsSymbol
|
||||||
|
alias AprsmeWeb.MapLive.PacketUtils
|
||||||
|
|
||||||
@neighbor_radius_km 10
|
@neighbor_radius_km 10
|
||||||
@neighbor_limit 10
|
@neighbor_limit 10
|
||||||
|
|
@ -326,14 +326,14 @@ defmodule AprsmeWeb.InfoLive.Show do
|
||||||
def render_symbol_html(packet, size \\ 32) do
|
def render_symbol_html(packet, size \\ 32) do
|
||||||
if packet do
|
if packet do
|
||||||
{symbol_table_id, symbol_code} = AprsSymbol.extract_from_packet(packet)
|
{symbol_table_id, symbol_code} = AprsSymbol.extract_from_packet(packet)
|
||||||
|
|
||||||
# Check if this is an overlay symbol
|
# Check if this is an overlay symbol
|
||||||
if symbol_table_id && String.match?(symbol_table_id, ~r/^[A-Z0-9]$/) do
|
if symbol_table_id && String.match?(symbol_table_id, ~r/^[A-Z0-9]$/) do
|
||||||
# Use layered sprite backgrounds for overlay symbols
|
# Use layered sprite backgrounds for overlay symbols
|
||||||
sprite_info = AprsSymbol.get_sprite_info(symbol_table_id, symbol_code)
|
sprite_info = AprsSymbol.get_sprite_info(symbol_table_id, symbol_code)
|
||||||
overlay_sprite_info = AprsSymbol.get_overlay_character_sprite_info(symbol_table_id)
|
overlay_sprite_info = AprsSymbol.get_overlay_character_sprite_info(symbol_table_id)
|
||||||
|
|
||||||
raw """
|
raw("""
|
||||||
<div style="
|
<div style="
|
||||||
position: relative;
|
position: relative;
|
||||||
width: #{size}px;
|
width: #{size}px;
|
||||||
|
|
@ -348,16 +348,16 @@ defmodule AprsmeWeb.InfoLive.Show do
|
||||||
margin-bottom: -6px;
|
margin-bottom: -6px;
|
||||||
">
|
">
|
||||||
</div>
|
</div>
|
||||||
"""
|
""")
|
||||||
else
|
else
|
||||||
# Use style rendering for non-overlay symbols
|
# Use style rendering for non-overlay symbols
|
||||||
raw """
|
raw("""
|
||||||
<div style="#{AprsSymbol.render_style(symbol_table_id, symbol_code, size)}"></div>
|
<div style="#{AprsSymbol.render_style(symbol_table_id, symbol_code, size)}"></div>
|
||||||
"""
|
""")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
# Return empty if no packet
|
# Return empty if no packet
|
||||||
raw ""
|
raw("")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
<div class="min-h-screen bg-base-200">
|
<div class="min-h-screen bg-base-200">
|
||||||
<!-- Page header -->
|
<!-- Page header -->
|
||||||
<div class="bg-base-100 shadow-sm">
|
<div class="bg-base-100 shadow-sm">
|
||||||
|
|
@ -15,9 +14,13 @@
|
||||||
</span>
|
</span>
|
||||||
<%= if @packet do %>
|
<%= if @packet do %>
|
||||||
<% {symbol_table, symbol_code} = AprsmeWeb.AprsSymbol.extract_from_packet(@packet) %>
|
<% {symbol_table, symbol_code} = AprsmeWeb.AprsSymbol.extract_from_packet(@packet) %>
|
||||||
<% display_symbol = if symbol_table && String.match?(symbol_table, ~r/^[A-Z0-9]$/), do: symbol_table, else: "#{AprsmeWeb.AprsSymbol.normalize_symbol_table(symbol_table)}#{AprsmeWeb.AprsSymbol.normalize_symbol_code(symbol_code)}" %>
|
<% display_symbol =
|
||||||
|
if symbol_table && String.match?(symbol_table, ~r/^[A-Z0-9]$/),
|
||||||
|
do: symbol_table,
|
||||||
|
else:
|
||||||
|
"#{AprsmeWeb.AprsSymbol.normalize_symbol_table(symbol_table)}#{AprsmeWeb.AprsSymbol.normalize_symbol_code(symbol_code)}" %>
|
||||||
<div title={display_symbol}>
|
<div title={display_symbol}>
|
||||||
<%= render_symbol_html(@packet) %>
|
{render_symbol_html(@packet)}
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -251,10 +254,15 @@
|
||||||
{ssid_info.callsign}
|
{ssid_info.callsign}
|
||||||
</.link>
|
</.link>
|
||||||
<%= if ssid_info.packet do %>
|
<%= if ssid_info.packet do %>
|
||||||
<% {symbol_table, symbol_code} = AprsmeWeb.AprsSymbol.extract_from_packet(ssid_info.packet) %>
|
<% {symbol_table, symbol_code} =
|
||||||
<% display_symbol = if symbol_table && String.match?(symbol_table, ~r/^[A-Z0-9]$/), do: symbol_table, else: "#{AprsmeWeb.AprsSymbol.normalize_symbol_table(symbol_table)}#{AprsmeWeb.AprsSymbol.normalize_symbol_code(symbol_code)}" %>
|
AprsmeWeb.AprsSymbol.extract_from_packet(ssid_info.packet) %>
|
||||||
|
<% display_symbol =
|
||||||
|
if symbol_table && String.match?(symbol_table, ~r/^[A-Z0-9]$/),
|
||||||
|
do: symbol_table,
|
||||||
|
else:
|
||||||
|
"#{AprsmeWeb.AprsSymbol.normalize_symbol_table(symbol_table)}#{AprsmeWeb.AprsSymbol.normalize_symbol_code(symbol_code)}" %>
|
||||||
<div title={display_symbol}>
|
<div title={display_symbol}>
|
||||||
<%= render_symbol_html(ssid_info.packet) %>
|
{render_symbol_html(ssid_info.packet)}
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -353,10 +361,15 @@
|
||||||
{neighbor.callsign}
|
{neighbor.callsign}
|
||||||
</.link>
|
</.link>
|
||||||
<%= if neighbor.packet do %>
|
<%= if neighbor.packet do %>
|
||||||
<% {symbol_table, symbol_code} = AprsmeWeb.AprsSymbol.extract_from_packet(neighbor.packet) %>
|
<% {symbol_table, symbol_code} =
|
||||||
<% display_symbol = if symbol_table && String.match?(symbol_table, ~r/^[A-Z0-9]$/), do: symbol_table, else: "#{AprsmeWeb.AprsSymbol.normalize_symbol_table(symbol_table)}#{AprsmeWeb.AprsSymbol.normalize_symbol_code(symbol_code)}" %>
|
AprsmeWeb.AprsSymbol.extract_from_packet(neighbor.packet) %>
|
||||||
|
<% display_symbol =
|
||||||
|
if symbol_table && String.match?(symbol_table, ~r/^[A-Z0-9]$/),
|
||||||
|
do: symbol_table,
|
||||||
|
else:
|
||||||
|
"#{AprsmeWeb.AprsSymbol.normalize_symbol_table(symbol_table)}#{AprsmeWeb.AprsSymbol.normalize_symbol_code(symbol_code)}" %>
|
||||||
<div title={display_symbol}>
|
<div title={display_symbol}>
|
||||||
<%= render_symbol_html(neighbor.packet) %>
|
{render_symbol_html(neighbor.packet)}
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
defmodule AprsmeWeb.AprsSymbolTest do
|
defmodule AprsmeWeb.AprsSymbolTest do
|
||||||
use ExUnit.Case, async: true
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
alias AprsmeWeb.AprsSymbol
|
alias AprsmeWeb.AprsSymbol
|
||||||
|
|
||||||
describe "overlay symbol rendering" do
|
describe "overlay symbol rendering" do
|
||||||
test "D& should show black diamond background from table 1" do
|
test "D& should show black diamond background from table 1" do
|
||||||
# Test the get_sprite_info for overlay symbol D&
|
# Test the get_sprite_info for overlay symbol D&
|
||||||
sprite_info = AprsSymbol.get_sprite_info("D", "&")
|
sprite_info = AprsSymbol.get_sprite_info("D", "&")
|
||||||
|
|
||||||
# Should use table 1 for the diamond background (alternate table)
|
# Should use table 1 for the diamond background (alternate table)
|
||||||
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-1@2x.png"
|
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-1@2x.png"
|
||||||
|
|
||||||
# Calculate expected position for & (ASCII 38)
|
# Calculate expected position for & (ASCII 38)
|
||||||
# index = 38 - 33 = 5
|
# index = 38 - 33 = 5
|
||||||
# column = 5 % 16 = 5
|
# column = 5 % 16 = 5
|
||||||
|
|
@ -23,10 +24,10 @@ defmodule AprsmeWeb.AprsSymbolTest do
|
||||||
test "N# should show green star background from table 1" do
|
test "N# should show green star background from table 1" do
|
||||||
# Test the get_sprite_info for overlay symbol N#
|
# Test the get_sprite_info for overlay symbol N#
|
||||||
sprite_info = AprsSymbol.get_sprite_info("N", "#")
|
sprite_info = AprsSymbol.get_sprite_info("N", "#")
|
||||||
|
|
||||||
# Should use table 1 for the green star background
|
# Should use table 1 for the green star background
|
||||||
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-1@2x.png"
|
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-1@2x.png"
|
||||||
|
|
||||||
# Calculate expected position for # (ASCII 35)
|
# Calculate expected position for # (ASCII 35)
|
||||||
# index = 35 - 33 = 2
|
# index = 35 - 33 = 2
|
||||||
# column = 2 % 16 = 2
|
# column = 2 % 16 = 2
|
||||||
|
|
@ -40,10 +41,10 @@ defmodule AprsmeWeb.AprsSymbolTest do
|
||||||
test "overlay character sprite info for D" do
|
test "overlay character sprite info for D" do
|
||||||
# Test getting the overlay character sprite for letter D
|
# Test getting the overlay character sprite for letter D
|
||||||
overlay_info = AprsSymbol.get_overlay_character_sprite_info("D")
|
overlay_info = AprsSymbol.get_overlay_character_sprite_info("D")
|
||||||
|
|
||||||
# Should use table 2 for overlay characters
|
# Should use table 2 for overlay characters
|
||||||
assert overlay_info.sprite_file == "/aprs-symbols/aprs-symbols-128-2@2x.png"
|
assert overlay_info.sprite_file == "/aprs-symbols/aprs-symbols-128-2@2x.png"
|
||||||
|
|
||||||
# Calculate expected position for D (ASCII 68)
|
# Calculate expected position for D (ASCII 68)
|
||||||
# index = 68 - 33 = 35
|
# index = 68 - 33 = 35
|
||||||
# column = 35 % 16 = 3
|
# column = 35 % 16 = 3
|
||||||
|
|
@ -57,10 +58,10 @@ defmodule AprsmeWeb.AprsSymbolTest do
|
||||||
test "overlay character sprite info for N" do
|
test "overlay character sprite info for N" do
|
||||||
# Test getting the overlay character sprite for letter N
|
# Test getting the overlay character sprite for letter N
|
||||||
overlay_info = AprsSymbol.get_overlay_character_sprite_info("N")
|
overlay_info = AprsSymbol.get_overlay_character_sprite_info("N")
|
||||||
|
|
||||||
# Should use table 2 for overlay characters
|
# Should use table 2 for overlay characters
|
||||||
assert overlay_info.sprite_file == "/aprs-symbols/aprs-symbols-128-2@2x.png"
|
assert overlay_info.sprite_file == "/aprs-symbols/aprs-symbols-128-2@2x.png"
|
||||||
|
|
||||||
# Calculate expected position for N (ASCII 78)
|
# Calculate expected position for N (ASCII 78)
|
||||||
# index = 78 - 33 = 45
|
# index = 78 - 33 = 45
|
||||||
# column = 45 % 16 = 13
|
# column = 45 % 16 = 13
|
||||||
|
|
@ -73,26 +74,28 @@ defmodule AprsmeWeb.AprsSymbolTest do
|
||||||
|
|
||||||
test "render_marker_html for overlay symbol D&" do
|
test "render_marker_html for overlay symbol D&" do
|
||||||
html = AprsSymbol.render_marker_html("D", "&", "W5MRC-15", 32)
|
html = AprsSymbol.render_marker_html("D", "&", "W5MRC-15", 32)
|
||||||
|
|
||||||
# Should contain both background images (overlay first from table 2, base from table 1)
|
# Should contain both background images (overlay first from table 2, base from table 1)
|
||||||
assert html =~ "background-image: url(/aprs-symbols/aprs-symbols-128-2@2x.png), url(/aprs-symbols/aprs-symbols-128-1@2x.png)"
|
assert html =~
|
||||||
|
"background-image: url(/aprs-symbols/aprs-symbols-128-2@2x.png), url(/aprs-symbols/aprs-symbols-128-1@2x.png)"
|
||||||
|
|
||||||
# Should have both background positions (overlay first, then base)
|
# Should have both background positions (overlay first, then base)
|
||||||
assert html =~ "background-position: -96.0px -64.0px, -160.0px 0.0px"
|
assert html =~ "background-position: -96.0px -64.0px, -160.0px 0.0px"
|
||||||
|
|
||||||
# Should include the callsign
|
# Should include the callsign
|
||||||
assert html =~ "W5MRC-15"
|
assert html =~ "W5MRC-15"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "render_marker_html for overlay symbol N#" do
|
test "render_marker_html for overlay symbol N#" do
|
||||||
html = AprsSymbol.render_marker_html("N", "#", "TEST-1", 32)
|
html = AprsSymbol.render_marker_html("N", "#", "TEST-1", 32)
|
||||||
|
|
||||||
# Should contain both background images (overlay first from table 2, base from table 1)
|
# Should contain both background images (overlay first from table 2, base from table 1)
|
||||||
assert html =~ "background-image: url(/aprs-symbols/aprs-symbols-128-2@2x.png), url(/aprs-symbols/aprs-symbols-128-1@2x.png)"
|
assert html =~
|
||||||
|
"background-image: url(/aprs-symbols/aprs-symbols-128-2@2x.png), url(/aprs-symbols/aprs-symbols-128-1@2x.png)"
|
||||||
|
|
||||||
# Should have both background positions (overlay first, then base)
|
# Should have both background positions (overlay first, then base)
|
||||||
assert html =~ "background-position: -416.0px -64.0px, -64.0px 0.0px"
|
assert html =~ "background-position: -416.0px -64.0px, -64.0px 0.0px"
|
||||||
|
|
||||||
# Should include the callsign
|
# Should include the callsign
|
||||||
assert html =~ "TEST-1"
|
assert html =~ "TEST-1"
|
||||||
end
|
end
|
||||||
|
|
@ -100,9 +103,9 @@ defmodule AprsmeWeb.AprsSymbolTest do
|
||||||
test "normal symbol /_" do
|
test "normal symbol /_" do
|
||||||
# Test a normal symbol from primary table
|
# Test a normal symbol from primary table
|
||||||
sprite_info = AprsSymbol.get_sprite_info("/", "_")
|
sprite_info = AprsSymbol.get_sprite_info("/", "_")
|
||||||
|
|
||||||
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-0@2x.png"
|
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-0@2x.png"
|
||||||
|
|
||||||
# Calculate expected position for _ (ASCII 95)
|
# Calculate expected position for _ (ASCII 95)
|
||||||
# index = 95 - 33 = 62
|
# index = 95 - 33 = 62
|
||||||
# column = 62 % 16 = 14
|
# column = 62 % 16 = 14
|
||||||
|
|
@ -116,9 +119,9 @@ defmodule AprsmeWeb.AprsSymbolTest do
|
||||||
test "alternate table symbol \\#" do
|
test "alternate table symbol \\#" do
|
||||||
# Test a symbol from alternate table
|
# Test a symbol from alternate table
|
||||||
sprite_info = AprsSymbol.get_sprite_info("\\", "#")
|
sprite_info = AprsSymbol.get_sprite_info("\\", "#")
|
||||||
|
|
||||||
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-1@2x.png"
|
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-1@2x.png"
|
||||||
|
|
||||||
# Calculate expected position for # (ASCII 35)
|
# Calculate expected position for # (ASCII 35)
|
||||||
# index = 35 - 33 = 2
|
# index = 35 - 33 = 2
|
||||||
# column = 2 % 16 = 2
|
# column = 2 % 16 = 2
|
||||||
|
|
@ -131,12 +134,18 @@ defmodule AprsmeWeb.AprsSymbolTest do
|
||||||
|
|
||||||
test "get_overlay_base_table_id mapping" do
|
test "get_overlay_base_table_id mapping" do
|
||||||
# Test the table mapping for overlay base symbols
|
# Test the table mapping for overlay base symbols
|
||||||
assert AprsSymbol.get_overlay_base_table_id("#") == "1" # Green star in alternate table
|
# Green star in alternate table
|
||||||
assert AprsSymbol.get_overlay_base_table_id("&") == "1" # Diamond in alternate table
|
assert AprsSymbol.get_overlay_base_table_id("#") == "1"
|
||||||
assert AprsSymbol.get_overlay_base_table_id("i") == "1" # Black square in alternate table
|
# Diamond in alternate table
|
||||||
assert AprsSymbol.get_overlay_base_table_id(">") == "1" # Arrow in alternate table
|
assert AprsSymbol.get_overlay_base_table_id("&") == "1"
|
||||||
assert AprsSymbol.get_overlay_base_table_id("^") == "1" # Arrow in alternate table
|
# Black square in alternate table
|
||||||
assert AprsSymbol.get_overlay_base_table_id("?") == "1" # Default to alternate table
|
assert AprsSymbol.get_overlay_base_table_id("i") == "1"
|
||||||
|
# Arrow in alternate table
|
||||||
|
assert AprsSymbol.get_overlay_base_table_id(">") == "1"
|
||||||
|
# Arrow in alternate table
|
||||||
|
assert AprsSymbol.get_overlay_base_table_id("^") == "1"
|
||||||
|
# Default to alternate table
|
||||||
|
assert AprsSymbol.get_overlay_base_table_id("?") == "1"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
defmodule AprsmeWeb.MapLive.OverlayRenderingTest do
|
defmodule AprsmeWeb.MapLive.OverlayRenderingTest do
|
||||||
use ExUnit.Case, async: true
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
alias AprsmeWeb.MapLive.PacketUtils
|
alias AprsmeWeb.MapLive.PacketUtils
|
||||||
|
|
||||||
describe "overlay symbol rendering in map" do
|
describe "overlay symbol rendering in map" do
|
||||||
|
|
@ -21,18 +22,19 @@ defmodule AprsmeWeb.MapLive.OverlayRenderingTest do
|
||||||
|
|
||||||
# Process the packet through PacketUtils
|
# Process the packet through PacketUtils
|
||||||
result = PacketUtils.build_packet_data(packet, true, "en-US")
|
result = PacketUtils.build_packet_data(packet, true, "en-US")
|
||||||
|
|
||||||
# Check that symbol_html was generated
|
# Check that symbol_html was generated
|
||||||
assert Map.has_key?(result, "symbol_html")
|
assert Map.has_key?(result, "symbol_html")
|
||||||
symbol_html = result["symbol_html"]
|
symbol_html = result["symbol_html"]
|
||||||
|
|
||||||
# Verify the overlay symbol is rendered correctly with overlay character on top
|
# Verify the overlay symbol is rendered correctly with overlay character on top
|
||||||
# The overlay character (D) should be first in the background-image list
|
# The overlay character (D) should be first in the background-image list
|
||||||
assert symbol_html =~ "background-image: url(/aprs-symbols/aprs-symbols-128-2@2x.png), url(/aprs-symbols/aprs-symbols-128-2@2x.png)"
|
assert symbol_html =~
|
||||||
|
"background-image: url(/aprs-symbols/aprs-symbols-128-2@2x.png), url(/aprs-symbols/aprs-symbols-128-2@2x.png)"
|
||||||
|
|
||||||
# Verify the positions (overlay character D first at -96.0px -64.0px, then base & at -160.0px 0.0px)
|
# Verify the positions (overlay character D first at -96.0px -64.0px, then base & at -160.0px 0.0px)
|
||||||
assert symbol_html =~ "background-position: -96.0px -64.0px, -160.0px 0.0px"
|
assert symbol_html =~ "background-position: -96.0px -64.0px, -160.0px 0.0px"
|
||||||
|
|
||||||
# Verify callsign is included
|
# Verify callsign is included
|
||||||
assert symbol_html =~ "W5MRC-15"
|
assert symbol_html =~ "W5MRC-15"
|
||||||
end
|
end
|
||||||
|
|
@ -56,14 +58,15 @@ defmodule AprsmeWeb.MapLive.OverlayRenderingTest do
|
||||||
# Process the packet
|
# Process the packet
|
||||||
result = PacketUtils.build_packet_data(packet, true, "en-US")
|
result = PacketUtils.build_packet_data(packet, true, "en-US")
|
||||||
symbol_html = result["symbol_html"]
|
symbol_html = result["symbol_html"]
|
||||||
|
|
||||||
# Verify the overlay uses different sprite tables
|
# Verify the overlay uses different sprite tables
|
||||||
# Overlay character N from table 2, base # from table 1
|
# Overlay character N from table 2, base # from table 1
|
||||||
assert symbol_html =~ "background-image: url(/aprs-symbols/aprs-symbols-128-2@2x.png), url(/aprs-symbols/aprs-symbols-128-1@2x.png)"
|
assert symbol_html =~
|
||||||
|
"background-image: url(/aprs-symbols/aprs-symbols-128-2@2x.png), url(/aprs-symbols/aprs-symbols-128-1@2x.png)"
|
||||||
|
|
||||||
# Verify the positions (overlay N first, then base #)
|
# Verify the positions (overlay N first, then base #)
|
||||||
assert symbol_html =~ "background-position: -416.0px -64.0px, -64.0px 0.0px"
|
assert symbol_html =~ "background-position: -416.0px -64.0px, -64.0px 0.0px"
|
||||||
|
|
||||||
# Verify callsign
|
# Verify callsign
|
||||||
assert symbol_html =~ "TEST-1"
|
assert symbol_html =~ "TEST-1"
|
||||||
end
|
end
|
||||||
|
|
@ -87,16 +90,16 @@ defmodule AprsmeWeb.MapLive.OverlayRenderingTest do
|
||||||
# Process the packet
|
# Process the packet
|
||||||
result = PacketUtils.build_packet_data(packet, true, "en-US")
|
result = PacketUtils.build_packet_data(packet, true, "en-US")
|
||||||
symbol_html = result["symbol_html"]
|
symbol_html = result["symbol_html"]
|
||||||
|
|
||||||
# Verify it's a single background image (no overlay)
|
# Verify it's a single background image (no overlay)
|
||||||
assert symbol_html =~ "background-image: url(/aprs-symbols/aprs-symbols-128-0@2x.png)"
|
assert symbol_html =~ "background-image: url(/aprs-symbols/aprs-symbols-128-0@2x.png)"
|
||||||
assert not (symbol_html =~ "background-image: url(/aprs-symbols/aprs-symbols-128-0@2x.png), url")
|
assert not (symbol_html =~ "background-image: url(/aprs-symbols/aprs-symbols-128-0@2x.png), url")
|
||||||
|
|
||||||
# Verify the position for _ symbol
|
# Verify the position for _ symbol
|
||||||
assert symbol_html =~ "background-position: -448.0px -96.0px"
|
assert symbol_html =~ "background-position: -448.0px -96.0px"
|
||||||
|
|
||||||
# Verify callsign
|
# Verify callsign
|
||||||
assert symbol_html =~ "WEATHER-1"
|
assert symbol_html =~ "WEATHER-1"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue