# Стратегии загрузки данных

## API ключи

| Ключ | Где хранится | Назначение |
|------|-------------|------------|
| `FLIGHTRADAR24_API_KEY` | `.env` | FR24 Explorer API — треки, снимки позиций |
| `YANDEX_RASP_API_KEY` | `.env` | Яндекс.Расписания — табло аэропортов |

Получить Яндекс.Расписания ключ: [developer.tech.yandex.ru](https://developer.tech.yandex.ru) → подключить «Расписания» (бесплатно).

Код станции SVO в Яндекс API: **`s9600213`**

---

## Общие параметры

```
Регион:   Московская область
bbox:     lat_max=57.0, lat_min=54.0, lon_min=35.5, lon_max=40.5
Формат bounds FR24 API: "57.0,54.0,35.5,40.5"  ← ВАЖНО: порядок lat_max,lat_min,lon_min,lon_max
                                                   (не lat_min,lon_min как обычно!)

Аэропорты:
  SVO — Шереметьево  (ICAO: UUEE)
  DME — Домодедово   (ICAO: UUDD)
  VKO — Внуково      (ICAO: UUWW)
  ZIA — Жуковский    (ICAO: UUBW)
```

---

## Стратегия А — Снимки позиций (реализована ✅)

### Принцип

```
Время:  00:00  03:00  06:00  09:00  12:00  15:00  18:00  21:00
         ●      ●      ●      ●      ●      ●      ●      ●
         │      │      │      │      │      │      │      │
         └──────┴──────┴──────┴──────┴──────┴──────┴──────┘
                   8 снимков за день, интервал 3 часа
```

Для каждого снимка — запрос `/historic/flight-positions/full`:
- Возвращает все самолёты над МО в этот момент
- Фильтруем по аэропорту (orig_icao или dest_icao)
- Собираем уникальные fr24_id

Затем для каждого уникального рейса — запрос `/flight-tracks`:
- Возвращает полный трек (все точки за весь полёт)
- Фильтруем точки по bbox МО

### Смещение для увеличения охвата

```
Основной:   00:00  03:00  06:00  ...
Смещение:   01:30  04:30  07:30  ...
Вместе:     00:00  01:30  03:00  04:30  ... (интервал 1.5ч)
```

Запуск: `python fetch_airport_offset.py SVO 2026-03-21 1.5`

### Скрипты

```bash
# Основная загрузка
python fetch_airport.py SVO 2026-03-21

# Со смещением
python fetch_airport_offset.py SVO 2026-03-21 1.5

# Оба варианта дают файлы:
#   data/flights_SVO_2026-03-21.json
#   data/flights_SVO_2026-03-21_offset90m.json
```

### Расход кредитов

| Операция | Endpoint | Кол-во | Кредитов |
|----------|---------|--------|----------|
| Снимки | `/historic/flight-positions/full` | 8 снимков × ~10 рейсов | ~80 |
| Треки | `/flight-tracks` | ~40 уник. рейсов × ~74 | ~3 000 |
| **Итого за 1 аэропорт/день** | | | **~3 100** |
| 4 аэропорта × 1 день | | | ~12 400 |
| 4 аэропорта × 7 дней | | | **~87 000** ✅ |

### Охват

- ~10% рейсов при интервале 3ч
- ~20% рейсов при интервале 1.5ч (со смещением)
- Причина: рейс над МО длится 10–20 минут, между снимками 90–180 минут

---

## Стратегия Б — Табло → Треки (запланирована ⏳)

### Принцип

```
1. Парсинг табло аэропорта (бесплатно)
   svo.aero / rasp.yandex.ru / flightradar24.com
         ↓
   список callsign: SU1234, SU567, AFL123...

2. Поиск fr24_id по callsign (1 кредит/рейс)
   GET /live/flight-positions/full?callsign=SU1234
         ↓
   fr24_id: 3ed756a5

3. Загрузка полного трека (74 кредита/рейс)
   GET /flight-tracks?flight_id=3ed756a5
         ↓
   701 точка, интервал 10 секунд

4. Фильтрация по bbox МО
   ~60–120 точек из 701 (10–20 мин полёта над МО)
```

### Важные ограничения

1. **Нет API для списка рейсов по дате** — нужен парсинг сайта (хрупко)
2. **`flight-tracks` не поддерживает временной фильтр** — отдаёт весь маршрут ~700 точек
   Платим за весь трек (~74 кредита), используем только МО-часть (~35 точек)
3. **Holding patterns** — ~5–10% прилётов кружат перед посадкой → трек над МО длиннее

### Расход кредитов

| Операция | Кол-во | Кредитов |
|----------|--------|----------|
| Поиск fr24_id | ~330 рейсов | ~330 |
| Треки (полный маршрут) | ~330 × 74 | ~24 000 |
| **Итого SVO за 1 день** | | **~24 500** |
| 4 аэропорта × 1 день | | ~80 000 |
| 4 аэропорта × 7 дней | | **~560 000 ❌** |

### Реалистичный план при промо 120k

| Вариант | Кредитов | % лимита |
|---------|----------|----------|
| SVO × 1 день | 24 500 | 20% ✅ |
| SVO × 5 дней | 122 500 | 102% ⚠️ |
| SVO × 3 дня | 73 500 | 61% ✅ |
| 4 аэропорта × 1 день | 80 000 | 67% ✅ |
| 4 аэропорта × 7 дней | 560 000 | 467% ❌ |

### Реализация

**Скрипты:**
```bash
# Шаг 1: собрать табло (Яндекс.Расписания)
# → data/tablo_SVO_2026-03-21.json  (750 рейсов)
# (встроено в fetch_strategy_b.py)

# Шаг 2: дедупликация с уже загруженными треками
# → data/tablo_need_load.json  (только новые)

# Шаг 3: загрузка треков
python fetch_strategy_b.py
# → data/flights_SVO_2026-03-21_strategy_b.json
```

**Алгоритм поиска fr24_id (эффективный):**
- Группируем рейсы по времени вылета (слоты по 30 мин)
- Один запрос `/historic/flight-positions/full` на слот → покрывает 10–20 рейсов
- Матчим по callsign/flight_number из снимка
- Результат кэшируется в `data/cache_SVO_b/id_{callsign}.json`

**Яндекс.Расписания — особенности:**
- Код станции SVO: `s9600213` (найден через `/nearest_stations/`)
- Пагинация через `pagination.total` (не `total` в корне)
- Возвращает только номер рейса и авиакомпанию — аэропорт назначения в `thread.title`
- Исторические данные доступны (в отличие от FR24 публичного сайта)

---

## Сравнительная таблица

| Критерий | Стратегия А | Стратегия Б |
|----------|-------------|-------------|
| Охват рейсов | ~10–20% | ~100% |
| Точность трека | 10 сек ✅ | 10 сек ✅ |
| Кредитов/день/аэропорт | ~3 100 | ~24 500 |
| 7 дней × 4 аэропорта | ~87 000 ✅ | ~560 000 ❌ |
| Парсинг табло | Не нужен | Нужен |
| Статус | ✅ Готова | ⏳ Планируется |

---

## Текущие данные (загружено)

| Файл | Стратегия | Дата | Аэропорт | Рейсов |
|------|-----------|------|----------|--------|
| flights_SVO_2026-03-21.json | А | 21.03 | SVO | 33 |
| flights_DME_2026-03-21.json | А | 21.03 | DME | 15 |
| flights_VKO_2026-03-21.json | А | 21.03 | VKO | 21 |
| flights_ZIA_2026-03-21.json | А | 21.03 | ZIA | 1 |
| flights_SVO_2026-03-20_offset90m.json | А+смещ | 20.03 | SVO | — |
| flights_DME_2026-03-20_offset90m.json | А+смещ | 20.03 | DME | — |
| flights_VKO_2026-03-20_offset90m.json | А+смещ | 20.03 | VKO | — |
| flights_ZIA_2026-03-20_offset90m.json | А+смещ | 20.03 | ZIA | — |
| flights_SVO_2026-03-21_strategy_b.json | Б v2 | 21.03 | SVO | 111 / 20 795 |
| **ИТОГО** | | | | **258 рейсов / 50 282 точки** |

**Вспомогательные файлы:**
- `tablo_SVO_2026-03-21.json` — табло SVO 21.03 из Яндекс.Расписаний (750 рейсов = 375 вылетов × 2)
- `tablo_need_load.json` — рейсы без треков после дедупликации (684 = 342 уникальных вылета)

**Кэш треков:**
| Папка | Треков | Назначение |
|-------|--------|------------|
| `data/cache_SVO/` | 111 | SVO стратегия А + Б (общий) |
| `data/cache_DME/` | 16 | DME стратегия А |
| `data/cache_VKO/` | 21 | VKO стратегия А |
| `data/cache_ZIA/` | 1 | ZIA стратегия А |
| `data/cache_SVO_b/` | 342 | id-файлы поиска fr24_id (стратегия Б) |

---

## Расход кредитов (на 22.03.2026)

| Endpoint | Кредитов | Запросов | Назначение |
|----------|----------|----------|------------|
| `historic/flight-positions/light` | 1 717 | 18 | Ранние тесты (неверный bounds) |
| `historic/flight-positions/full` | 5 564 | ~32 | Снимки над МО |
| `flight-tracks` | 8 880 | ~120 | Треки рейсов |
| **Итого** | **~16 161** | | **13.5% промо-лимита** |
| **Остаток** | **~103 839** | | |

---

## FAQ

**Q: Почему bounds в формате lat_max,lat_min,lon_min,lon_max?**
A: FR24 API использует нестандартный порядок. Ошибка обнаружена при первой загрузке —
   с неверным форматом возвращались самолёты над США вместо МО.

**Q: Почему `flight-tracks` дорогой?**
A: API возвращает полный трек рейса (~700 точек, 10 сек интервал) без возможности
   ограничить по времени. Мы платим за 700 точек, используем ~60-120 (МО-часть).

**Q: Можно ли улучшить охват без роста стоимости?**
A: Частично — через смещение снимков. Интервал 1.5ч (стратегия А+) даёт ~20% охват
   при двойной стоимости. Фундаментально лучший охват только через стратегию Б.
