generated from Grigo/AndroidTemplate
fix
This commit is contained in:
+69
-28
@@ -361,7 +361,7 @@
|
||||
{ position: 'topright', collapsed: true }
|
||||
).addTo(map);
|
||||
|
||||
const API_BUILD = '2026-06-16c';
|
||||
const API_BUILD = '2026-06-16d';
|
||||
|
||||
const markers = {};
|
||||
let selectedId = null;
|
||||
@@ -560,10 +560,13 @@
|
||||
}
|
||||
|
||||
function snapAtCursor(track, telemetryRows, cursor, roleFallback) {
|
||||
const pos = trackPointAt(track, cursor);
|
||||
if (pos?.meta && String(pos.meta).length > 2) {
|
||||
const ts = timelineUseProgress ? null : cursor.t;
|
||||
return snapFromTrackPoint(pos, ts, roleFallback || track?.role);
|
||||
}
|
||||
if (timelineUseProgress) {
|
||||
const pos = positionAtProgress(track?.points, cursor.progress);
|
||||
if (!pos) return null;
|
||||
return { meta: pos.meta, role: roleFallback, rssi: pos.rssi, ts: cursor.progress };
|
||||
return snapFromTrackPoint(pos, null, roleFallback || track?.role);
|
||||
}
|
||||
return snapAtTime(track, telemetryRows, cursor.t, roleFallback);
|
||||
}
|
||||
@@ -592,21 +595,42 @@
|
||||
return { ...track, points };
|
||||
}
|
||||
|
||||
function snapAtTime(track, telemetryRows, t, roleFallback) {
|
||||
const tel = telemetryAtTime(telemetryRows, t);
|
||||
if (tel) return tel;
|
||||
const pos = positionAt(track?.points, t);
|
||||
function normalizeTelemetry(rows) {
|
||||
if (!rows?.length) return [];
|
||||
return rows
|
||||
.map(r => ({ ...r, ts: Number(r.ts) }))
|
||||
.sort((a, b) => a.ts - b.ts);
|
||||
}
|
||||
|
||||
function trackPointAt(track, cursor) {
|
||||
if (!track?.points?.length) return null;
|
||||
return timelineUseProgress
|
||||
? positionAtProgress(track.points, cursor.progress)
|
||||
: positionAt(track.points, cursor.t);
|
||||
}
|
||||
|
||||
function snapFromTrackPoint(pos, t, roleFallback) {
|
||||
if (!pos) return null;
|
||||
return {
|
||||
meta: pos.meta,
|
||||
role: roleFallback || track?.role,
|
||||
role: roleFallback,
|
||||
rssi: pos.rssi,
|
||||
ts: t,
|
||||
lat: pos.lat,
|
||||
lon: pos.lon
|
||||
lon: pos.lon,
|
||||
};
|
||||
}
|
||||
|
||||
function snapAtTime(track, telemetryRows, t, roleFallback) {
|
||||
const pos = positionAt(track?.points, t);
|
||||
if (pos?.meta && String(pos.meta).length > 2) {
|
||||
return snapFromTrackPoint(pos, t, roleFallback || track?.role);
|
||||
}
|
||||
const tel = telemetryAtTime(telemetryRows, t);
|
||||
if (tel) return tel;
|
||||
return snapFromTrackPoint(pos, t, roleFallback || track?.role);
|
||||
}
|
||||
|
||||
function rxQualityFromMeta(meta) {
|
||||
if (!meta) return null;
|
||||
const snap = RadioUI.parseRadioSnapshot(meta);
|
||||
@@ -1847,18 +1871,17 @@
|
||||
|
||||
function telemetryAtTime(rows, t) {
|
||||
if (!rows?.length) return null;
|
||||
const first = rows[0];
|
||||
const last = rows[rows.length - 1];
|
||||
if (t <= first.ts) return first;
|
||||
if (t >= last.ts) return last;
|
||||
for (let i = 0; i < rows.length - 1; i++) {
|
||||
const a = rows[i];
|
||||
const b = rows[i + 1];
|
||||
if (t >= a.ts && t <= b.ts) {
|
||||
return t - a.ts <= b.ts - t ? a : b;
|
||||
const tNum = Number(t);
|
||||
let best = null;
|
||||
let bestD = Infinity;
|
||||
for (const r of rows) {
|
||||
const d = Math.abs(Number(r.ts) - tNum);
|
||||
if (d < bestD) {
|
||||
best = r;
|
||||
bestD = d;
|
||||
}
|
||||
}
|
||||
return last;
|
||||
return best;
|
||||
}
|
||||
|
||||
function telemetryFromTrackPoint(track, t, roleFallback) {
|
||||
@@ -1890,9 +1913,21 @@
|
||||
return bestD === 0 ? best : null;
|
||||
}
|
||||
|
||||
function trackMetaDiversity(points) {
|
||||
const packets = new Set();
|
||||
let withMeta = 0;
|
||||
for (const p of points || []) {
|
||||
if (!p.meta || String(p.meta).length < 3) continue;
|
||||
withMeta++;
|
||||
const snap = RadioUI.parseRadioSnapshot(p.meta);
|
||||
if (snap.packet != null) packets.add(snap.packet);
|
||||
}
|
||||
return { withMeta, uniquePackets: packets.size, total: points?.length || 0 };
|
||||
}
|
||||
|
||||
function pairedTelemetryAtTime(txTrack, rxTrack, telemetryTx, telemetryRx, t) {
|
||||
let txTel = telemetryAtTime(telemetryTx, t) || telemetryFromTrackPoint(txTrack, t, 'TX');
|
||||
let rxTel = telemetryAtTime(telemetryRx, t) || telemetryFromTrackPoint(rxTrack, t, 'RX');
|
||||
let txTel = snapAtTime(txTrack, telemetryTx, t, 'TX');
|
||||
let rxTel = snapAtTime(rxTrack, telemetryRx, t, 'RX');
|
||||
const txSnap = txTel ? telemetryToSnap(txTel) : null;
|
||||
const rxSnap = rxTel ? telemetryToSnap(rxTel) : null;
|
||||
if (txSnap?.packet != null) {
|
||||
@@ -2211,6 +2246,12 @@
|
||||
noteText =
|
||||
'Треки не пересекаются по времени — шкала на полном диапазоне; вне записи позиция удерживается на краю.';
|
||||
}
|
||||
const txDiv = trackMetaDiversity(loadedTxTrack.points);
|
||||
const rxDiv = trackMetaDiversity(loadedRxTrack.points);
|
||||
if (txDiv.uniquePackets <= 1 && rxDiv.uniquePackets <= 1
|
||||
&& (txDiv.withMeta > 1 || rxDiv.withMeta > 1)) {
|
||||
noteText += ' Радио-статистика в точках трека не менялась при записи.';
|
||||
}
|
||||
applyTimelineRange(range, noteText);
|
||||
}
|
||||
setTimelineVisible(true);
|
||||
@@ -2227,7 +2268,7 @@
|
||||
`/api/telemetry?device_id=${encodeURIComponent(loadedSingleTrack.device_id)}&since=${range.min}&until=${range.max}&limit=500`,
|
||||
{ cache: 'no-store' }
|
||||
);
|
||||
if (res.ok) telemetrySingle = await res.json();
|
||||
if (res.ok) telemetrySingle = normalizeTelemetry(await res.json());
|
||||
}
|
||||
updateTimelineAtSingle(timelineCursor());
|
||||
return;
|
||||
@@ -2240,8 +2281,8 @@
|
||||
fetch(`/api/telemetry?device_id=${encodeURIComponent(loadedTxTrack.device_id)}&since=${range.min}&until=${range.max}&limit=500`, { cache: 'no-store' }),
|
||||
fetch(`/api/telemetry?device_id=${encodeURIComponent(loadedRxTrack.device_id)}&since=${range.min}&until=${range.max}&limit=500`, { cache: 'no-store' })
|
||||
]);
|
||||
if (telTx.ok) telemetryTx = await telTx.json();
|
||||
if (telRx.ok) telemetryRx = await telRx.json();
|
||||
if (telTx.ok) telemetryTx = normalizeTelemetry(await telTx.json());
|
||||
if (telRx.ok) telemetryRx = normalizeTelemetry(await telRx.json());
|
||||
}
|
||||
updateTimelineAt(timelineCursor());
|
||||
}
|
||||
@@ -2326,7 +2367,7 @@
|
||||
`/api/telemetry?device_id=${encodeURIComponent(loadedSingleTrack.device_id)}&since=${range.min}&until=${range.max}&limit=500`,
|
||||
{ cache: 'no-store' }
|
||||
);
|
||||
if (telRes.ok) telemetrySingle = await telRes.json();
|
||||
if (telRes.ok) telemetrySingle = normalizeTelemetry(await telRes.json());
|
||||
updateTimelineAtSingle(timelineCursor());
|
||||
}
|
||||
document.getElementById('trackInfo').textContent =
|
||||
@@ -2387,8 +2428,8 @@
|
||||
fetch(`/api/telemetry?device_id=${encodeURIComponent(loadedTxTrack.device_id)}&since=${range.min}&until=${range.max}&limit=500`, { cache: 'no-store' }),
|
||||
fetch(`/api/telemetry?device_id=${encodeURIComponent(loadedRxTrack.device_id)}&since=${range.min}&until=${range.max}&limit=500`, { cache: 'no-store' })
|
||||
]);
|
||||
if (telTx.ok) telemetryTx = await telTx.json();
|
||||
if (telRx.ok) telemetryRx = await telRx.json();
|
||||
if (telTx.ok) telemetryTx = normalizeTelemetry(await telTx.json());
|
||||
if (telRx.ok) telemetryRx = normalizeTelemetry(await telRx.json());
|
||||
updateTimelineAt(timelineCursor());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user