auto-sync: 2026-05-05 00:30:01
This commit is contained in:
@@ -480,7 +480,7 @@ body {
|
||||
.recon-radius-btn.active { background: #ff6600; color: #fff; border-color: #ff6600; font-weight: 600; }
|
||||
|
||||
/* ─── Фаза 4: Красивый маршрут ─────────────────────────────────────────── */
|
||||
.scenic-dist-btn {
|
||||
.scenic-km-btn {
|
||||
flex: 1;
|
||||
padding: 4px 0;
|
||||
border: 1px solid #ccc;
|
||||
@@ -490,8 +490,8 @@ body {
|
||||
background: #f0f0f0;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
.scenic-dist-btn:hover { background: #e0e0e0; }
|
||||
.scenic-dist-btn.active { background: #ff6600; color: #fff; border-color: #ff6600; font-weight: 600; }
|
||||
.scenic-km-btn:hover { background: #e0e0e0; }
|
||||
.scenic-km-btn.active { background: #ff6600; color: #fff; border-color: #ff6600; font-weight: 600; }
|
||||
|
||||
.scenic-poi-item {
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
|
||||
108
tasks/enduro-trails/prototype/static/app.js
vendored
108
tasks/enduro-trails/prototype/static/app.js
vendored
@@ -1,23 +1,12 @@
|
||||
// ─── Общее: деактивация всех режимов ────────────────────────────────────────────
|
||||
|
||||
function deactivateAllModes() {
|
||||
if (routeMode) toggleRouteMode();
|
||||
if (rulerMode) toggleRuler();
|
||||
if (markerMode) toggleMarkerMode();
|
||||
if (typeof reconMode !== 'undefined' && reconMode) toggleReconMode();
|
||||
if (typeof linkMode !== 'undefined' && linkMode) toggleLinkMode();
|
||||
if (typeof scenicMode !== 'undefined' && scenicMode) toggleScenicMode();
|
||||
}
|
||||
|
||||
// ─── Общее: деактивация всех режимов ────────────────────────────────────────────
|
||||
|
||||
function deactivateAllModes() {
|
||||
if (routeMode) { routeMode = false; document.getElementById('btn-route').classList.remove('active'); document.getElementById('route-panel').style.display = 'none'; clearRoute(); }
|
||||
if (rulerMode) toggleRuler();
|
||||
if (markerMode) toggleMarkerMode();
|
||||
if (reconMode) toggleReconMode();
|
||||
if (linkMode) toggleLinkMode();
|
||||
if (scenicMode) toggleScenicMode();
|
||||
if (typeof reconMode !== 'undefined' && reconMode) toggleReconMode();
|
||||
if (typeof linkMode !== 'undefined' && linkMode) toggleLinkMode();
|
||||
if (typeof scenicMode !== 'undefined' && scenicMode) toggleScenicMode();
|
||||
if (window._map) window._map.getCanvas().style.cursor = '';
|
||||
}
|
||||
|
||||
@@ -948,8 +937,6 @@ function initRouteClicks(map) {
|
||||
|
||||
if (!routeMode) return;
|
||||
|
||||
const { lng, lat } = e.lngLat;
|
||||
|
||||
// Режим добавления промежуточной точки
|
||||
if (addingWaypoint) {
|
||||
addingWaypoint = false;
|
||||
@@ -1252,11 +1239,9 @@ function toggleLinkMode() {
|
||||
linkMode = true;
|
||||
btn.classList.add('active');
|
||||
window._map.getCanvas().style.cursor = 'crosshair';
|
||||
document.getElementById('route-panel').style.display = 'block';
|
||||
document.querySelector('#route-panel > div:first-child').textContent = '🔗 Связка';
|
||||
document.getElementById('route-status').textContent = 'Кликни первую точку';
|
||||
document.getElementById('route-info').style.display = 'none';
|
||||
document.getElementById('route-actions').style.display = 'none';
|
||||
document.getElementById('link-panel').style.display = 'block';
|
||||
document.getElementById('link-status').textContent = '1️⃣ Кликни конец первого трека';
|
||||
document.getElementById('link-cards').innerHTML = '';
|
||||
} else {
|
||||
btn.classList.remove('active');
|
||||
window._map.getCanvas().style.cursor = '';
|
||||
@@ -1275,7 +1260,7 @@ function addLinkPoint(lng, lat) {
|
||||
linkMarkers.push(marker);
|
||||
|
||||
if (idx === 1) {
|
||||
document.getElementById('route-status').textContent = 'Кликни вторую точку';
|
||||
document.getElementById('link-status').textContent = '2️⃣ Кликни начало второго трека';
|
||||
} else if (idx >= 2) {
|
||||
buildLinkRoute();
|
||||
}
|
||||
@@ -1283,7 +1268,7 @@ function addLinkPoint(lng, lat) {
|
||||
|
||||
async function buildLinkRoute() {
|
||||
const map = window._map;
|
||||
document.getElementById('route-status').textContent = '⏳ Ищу связку...';
|
||||
document.getElementById('link-status').textContent = '⏳ Ищу связку...';
|
||||
const basePath = window.location.pathname.replace(/\/[^/]*$/, '') || '';
|
||||
try {
|
||||
const resp = await fetch(`${basePath}/api/route`, {
|
||||
@@ -1294,13 +1279,69 @@ async function buildLinkRoute() {
|
||||
if (!resp.ok) throw new Error('Не найдена');
|
||||
const data = await resp.json();
|
||||
if (data.routes && data.routes.length > 0) {
|
||||
renderRouteCards(data.routes, 'link');
|
||||
document.getElementById('route-status').textContent = '✅ Связка найдена';
|
||||
renderLinkCards(data.routes);
|
||||
document.getElementById('link-status').textContent = '✅ Связка найдена';
|
||||
} else {
|
||||
document.getElementById('route-status').textContent = '❌ Грунтовая связка не найдена';
|
||||
document.getElementById('link-status').textContent = '❌ Грунтовая связка не найдена';
|
||||
}
|
||||
} catch(e) {
|
||||
document.getElementById('route-status').textContent = '❌ ' + e.message;
|
||||
document.getElementById('link-status').textContent = '❌ ' + e.message;
|
||||
}
|
||||
}
|
||||
|
||||
function renderLinkCards(routes) {
|
||||
const map = window._map;
|
||||
const colors = ['#0066ff', '#00aa44', '#9933cc'];
|
||||
const cardsEl = document.getElementById('link-cards');
|
||||
cardsEl.innerHTML = '';
|
||||
|
||||
routes.forEach((r, i) => {
|
||||
const geojson = { type: 'Feature', geometry: r.geometry, properties: {} };
|
||||
const sid = `link-src-${i}`;
|
||||
const lid = `link-line-${i}`;
|
||||
if (map.getSource(sid)) map.removeSource(sid);
|
||||
if (map.getLayer(lid)) map.removeLayer(lid);
|
||||
map.addSource(sid, { type: 'geojson', data: geojson });
|
||||
map.addLayer({
|
||||
id: lid, type: 'line', source: sid,
|
||||
paint: {
|
||||
'line-color': colors[i % colors.length],
|
||||
'line-width': i === 0 ? 5 : 3,
|
||||
'line-opacity': i === 0 ? 0.9 : 0.5,
|
||||
},
|
||||
layout: { 'line-cap': 'round', 'line-join': 'round' }
|
||||
});
|
||||
|
||||
const km = (r.distance / 1000).toFixed(0);
|
||||
const time = formatDuration(r.duration);
|
||||
const dirt = r.stats?.dirt_total_pct || '?';
|
||||
const col = colors[i % colors.length];
|
||||
const card = document.createElement('div');
|
||||
card.className = 'route-card' + (i === 0 ? ' active' : '');
|
||||
card.innerHTML = `
|
||||
<div class="route-card-header">
|
||||
<span class="route-color-dot" style="background:${col}"></span>
|
||||
<span class="route-card-title">Вариант ${i+1}</span>
|
||||
<span class="route-card-dist">${km} км</span>
|
||||
<span class="route-card-time">${time}</span>
|
||||
</div>
|
||||
<div style="font-size:11px;color:#666">${dirt}% грунт</div>
|
||||
`;
|
||||
card.onclick = () => selectLinkRoute(i);
|
||||
cardsEl.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
function selectLinkRoute(idx) {
|
||||
const map = window._map;
|
||||
document.querySelectorAll('#link-cards .route-card').forEach((c, i) => c.classList.toggle('active', i === idx));
|
||||
// Highlight selected route
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const lid = `link-line-${i}`;
|
||||
if (map.getLayer(lid)) {
|
||||
map.setPaintProperty(lid, 'line-width', i === idx ? 5 : 3);
|
||||
map.setPaintProperty(lid, 'line-opacity', i === idx ? 0.9 : 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1309,15 +1350,14 @@ function clearLink() {
|
||||
linkMarkers.forEach(m => m.remove());
|
||||
linkMarkers = [];
|
||||
const map = window._map;
|
||||
// Remove route layers
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const lid = `link-line-${i}`;
|
||||
if (map.getLayer(lid)) map.removeLayer(lid);
|
||||
const sid = `link-src-${i}`;
|
||||
if (map.getSource(sid)) map.removeSource(sid);
|
||||
}
|
||||
document.getElementById('route-panel').style.display = 'none';
|
||||
document.getElementById('route-cards').innerHTML = '';
|
||||
document.getElementById('link-panel').style.display = 'none';
|
||||
document.getElementById('link-cards').innerHTML = '';
|
||||
}
|
||||
|
||||
// ─── Фаза 4: Красивый маршрут ────────────────────────────────────────────────
|
||||
@@ -1345,12 +1385,12 @@ function toggleScenicMode() {
|
||||
}
|
||||
}
|
||||
|
||||
function setScenicDist(km) {
|
||||
function setScenicKm(km) {
|
||||
scenicTargetKm = km;
|
||||
document.querySelectorAll('.scenic-dist-btn').forEach(b => {
|
||||
b.classList.toggle('active', +b.textContent === km);
|
||||
document.querySelectorAll('.scenic-km-btn').forEach(b => {
|
||||
b.classList.toggle('active', +b.dataset.km === km);
|
||||
});
|
||||
const inp = document.getElementById('scenic-dist-input');
|
||||
const inp = document.getElementById('scenic-custom-km');
|
||||
if (inp) inp.value = km;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user