From eb8e09b8351eaad752bec18b99a5634aa05616d3 Mon Sep 17 00:00:00 2001 From: vcoppe Date: Wed, 30 Sep 2026 19:19:23 +0200 Subject: [PATCH] progress --- gpx-rs/src/action/action.rs | 5 ++++ gpx-rs/src/action/file.rs | 1 + gpx-rs/src/action/mod.rs | 4 +++ gpx-rs/src/engine.rs | 2 +- gpx-rs/src/lib.rs | 2 +- gpx-rs/src/state/mod.rs | 3 +++ gpx-rs/src/{ => state}/stack.rs | 0 gpx-rs/src/statistics/buffer.rs | 32 +++++++++++++++++++--- gpx-rs/src/statistics/mod.rs | 2 ++ gpx-rs/src/statistics/statistics.rs | 42 +++++++++++++---------------- gpx-rs/src/statistics/utils.rs | 13 +++++++++ 11 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 gpx-rs/src/action/action.rs create mode 100644 gpx-rs/src/action/file.rs create mode 100644 gpx-rs/src/state/mod.rs rename gpx-rs/src/{ => state}/stack.rs (100%) create mode 100644 gpx-rs/src/statistics/utils.rs diff --git a/gpx-rs/src/action/action.rs b/gpx-rs/src/action/action.rs new file mode 100644 index 000000000..595a3b54a --- /dev/null +++ b/gpx-rs/src/action/action.rs @@ -0,0 +1,5 @@ +use crate::state::StackEntry; + +pub trait Action { + fn apply(entry: &mut StackEntry) -> Result<(), &'static str>; +} diff --git a/gpx-rs/src/action/file.rs b/gpx-rs/src/action/file.rs new file mode 100644 index 000000000..ea14c4947 --- /dev/null +++ b/gpx-rs/src/action/file.rs @@ -0,0 +1 @@ +use crate::action::Action; diff --git a/gpx-rs/src/action/mod.rs b/gpx-rs/src/action/mod.rs index 8b1378917..ff9d46028 100644 --- a/gpx-rs/src/action/mod.rs +++ b/gpx-rs/src/action/mod.rs @@ -1 +1,5 @@ +mod action; +mod file; +pub use action::*; +pub use file::*; diff --git a/gpx-rs/src/engine.rs b/gpx-rs/src/engine.rs index 9180f825c..9c1e0a7ca 100644 --- a/gpx-rs/src/engine.rs +++ b/gpx-rs/src/engine.rs @@ -8,7 +8,7 @@ use crate::{ gpx::GPXFile, io::parse, selection::Selection, - stack::{Stack, StackEntry}, + state::{Stack, StackEntry}, }; // Control flow diff --git a/gpx-rs/src/lib.rs b/gpx-rs/src/lib.rs index b35d0c364..11524e3e7 100644 --- a/gpx-rs/src/lib.rs +++ b/gpx-rs/src/lib.rs @@ -4,6 +4,6 @@ mod engine; mod gpx; mod io; mod selection; -mod stack; +mod state; mod statistics; mod utils; diff --git a/gpx-rs/src/state/mod.rs b/gpx-rs/src/state/mod.rs new file mode 100644 index 000000000..b21354ddf --- /dev/null +++ b/gpx-rs/src/state/mod.rs @@ -0,0 +1,3 @@ +mod stack; + +pub use stack::*; diff --git a/gpx-rs/src/stack.rs b/gpx-rs/src/state/stack.rs similarity index 100% rename from gpx-rs/src/stack.rs rename to gpx-rs/src/state/stack.rs diff --git a/gpx-rs/src/statistics/buffer.rs b/gpx-rs/src/statistics/buffer.rs index bbd4049b1..74768be37 100644 --- a/gpx-rs/src/statistics/buffer.rs +++ b/gpx-rs/src/statistics/buffer.rs @@ -1,7 +1,8 @@ -use crate::statistics::{GPXStatistics, GlobalStatistics}; +use crate::statistics::{GPXStatistics, GlobalStatistics, sum_options}; pub struct Buffer { pub total_distance: Vec, + pub moving_distance: Vec, pub total_time: Vec, pub moving_time: Vec, pub speed: Vec, @@ -15,6 +16,7 @@ pub struct Buffer { impl Buffer { pub fn update(&mut self, stats: &[&GPXStatistics]) { self.total_distance.clear(); + self.moving_distance.clear(); self.total_time.clear(); self.moving_time.clear(); self.speed.clear(); @@ -26,8 +28,32 @@ impl Buffer { let mut cumul_stats = GlobalStatistics::default(); for stats in stats { - // add stats - // merge global ones into cumul + for trkpt_stats in stats.local.iter() { + self.total_distance + .push(cumul_stats.total_distance + trkpt_stats.total_distance); + self.moving_distance.push( + sum_options(cumul_stats.moving_distance, trkpt_stats.moving_distance) + .unwrap_or_default(), + ); + self.total_time.push( + sum_options(cumul_stats.total_time(), trkpt_stats.total_time) + .unwrap_or_default(), + ); + self.moving_time.push( + sum_options(cumul_stats.moving_time, trkpt_stats.moving_time) + .unwrap_or_default(), + ); + self.speed.push(trkpt_stats.speed.unwrap_or_default()); + self.elevation_gain + .push(cumul_stats.elevation_gain + trkpt_stats.elevation_gain); + self.elevation_loss + .push(cumul_stats.elevation_loss + trkpt_stats.elevation_loss); + self.slope.push(trkpt_stats.slope); + self.slope_segment_slope + .push(trkpt_stats.slope_segment.slope); + self.slope_segment_distance + .push(trkpt_stats.slope_segment.distance); + } cumul_stats.merge(&stats.global); } } diff --git a/gpx-rs/src/statistics/mod.rs b/gpx-rs/src/statistics/mod.rs index 5bd15f937..0db599c42 100644 --- a/gpx-rs/src/statistics/mod.rs +++ b/gpx-rs/src/statistics/mod.rs @@ -1,5 +1,7 @@ mod buffer; mod statistics; +mod utils; pub use buffer::*; pub use statistics::*; +pub use utils::*; diff --git a/gpx-rs/src/statistics/statistics.rs b/gpx-rs/src/statistics/statistics.rs index 3aa3f120d..1bac18b02 100644 --- a/gpx-rs/src/statistics/statistics.rs +++ b/gpx-rs/src/statistics/statistics.rs @@ -1,9 +1,8 @@ -use std::ops::Add; - use crate::{ algorithm::ramer_douglas_peucker, for_each_window, gpx::{LngLat, LngLatBounds, TrackSegment, Trackpoint}, + statistics::sum_options, utils::{distance, slope, speed}, }; @@ -15,22 +14,15 @@ pub struct GPXStatistics { impl GPXStatistics { pub fn total_time(&self) -> Option { - self.global - .start_time - .zip(self.global.end_time) - .map(|(t1, t2)| t2 - t1) + self.global.total_time() } pub fn total_speed(&self) -> Option { - self.total_time() - .map(|t| speed(self.global.total_distance, t)) + self.global.total_speed() } pub fn moving_speed(&self) -> Option { - self.global - .moving_distance - .zip(self.global.moving_time) - .map(|(d, t)| speed(d, t)) + self.global.moving_speed() } pub fn compute(trkseg: &TrackSegment) -> Self { @@ -244,19 +236,21 @@ pub struct GlobalStatistics { pub bounds: LngLatBounds, } -fn sum_options(a: Option, b: Option) -> Option -where - T: Add, -{ - match (a, b) { - (Some(a), Some(b)) => Some(a + b), - (Some(a), None) => Some(a), - (None, Some(b)) => Some(b), - (None, None) => None, - } -} - impl GlobalStatistics { + pub fn total_time(&self) -> Option { + self.start_time.zip(self.end_time).map(|(t1, t2)| t2 - t1) + } + + pub fn total_speed(&self) -> Option { + self.total_time().map(|t| speed(self.total_distance, t)) + } + + pub fn moving_speed(&self) -> Option { + self.moving_distance + .zip(self.moving_time) + .map(|(d, t)| speed(d, t)) + } + pub fn merge(&mut self, other: &GlobalStatistics) { self.total_distance += other.total_distance; self.moving_distance = sum_options(self.moving_distance, other.moving_distance); diff --git a/gpx-rs/src/statistics/utils.rs b/gpx-rs/src/statistics/utils.rs new file mode 100644 index 000000000..48b710165 --- /dev/null +++ b/gpx-rs/src/statistics/utils.rs @@ -0,0 +1,13 @@ +use std::ops::Add; + +pub fn sum_options(a: Option, b: Option) -> Option +where + T: Add, +{ + match (a, b) { + (Some(a), Some(b)) => Some(a + b), + (Some(a), None) => Some(a), + (None, Some(b)) => Some(b), + (None, None) => None, + } +}