mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-09 23:26:31 +00:00
remove unused fields
This commit is contained in:
1 parent
83b76bb838
commit
3bb553d6b5
5 files changed
+2
-114
No files matched your search
@@ -55,10 +55,6 @@ impl Statistics {
|
|||||||
self.accumulate_distance_and_time(prev, cur);
|
self.accumulate_distance_and_time(prev, cur);
|
||||||
self.update_time_bounds(cur.time);
|
self.update_time_bounds(cur.time);
|
||||||
self.update_bounds(cur.coordinates);
|
self.update_bounds(cur.coordinates);
|
||||||
self.global.hr.add(cur.hr.map(f64::from));
|
|
||||||
self.global.cad.add(cur.cad.map(f64::from));
|
|
||||||
self.global.atemp.add(cur.atemp.map(f64::from));
|
|
||||||
self.global.power.add(cur.power.map(f64::from));
|
|
||||||
self.local
|
self.local
|
||||||
.push(TrackpointStatistics::from_partial_stats(self));
|
.push(TrackpointStatistics::from_partial_stats(self));
|
||||||
}
|
}
|
||||||
@@ -238,32 +234,6 @@ impl Statistics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Average of an optional measure (heart rate, cadence...) over the trackpoints that have it.
|
|
||||||
/// Keeps the sum so that averages can be merged.
|
|
||||||
#[derive(Default, Debug, Clone, Copy, PartialEq)]
|
|
||||||
pub struct Average {
|
|
||||||
pub sum: f64,
|
|
||||||
pub count: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Average {
|
|
||||||
pub fn add(&mut self, value: Option<f64>) {
|
|
||||||
if let Some(value) = value {
|
|
||||||
self.sum += value;
|
|
||||||
self.count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn merge(&mut self, other: &Average) {
|
|
||||||
self.sum += other.sum;
|
|
||||||
self.count += other.count;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn avg(&self) -> Option<f64> {
|
|
||||||
(self.count > 0).then(|| self.sum / self.count as f64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct GlobalStatistics {
|
pub struct GlobalStatistics {
|
||||||
pub total_distance: f64,
|
pub total_distance: f64,
|
||||||
@@ -275,10 +245,6 @@ pub struct GlobalStatistics {
|
|||||||
pub start_time: Option<i64>,
|
pub start_time: Option<i64>,
|
||||||
pub end_time: Option<i64>,
|
pub end_time: Option<i64>,
|
||||||
pub bounds: LngLatBounds,
|
pub bounds: LngLatBounds,
|
||||||
pub hr: Average,
|
|
||||||
pub cad: Average,
|
|
||||||
pub atemp: Average,
|
|
||||||
pub power: Average,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalStatistics {
|
impl GlobalStatistics {
|
||||||
@@ -305,10 +271,6 @@ impl GlobalStatistics {
|
|||||||
self.start_time = min_options(self.start_time, other.start_time);
|
self.start_time = min_options(self.start_time, other.start_time);
|
||||||
self.end_time = max_options(self.end_time, other.end_time);
|
self.end_time = max_options(self.end_time, other.end_time);
|
||||||
self.bounds.merge(&other.bounds);
|
self.bounds.merge(&other.bounds);
|
||||||
self.hr.merge(&other.hr);
|
|
||||||
self.cad.merge(&other.cad);
|
|
||||||
self.atemp.merge(&other.atemp);
|
|
||||||
self.power.merge(&other.power);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,50 +524,4 @@ mod tests {
|
|||||||
assert_eq!(cumul.total_time, Some(7_000));
|
assert_eq!(cumul.total_time, Some(7_000));
|
||||||
assert_eq!((a.bounds.ne.lng, a.bounds.ne.lat), (2.0, 3.0));
|
assert_eq!((a.bounds.ne.lng, a.bounds.ne.lat), (2.0, 3.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_average() {
|
|
||||||
let mut average = Average::default();
|
|
||||||
assert_eq!(average.avg(), None);
|
|
||||||
average.add(None);
|
|
||||||
assert_eq!(average.avg(), None);
|
|
||||||
average.add(Some(100.0));
|
|
||||||
average.add(Some(110.0));
|
|
||||||
assert_eq!(average.avg(), Some(105.0));
|
|
||||||
|
|
||||||
let mut other = Average::default();
|
|
||||||
other.add(Some(130.0));
|
|
||||||
average.merge(&other);
|
|
||||||
assert_eq!(average.count, 3);
|
|
||||||
assert_eq!(average.avg(), Some(113.33333333333333));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_measures_of_the_trackpoints_are_averaged() {
|
|
||||||
for (path, measure) in [
|
|
||||||
("data/with_hr.gpx", 0),
|
|
||||||
("data/with_cad.gpx", 1),
|
|
||||||
("data/with_temp.gpx", 2),
|
|
||||||
("data/with_power_1.gpx", 3),
|
|
||||||
] {
|
|
||||||
let data = std::fs::read(path).unwrap();
|
|
||||||
let gpx = parse(&data, &mut Default::default()).unwrap();
|
|
||||||
let trkseg = &gpx.trk[0].trkseg[0];
|
|
||||||
let global = Statistics::compute(trkseg).global;
|
|
||||||
let values: Vec<f64> = trkseg
|
|
||||||
.iter()
|
|
||||||
.filter_map(|trkpt| match measure {
|
|
||||||
0 => trkpt.hr.map(f64::from),
|
|
||||||
1 => trkpt.cad.map(f64::from),
|
|
||||||
2 => trkpt.atemp.map(f64::from),
|
|
||||||
_ => trkpt.power.map(f64::from),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let average = [global.hr, global.cad, global.atemp, global.power][measure];
|
|
||||||
assert!(!values.is_empty(), "{path}");
|
|
||||||
assert_eq!(average.count as usize, values.len(), "{path}");
|
|
||||||
let expected = values.iter().sum::<f64>() / values.len() as f64;
|
|
||||||
assert!((average.avg().unwrap() - expected).abs() < 1e-9, "{path}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -211,10 +211,6 @@ impl StatisticsBuffer {
|
|||||||
start_time: time(start),
|
start_time: time(start),
|
||||||
end_time: time(end),
|
end_time: time(end),
|
||||||
bounds: self.global.bounds,
|
bounds: self.global.bounds,
|
||||||
hr: self.global.hr,
|
|
||||||
cad: self.global.cad,
|
|
||||||
atemp: self.global.atemp,
|
|
||||||
power: self.global.power,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,7 +350,6 @@ mod tests {
|
|||||||
assert!(buffer.cad.is_none());
|
assert!(buffer.cad.is_none());
|
||||||
assert!(buffer.atemp.is_none());
|
assert!(buffer.atemp.is_none());
|
||||||
assert!(buffer.power.is_none());
|
assert!(buffer.power.is_none());
|
||||||
assert_eq!(buffer.global.hr.count, 0);
|
|
||||||
assert_eq!(buffer.global.total_time, None);
|
assert_eq!(buffer.global.total_time, None);
|
||||||
assert_eq!(buffer.len(), s.local.len());
|
assert_eq!(buffer.len(), s.local.len());
|
||||||
// they need times
|
// they need times
|
||||||
@@ -638,21 +633,16 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slice_keeps_the_bounds_and_averages_of_the_selection() {
|
fn test_slice_keeps_the_bounds_of_the_selection() {
|
||||||
let data = std::fs::read("data/with_hr.gpx").unwrap();
|
let data = std::fs::read("data/with_hr.gpx").unwrap();
|
||||||
let file = parse(&data, &mut Default::default()).unwrap();
|
let file = parse(&data, &mut Default::default()).unwrap();
|
||||||
let segment = file.trk[0].trkseg[0].clone();
|
let segment = file.trk[0].trkseg[0].clone();
|
||||||
let s = Statistics::compute(&segment);
|
let s = Statistics::compute(&segment);
|
||||||
let mut buffer = StatisticsBuffer::default();
|
let mut buffer = StatisticsBuffer::default();
|
||||||
buffer.update(&[(&segment, &s)]);
|
buffer.update(&[(&segment, &s)]);
|
||||||
assert!(buffer.global.hr.count > 0);
|
|
||||||
|
|
||||||
let slice = buffer.slice(1, 3).unwrap();
|
let slice = buffer.slice(1, 3).unwrap();
|
||||||
let (global, bounds) = (&buffer.global, &slice.bounds);
|
let (global, bounds) = (&buffer.global, &slice.bounds);
|
||||||
assert_eq!(slice.hr, global.hr);
|
|
||||||
assert_eq!(slice.cad, global.cad);
|
|
||||||
assert_eq!(slice.atemp, global.atemp);
|
|
||||||
assert_eq!(slice.power, global.power);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
(bounds.sw.lng, bounds.sw.lat),
|
(bounds.sw.lng, bounds.sw.lat),
|
||||||
(global.bounds.sw.lng, global.bounds.sw.lat)
|
(global.bounds.sw.lng, global.bounds.sw.lat)
|
||||||
|
|||||||
@@ -167,14 +167,6 @@ pub(crate) fn statistics_object(stats: &engine::GlobalStatistics) -> GlobalStati
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let seconds = |ms: Option<i64>| ms.map(|ms| ms as f64 / 1000.0);
|
let seconds = |ms: Option<i64>| ms.map(|ms| ms as f64 / 1000.0);
|
||||||
let average = |key: &str, average: &engine::Average| {
|
|
||||||
if let Some(avg) = average.avg() {
|
|
||||||
let value = Object::new();
|
|
||||||
set(&value, "avg", avg);
|
|
||||||
set(&value, "count", f64::from(average.count));
|
|
||||||
set(&object, key, value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
set(&object, "totalDistance", stats.total_distance);
|
set(&object, "totalDistance", stats.total_distance);
|
||||||
optional("movingDistance", stats.moving_distance);
|
optional("movingDistance", stats.moving_distance);
|
||||||
optional("totalTime", seconds(stats.total_time));
|
optional("totalTime", seconds(stats.total_time));
|
||||||
@@ -185,10 +177,6 @@ pub(crate) fn statistics_object(stats: &engine::GlobalStatistics) -> GlobalStati
|
|||||||
optional("endTime", stats.end_time.map(|t| t as f64));
|
optional("endTime", stats.end_time.map(|t| t as f64));
|
||||||
optional("totalSpeed", stats.total_speed());
|
optional("totalSpeed", stats.total_speed());
|
||||||
optional("movingSpeed", stats.moving_speed());
|
optional("movingSpeed", stats.moving_speed());
|
||||||
average("hr", &stats.hr);
|
|
||||||
average("cad", &stats.cad);
|
|
||||||
average("atemp", &stats.atemp);
|
|
||||||
average("power", &stats.power);
|
|
||||||
let (sw, ne) = (&stats.bounds.sw, &stats.bounds.ne);
|
let (sw, ne) = (&stats.bounds.sw, &stats.bounds.ne);
|
||||||
if sw.lng <= ne.lng && sw.lat <= ne.lat {
|
if sw.lng <= ne.lng && sw.lat <= ne.lat {
|
||||||
let bounds = Object::new();
|
let bounds = Object::new();
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ export interface FileStructure {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Global statistics of a file, of the selection, or of a part of it. The optional fields are
|
* Global statistics of a file, of the selection, or of a part of it. The optional fields are
|
||||||
* absent when there is no data for them (no timestamps, no heart rate...).
|
* absent when there is no data for them (no timestamps...).
|
||||||
*/
|
*/
|
||||||
export interface GlobalStatistics {
|
export interface GlobalStatistics {
|
||||||
/** km */
|
/** km */
|
||||||
@@ -130,11 +130,6 @@ export interface GlobalStatistics {
|
|||||||
/** km/h */
|
/** km/h */
|
||||||
totalSpeed?: number;
|
totalSpeed?: number;
|
||||||
movingSpeed?: number;
|
movingSpeed?: number;
|
||||||
/** Average and number of trackpoints having the measure. */
|
|
||||||
hr?: { avg: number; count: number };
|
|
||||||
cad?: { avg: number; count: number };
|
|
||||||
atemp?: { avg: number; count: number };
|
|
||||||
power?: { avg: number; count: number };
|
|
||||||
/** Absent when there are no trackpoints. */
|
/** Absent when there are no trackpoints. */
|
||||||
bounds?: { west: number; south: number; east: number; north: number };
|
bounds?: { west: number; south: number; east: number; north: number };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ export const exampleData = {
|
|||||||
endTime: 1672538633024,
|
endTime: 1672538633024,
|
||||||
totalSpeed: 11.737617486742575,
|
totalSpeed: 11.737617486742575,
|
||||||
movingSpeed: 11.737617486742575,
|
movingSpeed: 11.737617486742575,
|
||||||
atemp: { avg: 17.676470588235293, count: 102 },
|
|
||||||
bounds: { west: -66.660451, south: 48.745764, east: -66.510044, north: 48.92168 },
|
bounds: { west: -66.660451, south: 48.745764, east: -66.510044, north: 48.92168 },
|
||||||
},
|
},
|
||||||
totalDistance: [
|
totalDistance: [
|
||||||
|
|||||||
Reference in new issue
Block a user