Complete Beast format implementation with enhanced features and fixes #19

Merged
olemd merged 38 commits from beast-format-refactor into main 2025-08-24 20:50:38 +02:00
5 changed files with 231 additions and 32 deletions
Showing only changes of commit da4645d483 - Show all commits

Implement server-side trail tracking and fix aircraft marker orientation

- 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>
Ole-Morten Duesund 2025-08-24 15:18:51 +02:00

View file

@ -74,16 +74,13 @@ export class AircraftManager {
const oldPos = marker.getLatLng();
marker.setLatLng(pos);
// Update rotation using Leaflet's options if available, otherwise skip rotation
// Update icon if track has changed to apply new rotation
if (aircraft.Track !== undefined) {
if (marker.setRotationAngle) {
// Use Leaflet rotation plugin method if available
marker.setRotationAngle(aircraft.Track);
} else if (marker.options) {
// Update the marker's options for consistency
marker.options.rotationAngle = aircraft.Track;
const currentRotation = marker._currentRotation || 0;
if (Math.abs(currentRotation - aircraft.Track) > 5) { // Update if rotation changed by more than 5 degrees
marker.setIcon(this.createAircraftIcon(aircraft));
marker._currentRotation = aircraft.Track;
}
// Don't manually set CSS transforms - let Leaflet handle it
}
// Handle popup exactly like Leaflet expects
@ -99,10 +96,12 @@ export class AircraftManager {
try {
const marker = L.marker(pos, {
icon: icon,
rotationAngle: aircraft.Track || 0
icon: icon
}).addTo(this.map);
// Store current rotation for future updates
marker._currentRotation = aircraft.Track || 0;
marker.bindPopup(this.createPopupContent(aircraft), {
maxWidth: 450,
className: 'aircraft-popup'
@ -124,7 +123,7 @@ export class AircraftManager {
// Update trails
if (this.showTrails) {
this.updateAircraftTrail(icao, pos);
this.updateAircraftTrail(icao, aircraft);
}
}
@ -132,6 +131,7 @@ export class AircraftManager {
const iconType = this.getAircraftIconType(aircraft);
const color = this.getAircraftColor(iconType);
const size = aircraft.OnGround ? 12 : 16;
const rotation = aircraft.Track || 0;
// Create different SVG shapes based on aircraft type
let aircraftPath;
@ -182,7 +182,7 @@ export class AircraftManager {
const svg = `
<svg width="${size * 2}" height="${size * 2}" viewBox="0 0 32 32">
<g transform="translate(16,16)">
<g transform="translate(16,16) rotate(${rotation})">
${aircraftPath}
</g>
</svg>
@ -236,33 +236,48 @@ export class AircraftManager {
}
updateAircraftTrail(icao, pos) {
updateAircraftTrail(icao, aircraft) {
// Use server-provided position history
if (!aircraft.position_history || aircraft.position_history.length < 2) {
// No trail data available or not enough points
if (this.aircraftTrails.has(icao)) {
const trail = this.aircraftTrails.get(icao);
if (trail.polyline) {
this.map.removeLayer(trail.polyline);
}
this.aircraftTrails.delete(icao);
}
return;
}
// Convert position history to Leaflet format
const trailPoints = aircraft.position_history.map(point => [point.lat, point.lon]);
// Get or create trail object
if (!this.aircraftTrails.has(icao)) {
this.aircraftTrails.set(icao, []);
this.aircraftTrails.set(icao, {});
}
const trail = this.aircraftTrails.get(icao);
trail.push(pos);
// Keep only last 50 positions
if (trail.length > 50) {
trail.shift();
// Remove old polyline if it exists
if (trail.polyline) {
this.map.removeLayer(trail.polyline);
}
// Draw polyline
const trailLine = L.polyline(trail, {
color: '#00d4ff',
weight: 2,
opacity: 0.6
}).addTo(this.map);
// Store reference for cleanup
if (!this.aircraftTrails.get(icao).polyline) {
this.aircraftTrails.get(icao).polyline = trailLine;
} else {
this.map.removeLayer(this.aircraftTrails.get(icao).polyline);
this.aircraftTrails.get(icao).polyline = trailLine;
// Create gradient effect - newer points are brighter
const segments = [];
for (let i = 1; i < trailPoints.length; i++) {
const opacity = 0.2 + (0.6 * (i / trailPoints.length)); // Fade from 0.2 to 0.8
const segment = L.polyline([trailPoints[i-1], trailPoints[i]], {
color: '#00d4ff',
weight: 2,
opacity: opacity
});
segments.push(segment);
}
// Create a feature group for all segments
trail.polyline = L.featureGroup(segments).addTo(this.map);
}
createPopupContent(aircraft) {

View file

@ -19,4 +19,5 @@ Description: Multi-source ADS-B aircraft tracker with Beast format support
- Historical flight tracking
- Mobile-responsive design
- Systemd integration for service management
- Beast-dump utility for raw ADS-B data analysis
Homepage: https://github.com/skyview/skyview

BIN
debian/usr/bin/beast-dump vendored Executable file

Binary file not shown.

95
debian/usr/share/man/man1/beast-dump.1 vendored Normal file
View file

@ -0,0 +1,95 @@
.TH BEAST-DUMP 1 "2024-08-24" "SkyView 2.0.0" "User Commands"
.SH NAME
beast-dump \- Utility for analyzing raw ADS-B data in Beast binary format
.SH SYNOPSIS
.B beast-dump
[\fIOPTIONS\fR] [\fIFILE\fR]
.SH DESCRIPTION
beast-dump is a command-line utility for analyzing and decoding ADS-B
(Automatic Dependent Surveillance-Broadcast) data stored in Beast binary
format. It can read from files or connect to Beast format TCP streams
to decode and display aircraft messages.
.PP
The Beast format is a compact binary representation of Mode S/ADS-B
messages commonly used by dump1090 and similar software-defined radio
applications for aircraft tracking.
.SH OPTIONS
.TP
.B \-host \fIstring\fR
Connect to TCP host instead of reading from file
.TP
.B \-port \fIint\fR
TCP port to connect to (default 30005)
.TP
.B \-format \fIstring\fR
Output format: text, json, or csv (default "text")
.TP
.B \-filter \fIstring\fR
Filter by ICAO hex code (e.g., "A1B2C3")
.TP
.B \-types \fIstring\fR
Message types to display (comma-separated)
.TP
.B \-count \fIint\fR
Maximum number of messages to process
.TP
.B \-stats
Show statistics summary
.TP
.B \-verbose
Enable verbose output
.TP
.B \-h, \-help
Show help message and exit
.SH EXAMPLES
.TP
Analyze Beast format file:
.B beast-dump data.bin
.TP
Connect to live Beast stream:
.B beast-dump \-host localhost \-port 30005
.TP
Export to JSON format with statistics:
.B beast-dump \-format json \-stats data.bin
.TP
Filter messages for specific aircraft:
.B beast-dump \-filter A1B2C3 \-verbose data.bin
.TP
Process only first 1000 messages as CSV:
.B beast-dump \-format csv \-count 1000 data.bin
.SH OUTPUT FORMAT
The default text output shows decoded message fields:
.PP
.nf
ICAO: A1B2C3 Type: 17 Time: 12:34:56.789
Position: 51.4700, -0.4600
Altitude: 35000 ft
Speed: 450 kt
Track: 090°
.fi
.PP
JSON output provides structured data suitable for further processing.
CSV output includes headers and is suitable for spreadsheet import.
.SH MESSAGE TYPES
Common ADS-B message types:
.IP \(bu 2
Type 4/20: Altitude and identification
.IP \(bu 2
Type 5/21: Surface position
.IP \(bu 2
Type 9/18/22: Airborne position (baro altitude)
.IP \(bu 2
Type 10/18/22: Airborne position (GNSS altitude)
.IP \(bu 2
Type 17: Extended squitter ADS-B
.IP \(bu 2
Type 19: Military extended squitter
.SH FILES
Beast format files typically use .bin or .beast extensions.
.SH SEE ALSO
.BR skyview (1),
.BR dump1090 (1)
.SH BUGS
Report bugs at: https://github.com/skyview/skyview/issues
.SH AUTHOR
SkyView Team <admin@skyview.local>

88
debian/usr/share/man/man1/skyview.1 vendored Normal file
View file

@ -0,0 +1,88 @@
.TH SKYVIEW 1 "2024-08-24" "SkyView 2.0.0" "User Commands"
.SH NAME
skyview \- Multi-source ADS-B aircraft tracker with Beast format support
.SH SYNOPSIS
.B skyview
[\fIOPTIONS\fR]
.SH DESCRIPTION
SkyView is a standalone application that connects to multiple dump1090 Beast
format TCP streams and provides a modern web frontend for aircraft tracking.
It features real-time aircraft tracking, signal strength analysis, coverage
mapping, and 3D radar visualization.
.PP
The application serves a web interface on port 8080 by default and connects
to one or more Beast format data sources (typically dump1090 instances) to
aggregate aircraft data from multiple receivers.
.SH OPTIONS
.TP
.B \-config \fIstring\fR
Path to configuration file (default "config.json")
.TP
.B \-port \fIint\fR
HTTP server port (default 8080)
.TP
.B \-debug
Enable debug logging
.TP
.B \-version
Show version information and exit
.TP
.B \-h, \-help
Show help message and exit
.SH FILES
.TP
.I /etc/skyview/config.json
System-wide configuration file
.TP
.I ~/.config/skyview/config.json
Per-user configuration file
.SH EXAMPLES
.TP
Start with default configuration:
.B skyview
.TP
Start with custom config file:
.B skyview \-config /path/to/config.json
.TP
Start on port 9090 with debug logging:
.B skyview \-port 9090 \-debug
.SH CONFIGURATION
The configuration file uses JSON format with the following structure:
.PP
.nf
{
"sources": [
{
"id": "source1",
"name": "Local Receiver",
"host": "localhost",
"port": 30005,
"latitude": 51.4700,
"longitude": -0.4600
}
],
"web": {
"port": 8080,
"assets_path": "/usr/share/skyview/assets"
}
}
.fi
.SH WEB INTERFACE
The web interface provides:
.IP \(bu 2
Interactive map view with aircraft markers
.IP \(bu 2
Aircraft data table with filtering and sorting
.IP \(bu 2
Real-time statistics and charts
.IP \(bu 2
Coverage heatmaps and range circles
.IP \(bu 2
3D radar visualization
.SH SEE ALSO
.BR beast-dump (1),
.BR dump1090 (1)
.SH BUGS
Report bugs at: https://github.com/skyview/skyview/issues
.SH AUTHOR
SkyView Team <admin@skyview.local>