Save up to 17% with yearly billing

See pricing

Расстояние

Готовые к запуску примеры расчёта расстояния по ортодромии через эндпоинт Distance. Рассмотрены измерение одного маршрута и сравнение нескольких маршрутов для планирования маршрутной сети.

#ВопросИспользуемые данные
1Расстояние по ортодромии между двумя аэропортами для планирования маршрутаDistance
2Сравнение расстояний нескольких маршрутов: ранжирование маршрутов из EGLL по расстояниюDistance

Требования

Авторизация
x-api-key в каждом запросе (прямая подписка). Подробнее →

Установка

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

pip install requests rich

1. Расстояние маршрута между двумя аэропортами

Вопрос: Каково расстояние по ортодромии между KJFK и KLAX и каков начальный пеленг?

import os

import requests
from rich.console import Console
from rich.panel import Panel
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_distance(from_icao: str, to_icao: str) -> dict | None:
    r = requests.get(
        f"{BASE}/distance",
        headers=HEADERS,
        params={"from_icao": from_icao, "to_icao": to_icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()


def main() -> None:
    data = fetch_distance("KJFK", "KLAX")
    if not data:
        console.print("[yellow]No distance data returned.[/]")
        return

    table = Table(title="Route Distance")
    table.add_column("Field", style="cyan", min_width=22)
    table.add_column("Value")

    table.add_row("Origin", data.get("from_airport_name", data.get("from_icao", "—")))
    table.add_row("Destination", data.get("to_airport_name", data.get("to_icao", "—")))
    table.add_row("Distance (nm)", f"{data.get('distance_nm', '—')} nm")
    table.add_row("Distance (km)", f"{data.get('distance_km', '—')} km")
    table.add_row("Distance (mi)", f"{data.get('distance_mi', '—')} mi")
    table.add_row("Initial bearing", f"{data.get('bearing_deg', '—')}° true")

    console.print(table)
    console.print(Panel(
        "Distance shown is great-circle (shortest path on a sphere). "
        "Actual filed routes are typically longer due to airways, wind routing, and restricted airspace.",
        title="Note",
        style="dim",
    ))


if __name__ == "__main__":
    main()

Результат: Таблица с названиями аэропортов вылета и назначения, расстоянием в морских милях, километрах и сухопутных милях, а также начальным истинным пеленгом. Примечание поясняет, что расстояние по ортодромии отличается от фактических маршрутов в поданных планах полёта.


2. Ранжирование нескольких маршрутов из EGLL по расстоянию

Вопрос: Какие из четырёх направлений из лондонского Хитроу самые короткие, а какие самые длинные?

Скрипт параллельно запрашивает все маршруты, а затем сортирует их по возрастанию расстояния в морских милях.

import os
import concurrent.futures

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"

ORIGIN = "EGLL"
DESTINATIONS: list[tuple[str, str]] = [
    ("KJFK", "New York"),
    ("OMDB", "Dubai"),
    ("YSSY", "Sydney"),
    ("RJTT", "Tokyo"),
]


def fetch_distance(from_icao: str, to_icao: str) -> dict | None:
    r = requests.get(
        f"{BASE}/distance",
        headers=HEADERS,
        params={"from_icao": from_icao, "to_icao": to_icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()


def main() -> None:
    results: list[tuple[str, str, dict]] = []

    with concurrent.futures.ThreadPoolExecutor(max_workers=4) as ex:
        futures = {
            ex.submit(fetch_distance, ORIGIN, icao): (icao, city)
            for icao, city in DESTINATIONS
        }
        for fut, (icao, city) in futures.items():
            data = fut.result()
            if data:
                results.append((icao, city, data))

    results.sort(key=lambda x: x[2].get("distance_nm", float("inf")))

    table = Table(title=f"Routes from {ORIGIN} — sorted by distance")
    table.add_column("Destination", style="cyan")
    table.add_column("City")
    table.add_column("Distance (nm)", justify="right")
    table.add_column("Distance (km)", justify="right")
    table.add_column("Bearing", justify="right")

    for icao, city, data in results:
        table.add_row(
            icao,
            city,
            str(data.get("distance_nm", "—")),
            str(data.get("distance_km", "—")),
            f"{data.get('bearing_deg', '—')}°",
        )

    console.print(table)


if __name__ == "__main__":
    main()

Результат: Таблица четырёх маршрутов из EGLL, отсортированных по возрастанию расстояния в морских милях, с кодом ICAO аэропорта назначения, названием города, расстоянием в nm и km и начальным пеленгом.