124 lines
9.7 KiB
Markdown
124 lines
9.7 KiB
Markdown
# BRD: Скачивание трека из popup на карте
|
||
|
||
**Work Item:** ET-011
|
||
**Стадия:** Анализ
|
||
**Автор:** analyst
|
||
**Дата:** 2026-06-03
|
||
|
||
---
|
||
|
||
## 1. Контекст и проблема
|
||
|
||
Пользователь (мотоциклист-эндурист) изучает карту, видит публичные GPS-треки
|
||
(слой ET-008 «Публичные треки»), тапает понравившийся трек и видит во
|
||
всплывающем окне его метаданные: название, активность, длину, точки, дату,
|
||
источники. Однако сейчас **нет способа сохранить трек к себе** — приходится
|
||
переходить по внешней ссылке источника (если она есть) и искать там кнопку
|
||
скачивания, либо вообще нет возможности (например, в OSM-источнике).
|
||
|
||
**Боль:** мотоциклист, готовясь к выезду в офлайн-режиме, не может за один
|
||
тап забрать понравившийся трек в свой GPS-навигатор (Garmin, OsmAnd,
|
||
Locus, smartphone) или планировщик.
|
||
|
||
## 2. Цель
|
||
|
||
Дать пользователю **скачать понравившийся трек прямо из popup на карте**
|
||
одним нажатием — получить файл в стандартном формате (GPX), пригодный
|
||
для импорта в любой GPS-софт.
|
||
|
||
## 3. Целевая аудитория
|
||
|
||
- Мотоциклист-эндурист, изучающий маршруты перед поездкой
|
||
- Велосипедист / турист, скачивающий чужой трек для повторного прохождения
|
||
- Турфирма / организатор, готовящая раздаточный материал
|
||
|
||
## 4. Бизнес-ценность
|
||
|
||
| Метрика | Эффект ожидаемый |
|
||
|------------------------------------------------------|-------------------------------------------------|
|
||
| Доля сессий с тапом по треку → действие | Сейчас 0% (только просмотр), цель ≥ 20% |
|
||
| Возвраты пользователя за треками | ↑ (приложение становится «полезным», а не «смотровым») |
|
||
| Конверсия публичных треков в реальные пройденные | ↑ (треки начинают перетекать в GPS) |
|
||
|
||
## 5. Область (Scope)
|
||
|
||
### В скоупе
|
||
|
||
1. **UI:** в существующем popup публичного трека (`_renderTrackPopupHtml`
|
||
в `src/web/gps_tracks.js`) появляется кнопка/иконка «Скачать».
|
||
2. **Backend:** новый эндпоинт отдачи GPX-файла по идентификатору трека
|
||
из таблицы `tracks` БД `gps_tracks.sqlite`.
|
||
3. **Формат:** GPX 1.1 — обязательно.
|
||
4. **Формат:** KML 2.2 — опционально, если бюджет позволяет (R-K-01,
|
||
см. ниже).
|
||
5. **Имя файла:** человекочитаемое, из имени трека (см. NFR-04).
|
||
|
||
### Вне скоупа
|
||
|
||
- Авторизация / приватные треки — все треки в БД публичны.
|
||
- Массовое скачивание (пачкой) — только по одному.
|
||
- Кастомизация GPX (waypoints, расширения Garmin, цвета) — отдаём
|
||
«голую» трассу.
|
||
- Скачивание загруженных пользователем GPX (ET-006) — там уже есть
|
||
кнопка скачивания в panel `sheet-gpx`, и это другой источник данных.
|
||
- Скачивание построенного маршрута (Route / Scenic / Link) — это
|
||
отдельный поток `downloadGPX()` в `sheet-route`, не трогаем.
|
||
- Регулирование rate limit и квоты — нет, трафик низкий.
|
||
|
||
## 6. Пользовательские истории
|
||
|
||
**US-1 (Mandatory):** Как мотоциклист, я хочу тапнуть трек на карте,
|
||
увидеть popup с его метаданными и нажать «Скачать», чтобы получить GPX-файл
|
||
в загрузках браузера — без перехода на сторонний сайт.
|
||
|
||
**US-2 (Mandatory):** Как пользователь мобильного браузера, я хочу получить
|
||
файл в формате, который мой телефон сразу предложит «Открыть в…» или
|
||
«Сохранить» (стандартный `Content-Disposition: attachment`).
|
||
|
||
**US-3 (Optional, R-K-01):** Как пользователь Google Earth / некоторых
|
||
старых навигаторов, я хочу выбрать формат KML вместо GPX.
|
||
|
||
**US-4 (Mandatory):** Как пользователь, я хочу, чтобы имя файла отражало
|
||
название трека (а не голый `id.gpx`), чтобы не путаться в загрузках.
|
||
|
||
## 7. Ограничения и допущения
|
||
|
||
- A1: треки в БД хранятся как WKB LineString в столбце `tracks.geom`,
|
||
координаты EPSG:4326 (lon, lat).
|
||
- A2: высоты (`ele`) в БД **не хранятся** — отдаём GPX без `<ele>`.
|
||
Время точек (`time`) — тоже не хранится, отдаём без `<time>`.
|
||
- A3: трек идентифицируется числовым `tracks.id`.
|
||
- A4: атрибуция источника (OSM / EnduroRussia / Wikiloc / ttrails) уже
|
||
попадает в popup как ссылки и должна **попасть в GPX как metadata**
|
||
(см. NFR-03).
|
||
- C1: размер ответа разумно ограничить (см. NFR-02) — кейс трека на
|
||
десятки тысяч точек редок, но возможен.
|
||
|
||
## 8. Риски
|
||
|
||
| ID | Риск | Митигация |
|
||
|--------|----------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|
|
||
| R-1 | iOS Safari не отдаёт файл по `Content-Disposition`, открывает inline | Тестировать на iOS Safari, при необходимости использовать `<a download="...">` с `URL.createObjectURL` |
|
||
| R-2 | Имя файла с кириллицей ломается в некоторых браузерах | RFC 5987 `filename*=UTF-8''...` (NFR-04) |
|
||
| R-3 | Треки с десятками тысяч точек дают тяжёлый XML (> 5 МБ) | Логировать размер, NFR-02 устанавливает потолок |
|
||
| R-4 | Лицензия источника (Wikiloc ARR) запрещает реэкспорт | Решение: для OSM (ODbL) — можно; для остальных — обсудить с Owner. См. **Открытые вопросы Q-1** |
|
||
| R-5 | Лицензия должна попасть в файл (OSM ODbL требует атрибуции) | NFR-03: metadata в GPX содержит атрибуцию источника |
|
||
|
||
## 9. Открытые вопросы для Owner
|
||
|
||
| ID | Вопрос | Дефолт (если не ответят) |
|
||
|-----|---------------------------------------------------------------------------------------------------------|-----------------------------------------------------|
|
||
| Q-1 | Можно ли отдавать треки источников Wikiloc / EnduroRussia / ttrails? Их лицензии — All Rights Reserved. | **Только OSM-источник**. Для остальных — 403 + tooltip «Источник запрещает скачивание, перейдите на сайт источника». |
|
||
| Q-2 | KML делаем в этой итерации или откладываем? | **Откладываем.** Только GPX (R-K-01 переезжает в backlog). |
|
||
| Q-3 | Кнопку рисовать иконкой (как в `sheet-route`) или текстовой кнопкой «Скачать GPX»? | **Иконка ⬇** + tooltip «Скачать GPX», по тапу на мобильных — лейбл. |
|
||
|
||
> Эти вопросы должны быть закрыты до перехода в Architecture. Если ответы
|
||
> не получены — реализация идёт по дефолтам.
|
||
|
||
## 10. Acceptance summary
|
||
|
||
См. `03-acceptance-criteria.md`. Кратко: пользователь нажимает «Скачать»
|
||
в popup трека → браузер скачивает валидный GPX 1.1 с именем
|
||
`<trail-name>.gpx`, который импортируется в OsmAnd, Garmin BaseCamp и
|
||
QGIS без ошибок.
|