This commit is contained in:
@@ -32,7 +32,7 @@ type Aircraft struct {
|
||||
// indicates a non-ICAO address (TIS-B).
|
||||
Hex string `json:"hex"`
|
||||
// Type is the message source/type, e.g. "adsb_icao", "mode_s", "mlat".
|
||||
Type string `json:"type"`
|
||||
Type MessageType `json:"type"`
|
||||
// Flight is the callsign. readsb space-pads it; use Callsign for a trimmed value.
|
||||
Flight string `json:"flight,omitempty"`
|
||||
// Registration (r) and aircraft type (t) come from an optional database.
|
||||
@@ -61,9 +61,9 @@ type Aircraft struct {
|
||||
// Squawk is the Mode A code as 4 octal digits.
|
||||
Squawk string `json:"squawk,omitempty"`
|
||||
// Emergency is the emergency/priority status; "none" when not declared.
|
||||
Emergency string `json:"emergency,omitempty"`
|
||||
Emergency EmergencyStatus `json:"emergency,omitempty"`
|
||||
// Category is the emitter category, e.g. "A0".."A7", "B0".. (see README-json).
|
||||
Category string `json:"category,omitempty"`
|
||||
Category EmitterCategory `json:"category,omitempty"`
|
||||
|
||||
// Lat/Lon are the last known position in decimal degrees.
|
||||
Lat float64 `json:"lat,omitempty"`
|
||||
@@ -89,14 +89,14 @@ type Aircraft struct {
|
||||
NavModes []string `json:"nav_modes,omitempty"`
|
||||
|
||||
// ADS-B version and quality/accuracy indicators.
|
||||
Version int `json:"version,omitempty"`
|
||||
NICBaro int `json:"nic_baro,omitempty"`
|
||||
NACP int `json:"nac_p,omitempty"`
|
||||
NACV int `json:"nac_v,omitempty"`
|
||||
SIL int `json:"sil,omitempty"`
|
||||
SILType string `json:"sil_type,omitempty"`
|
||||
GVA int `json:"gva,omitempty"`
|
||||
SDA int `json:"sda,omitempty"`
|
||||
Version int `json:"version,omitempty"`
|
||||
NICBaro int `json:"nic_baro,omitempty"`
|
||||
NACP int `json:"nac_p,omitempty"`
|
||||
NACV int `json:"nac_v,omitempty"`
|
||||
SIL int `json:"sil,omitempty"`
|
||||
SILType SILType `json:"sil_type,omitempty"`
|
||||
GVA int `json:"gva,omitempty"`
|
||||
SDA int `json:"sda,omitempty"`
|
||||
|
||||
// Alert and special position identification flags.
|
||||
Alert int `json:"alert,omitempty"`
|
||||
@@ -133,7 +133,7 @@ func (a Aircraft) HasPosition() bool { return a.Lat != 0 || a.Lon != 0 }
|
||||
|
||||
// InEmergency reports whether a non-routine emergency/priority code is set.
|
||||
func (a Aircraft) InEmergency() bool {
|
||||
return a.Emergency != "" && a.Emergency != "none"
|
||||
return a.Emergency != "" && a.Emergency != EmergencyNone
|
||||
}
|
||||
|
||||
// SeenFor returns the time since the last message was received.
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package readsb
|
||||
|
||||
// MessageType is the source/type of an aircraft's data (the "type" field). It is
|
||||
// a named string so callers can compare against typed constants; it decodes from
|
||||
// and encodes to JSON exactly like a plain string. readsb lists these values in
|
||||
// descending order of trustworthiness in README-json.md.
|
||||
type MessageType string
|
||||
|
||||
const (
|
||||
TypeADSBICAO MessageType = "adsb_icao" // Mode S/ADS-B transponder, ICAO address
|
||||
TypeADSBICAONT MessageType = "adsb_icao_nt" // ADS-B non-transponder emitter, ICAO address
|
||||
TypeADSRICAO MessageType = "adsr_icao" // ADS-B rebroadcast (e.g. UAT), ICAO address
|
||||
TypeTISBICAO MessageType = "tisb_icao" // TIS-B about a non-ADS-B target, ICAO address
|
||||
TypeADSC MessageType = "adsc" // ADS-C via satellite downlink
|
||||
TypeMLAT MessageType = "mlat" // position from multilateration
|
||||
TypeOther MessageType = "other" // miscellaneous Basestation/SBS data
|
||||
TypeModeS MessageType = "mode_s" // Mode S only, no position
|
||||
TypeADSBOther MessageType = "adsb_other" // ADS-B transponder, non-ICAO address
|
||||
TypeADSROther MessageType = "adsr_other" // ADS-B rebroadcast, non-ICAO address
|
||||
TypeTISBOther MessageType = "tisb_other" // TIS-B about a non-ADS-B target, non-ICAO address
|
||||
TypeTISBTrackfile MessageType = "tisb_trackfile" // TIS-B keyed by track/file id (radar)
|
||||
)
|
||||
|
||||
// EmitterCategory is the ADS-B emitter category (the "category" field): a class
|
||||
// letter A-D and a digit 0-7. The A0/B0/C0/D0 codes mean "no category info"; the
|
||||
// remaining D codes and a few others are reserved. Decodes/encodes as a string.
|
||||
type EmitterCategory string
|
||||
|
||||
const (
|
||||
CatNoInfo EmitterCategory = "A0" // also B0/C0/D0: no category information
|
||||
|
||||
CatLight EmitterCategory = "A1" // < 15,500 lb
|
||||
CatSmall EmitterCategory = "A2" // 15,500-75,000 lb
|
||||
CatLarge EmitterCategory = "A3" // 75,000-300,000 lb
|
||||
CatHighVortex EmitterCategory = "A4" // high-vortex large, e.g. B757
|
||||
CatHeavy EmitterCategory = "A5" // > 300,000 lb
|
||||
CatHighPerf EmitterCategory = "A6" // > 5g and > 400 kt
|
||||
CatRotorcraft EmitterCategory = "A7"
|
||||
|
||||
CatGlider EmitterCategory = "B1" // glider / sailplane
|
||||
CatLighterThanAir EmitterCategory = "B2"
|
||||
CatParachutist EmitterCategory = "B3" // parachutist / skydiver
|
||||
CatUltralight EmitterCategory = "B4" // ultralight / hang-glider / paraglider
|
||||
CatUAV EmitterCategory = "B6" // unmanned aerial vehicle
|
||||
CatSpace EmitterCategory = "B7" // space / transatmospheric vehicle
|
||||
|
||||
CatSurfaceEmergency EmitterCategory = "C1" // surface vehicle, emergency
|
||||
CatSurfaceService EmitterCategory = "C2" // surface vehicle, service
|
||||
CatPointObstacle EmitterCategory = "C3" // point obstacle (incl. tethered balloons)
|
||||
CatClusterObstacle EmitterCategory = "C4"
|
||||
CatLineObstacle EmitterCategory = "C5"
|
||||
)
|
||||
|
||||
// catDescriptions maps every defined emitter code (including reserved ones) to a
|
||||
// human label. Codes absent from the map are undefined.
|
||||
var catDescriptions = map[EmitterCategory]string{
|
||||
"A0": "no information", "A1": "light", "A2": "small", "A3": "large",
|
||||
"A4": "high-vortex large", "A5": "heavy", "A6": "high performance", "A7": "rotorcraft",
|
||||
"B0": "no information", "B1": "glider/sailplane", "B2": "lighter-than-air",
|
||||
"B3": "parachutist", "B4": "ultralight", "B5": "reserved",
|
||||
"B6": "unmanned aerial vehicle", "B7": "space/transatmospheric",
|
||||
"C0": "no information", "C1": "surface emergency vehicle", "C2": "surface service vehicle",
|
||||
"C3": "point obstacle", "C4": "cluster obstacle", "C5": "line obstacle",
|
||||
"C6": "reserved", "C7": "reserved",
|
||||
"D0": "no information", "D1": "reserved", "D2": "reserved", "D3": "reserved",
|
||||
"D4": "reserved", "D5": "reserved", "D6": "reserved", "D7": "reserved",
|
||||
}
|
||||
|
||||
// Description returns the human-readable label for the emitter category, or ""
|
||||
// if the code is not a defined A0-D7 value.
|
||||
func (c EmitterCategory) Description() string { return catDescriptions[c] }
|
||||
|
||||
// EmergencyStatus is the emergency/priority status (the "emergency" field).
|
||||
// EmergencyNone means no emergency is declared. Decodes/encodes as a string.
|
||||
type EmergencyStatus string
|
||||
|
||||
const (
|
||||
EmergencyNone EmergencyStatus = "none"
|
||||
EmergencyGeneral EmergencyStatus = "general"
|
||||
EmergencyLifeguard EmergencyStatus = "lifeguard" // medical/lifeguard flight
|
||||
EmergencyMinFuel EmergencyStatus = "minfuel" // minimum fuel
|
||||
EmergencyNoRadio EmergencyStatus = "nordo" // no radio communication
|
||||
EmergencyUnlawful EmergencyStatus = "unlawful" // unlawful interference
|
||||
EmergencyDowned EmergencyStatus = "downed" // downed aircraft
|
||||
EmergencyReserved EmergencyStatus = "reserved"
|
||||
)
|
||||
|
||||
// SILType describes how the SIL (source integrity level) probability is scaled
|
||||
// (the "sil_type" field): per flight hour or per sample. Decodes/encodes as a string.
|
||||
type SILType string
|
||||
|
||||
const (
|
||||
SILUnknown SILType = "unknown"
|
||||
SILPerHour SILType = "perhour"
|
||||
SILPerSample SILType = "persample"
|
||||
)
|
||||
@@ -66,16 +66,16 @@ func WithSquawk(codes ...string) AircraftFilter {
|
||||
return func(a *Aircraft) bool { return set[strings.ToLower(a.Squawk)] }
|
||||
}
|
||||
|
||||
// WithCategory keeps aircraft of any of the given emitter categories (e.g. "A3").
|
||||
func WithCategory(cats ...string) AircraftFilter {
|
||||
set := lowerSet(nil, cats, "")
|
||||
return func(a *Aircraft) bool { return set[strings.ToLower(a.Category)] }
|
||||
// WithCategory keeps aircraft of any of the given emitter categories (e.g. CatLarge).
|
||||
func WithCategory(cats ...EmitterCategory) AircraftFilter {
|
||||
set := lowerSet(nil, strs(cats), "")
|
||||
return func(a *Aircraft) bool { return set[strings.ToLower(string(a.Category))] }
|
||||
}
|
||||
|
||||
// WithType keeps aircraft of any of the given source types (e.g. "adsb_icao", "mlat").
|
||||
func WithType(types ...string) AircraftFilter {
|
||||
set := lowerSet(nil, types, "")
|
||||
return func(a *Aircraft) bool { return set[strings.ToLower(a.Type)] }
|
||||
// WithType keeps aircraft of any of the given source types (e.g. TypeADSBICAO, TypeMLAT).
|
||||
func WithType(types ...MessageType) AircraftFilter {
|
||||
set := lowerSet(nil, strs(types), "")
|
||||
return func(a *Aircraft) bool { return set[strings.ToLower(string(a.Type))] }
|
||||
}
|
||||
|
||||
// InEmergency keeps only aircraft squawking a non-routine emergency/priority code.
|
||||
@@ -138,6 +138,15 @@ func Any(filters ...AircraftFilter) AircraftFilter {
|
||||
|
||||
// lowerSet builds a lowercased lookup set, optionally pre-processing each value
|
||||
// with trim(value, cut) when trim is non-nil.
|
||||
// strs widens a slice of any string-kind type to []string for the set helpers.
|
||||
func strs[T ~string](in []T) []string {
|
||||
out := make([]string, len(in))
|
||||
for i, v := range in {
|
||||
out[i] = string(v)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func lowerSet(trim func(string, string) string, values []string, cut string) map[string]bool {
|
||||
set := make(map[string]bool, len(values))
|
||||
for _, v := range values {
|
||||
|
||||
Reference in New Issue
Block a user