Files
vector/HEATMAP_API.md
T
2026-06-06 18:31:55 +00:00

222 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Heatmap API - Тепловые карты с кэшированием
## Endpoint
### GET /api/v1/stats/heatmap
Получить данные для тепловой карты находок с 4 типами визуализации и кэшированием на 1 час.
## Типы карт (map_type)
### 1. `all` - Все точки
Все точки с одинаковой интенсивностью (1.0).
**Использование:** Общий обзор всех находок.
**Пример:**
```bash
curl "http://localhost:8000/api/v1/stats/heatmap?map_type=all"
```
**Response:**
```json
{
"points": [
{
"lat": 53.92,
"lon": 27.58,
"intensity": 1.0,
"case_id": "uuid",
"metadata": {
"age": 10,
"season": "лето",
"outcome": "alive"
}
}
],
"total": 1,
"filters_applied": {"map_type": "all"}
}
```
### 2. `age` - По возрасту
Интенсивность зависит от возраста: младше = выше интенсивность (более критично).
**Формула:** `intensity = max(0.3, 1.0 - (age / 18.0))`
**Использование:** Приоритизация поиска младших детей.
**Пример:**
```bash
curl "http://localhost:8000/api/v1/stats/heatmap?map_type=age&age_group=8-11"
```
**Response:**
```json
{
"points": [
{
"lat": 53.92,
"lon": 27.58,
"intensity": 0.44,
"case_id": "uuid",
"metadata": {
"age": 10,
"age_group": "8-11"
}
}
],
"total": 1,
"filters_applied": {
"map_type": "age",
"age_group": "8-11"
}
}
```
### 3. `season` - По сезону
Интенсивность зависит от сезона (зима = критичнее).
**Интенсивности:**
- Зима: 1.0 (красный)
- Осень: 0.8 (оранжевый)
- Весна: 0.6 (желтый)
- Лето: 0.4 (зеленый)
**Использование:** Анализ сезонных паттернов.
**Пример:**
```bash
curl "http://localhost:8000/api/v1/stats/heatmap?map_type=season&season=зима"
```
### 4. `outcome` - По исходу
Интенсивность зависит от исхода поиска.
**Интенсивности:**
- Погиб: 1.0 (красный)
- Выжил: 0.5 (зеленый)
- Неизвестно: 0.3 (серый)
**Использование:** Анализ опасных зон.
**Пример:**
```bash
curl "http://localhost:8000/api/v1/stats/heatmap?map_type=outcome&outcome=alive"
```
**Response:**
```json
{
"points": [
{
"lat": 53.92,
"lon": 27.58,
"intensity": 0.5,
"case_id": "uuid",
"metadata": {
"outcome": "alive",
"distance_km": 2.5
}
}
],
"total": 1,
"filters_applied": {
"map_type": "outcome",
"outcome": "alive"
}
}
```
## Query Parameters (фильтры)
| Параметр | Тип | Описание | Пример |
|----------|-----|----------|--------|
| `map_type` | string | Тип карты: all, age, season, outcome | `map_type=age` |
| `age_group` | string | Возрастная группа: 0-3, 4-7, 8-11, 12-14, 15-17, 18+ | `age_group=8-11` |
| `season` | string | Сезон: зима, весна, лето, осень | `season=лето` |
| `year_from` | int | Год начала периода | `year_from=2020` |
| `year_to` | int | Год окончания периода | `year_to=2026` |
| `outcome` | string | Исход: alive, deceased | `outcome=alive` |
## Кэширование
**Механизм:** `functools.lru_cache` с автоматической инвалидацией каждый час.
**Параметры кэша:**
- Размер: 128 комбинаций параметров
- TTL: 1 час (автоматически через timestamp_hour)
- Ключ: `{map_type}_{age_group}_{season}_{year_from}_{year_to}_{outcome}_{hour}`
**Преимущества:**
- Быстрый отклик для повторных запросов
- Снижение нагрузки на БД
- Автоматическая очистка устаревших данных
## Примеры использования
### 1. Все находки за 2025 год
```bash
curl "http://localhost:8000/api/v1/stats/heatmap?map_type=all&year_from=2025&year_to=2025"
```
### 2. Младшие дети (0-7 лет) зимой
```bash
curl "http://localhost:8000/api/v1/stats/heatmap?map_type=age&age_group=0-3&season=зима"
```
### 3. Опасные зоны (погибшие)
```bash
curl "http://localhost:8000/api/v1/stats/heatmap?map_type=outcome&outcome=deceased"
```
### 4. Подростки летом (последние 3 года)
```bash
curl "http://localhost:8000/api/v1/stats/heatmap?map_type=age&age_group=12-14&season=лето&year_from=2023&year_to=2026"
```
## Интеграция с фронтендом
### Leaflet.js пример
```javascript
// Получить данные
const response = await fetch('/api/v1/stats/heatmap?map_type=age');
const data = await response.json();
// Создать heatmap слой
const heatPoints = data.points.map(p => [p.lat, p.lon, p.intensity]);
const heat = L.heatLayer(heatPoints, {
radius: 25,
blur: 15,
maxZoom: 17,
gradient: {
0.0: 'green',
0.5: 'yellow',
1.0: 'red'
}
}).addTo(map);
```
## Протестировано (2026-05-05)
✅ `map_type=all` - работает (intensity: 1.0)
✅ `map_type=age` - работает (intensity: 0.44 для 10 лет)
✅ `map_type=season` - работает
✅ `map_type=outcome` - работает (intensity: 0.5 для alive)
✅ Фильтры: age_group, season, outcome - работают
✅ Кэширование: lru_cache с TTL 1 час
## Технические детали
**Файлы:**
- `backend/services/stats_service.py` - функции `get_heatmap_with_cache()`, `get_heatmap_data_cached()`
- `backend/api/v1/stats.py` - endpoint `/heatmap`
**Зависимости:**
- `functools.lru_cache` - встроенный кэш Python
- SQLAlchemy - фильтрация по БД
- Pydantic - валидация типов
## Дата создания
2026-05-05