Phase 1: in-memory ConnectionManager viewport fan-out, 500ms map debounce, cachetools TTLCache, background masscan/ffmpeg, compose memory caps. Phase 2: PostGIS geofences + ST_Intersects alerts, Timescale 1-min CAGGs and timestamp playback, FIRMS/WFIGS x firefighting ADS-B within 20 miles. No Redis/Kafka/Celery.
66 lines
1.9 KiB
Python
66 lines
1.9 KiB
Python
"""WFIGS/FIRMS × firefighting ADS-B correlation within 20 miles."""
|
||
|
||
from __future__ import annotations
|
||
|
||
from fire_aircraft import (
|
||
FIREFIGHTER_ICAO,
|
||
RADIUS_MILES,
|
||
correlate_aircraft_to_fires,
|
||
is_firefighter,
|
||
)
|
||
|
||
|
||
def _ac(hex_id, lat, lon, icao, **extra):
|
||
return {
|
||
"id": hex_id,
|
||
"lat": lat,
|
||
"lon": lon,
|
||
"label": hex_id,
|
||
"heading": 0,
|
||
"speed": 120,
|
||
"extra": {"type": icao, "hex": hex_id, **extra},
|
||
}
|
||
|
||
|
||
def _fire(name, lat, lon, **extra):
|
||
return {
|
||
"id": name,
|
||
"lat": lat,
|
||
"lon": lon,
|
||
"label": name,
|
||
"extra": extra,
|
||
}
|
||
|
||
|
||
def test_air_tractor_is_firefighter_airliner_is_not():
|
||
assert is_firefighter(_ac("aaa", 0, 0, "AT802")) is True
|
||
assert is_firefighter(_ac("bbb", 0, 0, "C130")) is True
|
||
assert is_firefighter(_ac("ccc", 0, 0, "B738")) is False
|
||
assert "AT802" in FIREFIGHTER_ICAO
|
||
|
||
|
||
def test_flags_tanker_within_20_miles_of_fire():
|
||
# ~10 miles north of a Piedmont fire
|
||
fire = _fire("Jones Gap", 35.00, -82.00)
|
||
tanker = _ac("acf001", 35.145, -82.00, "AT802")
|
||
airliner = _ac("a0b738", 35.145, -82.00, "B738")
|
||
far = _ac("acfar", 35.50, -82.00, "C130") # ~34 miles
|
||
hits = correlate_aircraft_to_fires([fire], [tanker, airliner, far])
|
||
assert RADIUS_MILES == 20.0
|
||
assert len(hits) == 1
|
||
h = hits[0]
|
||
assert h["aircraft_hex"] == "acf001"
|
||
assert h["fire_id"] == "Jones Gap"
|
||
assert h["aircraft_type"] == "AT802"
|
||
assert 0 < h["distance_mi"] <= 20.0
|
||
|
||
|
||
def test_persist_shape_has_reload_fields():
|
||
fire = _fire("Jones Gap", 35.00, -82.00, src="wfigs")
|
||
tanker = _ac("acf001", 35.10, -82.00, "S64")
|
||
hits = correlate_aircraft_to_fires([fire], [tanker])
|
||
assert set(hits[0]).issuperset({
|
||
"fire_id", "fire_lat", "fire_lon",
|
||
"aircraft_hex", "aircraft_type", "aircraft_lat", "aircraft_lon",
|
||
"distance_mi",
|
||
})
|