Repository navigation
Expand file tree
/
Copy pathsmoother.js
More file actions
93 lines (74 loc) · 3.01 KB
/
Copy pathsmoother.js
File metadata and controls
93 lines (74 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// smoother.js — TrackMovingAverageSmoother (взвешенное скользящее среднее)
// Портировано с C# UCNLNav.TrackFilters.TrackMovingAverageSmoother
const SmoothModule = (() => {
class MPoint {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class TrackMovingAverageSmoother {
constructor(filterSize = 4, resetDeltaM = 3000) {
if (resetDeltaM <= 0) throw new Error('resetDeltaM must be > 0');
if (filterSize <= 0) throw new Error('filterSize must be > 0');
this.filterSize = filterSize;
this.maxDistToReset = resetDeltaM;
this.points = [];
this.anchorLat = NaN;
this.anchorLon = NaN;
this.prevLat = NaN;
this.prevLon = NaN;
}
process(lat, lon, dpt, ts) {
if (this.points.length === 0) {
this.anchorLat = lat;
this.anchorLon = lon;
this.points.push(new MPoint(0, 0));
this.prevLat = lat;
this.prevLon = lon;
return { lat, lon, dpt, ts };
}
const distToPrev = Haversine.haversineInverse(this.prevLat, this.prevLon, lat, lon);
if (distToPrev >= this.maxDistToReset) {
this.reset();
this.anchorLat = lat;
this.anchorLon = lon;
this.points.push(new MPoint(0, 0));
this.prevLat = lat;
this.prevLon = lon;
return { lat, lon, dpt, ts };
}
if (this.points.length >= this.filterSize) {
this.points.shift();
}
const deltas = GeoUtils.getDeltasByGeopoints_WGS84(this.anchorLat, this.anchorLon, lat, lon);
this.points.push(new MPoint(deltas.deltaLonM, deltas.deltaLatM));
let meanX = 0, meanY = 0;
for (let i = 0; i < this.points.length; i++) {
const weight = i + 1;
meanX += this.points[i].x * weight;
meanY += this.points[i].y * weight;
}
const fWeight = (this.points.length + this.points.length * this.points.length) / 2.0;
meanX /= fWeight;
meanY /= fWeight;
const result = GeoUtils.geopointOffsetByDeltas_WGS84(this.anchorLat, this.anchorLon, meanY, meanX);
this.prevLat = result.lat;
this.prevLon = result.lon;
return { lat: result.lat, lon: result.lon, dpt, ts };
}
reset() {
this.points = [];
this.anchorLat = NaN;
this.anchorLon = NaN;
this.prevLat = NaN;
this.prevLon = NaN;
}
}
// Экспорт в глобальную область
window.TrackMovingAverageSmoother = TrackMovingAverageSmoother;
return TrackMovingAverageSmoother;
})();
if (typeof module !== 'undefined' && module.exports) {
module.exports = TrackMovingAverageSmoother;
}