avwx.flight_path
Methods to resolve flight paths in coordinates
1""" 2Methods to resolve flight paths in coordinates 3""" 4 5# stdlib 6from typing import List, Optional, Union 7 8# library 9from geopy.distance import great_circle # type: ignore 10 11# module 12from avwx.exceptions import BadStation 13from avwx.load_utils import LazyLoad 14from avwx.station import Station 15from avwx.structs import Coord 16 17NAVAIDS = LazyLoad("navaids") 18QCoord = Union[Coord, List[Coord]] 19 20 21def _distance(near: Coord, far: Coord) -> float: 22 circle = great_circle(near.pair, far.pair).nm 23 if not isinstance(circle, float): 24 raise ValueError("Could not evaluate great circle distance") 25 return circle 26 27 28def _closest(coord: QCoord, coords: List[Coord]) -> Coord: 29 if isinstance(coord, Coord): 30 distances = [(_distance(coord, c), c) for c in coords] 31 else: 32 distances = [(_distance(c, _closest(c, coords)), c) for c in coord] 33 distances.sort(key=lambda x: x[0]) 34 return distances[0][1] 35 36 37def _best_coord( 38 previous: Optional[QCoord], 39 current: QCoord, 40 up_next: Optional[QCoord], 41) -> Coord: 42 """Determine the best coordinate based on surroundings 43 At least one of these should be a list 44 """ 45 if previous is None and up_next is None: 46 if isinstance(current, list): 47 raise ValueError("Unable to determine best coordinate") 48 return current 49 # NOTE: add handling to determine best midpoint 50 if up_next is None: 51 up_next = previous 52 if isinstance(up_next, list): 53 return _closest(current, up_next) 54 return _closest(up_next, current) # type: ignore 55 56 57def _to_coordinates( 58 values: List[Union[Coord, str]], last_value: Optional[QCoord] = None 59) -> List[Coord]: 60 if not values: 61 return [] 62 coord = values[0] 63 if isinstance(coord, str): 64 coord = coord.strip() 65 try: 66 value = coord 67 coord = Station.from_icao(coord).coord 68 coord.repr = value 69 except BadStation: 70 try: 71 coords = [Coord(lat=c[0], lon=c[1], repr=coord) for c in NAVAIDS[coord]] # type: ignore 72 except KeyError: 73 value = coord # type: ignore 74 coord = Station.from_code(coord).coord # type: ignore 75 coord.repr = value 76 else: 77 if len(coords) == 1: 78 coord = coords[0] 79 else: 80 new_coords = _to_coordinates(values[1:], coords) 81 new_coord = new_coords[0] if new_coords else None 82 coord = _best_coord(last_value, coords, new_coord) 83 return [coord] + new_coords 84 return [coord] + _to_coordinates(values[1:], coord) 85 86 87def to_coordinates(values: List[Union[Coord, str]]) -> List[Coord]: 88 """Convert any known idents found in a flight path into coordinates 89 90 Prefers Coord > ICAO > Navaid > IATA / GPS 91 """ 92 if not values: 93 return [] 94 cleaned = [] 95 for value in values: 96 if not value: 97 continue 98 if isinstance(value, str): 99 value = value.strip() 100 if not value: 101 continue 102 cleaned.append(value) 103 return _to_coordinates(values)
NAVAIDS =
<avwx.load_utils.LazyLoad object>
QCoord =
typing.Union[avwx.structs.Coord, typing.List[avwx.structs.Coord]]
88def to_coordinates(values: List[Union[Coord, str]]) -> List[Coord]: 89 """Convert any known idents found in a flight path into coordinates 90 91 Prefers Coord > ICAO > Navaid > IATA / GPS 92 """ 93 if not values: 94 return [] 95 cleaned = [] 96 for value in values: 97 if not value: 98 continue 99 if isinstance(value, str): 100 value = value.strip() 101 if not value: 102 continue 103 cleaned.append(value) 104 return _to_coordinates(values)
Convert any known idents found in a flight path into coordinates
Prefers Coord > ICAO > Navaid > IATA / GPS