fix(stats): reject sub-threshold gps drift
This commit is contained in:
@@ -17,6 +17,7 @@ const (
|
||||
gpsCoordinateSourceSuffix = "#GPS_COORDINATE"
|
||||
gpsMaxSegmentGap = 10 * time.Minute
|
||||
gpsMaxImpliedSpeedKMH = 220.0
|
||||
gpsMinimumDailyDistanceKM = 0.1
|
||||
)
|
||||
|
||||
const GPSMileageStateTableSQL = `CREATE TABLE IF NOT EXISTS vehicle_daily_gps_mileage_state (
|
||||
@@ -238,7 +239,7 @@ func AccumulateGPSMileage(ctx context.Context, exec Execer, point GPSMileagePoin
|
||||
_ = tx.Rollback()
|
||||
return GPSMileageState{}, false, err
|
||||
}
|
||||
if state.UsableSegmentCount == 0 {
|
||||
if !GPSMileageCandidateEligible(state.DailyMileageKM, state.UsableSegmentCount) {
|
||||
if err := tx.Commit(); err != nil {
|
||||
return GPSMileageState{}, false, err
|
||||
}
|
||||
@@ -258,6 +259,16 @@ func AccumulateGPSMileage(ctx context.Context, exec Execer, point GPSMileagePoin
|
||||
return state, true, nil
|
||||
}
|
||||
|
||||
// GPSMileageCandidateEligible keeps sub-100-metre stationary drift and
|
||||
// momentary speed noise in the durable accumulation state without exposing it
|
||||
// as a business daily-mileage candidate. Real movement continues accumulating
|
||||
// and becomes eligible once the evidence crosses the minimum distance.
|
||||
func GPSMileageCandidateEligible(distanceKM float64, usableSegmentCount int64) bool {
|
||||
return usableSegmentCount > 0 &&
|
||||
isFiniteNonNegative(distanceKM) &&
|
||||
distanceKM >= gpsMinimumDailyDistanceKM
|
||||
}
|
||||
|
||||
// AccumulateJT808GPSMileage remains as a compatibility wrapper for callers and
|
||||
// operational tooling compiled against the original JT808-only fallback.
|
||||
func AccumulateJT808GPSMileage(ctx context.Context, exec Execer, point GPSMileagePoint) (GPSMileageState, bool, error) {
|
||||
|
||||
Reference in New Issue
Block a user