wx

package
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: GPL-3.0 Imports: 33 Imported by: 0

Documentation

Index

Constants

View Source
const GetAtmosGridRPC = "SimManager.GetAtmosGrid"
View Source
const GetPrecipURLRPC = "SimManager.GetPrecipURL"
View Source
const METARFilename = "METAR-flate.msgpack.zst"

METARFilename is the standard filename for the consolidated METAR file

View Source
const ManifestFilename = "manifest-int64time.msgpack.zst"

ManifestFilename is the standard filename for int64-based compressed manifests

View Source
const NumSampleLevels = 40

This is fairly specialized to our needs we ingest from: at each lat-long, we store a vertical stack of 40 levels with samples from the source HRRR files (wind direction, speed, temperature, dewpoint, height). The vertical indexing of is low to high where LevelIndexFromId and IdFromLevelIndex perform the indexing and its inverse.

View Source
const TFRFilename = "TFRs.msgpack.zst"

TFRFilename is the standard filename for the consolidated TFR file.

Variables

View Source
var AtmosARTCCs = sync.OnceValue(func() []string {
	return util.FilterSlice(util.SortedMapKeys(av.DB.ARTCCs), func(id string) bool {
		return !slices.Contains(atmosExcludedARTCCs, id)
	})
})

AtmosARTCCs returns the ARTCCs to ingest atmos data for: all of them, minus exclusions. (Unlike TRACONs, this doesn't consider which have scenarios: center scenarios are under active development and pre-ingesting spares us historical backfills as they arrive.)

View Source
var AtmosTRACONs = sync.OnceValue(func() []string {
	tracons := util.FilterSlice(scenarioTRACONs(), func(id string) bool {
		return !slices.Contains(atmosExcludedTRACONs, id)
	})

	tracons = append(tracons, "FAI")
	slices.Sort(tracons)
	return slices.Compact(tracons)
})

AtmosTRACONs returns the TRACONs to ingest atmos data for: the ones with vice scenarios, minus exclusions.

Functions

func AtmosIntervals added in v0.13.2

func AtmosIntervals(times []time.Time) []util.TimeInterval

AtmosIntervals converts atmosphere timestamps to time intervals suitable for weather data.

func AtmosSeriesPath added in v0.15.0

func AtmosSeriesPath(facility string) string

AtmosSeriesPath returns the path to the object holding all of a facility's averaged vertical profiles as an AtmosByTimeSOA--the same thing, in the same format, as the facility's bundled resources/wx/atmos file.

func BuildObjectPath added in v0.13.2

func BuildObjectPath(prefix, identifier string, t time.Time) string

BuildObjectPath constructs a weather data object path from a prefix, identifier, and timestamp. Returns a path in the format: "prefix/identifier/{RFC3339 time}.msgpack.zst"

func CheckAtmosConversion added in v0.13.0

func CheckAtmosConversion(at AtmosByPoint, soa AtmosByPointSOA) (clampedHeights int, err error)

CheckAtmosConversion verifies that round-tripping through the SOA encoding preserves the data within quantization tolerances. The returned clampedHeights counts samples whose Height was outside the encoder's representable range (and thus lost precision); callers may want to log a warning if non-zero.

func CompressAirportMETAR added in v0.15.0

func CompressAirportMETAR(icao string, metar []METAR) ([]byte, error)

CompressAirportMETAR converts metar to SOA form, verifies that the conversion round trips, and returns the msgpack+flate encoding used for a single airport's entry in a CompressedMETAR. It is a standalone function so that callers can compress multiple airports concurrently and then store the results via SetCompressedAirportMETAR.

func FullDataDays added in v0.13.0

func FullDataDays(metar, precip, atmos []time.Time) []util.TimeInterval

FullDataDays computes time intervals where all three data sources (METAR, precip, atmos) have continuous coverage, aligned to full 24-hour periods at midnight UTC.

func GetARTCCTimeIntervals added in v0.14.1

func GetARTCCTimeIntervals() map[string][]util.TimeInterval

GetARTCCTimeIntervals returns available time intervals for ARTCCs from bundled resources. Returns a map from ARTCC id to available time intervals.

func GetCachedTFRsForARTCC added in v0.14.2

func GetCachedTFRsForARTCC(artcc string, t time.Time) ([]av.TFR, error)

GetCachedTFRsForARTCC returns TFRs from bundled resources matching the given ARTCC that are active at time t.

func GetCachedTFRsForTRACON added in v0.14.2

func GetCachedTFRsForTRACON(artcc string, center math.Point2LL,
	rangeNm float32, t time.Time) ([]av.TFR, error)

GetCachedTFRsForTRACON returns TFRs from bundled resources matching the parent ARTCC that are active at time t and geographically near center.

func GetMETAR added in v0.14.0

func GetMETAR(airports []string) (map[string]METARSOA, error)

GetMETAR returns METAR data from bundled resources for the specified airports.

func GetTFRsForARTCC added in v0.14.2

func GetTFRsForARTCC(tfrs []av.TFR, artcc string, t time.Time) []av.TFR

GetTFRsForARTCC returns all TFRs matching the given ARTCC that are active at time t (Effective <= t < Expire).

func GetTFRsForTRACON added in v0.14.2

func GetTFRsForTRACON(tfrs []av.TFR, artcc string, center math.Point2LL, rangeNm float32, t time.Time) []av.TFR

GetTFRsForTRACON returns TFRs matching the parent ARTCC that are active at time t and have at least one vertex within rangeNm of center.

func GetTRACONTimeIntervals added in v0.14.1

func GetTRACONTimeIntervals() map[string][]util.TimeInterval

GetTRACONTimeIntervals returns available time intervals for TRACONs from bundled resources. Returns a map from TRACON id to available time intervals.

func Init added in v0.14.1

func Init()

func LevelIndexFromId added in v0.13.0

func LevelIndexFromId(b []byte) int

func LoadCompressedTFRs added in v0.14.2

func LoadCompressedTFRs(r io.Reader) ([]av.TFR, error)

LoadCompressedTFRs reads msgpack+zstd compressed TFRs from r.

func METARIntervals added in v0.13.2

func METARIntervals(times []time.Time) []util.TimeInterval

METARIntervals converts METAR timestamps to time intervals suitable for weather data.

func ManifestPath added in v0.13.2

func ManifestPath(prefix string) string

ManifestPath returns the full path to a manifest file for a given prefix

func MergeAndAlignToMidnight added in v0.13.2

func MergeAndAlignToMidnight(intervals ...[]util.TimeInterval) []util.TimeInterval

MergeAndAlignToMidnight merges multiple sets of time intervals and aligns them to full 24-hour periods starting and ending at midnight UTC (0000Z).

func ParseWeatherObjectPath added in v0.13.2

func ParseWeatherObjectPath(relativePath string) (identifier string, timestamp int64, err error)

ParseWeatherObjectPath extracts the facility identifier and timestamp from a weather data object path. Expected format: "FACILITY/2025-08-06T03:00:00Z.msgpack.zst"

func PrecipIntervals added in v0.13.2

func PrecipIntervals(times []time.Time) []util.TimeInterval

PrecipIntervals converts precipitation timestamps to time intervals suitable for weather data.

func PressureFromLevelIndex added in v0.13.0

func PressureFromLevelIndex(i int) float32

PressureFromLevelIndex returns pressure in millibars at the level.

func RadarImageToDBZ

func RadarImageToDBZ(img image.Image, src PrecipSource) []byte

func SaveCompressedTFRs added in v0.14.2

func SaveCompressedTFRs(tfrs []av.TFR, w io.Writer) error

SaveCompressedTFRs writes the TFRs as msgpack+zstd to w.

Types

type AtmosByPoint added in v0.13.0

type AtmosByPoint struct {
	// Lat-longs to stack of levels
	SampleStacks map[math.Point2LL]*AtmosSampleStack
}

func MakeAtmosByPoint added in v0.13.0

func MakeAtmosByPoint() AtmosByPoint

func (AtmosByPoint) GetGrid added in v0.13.0

func (ap AtmosByPoint) GetGrid() *AtmosGrid

func (AtmosByPoint) ToSOA added in v0.13.0

func (ap AtmosByPoint) ToSOA() (AtmosByPointSOA, error)

type AtmosByPointSOA added in v0.13.0

type AtmosByPointSOA struct {
	Lat, Long []float32
	Levels    [NumSampleLevels]AtmosLevelsSOA
}

For storage, this information is encoded in structure-of-arrays format, which makes it more compressible.

func MakeFallbackAtmosFromMETAR added in v0.13.2

func MakeFallbackAtmosFromMETAR(metar METAR, location math.Point2LL) (*AtmosByPointSOA, error)

MakeFallbackAtmosFromMETAR creates a simple AtmosByPointSOA from METAR wind data. This is used as a fallback when actual atmospheric data is not available for a facility. The resulting grid has a single point at the specified location with uniform wind at all altitude levels based on the METAR surface wind.

func (AtmosByPointSOA) Average added in v0.15.0

func (atsoa AtmosByPointSOA) Average() *AtmosSampleStack

Average returns the vertical profile averaged over all of the grid's sample points, or nil if the grid is empty. Averaging the stored samples rather than the ones the grid was built from means the result depends only on the stored object, so recreating it later gives the same answer.

func (AtmosByPointSOA) ToAOS added in v0.13.0

func (atsoa AtmosByPointSOA) ToAOS() AtmosByPoint

type AtmosByTime added in v0.13.0

type AtmosByTime struct {
	SampleStacks map[time.Time]*AtmosSampleStack
}

func GetAtmosByTime added in v0.14.0

func GetAtmosByTime(facility string) (*AtmosByTime, error)

GetAtmosByTime returns atmospheric data for a facility from bundled resources.

func (*AtmosByTime) GetWindsAloftAtTime added in v0.14.0

func (at *AtmosByTime) GetWindsAloftAtTime(t time.Time, altitudeFeet float32) (direction, speed float32, ok bool)

GetWindsAloftAtTime returns wind direction (true heading, degrees) and speed (knots) at the given altitude for the given time. If no data is available, ok is false. Uses linear interpolation between pressure levels.

func (AtmosByTime) ToSOA added in v0.13.0

func (at AtmosByTime) ToSOA() (AtmosByTimeSOA, error)

type AtmosByTimeSOA added in v0.13.0

type AtmosByTimeSOA struct {
	Times  []int64 // Delta-encoded Unix timestamps
	Levels [NumSampleLevels]AtmosLevelsSOA
}

AtmosByTimeSOA stores atmospheric data for multiple time points at a single location (used for offline weather packaging)

func (AtmosByTimeSOA) ToAOS added in v0.13.0

func (atsoa AtmosByTimeSOA) ToAOS() AtmosByTime

type AtmosGrid added in v0.13.0

type AtmosGrid struct {
	Extent   math.Extent2D
	Res      [3]int
	AltRange [2]float32
	Points   []Sample
	// contains filtered or unexported fields
}

func MakeAtmosGrid added in v0.13.0

func MakeAtmosGrid(sampleStacks map[math.Point2LL]*AtmosSampleStack) *AtmosGrid

func (*AtmosGrid) AltitudeForIndex added in v0.13.0

func (g *AtmosGrid) AltitudeForIndex(idx int) float32

func (*AtmosGrid) Lookup added in v0.13.0

func (g *AtmosGrid) Lookup(p math.Point2LL, alt float32) (Sample, bool)

func (*AtmosGrid) PtToGrid added in v0.14.0

func (g *AtmosGrid) PtToGrid(p [2]float32) [2]float32

func (*AtmosGrid) SamplesAtLevel added in v0.13.0

func (g *AtmosGrid) SamplesAtLevel(level, step int) iter.Seq2[math.Point2LL, Sample]

type AtmosLevelsSOA added in v0.13.0

type AtmosLevelsSOA struct {
	// All of the following are delta encoded
	Heading     []uint8 // degrees/2
	Speed       []uint8 // knots
	Temperature []int8  // Temperature in Celsius
	Dewpoint    []int8  // Dewpoint in Celsius
	Height      []uint8 // geopotential height (MSL) + windHeightOffset in meters
}

type AtmosResult added in v0.13.0

type AtmosResult struct {
	Grid     *AtmosGrid
	Time     time.Time
	NextTime time.Time
	Err      error
}

type AtmosSample added in v0.13.0

type AtmosSample struct {
	UComponent  float32        // eastward velocity m/s
	VComponent  float32        // northward velocity m/s
	Temperature av.Temperature // temperature
	Dewpoint    av.Temperature // dewpoint
	Height      float32        // geopotential height (meters)
}

AtmosSample stores wind as velocity vectors (direction the air mass is moving). UComponent is the eastward wind velocity in m/s (positive = moving east). VComponent is the northward wind velocity in m/s (positive = moving north). These match the standard GRIB2 UGRD/VGRD convention.

type AtmosSampleStack added in v0.13.0

type AtmosSampleStack struct {
	Levels [NumSampleLevels]AtmosSample
}

type CompressedMETAR added in v0.13.2

type CompressedMETAR struct {
	// contains filtered or unexported fields
}

CompressedMETAR is a collection of compressed METAR data indexed by ICAO code.

func LoadCompressedMETAR added in v0.13.2

func LoadCompressedMETAR(r io.Reader) (CompressedMETAR, error)

LoadCompressedMETAR reads a complete compressed METAR file The reader should be the zstd-compressed msgpack file.

func NewCompressedMETAR added in v0.13.2

func NewCompressedMETAR() CompressedMETAR

NewCompressedMETAR creates a new empty CompressedMETAR collection.

func (CompressedMETAR) Airports added in v0.13.2

func (cm CompressedMETAR) Airports() iter.Seq[string]

func (*CompressedMETAR) DecodeMsgpack added in v0.14.4

func (cm *CompressedMETAR) DecodeMsgpack(dec *msgpack.Decoder) error

func (CompressedMETAR) EncodeMsgpack added in v0.14.4

func (cm CompressedMETAR) EncodeMsgpack(enc *msgpack.Encoder) error

EncodeMsgpack implements msgpack streaming encoding for CompressedMETAR. We use the streaming CustomEncoder/CustomDecoder interfaces rather than MarshalMsgpack/UnmarshalMsgpack because the buffered path internally records every byte of the value into a recovery buffer (so it can hand a complete []byte to the user's UnmarshalMsgpack) and then re-decodes it. For the multi-tens-of-MB METAR map that doubled allocations at startup; streaming avoids the intermediate buffer entirely. The on-wire format is unchanged: a msgpack map of string -> bin.

func (CompressedMETAR) GetAirportMETAR added in v0.13.2

func (cm CompressedMETAR) GetAirportMETAR(icao string) ([]METAR, error)

GetAirportMETAR retrieves and decodes METAR data for a specific ICAO airport code.

func (CompressedMETAR) GetAirportMETARSOA added in v0.13.2

func (cm CompressedMETAR) GetAirportMETARSOA(icao string) (METARSOA, error)

func (CompressedMETAR) HasAirport added in v0.15.0

func (cm CompressedMETAR) HasAirport(icao string) bool

HasAirport reports whether the collection has METAR for the given airport.

func (CompressedMETAR) Len added in v0.13.2

func (cm CompressedMETAR) Len() int

func (CompressedMETAR) RemoveAirport added in v0.15.0

func (cm CompressedMETAR) RemoveAirport(icao string)

RemoveAirport discards the collection's METAR for the given airport.

func (CompressedMETAR) Save added in v0.13.2

func (cm CompressedMETAR) Save(w io.Writer) error

SaveMETAR writes a complete METAR file (METARFilename format). The data should be a map of airport ICAO codes to compressed METARSOA data. The writer will receive zstd-compressed msgpack data.

func (CompressedMETAR) SetAirportMETAR added in v0.13.2

func (cm CompressedMETAR) SetAirportMETAR(icao string, metar []METAR) error

func (CompressedMETAR) SetCompressedAirportMETAR added in v0.15.0

func (cm CompressedMETAR) SetCompressedAirportMETAR(icao string, b []byte)

SetCompressedAirportMETAR stores an encoding previously returned by CompressAirportMETAR.

type FlightRulesFilter added in v0.14.0

type FlightRulesFilter int

FlightRulesFilter represents user preference for VMC/IMC

const (
	FlightRulesAny FlightRulesFilter = iota
	FlightRulesVMC
	FlightRulesIMC
)

type GetAtmosArgs added in v0.14.3

type GetAtmosArgs struct {
	Facility       string
	Time           time.Time
	WeatherStation string
}

type GetAtmosResult added in v0.14.3

type GetAtmosResult struct {
	AtmosByPointSOA *AtmosByPointSOA
	Time            time.Time
	NextTime        time.Time
}

type GustFilter added in v0.14.0

type GustFilter int

GustFilter represents user preference for gusting winds

const (
	GustAny GustFilter = iota
	GustYes
	GustNo
)

type METAR

type METAR struct {
	ICAO        string `json:"icaoId"`
	Time        time.Time
	Temperature av.Temperature `json:"temp"`
	Dewpoint    av.Temperature `json:"dewp"`
	Altimeter   float32        `json:"altim"`
	WindDir     *int           `json:"-"` // nil for variable winds; emitted/consumed as "wdir" by Marshal/UnmarshalJSON
	WindSpeed   int            `json:"wspd"`
	WindGust    *int           `json:"wgst"`
	Raw         string         `json:"rawOb"`
	ReportTime  string         `json:"reportTime"`
}

This is as much of the METAR as we need at runtime.

func METARForTime added in v0.13.0

func METARForTime(metar []METAR, t time.Time) METAR

func SampleMatchingMETAR added in v0.13.0

func SampleMatchingMETAR(metar []METAR, intervals []util.TimeInterval, match func(METAR) bool) *METAR

SampleMatchingMETAR randomly samples from METARs that match a predicate using reservoir sampling

func SampleWeatherWithFilter added in v0.14.0

func SampleWeatherWithFilter(
	metar []METAR,
	atmosByTime *AtmosByTime,
	intervals []util.TimeInterval,
	filter *WeatherFilter,
	windsAloftAltitudes [2]float32,
	magVar float32,
) *METAR

SampleWeatherWithFilter randomly samples a METAR that matches both ground wind filter (METAR) and winds aloft filters (atmospheric data at specified altitudes). If atmosByTime is nil, only the ground wind filter is checked. windsAloftAltitudes provides the altitude for each WindsAloft filter entry; entries with altitude 0 are skipped.

func (METAR) Altimeter_inHg

func (m METAR) Altimeter_inHg() float32

func (METAR) Ceiling added in v0.13.0

func (m METAR) Ceiling() (int, error)

Ceiling returns ceiling in feet AGL (above ground level)

func (METAR) EffectiveVisualRange added in v0.14.3

func (m METAR) EffectiveVisualRange(observerAltitudeAGL, targetAltitudeAGL float32) float32

EffectiveVisualRange returns the maximum distance (in nautical miles) at which an observer at observerAltitudeAGL can identify a target at targetAltitudeAGL, based on the METAR's surface visibility.

METAR visibility is a ground-level measurement. Aerosol concentration (and thus the extinction coefficient σ) decays exponentially with altitude: σ(z) = σ₀ × exp(-z/H), where H is the haze scale height (~2500 ft in the boundary layer). Integrating σ along the slant path between the observer and target (Beer-Lambert law), and using Koschmieder to convert METAR visibility to σ₀ (σ₀ = 3.912/V_surface), gives:

effectiveRange = surfaceVisibility / average(exp(-z/H))

where the average is taken along the line of sight. The result is capped at maxVisualRangeNM. A 15% penalty is applied when the METAR reports obscuration phenomena.

func (METAR) HasObscuration added in v0.14.3

func (m METAR) HasObscuration() bool

HasObscuration returns true if the METAR reports visibility-reducing weather phenomena such as haze, mist, fog, smoke, dust, sand, ash, or spray.

func (METAR) IsVMC added in v0.13.0

func (m METAR) IsVMC() bool

IsVMC returns true if Visual Meteorological Conditions apply VMC requires >= 3 miles visibility and >= 1000' ceiling AGL

func (METAR) MarshalJSON added in v0.14.3

func (m METAR) MarshalJSON() ([]byte, error)

MarshalJSON emits "wdir" from WindDir so JSON round-trips preserve direction.

func (METAR) Observation added in v0.14.6

func (m METAR) Observation() string

Observation returns Raw with any " RMK ..." remarks removed.

func (*METAR) UnmarshalJSON added in v0.13.0

func (m *METAR) UnmarshalJSON(data []byte) error

UnmarshalJSON reads "wdir" (number / "VRB" / null) and parses ReportTime.

func (METAR) Visibility added in v0.13.0

func (m METAR) Visibility() (float32, error)

Visibility extracts visibility in statute miles from the raw METAR

type METARSOA added in v0.13.0

type METARSOA struct {
	// These are all delta coded
	ReportTime  [][]byte
	Temperature []int16 // fixed point, one decimal digit
	Dewpoint    []int16 // fixed point, one decimal digit
	Altimeter   []int16 // fixed point, one decimal digit
	WindDir     []int16
	WindSpeed   []int16
	WindGust    []int16

	// This is not; it's not worth delta encoding the raw METAR reports
	// since there's generally not much character alignment between
	// successive reports.
	Raw []string
}

Structure-of-arrays representation of an array of METAR objects for better compressability.

func MakeMETARSOA added in v0.13.0

func MakeMETARSOA(recs []METAR) (METARSOA, error)

func (METARSOA) Check added in v0.13.2

func (soa METARSOA) Check(icao string, orig []METAR) error

func (METARSOA) Decode added in v0.13.2

func (soa METARSOA) Decode(icao string) []METAR

type Manifest added in v0.13.2

type Manifest struct {
	// contains filtered or unexported fields
}

Manifest represents a weather data manifest that maps facilities to compressed timestamps. The manifest provides efficient access to available data timestamps for each location.

func GenerateManifest added in v0.13.2

func GenerateManifest(paths map[string]int64, pathParser func(string) (string, int64, error)) (*Manifest, error)

GenerateManifest creates a manifest from a map of object paths to their sizes/timestamps. The pathParser function extracts the identifier and timestamp from each path. Timestamps are sorted, delta-encoded, and compressed for each identifier.

func GenerateManifestWithPrefix added in v0.13.2

func GenerateManifestWithPrefix(paths map[string]int64, prefix string) (*Manifest, error)

GenerateManifestWithPrefix is a convenience function that generates a manifest from paths that include a prefix. The prefix is stripped before parsing. This is commonly used with storage backends that return full paths.

func LoadManifest added in v0.13.2

func LoadManifest(r io.Reader) (*Manifest, error)

LoadManifest reads a manifest from an io.Reader. The manifest format is msgpack-encoded RawManifest, compressed with zstd.

func MakeManifest added in v0.13.2

func MakeManifest(data RawManifest) *Manifest

MakeManifest creates a manifest from raw manifest data. This is useful when loading data from storage systems.

func MakeManifestFromMap added in v0.13.2

func MakeManifestFromMap(m map[string][]time.Time) (*Manifest, error)

func NewManifest added in v0.13.2

func NewManifest() *Manifest

NewManifest creates an empty manifest with caching enabled

func (*Manifest) Count added in v0.13.2

func (m *Manifest) Count() int

Count returns the number of facilities in the manifest

func (*Manifest) Facilities added in v0.14.1

func (m *Manifest) Facilities() []string

Facilities returns a sorted list of all facility identifiers in the manifest.

func (*Manifest) GetAllTimestamps added in v0.13.2

func (m *Manifest) GetAllTimestamps() []time.Time

GetAllTimestamps returns all timestamps from all facilities in the manifest. The timestamps are collected in an unspecified order.

func (*Manifest) GetTimestamps added in v0.13.2

func (m *Manifest) GetTimestamps(identifier string) ([]time.Time, bool)

GetTimestamps retrieves and decompresses the timestamps for a specific facility. Results are cached to avoid repeated decompression. Returns nil, false if the facility is not in the manifest.

func (*Manifest) RawManifest added in v0.13.2

func (m *Manifest) RawManifest() RawManifest

RawManifest returns the underlying RawManifest for compatibility with storage systems that need the raw format.

func (*Manifest) Save added in v0.13.2

func (m *Manifest) Save(w io.Writer) error

Save writes the manifest to an io.Writer in the standard format (msgpack + zstd compression)

func (*Manifest) SetFacilityTimestamps added in v0.14.0

func (m *Manifest) SetFacilityTimestamps(facilityID string, times []time.Time) error

SetFacilityTimestamps stores timestamps for a facility (TRACON or ARTCC).

func (*Manifest) TotalEntries added in v0.13.2

func (m *Manifest) TotalEntries() int

TotalEntries returns the total number of timestamp entries across all facilities

type Model added in v0.13.0

type Model struct {
	// contains filtered or unexported fields
}

func MakeModel added in v0.13.0

func MakeModel(provider *Provider, facility string, station string, startTime time.Time, lg *log.Logger) *Model

func (*Model) GetAtmosGrid added in v0.13.0

func (m *Model) GetAtmosGrid() *AtmosGrid

func (*Model) Lookup added in v0.13.0

func (m *Model) Lookup(p math.Point2LL, alt float32, t time.Time) Sample

type Precip added in v0.13.0

type Precip struct {
	DBZ        []byte
	Resolution int
	Latitude   float32
	Longitude  float32
	NX, NY     int
	Bounds     math.Extent2D
}

Precip is the object type that is stored in GCS after wx ingest for precipitation.

func DecodePrecip added in v0.13.0

func DecodePrecip(r io.Reader) (*Precip, error)

func MakeDebugPrecip added in v0.14.6

func MakeDebugPrecip(center math.Point2LL, sideNM int) *Precip

MakeDebugPrecip returns a synthetic Precip blob shaped like an inscribed circle inside the scope's bounding square, divided into three horizontal bands so each ERAM/STARS render path lights up: severe (top, dBZ 55 → ERAM Extreme / STARS L5+), medium (middle, dBZ 45 → ERAM Heavy / STARS L3+), low (bottom, dBZ 35 → ERAM Moderate / STARS L2). Used to exercise the rendering pipeline without depending on the live precip server. sideNM is the full square side length in nautical miles; resolution is fixed at 2 px/NM.

func (Precip) BoundsLL added in v0.13.0

func (p Precip) BoundsLL() math.Extent2D

lat-long bounds

type PrecipSource added in v0.14.6

type PrecipSource string

PrecipSource identifies the provider a scraped radar image came from; the provider determines the color ramp used to recover dBZ from the image and how no-data pixels are encoded.

const (
	// PrecipSourceNWSWMS is the original opengeo.ncep.noaa.gov GeoServer
	// imagery (opaque, white background for no data). It is the zero value
	// since scrape blobs written before the Source field existed all came
	// from there.
	PrecipSourceNWSWMS PrecipSource = ""

	// PrecipSourceIEMN0Q is the Iowa Environmental Mesonet NEXRAD n0q
	// composite (transparent background for no data).
	PrecipSourceIEMN0Q PrecipSource = "iem-n0q"
)

type PrecipURL added in v0.14.3

type PrecipURL struct {
	URL      string
	NextTime time.Time
}

type PrecipURLArgs added in v0.14.3

type PrecipURLArgs struct {
	Facility string
	Time     time.Time
}

Since the server package imports wx, we need to define the details of the WX RPCs here, since wx needs to be able to call them. This is slightly messy.

type Provider added in v0.13.0

type Provider struct {
	// contains filtered or unexported fields
}

Provider is the public WX entry point for accessing historical weather data, handling fallbacks based on the local capabilities (network availability, GCS credentials, etc.)

func MakeProvider added in v0.14.3

func MakeProvider(serverAddress string, lg *log.Logger) *Provider

MakeProvider constructs the concrete WX provider.

func (*Provider) GetAtmosGrid added in v0.13.0

func (p *Provider) GetAtmosGrid(facility string, t time.Time, station string) (*AtmosByPointSOA, time.Time, time.Time, error)

GetAtmosGrid returns atmospheric grid for simulation. GCS and RPC provide full spatial grids; local fallback provides a single averaged sample. Returns atmos, its time, and the next time in the series. If station is non-empty and no atmos data is available, creates a fallback grid from that station's METAR wind data.

func (*Provider) GetPrecipURL added in v0.13.0

func (p *Provider) GetPrecipURL(facility string, t time.Time) (string, time.Time, error)

GetPrecipURL returns a URL to access the specified precipitation radar image. Returns the image at-or-before the given time.

type RawManifest added in v0.13.2

type RawManifest map[string][]byte

RawManifest is the underlying storage format for manifests. It maps facility identifiers to compressed, delta-encoded int64 Unix timestamps.

type Sample

type Sample struct {
	WindSample
	// contains filtered or unexported fields
}

func LerpSample added in v0.13.0

func LerpSample(x float32, s0, s1 Sample) Sample

func MakeSample added in v0.13.2

func MakeSample(windVec [2]float32, temperature, dewpoint, pressure float32) Sample

MakeSample creates a Sample from float32 values, quantizing them appropriately. Values are clamped to prevent overflow.

func MakeStandardSampleForAltitude added in v0.13.0

func MakeStandardSampleForAltitude(alt float32) Sample

func (Sample) Dewpoint added in v0.13.0

func (s Sample) Dewpoint() av.Temperature

Dewpoint returns the dewpoint

func (Sample) Pressure added in v0.13.0

func (s Sample) Pressure() float32

Pressure returns the pressure in millibars

func (Sample) RelativeHumidity added in v0.13.0

func (s Sample) RelativeHumidity() float32

func (Sample) String added in v0.13.0

func (s Sample) String() string

func (Sample) Temperature

func (s Sample) Temperature() av.Temperature

Temperature returns the temperature

type WeatherFilter added in v0.14.0

type WeatherFilter struct {
	FlightRules FlightRulesFilter

	// Ground wind speed range in knots (nil means no constraint)
	WindSpeedMin *int
	WindSpeedMax *int

	Gusting GustFilter

	// Ground wind direction range in magnetic degrees (nil means no constraint)
	// Uses the same wraparound logic as WindSpecifier
	WindDirMin *int
	WindDirMax *int

	// Temperature range in Celsius (nil means no constraint)
	TemperatureMin *int
	TemperatureMax *int

	// Winds aloft constraints at up to two altitudes. TRACONs use
	// WindsAloft[0] only (e.g. 5,000'). ARTCCs use both (e.g. FL240
	// and FL380).
	WindsAloft [2]WindsAloftFilter
}

WeatherFilter defines UI-specified constraints for sampling weather data. All fields are optional; nil/zero means "don't care".

func (*WeatherFilter) IsEmpty added in v0.14.0

func (wf *WeatherFilter) IsEmpty() bool

IsEmpty returns true if no filter constraints are set

func (*WeatherFilter) Matches added in v0.14.0

func (wf *WeatherFilter) Matches(metar METAR, magVar float32) bool

Matches checks if a METAR matches this weather filter

type WindSample

type WindSample struct {
	// contains filtered or unexported fields
}

func (WindSample) Component added in v0.13.0

func (s WindSample) Component(course float32) float32

Component calculates the wind component along a given course in knots. Positive values indicate tailwind, negative values indicate headwind.

func (WindSample) Deflection added in v0.13.0

func (s WindSample) Deflection(v [2]float32) float32

Deflection calculates the crab angle needed to compensate for wind. v is the desired ground track velocity vector (direction * groundspeed, in nm/hr). Returns the angle that should be subtracted from the track heading to get the aircraft heading that achieves that ground track.

func (WindSample) WindDirection added in v0.13.0

func (s WindSample) WindDirection() math.TrueHeading

func (WindSample) WindSpeed added in v0.13.0

func (s WindSample) WindSpeed() float32

func (WindSample) WindVec added in v0.13.0

func (s WindSample) WindVec() [2]float32

WindVec returns the dequantized wind velocity vector in nm/s

type WindSpecifier added in v0.13.0

type WindSpecifier struct {
	Direction   string `json:"direction,omitempty"`    // e.g., "30-90", "270", empty for any
	Speed       string `json:"speed,omitempty"`        // e.g., "5+", "5-", "5-15", empty for any
	FlightRules string `json:"flight_rules,omitempty"` // "VMC" or "IMC", empty defaults to "VMC"
}

WindSpecifier defines constraints for sampling weather data

func (*WindSpecifier) Matches added in v0.13.0

func (ws *WindSpecifier) Matches(metar METAR, magVar float32) bool

Matches checks if a METAR matches this wind specifier

func (*WindSpecifier) Validate added in v0.13.0

func (ws *WindSpecifier) Validate() error

Validate checks if the wind specifier is valid

type WindsAloftFilter added in v0.14.1

type WindsAloftFilter struct {
	SpeedMin *int // knots
	SpeedMax *int // knots
	DirMin   *int // magnetic degrees
	DirMax   *int // magnetic degrees
}

WindsAloftFilter defines constraints for winds at a specific altitude. All fields are optional; nil means "don't care".

func (*WindsAloftFilter) IsEmpty added in v0.14.1

func (f *WindsAloftFilter) IsEmpty() bool

IsEmpty returns true if no constraints are set

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL