feat(gps-tracks): lower public-tracks minzoom to z5 (ET-012)
All checks were successful
All checks were successful
Калибровка существующих tier-таблиц `build_gps_mvt` / `_simplify_coords` (ADR-016), чтобы при первом открытии карты пользователь видел общее покрытие сети треков, а не пустую подложку. Backend (src/api/gps_tracks/mvt.py): - build_gps_mvt: добавлены тиры z<=5 (min_length=10 км, limit=1500) и z=6 (5 км / 2000); z=7+ — без изменений (регрессия). - _simplify_coords: tolerance для z=6 = 0.018° (~2 км), для z<=5 = 0.04° (~4 км); z=7+ не меняется. Frontend: - GPS_TRACKS_MIN_ZOOM понижен с 8 до 5; vector-source.minzoom подхватывает константу автоматически. - line-width / halo получили stop на z=5 (0.8 / 1.8 CSS-px), чтобы линия была читаема на любом DPR. - Hint #public-tracks-zoom-hint: «Зум 8+» → «Зум 5+». Тесты: - 8 unit zoom-tier (UT-Z5/6/7/8/12) — REQ-F-09. - 10 unit simplify (UT-SIMP-*) — REQ-F-10. - 9 integration endpoint z5-z7 (IT-Z5/6/7, CACHE, REGRESS) — REQ-F-11/12. - 2 perf (PERF-Z5-01/02; avg ~64 ms, p95 ~89 ms при 500 треках — ниже бюджета 200/500 ms по M-6) — REQ-F-13. Маркер @pytest.mark.perf, не в основном CI-gate. Контракт API /api/gps-tracks* не меняется (REQ-F-15); localStorage-ключи и конфиги тоже (REQ-F-16, F-18). Refs: ET-012 ADR: docs/work-items/ET-012/06-adr/ADR-016-z5-tiling-policy.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,15 +31,28 @@ def clear_gps_tile_cache() -> None:
|
||||
# ─── Geometry helpers ────────────────────────────────────────────────────────
|
||||
|
||||
def _simplify_coords(coords: list, z: int) -> list:
|
||||
"""Упрощает геометрию трека по зуму через Douglas-Peucker."""
|
||||
"""Упрощает геометрию трека по зуму через Douglas-Peucker.
|
||||
|
||||
Tolerance задаётся в градусах WGS84. На широте 55° с.ш. 1° долготы
|
||||
≈ 64 км, поэтому tolerance=0.04 ≈ 2.6 км. На z5 один пиксель карты
|
||||
≈ 5 км по долготе на 55° с.ш., так что 2.6 км даёт «одна точка на
|
||||
пиксель» — оптимум обзорного зума.
|
||||
|
||||
ET-012 (ADR-016): добавлены тиры z==6 и z<=5; для z>=7 поведение
|
||||
не меняется (регрессия).
|
||||
"""
|
||||
if z >= 12:
|
||||
return coords
|
||||
elif z >= 10:
|
||||
tolerance = 0.0005 # ~50м
|
||||
tolerance = 0.0005 # ~50 м
|
||||
elif z >= 8:
|
||||
tolerance = 0.002 # ~200м
|
||||
tolerance = 0.002 # ~200 м
|
||||
elif z == 7:
|
||||
tolerance = 0.008 # ~800 м (как было до ET-012)
|
||||
elif z == 6:
|
||||
tolerance = 0.018 # ~2 км
|
||||
else:
|
||||
tolerance = 0.008 # ~800м на z7 и ниже
|
||||
tolerance = 0.04 # ~4 км (z5 и ниже)
|
||||
|
||||
if len(coords) < 3:
|
||||
return coords
|
||||
@@ -101,9 +114,18 @@ def build_gps_mvt(rows: list, z: int, x: int, y: int) -> bytes:
|
||||
|
||||
west, south, east, north = _tile_to_bbox(z, x, y)
|
||||
|
||||
# Min-length фильтр по зуму
|
||||
if z <= 7:
|
||||
min_length_m = 2000
|
||||
# Min-length фильтр и cap на число фич по зуму.
|
||||
# ET-012 (ADR-016): добавлены тиры z<=5 и z==6, чтобы при понижении
|
||||
# GPS_TRACKS_MIN_ZOOM до 5 размер тайла оставался <= 200 KB (M-8)
|
||||
# и в кадре оставались только «магистральные» треки (M-9).
|
||||
if z <= 5:
|
||||
min_length_m = 10000 # 10 км — только «магистральные» треки
|
||||
limit = 1500
|
||||
elif z == 6:
|
||||
min_length_m = 5000 # 5 км
|
||||
limit = 2000
|
||||
elif z == 7:
|
||||
min_length_m = 2000 # как было для z<=7 до ET-012
|
||||
limit = 3000
|
||||
elif z <= 9:
|
||||
min_length_m = 0
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
// ─── Константы ────────────────────────────────────────────────────
|
||||
|
||||
const GPS_TRACKS_ZOOM_CUTOFF = 12; // ниже — MVT, выше — GeoJSON
|
||||
const GPS_TRACKS_MIN_ZOOM = 8; // ниже — слой скрыт
|
||||
// ET-012 (ADR-016): порог понижен с 8 до 5, чтобы при обзорном зуме
|
||||
// пользователь видел общее покрытие сети треков. Серверная сторона
|
||||
// (build_gps_mvt z<=5 / z==6) даёт корректный размер MVT и читаемость.
|
||||
const GPS_TRACKS_MIN_ZOOM = 5; // ниже — слой скрыт
|
||||
|
||||
const GPS_SOURCE_COLORS = {
|
||||
osm: '#3cb44b',
|
||||
@@ -129,7 +132,14 @@ function _gpsLayerDef(id, source, sourceLayer) {
|
||||
'source-layer': sourceLayer || undefined,
|
||||
paint: {
|
||||
'line-color': colorExpr,
|
||||
'line-width': ['interpolate', ['linear'], ['zoom'], 8, 1.0, 12, 2.0, 16, 3.0],
|
||||
// ET-012 (REQ-F-05): stop на z=5 = 0.8 CSS-px. На 1×-дисплеях это
|
||||
// даёт 1 физ.px (с округлением GPU), на 2× — 1.6, на 3× — 2.4.
|
||||
// Линия гарантированно видна на любом DPR.
|
||||
'line-width': ['interpolate', ['linear'], ['zoom'],
|
||||
5, 0.8,
|
||||
8, 1.0,
|
||||
12, 2.0,
|
||||
16, 3.0],
|
||||
'line-opacity': 0.75,
|
||||
},
|
||||
layout: { 'line-cap': 'round', 'line-join': 'round', visibility: 'none' }
|
||||
@@ -144,7 +154,14 @@ function _gpsHaloDef(id, source, sourceLayer) {
|
||||
'source-layer': sourceLayer || undefined,
|
||||
paint: {
|
||||
'line-color': '#ffffff',
|
||||
'line-width': ['interpolate', ['linear'], ['zoom'], 8, 2.5, 12, 4.0, 16, 6.0],
|
||||
// ET-012 (REQ-F-06): halo на z=5 = 1.8 CSS-px при основной линии 0.8 px
|
||||
// (соотношение ~2.25×). Ореол не «съедает» линию: по 0.5 px с каждой
|
||||
// стороны, остаётся видна цветная сердцевина.
|
||||
'line-width': ['interpolate', ['linear'], ['zoom'],
|
||||
5, 1.8,
|
||||
8, 2.5,
|
||||
12, 4.0,
|
||||
16, 6.0],
|
||||
'line-opacity': 0.6,
|
||||
},
|
||||
layout: { visibility: 'none' }
|
||||
@@ -355,7 +372,7 @@ function _syncGpsLayersVisibility(map) {
|
||||
setVis(window.gpsTracksLayer.layerId, mvtVisible);
|
||||
setVis(window.gpsTracksLayer.layerGeoId, geoVisible);
|
||||
|
||||
// Hint «Зум 8+»
|
||||
// Hint «Зум 5+» (ET-012: порог переехал автоматически через GPS_TRACKS_MIN_ZOOM)
|
||||
const hint = document.getElementById('public-tracks-zoom-hint');
|
||||
if (hint) {
|
||||
hint.style.display = (enabled && zoom < GPS_TRACKS_MIN_ZOOM) ? 'inline' : 'none';
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
<input type="checkbox" id="public-tracks-cb" onchange="onPublicTracksCheckbox()">
|
||||
<span>Публичные треки</span>
|
||||
</label>
|
||||
<span class="terrain-hint" id="public-tracks-zoom-hint" style="display:none">Зум 8+</span>
|
||||
<span class="terrain-hint" id="public-tracks-zoom-hint" style="display:none">Зум 5+</span>
|
||||
<button class="terrain-link-btn" id="public-tracks-filters-btn"
|
||||
onclick="togglePublicTracksFiltersSheet()" style="display:none">
|
||||
Фильтры…
|
||||
|
||||
Reference in New Issue
Block a user