fix proxy

This commit is contained in:
2026-06-23 14:54:48 +03:00
parent 4fd6da1295
commit 7a04cc166d
+124 -10
View File
@@ -226,6 +226,12 @@
color: #d7f7ff; font-size: 0.72rem; white-space: pre-wrap;
}
#apiDebugChart { width: 100%; height: 140px; display: block; margin-top: 8px; background: #0a0a14; border-radius: 4px; }
.api-debug-legend {
display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
margin-top: 5px; color: #aaa; font-size: 0.7rem;
}
.api-debug-legend span { display: inline-flex; align-items: center; gap: 4px; }
.api-debug-swatch { width: 16px; height: 3px; border-radius: 2px; display: inline-block; }
#apiDebugSummary {
margin-top: 8px; padding: 8px; background: #0a0a14; border: 1px solid #333; border-radius: 4px;
font-size: 0.75rem; line-height: 1.45;
@@ -304,6 +310,11 @@
<div id="apiDebugStatus">Готово</div>
<div class="api-debug-mini">“Расчёт линии” вызывает profile + LOS + link budget и строит график земли/поверхности.</div>
<canvas id="apiDebugChart" width="800" height="140"></canvas>
<div class="api-debug-legend">
<span><i class="api-debug-swatch" style="background:#4fc3f7"></i> земля DEM</span>
<span><i class="api-debug-swatch" style="background:#00ff88"></i> поверхность/препятствия</span>
<span><i class="api-debug-swatch" style="background:#ff9800"></i> прямая TX→RX</span>
</div>
<div id="apiDebugSummary">Нет расчёта.</div>
<pre id="apiDebugOutput">Выберите запрос для проверки RF API.</pre>
</div>
@@ -536,6 +547,12 @@
let apiDebugTxMarker = null;
let apiDebugRxMarker = null;
let apiDebugLineLayer = null;
let apiDebugCursorDist = null;
let apiDebugCursorMarker = null;
let apiDebugGroundProfile = null;
let apiDebugSurfaceProfile = null;
let apiDebugLosLine = null;
let apiDebugBaseSummaryHtml = 'Нет расчёта.';
let mapRulerMode = 'pick';
let mapRulerPtA = null;
let mapRulerPtB = null;
@@ -2184,6 +2201,80 @@
}
}
function clearApiDebugCursorMarker() {
if (apiDebugCursorMarker) {
map.removeLayer(apiDebugCursorMarker);
apiDebugCursorMarker = null;
}
}
function clearApiDebugCursor() {
apiDebugCursorDist = null;
clearApiDebugCursorMarker();
apiDebugSetStatus('RF расчёт линии готов');
apiDebugSetSummary(apiDebugBaseSummaryHtml);
drawApiDebugChart();
}
function drawApiDebugChart() {
const series = [];
if (apiDebugGroundProfile) {
series.push({
color: '#4fc3f7',
profile: apiDebugGroundProfile,
label: 'земля DEM'
});
}
if (apiDebugSurfaceProfile) {
series.push({
color: '#00ff88',
profile: apiDebugSurfaceProfile,
label: 'поверхность',
losLine: apiDebugLosLine,
cursor: apiDebugCursorDist
});
}
renderElevationCanvas(
document.getElementById('apiDebugChart'),
series,
'done',
'Запустите расчёт линии'
);
}
function setApiDebugChartCursor(distM) {
if (!apiDebugSurfaceProfile || !apiDebugGroundProfile) return;
const tx = apiDebugLatLon('tx');
const rx = apiDebugLatLon('rx');
if (!tx || !rx) return;
const total = apiDebugSurfaceProfile.total_m || lineLengthM(tx, rx);
apiDebugCursorDist = Math.max(0, Math.min(distM, total));
const pt = latLonAtLineDist(tx, rx, apiDebugCursorDist);
clearApiDebugCursorMarker();
apiDebugCursorMarker = L.circleMarker([pt.lat, pt.lon], {
radius: 8,
color: '#fff',
weight: 2,
fillColor: '#ff9800',
fillOpacity: 0.95,
interactive: false
}).addTo(map);
const ground = elevationAtDist(apiDebugGroundProfile, apiDebugCursorDist);
const surface = elevationAtDist(apiDebugSurfaceProfile, apiDebugCursorDist);
const delta = ground != null && surface != null ? surface - ground : null;
apiDebugSetStatus(
`${apiDebugCursorDist.toFixed(0)} m · земля ${fmtNum(ground, 1, ' m')} · поверхность ${fmtNum(surface, 1, ' m')}`
);
apiDebugSetSummary(
`${apiDebugBaseSummaryHtml}<hr style="border:0;border-top:1px solid #333;margin:6px 0">` +
`<b>Точка на графике:</b> ${fmtNum(apiDebugCursorDist, 0, ' m')} от TX<br>` +
`<b>Координаты:</b> ${fmtNum(pt.lat, 6)}, ${fmtNum(pt.lon, 6)}<br>` +
`<b>Земля DEM:</b> ${fmtNum(ground, 1, ' m')} · <b>поверхность:</b> ${fmtNum(surface, 1, ' m')}` +
(delta != null && Math.abs(delta) > 0.05 ? ` · препятствие +${fmtNum(delta, 1, ' m')}` : '')
);
drawApiDebugChart();
}
function setApiDebugPoint(which, lat, lon) {
const prefix = which === 'tx' ? 'Tx' : 'Rx';
document.getElementById(`apiDebug${prefix}Lat`).value = Number(lat).toFixed(6);
@@ -2227,6 +2318,13 @@
if (el) el.value = '';
});
refreshApiDebugOverlay();
clearApiDebugCursorMarker();
apiDebugGroundProfile = null;
apiDebugSurfaceProfile = null;
apiDebugLosLine = null;
apiDebugCursorDist = null;
apiDebugBaseSummaryHtml = 'Нет расчёта.';
drawApiDebugChart();
setApiDebugPickMode(null);
apiDebugSetStatus('Точки очищены');
apiDebugSetSummary('Выберите TX и RX на карте или из линейки.');
@@ -2454,16 +2552,14 @@
const last = profile.samples[profile.samples.length - 1] || {};
const elevA = Number(first.ground_m ?? first.surface_m ?? 0) + f.txHeight;
const elevB = Number(last.ground_m ?? last.surface_m ?? 0) + f.rxHeight;
renderElevationCanvas(
document.getElementById('apiDebugChart'),
[
{ color: '#4fc3f7', profile: ground, label: 'земля' },
{ color: '#00ff88', profile: surface, label: 'поверхность', losLine: { elevA, elevB } }
],
'done',
'RF profile пустой'
);
apiDebugSetSummary(formatApiDebugLineSummary(profile, los, budget));
apiDebugGroundProfile = ground;
apiDebugSurfaceProfile = surface;
apiDebugLosLine = { elevA, elevB };
apiDebugCursorDist = null;
clearApiDebugCursorMarker();
drawApiDebugChart();
apiDebugBaseSummaryHtml = formatApiDebugLineSummary(profile, los, budget);
apiDebugSetSummary(apiDebugBaseSummaryHtml);
}
function fmtBool(v) {
@@ -3553,6 +3649,24 @@
});
})();
(function bindApiDebugChartProbe() {
const canvas = document.getElementById('apiDebugChart');
if (!canvas) return;
canvas.addEventListener('mousemove', e => {
if (!apiDebugSurfaceProfile) return;
const layout = canvas._elevLayout;
if (!layout || layout.plotW <= 0) return;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const dist = ((x - layout.margin.l) / layout.plotW) * layout.maxDist;
setApiDebugChartCursor(dist);
});
canvas.addEventListener('mouseleave', () => {
if (!apiDebugSurfaceProfile) return;
clearApiDebugCursor();
});
})();
async function refreshPairedStatus() {
try {
const res = await fetch('/api/paired-tracks/active', { cache: 'no-store' });