generated from Grigo/AndroidTemplate
fix proxy
This commit is contained in:
+124
-10
@@ -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' });
|
||||
|
||||
Reference in New Issue
Block a user