Import Vector lab project

This commit is contained in:
root
2026-06-06 18:31:55 +00:00
commit fcc22063ed
105 changed files with 31639 additions and 0 deletions
+221
View File
@@ -0,0 +1,221 @@
# 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