feat(2-4): implement altitude colour bands and aircraft type icons
Implements altitude_to_colour() mapping altitude bands to the 6 e-ink palette colours, and classify_aircraft_type() resolving ADS-B category, callsign prefix, and altitude fallback to AircraftType enum. Adds 21 new tests (13 parametrised boundary cases + 8 icon classification); 89 tests total, all quality gates green. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1,10 @@
|
||||
# stub
|
||||
from __future__ import annotations
|
||||
|
||||
from planemapper.constants import ALTITUDE_BANDS_FT, ALTITUDE_COLOURS
|
||||
|
||||
|
||||
def altitude_to_colour(altitude_ft: int) -> tuple[int, int, int]:
|
||||
for i, band in enumerate(ALTITUDE_BANDS_FT):
|
||||
if altitude_ft <= band:
|
||||
return ALTITUDE_COLOURS[i]
|
||||
return ALTITUDE_COLOURS[-1]
|
||||
|
||||
@@ -1 +1,71 @@
|
||||
# stub
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from planemapper.models import Aircraft
|
||||
|
||||
|
||||
class AircraftType(Enum):
|
||||
GA_LIGHT = "ga_light"
|
||||
COMMERCIAL = "commercial"
|
||||
PRIVATE_JET = "private_jet"
|
||||
AIRLINER = "airliner"
|
||||
HELICOPTER = "helicopter"
|
||||
MILITARY = "military"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
|
||||
_AIRLINE_PREFIXES: frozenset[str] = frozenset(
|
||||
{
|
||||
"BAW",
|
||||
"EIN",
|
||||
"RYR",
|
||||
"EZY",
|
||||
"THY",
|
||||
"DLH",
|
||||
"AFR",
|
||||
"IBE",
|
||||
"KLM",
|
||||
"UAE",
|
||||
"SWR",
|
||||
"AAL",
|
||||
"UAL",
|
||||
"DAL",
|
||||
"SAS",
|
||||
"TAP",
|
||||
"VLG",
|
||||
"NOS",
|
||||
"WZZ",
|
||||
"AEA",
|
||||
"NAX",
|
||||
"FIN",
|
||||
"CSN",
|
||||
"CCA",
|
||||
}
|
||||
)
|
||||
|
||||
_CATEGORY_MAP: dict[str, AircraftType] = {
|
||||
"A1": AircraftType.GA_LIGHT,
|
||||
"A2": AircraftType.GA_LIGHT,
|
||||
"A3": AircraftType.COMMERCIAL,
|
||||
"A4": AircraftType.COMMERCIAL,
|
||||
"A5": AircraftType.COMMERCIAL,
|
||||
"A7": AircraftType.HELICOPTER,
|
||||
"B1": AircraftType.MILITARY,
|
||||
"B2": AircraftType.MILITARY,
|
||||
"B3": AircraftType.MILITARY,
|
||||
"B4": AircraftType.MILITARY,
|
||||
}
|
||||
|
||||
|
||||
def classify_aircraft_type(aircraft: Aircraft) -> AircraftType:
|
||||
if aircraft.category and aircraft.category in _CATEGORY_MAP:
|
||||
return _CATEGORY_MAP[aircraft.category]
|
||||
callsign = aircraft.callsign.strip()
|
||||
if len(callsign) >= 3 and callsign[:3].upper() in _AIRLINE_PREFIXES:
|
||||
return AircraftType.COMMERCIAL
|
||||
if aircraft.altitude_ft < 10000:
|
||||
return AircraftType.GA_LIGHT
|
||||
if aircraft.altitude_ft < 30000:
|
||||
return AircraftType.PRIVATE_JET
|
||||
return AircraftType.AIRLINER
|
||||
|
||||
Reference in New Issue
Block a user