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
10 changed files with 175 additions and 42 deletions
Showing only changes of commit ed1e03382a - Show all commits

Improve aircraft icons and add weight-based color coding

- Replaced simple geometric shapes with detailed, realistic SVG icons for all aircraft types
- Implemented color differentiation based on aircraft weight categories:
  * Light (<7000kg): Sky blue
  * Medium (7000-34000kg): Green
  * Large (34000-136000kg): Orange
  * Heavy (>136000kg): Red
- Created new icons for: commercial airliner, helicopter, cargo aircraft, general aviation, military fighter, ground vehicle
- Updated legend to reflect new weight-based categories
- Modified getAircraftColor() to assign colors based on aircraft category/weight

Closes #17

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Ole-Morten Duesund 2025-08-24 20:16:25 +02:00

View file

@ -268,12 +268,14 @@ body {
border: 1px solid #ffffff;
}
.legend-icon.commercial { background: #00ff88; }
.legend-icon.cargo { background: #ff8c00; }
.legend-icon.helicopter { background: #00d4ff; }
.legend-icon.military { background: #ff4444; }
.legend-icon.ga { background: #ffff00; }
.legend-icon.ground { background: #888888; }
.legend-icon.light { background: #00bfff; } /* Sky blue for light aircraft */
.legend-icon.medium { background: #00ff88; } /* Green for medium aircraft */
.legend-icon.large { background: #ff8c00; } /* Orange for large aircraft */
.legend-icon.heavy { background: #ff0000; } /* Red for heavy aircraft */
.legend-icon.helicopter { background: #ff00ff; } /* Magenta for helicopters */
.legend-icon.military { background: #ff4444; } /* Red-orange for military */
.legend-icon.ga { background: #ffff00; } /* Yellow for general aviation */
.legend-icon.ground { background: #888888; } /* Gray for ground vehicles */
.table-controls {
display: flex;

View file

@ -1,9 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(16,16)">
<!-- Wide-body cargo aircraft shape -->
<path d="M0,-12 L-10,8 L-3,8 L0,12 L3,8 L10,8 Z" fill="currentColor"/>
<!-- Fuselage bulk -->
<rect x="-2" y="-6" width="4" height="8" fill="currentColor"/>
<!-- Wide-body cargo aircraft -->
<!-- Fuselage (wider) -->
<path d="M0,-14 L-2,-11 L-2,6 L-1.5,9 L0,10 L1.5,9 L2,6 L2,-11 Z" fill="currentColor"/>
<!-- Cargo door outline -->
<rect x="-1.5" y="-2" width="3" height="4" fill="none" stroke="currentColor" stroke-width="0.3" opacity="0.5"/>
<!-- Main wings (swept back more) -->
<path d="M-1.5,1 L-13,4 L-13,6 L-1.5,3.5 Z" fill="currentColor"/>
<path d="M1.5,1 L13,4 L13,6 L1.5,3.5 Z" fill="currentColor"/>
<!-- Winglets -->
<path d="M-13,4 L-13,2 L-12,4 Z" fill="currentColor"/>
<path d="M13,4 L13,2 L12,4 Z" fill="currentColor"/>
<!-- Tail wings (larger) -->
<path d="M-1,7 L-6,9 L-6,10 L-1,9 Z" fill="currentColor"/>
<path d="M1,7 L6,9 L6,10 L1,9 Z" fill="currentColor"/>
<!-- Vertical stabilizer (taller) -->
<path d="M0,5 L-0.7,5 L-3,10 L0,10 L3,10 L0.7,5 Z" fill="currentColor"/>
<!-- Nose cone (blunter for cargo) -->
<ellipse cx="0" cy="-13" rx="2" ry="2.5" fill="currentColor"/>
<!-- Engine nacelles (4 engines for heavy cargo) -->
<ellipse cx="-5" cy="2.5" rx="1.2" ry="2.2" fill="currentColor"/>
<ellipse cx="-8" cy="3" rx="1" ry="1.8" fill="currentColor"/>
<ellipse cx="5" cy="2.5" rx="1.2" ry="2.2" fill="currentColor"/>
<ellipse cx="8" cy="3" rx="1" ry="1.8" fill="currentColor"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,7 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(16,16)">
<!-- Standard commercial aircraft shape -->
<path d="M0,-12 L-8,8 L-2,8 L0,12 L2,8 L8,8 Z" fill="currentColor"/>
<!-- Commercial airliner with more realistic proportions -->
<!-- Fuselage -->
<path d="M0,-14 L-1.5,-12 L-1.5,7 L-1,10 L0,11 L1,10 L1.5,7 L1.5,-12 Z" fill="currentColor"/>
<!-- Main wings -->
<path d="M-1,0 L-12,3 L-12,5 L-1,3 Z" fill="currentColor"/>
<path d="M1,0 L12,3 L12,5 L1,3 Z" fill="currentColor"/>
<!-- Tail wings (horizontal stabilizers) -->
<path d="M-0.8,8 L-5,9.5 L-5,10.5 L-0.8,9.5 Z" fill="currentColor"/>
<path d="M0.8,8 L5,9.5 L5,10.5 L0.8,9.5 Z" fill="currentColor"/>
<!-- Vertical stabilizer -->
<path d="M0,6 L-0.5,6 L-2,11 L0,11 L2,11 L0.5,6 Z" fill="currentColor"/>
<!-- Nose cone -->
<ellipse cx="0" cy="-13.5" rx="1.5" ry="2" fill="currentColor"/>
<!-- Engine nacelles -->
<ellipse cx="-4" cy="2" rx="1" ry="2" fill="currentColor"/>
<ellipse cx="4" cy="2" rx="1" ry="2" fill="currentColor"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -1,7 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(16,16)">
<!-- Small general aviation aircraft -->
<path d="M0,-10 L-5,6 L-1,6 L0,10 L1,6 L5,6 Z" fill="currentColor"/>
<!-- Small general aviation aircraft (Cessna-style) -->
<!-- Fuselage -->
<path d="M0,-12 L-1,-10 L-1,6 L-0.5,8 L0,9 L0.5,8 L1,6 L1,-10 Z" fill="currentColor"/>
<!-- High wings (typical of GA aircraft) -->
<path d="M-1,-2 L-10,0 L-10,1.5 L-1,0 Z" fill="currentColor"/>
<path d="M1,-2 L10,0 L10,1.5 L1,0 Z" fill="currentColor"/>
<!-- Wing struts -->
<path d="M-1,2 L-6,-1" stroke="currentColor" stroke-width="0.5"/>
<path d="M1,2 L6,-1" stroke="currentColor" stroke-width="0.5"/>
<!-- Tail wings -->
<path d="M-0.5,6 L-3.5,7.5 L-3.5,8.5 L-0.5,7.5 Z" fill="currentColor"/>
<path d="M0.5,6 L3.5,7.5 L3.5,8.5 L0.5,7.5 Z" fill="currentColor"/>
<!-- Vertical stabilizer -->
<path d="M0,5 L-0.4,5 L-1.5,9 L0,9 L1.5,9 L0.4,5 Z" fill="currentColor"/>
<!-- Propeller spinner -->
<circle cx="0" cy="-12" r="1.5" fill="currentColor"/>
<!-- Propeller blades -->
<path d="M-4,-12 L4,-12" stroke="currentColor" stroke-width="1" opacity="0.3"/>
<!-- Landing gear -->
<circle cx="-1" cy="5" r="0.8" fill="currentColor"/>
<circle cx="1" cy="5" r="0.8" fill="currentColor"/>
<circle cx="0" cy="-8" r="0.6" fill="currentColor"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,10 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(16,16)">
<!-- Ground vehicle - truck/car shape -->
<rect x="-6" y="-4" width="12" height="8" fill="currentColor" rx="2"/>
<!-- Airport ground service vehicle -->
<!-- Main body -->
<path d="M-6,-3 L-6,3 L6,3 L6,-1 L4,-3 Z" fill="currentColor"/>
<!-- Cab/cockpit -->
<path d="M4,-3 L4,1 L6,1 L6,-1 Z" fill="currentColor" opacity="0.8"/>
<!-- Windows -->
<rect x="4.5" y="-2.5" width="1" height="1.5" fill="currentColor" opacity="0.5"/>
<!-- Cargo area -->
<rect x="-5" y="-2" width="7" height="3" fill="none" stroke="currentColor" stroke-width="0.3" opacity="0.5"/>
<!-- Wheels -->
<circle cx="-3" cy="2" r="2" fill="#333"/>
<circle cx="3" cy="2" r="2" fill="#333"/>
<circle cx="-4" cy="4" r="1.5" fill="currentColor" opacity="0.7"/>
<circle cx="-1" cy="4" r="1.5" fill="currentColor" opacity="0.7"/>
<circle cx="4" cy="4" r="1.5" fill="currentColor" opacity="0.7"/>
<!-- Wheel details -->
<circle cx="-4" cy="4" r="0.5" fill="currentColor" opacity="0.4"/>
<circle cx="-1" cy="4" r="0.5" fill="currentColor" opacity="0.4"/>
<circle cx="4" cy="4" r="0.5" fill="currentColor" opacity="0.4"/>
<!-- Beacon light on top -->
<rect x="-1" y="-4" width="2" height="1" fill="currentColor" opacity="0.6"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,12 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(16,16)">
<!-- Rotor disc -->
<circle cx="0" cy="0" r="10" fill="none" stroke="currentColor" stroke-width="1" opacity="0.3"/>
<!-- Main body -->
<path d="M0,-8 L-6,6 L-1,6 L0,8 L1,6 L6,6 Z" fill="currentColor"/>
<!-- Rotor mast -->
<path d="M0,-6 L0,-10" stroke="currentColor" stroke-width="2"/>
<path d="M0,6 L0,8" stroke="currentColor" stroke-width="2"/>
<!-- Main rotor disc (animated feel) -->
<ellipse cx="0" cy="-2" rx="11" ry="1" fill="currentColor" opacity="0.2"/>
<path d="M-11,-2 L11,-2" stroke="currentColor" stroke-width="0.5" opacity="0.4"/>
<path d="M0,-13 L0,9" stroke="currentColor" stroke-width="0.5" opacity="0.4"/>
<!-- Main fuselage -->
<path d="M0,-8 C-3,-8 -4,-6 -4,-3 L-4,4 C-4,6 -3,7 -1,7 L1,7 C3,7 4,6 4,4 L4,-3 C4,-6 3,-8 0,-8 Z" fill="currentColor"/>
<!-- Cockpit windscreen -->
<path d="M0,-8 C-2,-8 -3,-7 -3,-5 L-3,-3 L3,-3 L3,-5 C3,-7 2,-8 0,-8 Z" fill="currentColor" opacity="0.7"/>
<!-- Tail boom -->
<rect x="-1" y="6" width="2" height="8" fill="currentColor"/>
<!-- Tail rotor -->
<ellipse cx="0" cy="13" rx="1" ry="3" fill="currentColor"/>
<path d="M-3,13 L3,13" stroke="currentColor" stroke-width="0.8"/>
<!-- Landing skids -->
<path d="M-3,7 L-3,9 L-1,9" stroke="currentColor" stroke-width="1" fill="none"/>
<path d="M3,7 L3,9 L1,9" stroke="currentColor" stroke-width="1" fill="none"/>
<!-- Rotor hub -->
<circle cx="0" cy="-2" r="1" fill="currentColor"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,7 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(16,16)">
<!-- Swept-wing fighter jet shape -->
<path d="M0,-12 L-4,2 L-8,8 L-2,6 L0,12 L2,6 L8,8 L4,2 Z" fill="currentColor"/>
<!-- Fighter jet with delta wings -->
<!-- Fuselage -->
<path d="M0,-14 L-0.8,-11 L-0.8,8 L0,10 L0.8,8 L0.8,-11 Z" fill="currentColor"/>
<!-- Delta wings (swept back aggressively) -->
<path d="M-0.8,2 L-10,8 L-9,9 L-0.8,5 Z" fill="currentColor"/>
<path d="M0.8,2 L10,8 L9,9 L0.8,5 Z" fill="currentColor"/>
<!-- Canards (small forward wings) -->
<path d="M-0.5,-4 L-3,-3 L-3,-2 L-0.5,-3 Z" fill="currentColor"/>
<path d="M0.5,-4 L3,-3 L3,-2 L0.5,-3 Z" fill="currentColor"/>
<!-- Vertical stabilizers (twin tails) -->
<path d="M-1,6 L-1.5,6 L-2.5,10 L-1,10 Z" fill="currentColor"/>
<path d="M1,6 L1.5,6 L2.5,10 L1,10 Z" fill="currentColor"/>
<!-- Nose cone (pointed) -->
<path d="M0,-14 L-0.8,-11 L0,-10 L0.8,-11 Z" fill="currentColor"/>
<!-- Air intakes -->
<rect x="-1.5" y="-2" width="0.7" height="3" fill="currentColor" opacity="0.7"/>
<rect x="0.8" y="-2" width="0.7" height="3" fill="currentColor" opacity="0.7"/>
<!-- Weapons hardpoints -->
<rect x="-5" y="6" width="0.5" height="2" fill="currentColor"/>
<rect x="4.5" y="6" width="0.5" height="2" fill="currentColor"/>
<!-- Exhaust nozzle -->
<ellipse cx="0" cy="9" rx="0.8" ry="1.5" fill="currentColor" opacity="0.8"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -107,19 +107,19 @@
<div class="legend">
<h4>ADS-B Categories</h4>
<div class="legend-item">
<span class="legend-icon commercial"></span>
<span class="legend-icon light"></span>
<span>Light &lt; 7000kg</span>
</div>
<div class="legend-item">
<span class="legend-icon commercial"></span>
<span class="legend-icon medium"></span>
<span>Medium 7000-34000kg</span>
</div>
<div class="legend-item">
<span class="legend-icon commercial"></span>
<span class="legend-icon large"></span>
<span>Large 34000-136000kg</span>
</div>
<div class="legend-item">
<span class="legend-icon cargo"></span>
<span class="legend-icon heavy"></span>
<span>Heavy &gt; 136000kg</span>
</div>
<div class="legend-item">

View file

@ -215,7 +215,7 @@ export class AircraftManager {
createAircraftIcon(aircraft) {
const iconType = this.getAircraftIconType(aircraft);
const color = this.getAircraftColor(iconType);
const color = this.getAircraftColor(iconType, aircraft);
const size = aircraft.OnGround ? 12 : 16;
const rotation = aircraft.Track || 0;
@ -277,16 +277,38 @@ export class AircraftManager {
return 'commercial';
}
getAircraftColor(type) {
const colors = {
commercial: '#00ff88',
cargo: '#ff8c00',
military: '#ff4444',
ga: '#ffff00',
ground: '#888888',
helicopter: '#ff00ff' // Magenta for helicopters
};
return colors[type] || colors.commercial;
getAircraftColor(type, aircraft) {
// Special colors for specific types
if (type === 'military') return '#ff4444';
if (type === 'helicopter') return '#ff00ff';
if (type === 'ground') return '#888888';
if (type === 'ga') return '#ffff00';
// For commercial and cargo types, use weight-based colors
if (aircraft && aircraft.Category) {
const cat = aircraft.Category.toLowerCase();
// Check for specific weight ranges in the category string
// Light aircraft (< 7000kg) - Sky blue
if (cat.includes('light') || cat.includes('7000kg')) {
return '#00bfff';
}
// Medium aircraft (7000-34000kg) - Green
if (cat.includes('medium 7000')) {
return '#00ff88';
}
// Large aircraft (34000-136000kg) - Orange
if (cat.includes('medium 34000') || cat.includes('large')) {
return '#ff8c00';
}
// Heavy aircraft (> 136000kg) - Red
if (cat.includes('heavy') || cat.includes('136000kg') || cat.includes('super')) {
return '#ff0000';
}
}
// Default to green for unknown commercial aircraft
return '#00ff88';
}

View file

@ -232,6 +232,11 @@ func (d *Decoder) Decode(data []byte) (*Aircraft, error) {
df := (data[0] >> 3) & 0x1F
icao := d.extractICAO(data, df)
// Debug: Log DF types to verify we're processing new formats
if df == 0 || df == 11 || df == 16 || df == 19 || df == 24 {
fmt.Printf("DEBUG: Processing new DF%d message for ICAO %06X\n", df, icao)
}
aircraft := &Aircraft{
ICAO24: icao,