- Continuous path connection for long-distance travel - No distance-based filtering or gap detection - Important for aircraft, vehicles, intermittent coverage scenarios
6.1 KiB
Trail Line Display for Tracked Callsigns at Low Zoom
Problem Statement
When tracking a specific callsign (e.g., W5ISP-9), the map currently displays aggregated heat map data at zoom levels ≤ 8. This makes it impossible to see the individual path points and trajectory of the tracked station when zoomed out. Users need to see the complete path of a tracked callsign regardless of zoom level.
Solution Overview
Implement a trail line visualization that displays when tracking a specific callsign at low zoom levels (≤ 8). Instead of showing a heat map, the system will draw a polyline connecting all the station's position points in chronological order, clearly showing the path traveled.
Behavior Specification
When Tracking a Callsign
-
Zoom ≤ 8: Display trail line (polyline) connecting all positions chronologically
- Clear any existing heat map
- Fetch all packets for tracked callsign within time threshold
- Sort by timestamp (chronological order)
- Draw polyline on map
-
Zoom > 8: Display individual markers (current behavior)
- Show APRS symbols at each position
- Enable popup interactions
When NOT Tracking a Callsign
- Zoom ≤ 8: Display heat map (current behavior)
- Zoom > 8: Display individual markers (current behavior)
Technical Design
Backend Changes (Elixir)
File: lib/aprsme_web/live/map_live/display_manager.ex
-
Modify
handle_zoom_threshold_crossing/2:- Check if
socket.assigns.tracked_callsign != "" - If tracking and zoom ≤ 8: call new function to send trail line
- If tracking and zoom > 8: show markers as normal
- If not tracking: use existing heat map/marker logic
- Check if
-
Add new function
send_trail_line_for_tracked_callsign/1:- Query all packets for tracked callsign within time threshold
- Sort packets by
received_at(chronological order) - Extract coordinates (lat, lng, timestamp)
- Push event
show_trail_linewith trail data
File: lib/aprsme_web/live/map_live/index.ex
- Update bounds update logic:
- When processing bounds updates at zoom ≤ 8 with tracked callsign
- Send trail line instead of heat map
Frontend Changes (TypeScript)
File: assets/js/map.ts
-
Add state tracking:
currentTrailLine: Polyline | null- store reference to current trail line
-
Add event handler
show_trail_line:- Clear existing trail line if present
- Create Leaflet Polyline from coordinates
- Style the polyline (color, weight, opacity)
- Add to map
- Store reference in state
-
Add event handler
clear_trail_line:- Remove trail line from map
- Clear state reference
-
Update existing handlers:
show_heat_map: Clear trail line before showing heat mapshow_markers: Clear trail line before showing markersclear_all_markers: Also clear trail line
Data Structure
Trail Line Event Payload:
{
callsign: string,
points: Array<{
lat: number,
lng: number,
timestamp: string
}>
}
Visual Styling
Trail Line Appearance:
- Color:
#3B82F6(blue-500) - distinct from other map elements - Weight: 3 pixels - visible but not overwhelming
- Opacity: 0.8 - allows seeing map features underneath
- Line Cap: round - smoother appearance at endpoints
- Line Join: round - smoother corners
- Interactive: true - allow clicking for info
- Dash Pattern: none (solid line)
Optional Enhancement (Future):
- Direction arrows along the line
- Gradient color showing time progression
- Click on line to show timestamp at that point
Implementation Notes
Continuous Path Connection
- Connect all points regardless of distance: The trail line should connect all position points in chronological order, even if there are large gaps between positions
- This is important for tracking stations that:
- Travel long distances (aircraft, vehicles on highways)
- Have intermittent coverage (gaps in digipeater/igate range)
- Cross large geographic areas
- Do NOT apply distance-based filtering or gap detection
- The continuous line shows the complete journey path for the tracked callsign
Time Threshold Handling
- Use existing
socket.assigns.packet_age_thresholdfor filtering - Trail line respects the "Trail Duration" setting (1 hour, 6 hours, etc.)
- When trail duration changes, regenerate trail line
Performance Considerations
- Trail lines are only generated for tracked callsigns (not all stations)
- Polylines are efficient for rendering many points
- Clear trail line when switching away from tracked callsign
- Debounce trail line updates during rapid zoom changes
Edge Cases
- Empty trail (no packets): Don't draw anything
- Single point: Don't draw line (show marker instead)
- Zoom threshold crossing: Smoothly transition between trail and markers
- Callsign tracking cleared: Remove trail line immediately
- International date line crossing: Trail line should wrap correctly around the date line (Leaflet handles this automatically with proper coordinate ordering)
- Large distance gaps: Continue drawing line even with large geographic gaps between consecutive points
Testing Strategy
-
Manual Testing:
- Track a callsign and zoom out to ≤ 8: verify trail line appears
- Zoom in to > 8: verify markers appear
- Clear tracking: verify trail line disappears
- Change trail duration: verify trail line updates
-
Visual Testing:
- Verify trail line color and styling
- Check line smoothness and appearance
- Ensure map features remain visible underneath
-
Edge Cases:
- Callsign with no packets
- Callsign with single packet
- Callsign with very long trail (performance)
- International date line crossing
Future Enhancements
- Direction Indicators: Add small arrows along the trail to show direction of travel
- Time-based Coloring: Gradient color from old (gray) to new (bright blue)
- Interactive Points: Click on trail to see packet details at that position
- Trail Simplification: Use line simplification algorithm (Douglas-Peucker) for very long trails
- Multiple Callsigns: Support tracking multiple callsigns with different colored trails