Правки по код-ревью ET-006 (docs/work-items/ET-006/12-review.md):
- P1-1: trackStats считал min/max высот через Math.min/max.apply — на
треках в сотни тысяч точек это бросало RangeError и валило загрузку
файла (нарушение REQ-NF-01). Расчёт переписан на однопроходный
аккумулятор (makeStatsAccumulator/accumulatePoint/finalizeStats)
без apply.
- P2-1: статистика и профиль высот учитывали только tracks[0].
Добавлены aggregateStats() и buildFileProfileSamples() — сводка и
профиль теперь охватывают все треки файла (REQ-F-09, AC-02).
- P2-2: расчёт статистики на async-пути парсинга вынесен в чанковый
trackStatsChunked() — соответствие букве ADR-003 §2.
- P3-1: ось и tooltip профиля высот форматируют расстояние через
formatKm() — согласование с выбором км/мили из ET-005.
- P3-2: childText() переименована в firstTagText() — имя соответствует
фактическому поведению (поиск по всем потомкам).
- P3-4: убран дублирующийся 'use strict'.
Добавлены регрессионные unit-тесты: большой трек без падения,
эквивалентность trackStatsChunked синхронному trackStats (в т.ч. на
треке длиннее размера чанка), агрегация статистики и профиля по
многотрековому файлу.
Refs: ET-006
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Добавляет сегментированный toggle км/мили в попап рельефа. Новый модуль
src/web/units.js — единственный источник истины по выбору единицы, её
персистентности (localStorage: distance_unit, дефолт km) и форматированию
отображаемых расстояний (Units.formatDistance).
Все места форматирования в app.js переведены на централизованный
форматтер; пересчёт всех видимых расстояний выполняет единый оркестратор
onUnitChange по событию unitchange (карточки маршрутов, лист точек,
линейка, масштабная линейка, связка, «красивый» маршрут).
Экспорт GPX и параметры построения маршрута остаются метрическими
(риск R6). units.js подключается строго перед app.js (риск R7).
Refs: ET-005
Adds a «POI» checkbox to the terrain popup that toggles the
poi-circles and poi-labels layers via map.setLayoutProperty. The
choice is persisted in localStorage (key `poi-visible`) and restored
on page load and after style changes, kept consistent with the
runtime layerState.poi per ADR-0001.
Tests: behavioral JS unit tests (TP-01..TP-04) run via `node --test`,
wrapped by tests/unit/test_poi_toggle.py with static structure checks
so they execute under the existing `pytest tests/` CI step.
Refs: ET-002
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- enduro.lua: блокировка нод barrier=gate|bollard|lift_gate|chain|cycle_barrier|
motorcycle_barrier|border_control|block через mode.inaccessible (ADR-001).
cattle_grid и ford остаются проезжими.
- enduro.lua: highway=footway|pedestrian|steps|corridor полностью исключены
из графа (early return в process_way). Эти типы удалены из highway_rate
и highway_speeds, чтобы профиль был самодостаточным.
- scripts/rebuild-osrm.sh: пересборка графа (extract → partition → customize)
и рестарт контейнера osrm-routed.
- tests/integration/test_routing_barriers.py: 7 тестов (TC-001..TC-005 +
статический анализ blocked_barriers/excluded_highways). Интеграционные тесты
скипаются если OSRM не доступен.
Refs: ET-001