- Extract all aircraft type SVG designs to separate files in /static/icons/
- Add icon caching system with async loading and fallback mechanisms
- Implement dynamic marker icon updates when aircraft properties change
- Detect and respond to aircraft type/category, ground status, and rotation changes
- Use currentColor in SVG files for dynamic color application
- Maintain performance with intelligent change detection (5° rotation threshold)
- Support real-time marker updates for weight class transitions and ADS-B changes
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace client-side trail collection with server-provided position history
- Fix aircraft markers to properly orient based on track heading using SVG rotation
- Add beast-dump binary to debian package with comprehensive man pages
- Trail visualization now uses gradient effect where newer positions are brighter
- Marker icons update when track heading changes by more than 5 degrees for performance
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major improvements to map theming and aircraft type display:
Map Theme Changes:
- Changed default map from dark to light theme (CartoDB Positron)
- Added night mode toggle button with sun/moon icons
- Both main map and coverage map now switch themes together
- Light theme provides better daylight visibility
Aircraft Type Display:
- Now displays actual ADS-B category directly (e.g., "Medium 34000-136000kg")
- Removed guessing/interpretation of aircraft types
- Icons still use simplified categories for visual distinction
- More accurate and standards-compliant display
This provides a cleaner, more professional appearance with the light map
and gives users accurate ADS-B category information instead of interpreted types.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced popup text contrast and readability:
- Added text-shadow to all values for better contrast against dark background
- Properly handle zero/null values (e.g., Track: 0° now shows instead of N/A)
- Style N/A values with slightly dimmed gray (#aaaaaa) but still clearly visible
- Add 'no-data' class to distinguish missing data from actual zero values
- Ensure all text has strong white color with !important declarations
This fixes visibility issues where some values appeared too faint or were
incorrectly treated as missing when they were actually zero.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Override Leaflet's default popup styles with !important declarations to ensure
proper text visibility in aircraft information popups:
- Set dark background (#2d2d2d) for popup content wrapper and tip
- Force white text color (#ffffff) for all popup text elements
- Ensure labels remain muted gray (#888) for visual hierarchy
- Preserve accent colors for flight ID (blue) and callsign (green)
The issue was caused by Leaflet CSS overriding custom popup styling,
resulting in poor readability with white text on white backgrounds.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove verbose console.log statements from WebSocket, map, and aircraft managers
- Keep essential error messages and warnings for debugging
- Consolidate app-new.js into app.js to eliminate confusing duplicate files
- Update HTML reference to use clean app.js with incremented cache version
- Significantly reduce console noise for better user experience
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
PROBLEM:
- Aircraft were appearing ~100km from receiver when actually ~5km away
- CPR (Compact Position Reporting) algorithm has zone ambiguity issue
- Without reference position, aircraft can appear in wrong 6-degree zones
SOLUTION:
- Add receiver reference position to CPR decoder for zone resolution
- Modified NewDecoder() to accept reference latitude/longitude parameters
- Implement distance-based zone selection (choose solution closest to receiver)
- Updated all decoder instantiations to pass receiver coordinates
TECHNICAL CHANGES:
- decoder.go: Add refLatitude/refLongitude fields and zone ambiguity resolution
- beast.go: Pass source coordinates to NewDecoder()
- beast-dump/main.go: Use default coordinates (0,0) for command-line tool
- merger.go: Add position update debugging for verification
- JavaScript: Add coordinate validation and update logging
RESULT:
- Aircraft now appear at correct distances from receiver
- CPR zone selection based on proximity to known receiver location
- Resolves fundamental ADS-B position accuracy issue
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause: The merger was blocking position updates from the same source
after the first position was established, designed for multi-source scenarios
but preventing single-source position updates.
Changes:
- Refactor JavaScript into modular architecture (WebSocketManager, AircraftManager, MapManager, UIManager)
- Add CPR coordinate validation to prevent invalid latitude/longitude values
- Fix merger to allow position updates from same source for moving aircraft
- Add comprehensive coordinate bounds checking in CPR decoder
- Update HTML to use new modular JavaScript with cache busting
- Add WebSocket debug logging to track data flow
Technical details:
- CPR decoder now validates coordinates within ±90° latitude, ±180° longitude
- Merger allows updates when currentBest == sourceID (same source continuous updates)
- JavaScript modules provide better separation of concerns and debugging
- WebSocket properly transmits updated aircraft coordinates to frontend
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major improvements to Beast message decoding and data presentation:
Speed & Track Formatting:
- Convert ground speed from float to integer (knots)
- Convert track angle from float to integer (0-359 degrees)
- Add proper rounding for velocity calculations
- Fix surface movement speed calculations
Altitude Decoding Enhancement:
- Implement proper Q-bit handling in altitude decoding
- Add altitude validation (range: -1000 to 60000 feet)
- Fix standard altitude encoding with 25-foot increments
- Add legacy Gray code support for older transponders
- Remove duplicate altitude values caused by incorrect decoding
ICAO Address Display:
- Fix JavaScript hex conversion that caused display corruption
- Remove duplicate toString(16) calls on already-formatted hex strings
- Proper ICAO display format (6-character hex like "4ACA0C")
Data Type Consistency:
- Update Aircraft struct to use integers for GroundSpeed and Track
- Update SpeedPoint struct for consistent integer speed/track storage
- Maintain float64 precision internally while displaying clean integers
Signal Strength:
- Confirm signal strength extraction is working properly
- Signal levels properly flow from Beast parser through merger to frontend
- Display in dBFS format (e.g., -1.57 dBFS)
Results:
- Clean integer speed values (198 kt instead of 238.03361107205006 kt)
- Proper track angles (41° instead of 37.83276127148023°)
- Realistic varying altitudes (1750-1825 ft instead of repeated 24450 ft)
- Correct ICAO formatting (4ACA0C instead of corrupted 103A)
- Working signal strength display (-0.98 to -2.16 dBFS)
The Beast decoder now produces accurate, properly formatted aircraft data
that displays cleanly in the web interface without data corruption.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major cleanup and documentation effort:
Code Cleanup:
- Remove 668+ lines of dead code from legacy SBS-1 implementation
- Delete unused packages: internal/config, internal/parser, internal/client/dump1090
- Remove broken test file internal/server/server_test.go
- Remove unused struct fields and imports
Code Quality:
- Format all Go code with gofmt
- Fix all go vet issues
- Fix staticcheck linting issues (error capitalization, unused fields)
- Clean up module dependencies with go mod tidy
Documentation:
- Add comprehensive godoc documentation to all packages
- Document CPR position decoding algorithm with mathematical details
- Document multi-source data fusion strategies
- Add function/method documentation with parameters and return values
- Document error handling and recovery strategies
- Add performance considerations and architectural decisions
README Updates:
- Update project structure to reflect assets/ organization
- Add new features: smart origin, Reset Map button, map controls
- Document origin configuration in config examples
- Add /api/origin endpoint to API documentation
- Update REST endpoints with /api/aircraft/{icao}
Analysis:
- Analyzed adsb-tools and go-adsb for potential improvements
- Confirmed current Beast implementation is production-ready
- Identified optional enhancements for future consideration
The codebase is now clean, well-documented, and follows Go best practices
with zero linting issues and comprehensive documentation throughout.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Move assets from internal/assets to top-level assets/ package for clean embed directive
- Consolidate all static files in single location (assets/static/)
- Remove duplicate static file locations to maintain single source of truth
- Add Reset Map button to map controls with full functionality
- Implement resetMap() method to return map to calculated origin position
- Store origin in this.mapOrigin for reset functionality
- Fix go:embed pattern to work without parent directory references
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Backend Changes:
- Added OriginConfig struct to server package
- Modified NewServer to accept origin configuration
- Added /api/origin endpoint to serve origin data to frontend
- Updated main.go to pass origin configuration to server
Frontend Changes:
- Modified initializeMap() to fetch origin from API before map creation
- Updated initializeCoverageMap() to also use origin data
- Added fallback coordinates in case API request fails
- Maps now center on the calculated origin position instead of hardcoded coordinates
The map now properly centers on the calculated average position of enabled
sources (or manually configured origin), providing a much better user experience
with appropriate regional view.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Asset Module:
- Created internal/assets package for clean embedded static file management
- Embedded static files from single source location (static/ directory)
- Eliminated need for duplicate static files or symlinks
- Assets accessible via assets.Static from any package
Origin Configuration:
- Added origin field to configuration with latitude, longitude, and name
- Automatically calculates origin as average of source positions if not specified
- Displays origin information on startup
- Updated config.example.json to show origin usage
Architecture:
- Moved main.go back to cmd/skyview/ structure
- Updated Makefile to build from cmd/skyview
- Clean separation of concerns with reusable asset module
This provides a robust foundation for asset management and proper origin
handling for distance calculations and map centering.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Clicking on tabs other than Map caused JavaScript errors due to
incorrect DOM element ID resolution in switchView() method.
Root cause: The viewId extraction from button IDs didn't match the expected
view element IDs, causing null reference errors when trying to add classes.
Solution:
- Fixed switchView() to correctly handle view IDs (e.g., "map-view")
- Added null checks for DOM elements to prevent crashes
- Updated this.currentView initialization and comparisons to match full IDs
- Ensured view-specific initialization works with correct baseName extraction
Now all tabs (Map, Table, Statistics, Coverage, 3D Radar) work without errors.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Source markers were being recreated on every WebSocket update
(every second), which destroyed any open popups.
Solution: Modified updateSourceMarkers() to:
- Only remove markers for sources that no longer exist
- Update existing markers in-place instead of recreating them
- Preserve open popups by updating content instead of recreating markers
- Only create new markers when sources are actually added
This ensures that clicking on a source marker opens a popup that stays
open for user interaction, similar to aircraft popups.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
JavaScript fixes:
- Added missing initializeClocks() method
- Added missing updatePopupContent() method for real-time popup updates
- Both methods are now properly integrated into the SkyView class
Three.js improvements:
- Migrated to ES modules for modern Three.js compatibility
- Updated import map for Three.js and OrbitControls
- Implemented full 3D radar visualization with aircraft positioning
- Added proper scene setup with lighting, ground plane, and grid
- Aircraft rendered as 3D cone meshes with altitude and orientation
- Real-time updates when switching to 3D radar view
These changes resolve all browser console errors and provide a working
3D radar visualization feature.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fixed static file path construction in staticFileHandler
- Removed duplicate 'static' prefix that was causing incorrect file paths
- Now properly serves CSS and JS files with correct MIME types
- Resolves browser security errors from MIME type mismatches
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major features implemented:
- Beast binary format parser with full Mode S/ADS-B decoding
- Multi-source data merger with intelligent signal-based fusion
- Advanced web frontend with 5 view modes (Map, Table, Stats, Coverage, 3D)
- Real-time WebSocket updates with sub-second latency
- Signal strength analysis and coverage heatmaps
- Debian packaging with systemd integration
- Production-ready deployment with security hardening
Technical highlights:
- Concurrent TCP clients with auto-reconnection
- CPR position decoding and aircraft identification
- Historical flight tracking with position trails
- Range circles and receiver location visualization
- Mobile-responsive design with professional UI
- REST API and WebSocket real-time updates
- Comprehensive build system and documentation
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add country lookup from ICAO hex codes with flag display
- Implement UTC clocks and last update time indicators
- Enhance aircraft table with ICAO, squawk, and RSSI columns
- Add color-coded RSSI signal strength indicators
- Fix calculateDistance returning string instead of number
- Accept all SBS-1 message types for complete data capture
- Improve data merging to preserve country and registration
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Store track history with position, altitude, speed, and timestamp
- Automatic track point collection every 30 seconds when position changes
- API endpoint /api/aircraft/{hex}/history for individual aircraft tracks
- Frontend "Show History" button to display historical flight paths
- Click aircraft markers to show their historical track (dashed red line)
- Track cleanup: keep last 200 points per aircraft, 24-hour retention
- Add aircraft type badges in table view with color coding
- Start/end markers for historical tracks with timestamps
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Commercial aircraft: Green airplane icon (default)
- Cargo aircraft: Orange box icon (UPS, FedEx, etc.)
- Military aircraft: Red fighter-style icon (RCH, CNV, etc.)
- General aviation: Yellow light aircraft icon
- Ground aircraft: Gray circle with 'G' indicator
- Add visual legend on map showing aircraft type colors
- Aircraft type detection based on flight number patterns
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Increase aircraft marker size from 20px to 24px
- Add aircraft wing elements for better aircraft appearance
- Use bright green color for aircraft with position data
- Add stronger drop shadow for better contrast against map
- Gray out aircraft without position data
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Switch from chart.min.js to chart.umd.js for proper module loading
- Add favicon.ico file and proper serving
- Add favicon link in HTML head to prevent 404 errors
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add custom static file handler with proper Content-Type headers
- Fix CSS and JavaScript files being served as text/plain
- Add favicon handler to prevent 404 errors
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Go application with embedded static files for dump1090 frontend
- TCP client for SBS-1/BaseStation format (port 30003)
- Real-time WebSocket updates with aircraft tracking
- Modern web frontend with Leaflet maps and mobile-responsive design
- Aircraft table with filtering/sorting and statistics dashboard
- Origin configuration for receiver location and distance calculations
- Automatic config.json loading from current directory
- Foreground execution by default with optional -daemon flag
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>