fix(gps): гистерезис подтверждения jump-кандидата — latch-up на LBS, реальные переезды принимаются после 3 точек

This commit is contained in:
2026-08-25 18:06:43 +03:00
parent 3d24a15fb3
commit a4b508f70e
2 changed files with 142 additions and 46 deletions

View File

@@ -2,7 +2,7 @@ import { Router } from "express";
import type { Express, Response } from "express";
import { authenticateToken, type AuthenticatedRequest } from "../middleware/auth.middleware";
import { gpsStorage } from "./storage";
import { processPosition, classifyPoint } from "./geozone.service";
import { processPosition, filterTrackPoints } from "./geozone.service";
import { ensureDevice, deleteDevice } from "./traccar.client";
import { storage } from "../storage";
@@ -319,21 +319,10 @@ export function registerGpsRoutes(app: Express) {
const total = all.length;
// Фильтрация сохранённых данных при выдаче (без удаления из БД):
// пропускаем stale (устаревшие копии) и jump (LBS-скачки) — те же правила,
// что при приёме, сравнение с предыдущей принятой точкой
// пропускаем stale (устаревшие копии) и jump (LBS-скачки) — те же правила
// с гистерезисом подтверждения, что при приёме (общий walker по точкам)
const settings = await gpsStorage.getSettings(orgId);
const filtered: typeof all = [];
let filteredCount = 0;
let prevAccepted: { lat: number; lng: number; recordedAt: Date } | null = null;
for (const point of all) {
const current = { lat: point.lat, lng: point.lng, recordedAt: point.recordedAt };
if (classifyPoint(prevAccepted, current, settings) === "accept") {
filtered.push(point);
prevAccepted = current;
} else {
filteredCount++;
}
}
const { points: filtered, filteredCount } = filterTrackPoints(all, settings);
let points = filtered;
let sampled = false;