# Радионавигационные средства

Интеграция поиска радионавигационных средств (navaids) — VOR, NDB, ILS и запросы по ограничивающему прямоугольнику с координатами, готовыми для карты.



Готовые к запуску примеры запросов радионавигационных средств через эндпоинт [Navaids](/docs/v31/navaids): наложение на аэронавигационную карту района вокруг аэропорта и фильтрация заходов по [ILS](https://en.wikipedia.org/wiki/Instrument_landing_system).

| # | Вопрос                                                                                       | Используемые данные |
| - | -------------------------------------------------------------------------------------------- | ------------------- |
| 1 | Список всех радионавигационных средств рядом с KJFK для наложения на аэронавигационную карту | /navaids            |
| 2 | Найти все заходы по ILS в аэропорту                                                          | /navaids            |

<DocRequirements>
  <DocRequirementAuth />
</DocRequirements>

### Установка [#install]

Приведённые ниже скрипты используют `requests` для вызовов API и `rich` для вывода в терминал. Установите один раз:

```bash
pip install requests rich
```

***

### 1. Радионавигационные средства рядом с аэропортом для наложения на карту [#1-navaids-near-an-airport-for-sectional-chart-overlay]

**Вопрос:** Перечислить все радионавигационные средства рядом с KJFK для наложения на аэронавигационную карту.

Для ОВЧ-средств ([VOR](https://en.wikipedia.org/wiki/VHF_omnidirectional_range), [VOR-DME](https://en.wikipedia.org/wiki/VHF_omnidirectional_range), VORDME, [ILS](https://en.wikipedia.org/wiki/Instrument_landing_system), LOC) возвращается `frequency_khz` — разделите значение на 1000, чтобы получить частоту в MHz, указываемую на картах. Частоты [NDB](https://en.wikipedia.org/wiki/Non-directional_beacon) остаются в kHz. Результаты сгруппированы по типу средства.

```python
import os
from collections import defaultdict

import requests
from rich.console import Console
from rich.table import Table

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"

VHF_TYPES = {"VOR", "VOR-DME", "VORDME", "ILS", "LOC", "DME", "TACAN"}


def fetch_navaids(airport: str) -> list[dict]:
    r = requests.get(
        f"{BASE}/navaids",
        headers=HEADERS,
        params={"airport": airport},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return []
    r.raise_for_status()
    return r.json().get("navaids") or []


def format_freq(navaid: dict) -> str:
    freq_khz = navaid.get("frequency_khz")
    if freq_khz is None:
        return "—"
    nav_type = navaid.get("type", "").upper()
    if nav_type in VHF_TYPES:
        return f"{freq_khz / 1000:.3f} MHz"
    return f"{freq_khz:.0f} kHz"


def main() -> None:
    navaids = fetch_navaids("KJFK")
    if not navaids:
        console.print("[yellow]No navaids found near KJFK.[/]")
        return

    grouped: dict[str, list[dict]] = defaultdict(list)
    for nav in navaids:
        grouped[nav.get("type", "UNKNOWN")].append(nav)

    for nav_type in sorted(grouped):
        table = Table(title=f"{nav_type} Navaids")
        table.add_column("Ident", style="cyan", no_wrap=True)
        table.add_column("Name")
        table.add_column("Frequency")
        table.add_column("Lat", justify="right")
        table.add_column("Lon", justify="right")

        for nav in grouped[nav_type]:
            table.add_row(
                nav.get("ident", "—"),
                nav.get("name", "—"),
                format_freq(nav),
                f"{nav.get('latitude_deg', '—')}",
                f"{nav.get('longitude_deg', '—')}",
            )

        console.print(table)


if __name__ == "__main__":
    main()
```

**Результат:** По одной таблице на каждый тип средства ([VOR](https://en.wikipedia.org/wiki/VHF_omnidirectional_range), [NDB](https://en.wikipedia.org/wiki/Non-directional_beacon), [ILS](https://en.wikipedia.org/wiki/Instrument_landing_system) и т. д.) с идентификатором, названием, частотой (MHz для ОВЧ-типов, kHz для [NDB](https://en.wikipedia.org/wiki/Non-directional_beacon)) и координатами всех радионавигационных средств рядом с KJFK.

***

### 2. Заходы по ILS в аэропорту [#2-ils-approaches-at-an-airport]

**Вопрос:** Найти все заходы по [ILS](https://en.wikipedia.org/wiki/Instrument_landing_system) в аэропорту (фильтр по типу [ILS](https://en.wikipedia.org/wiki/Instrument_landing_system)).

Фильтр `type=[ILS](https://en.wikipedia.org/wiki/Instrument_landing_system)` возвращает только средства системы посадки по приборам. В небольших и региональных аэропортах [ILS](https://en.wikipedia.org/wiki/Instrument_landing_system) часто нет — скрипт явно обрабатывает этот случай.

```python
import os

import requests
from rich.console import Console
from rich.table import Table

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"


def fetch_ils(airport: str) -> list[dict]:
    r = requests.get(
        f"{BASE}/navaids",
        headers=HEADERS,
        params={"airport": airport, "type": "ILS"},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return []
    r.raise_for_status()
    return r.json().get("navaids") or []


def main() -> None:
    icao = "EGLL"
    ils_list = fetch_ils(icao)

    if not ils_list:
        console.print(
            f"[yellow]No ILS approaches found at {icao}. "
            "Small and regional airports often rely on RNAV/GPS approaches only.[/]"
        )
        return

    table = Table(title=f"ILS Approaches — {icao}")
    table.add_column("Ident", style="cyan", no_wrap=True)
    table.add_column("Name")
    table.add_column("Frequency (MHz)", justify="right")
    table.add_column("Associated Airport")

    for ils in ils_list:
        freq_khz = ils.get("frequency_khz")
        freq_str = f"{freq_khz / 1000:.2f}" if freq_khz is not None else "—"
        table.add_row(
            ils.get("ident", "—"),
            ils.get("name", "—"),
            freq_str,
            ils.get("associated_airport", "—"),
        )

    console.print(table)
    console.print(
        f"\n[dim]{len(ils_list)} ILS approach(es) found. "
        "Ident typically encodes the runway (e.g. I-27L → Runway 27L).[/]"
    )


if __name__ == "__main__":
    main()
```

**Результат:** Таблица заходов по [ILS](https://en.wikipedia.org/wiki/Instrument_landing_system) в EGLL с идентификатором, названием, частотой курсового радиомаяка в MHz и связанным аэропортом. Внизу выводятся количество найденных заходов и подсказка о том, как по идентификатору определить ВПП.
