mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-03 12:28:22 +00:00
progress
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
use crate::state::StackEntry;
|
||||||
|
|
||||||
|
pub trait Action {
|
||||||
|
fn apply(entry: &mut StackEntry) -> Result<(), &'static str>;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
use crate::action::Action;
|
||||||
@@ -1 +1,5 @@
|
|||||||
|
mod action;
|
||||||
|
mod file;
|
||||||
|
|
||||||
|
pub use action::*;
|
||||||
|
pub use file::*;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::{
|
|||||||
gpx::GPXFile,
|
gpx::GPXFile,
|
||||||
io::parse,
|
io::parse,
|
||||||
selection::Selection,
|
selection::Selection,
|
||||||
stack::{Stack, StackEntry},
|
state::{Stack, StackEntry},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Control flow
|
// Control flow
|
||||||
|
|||||||
+1
-1
@@ -4,6 +4,6 @@ mod engine;
|
|||||||
mod gpx;
|
mod gpx;
|
||||||
mod io;
|
mod io;
|
||||||
mod selection;
|
mod selection;
|
||||||
mod stack;
|
mod state;
|
||||||
mod statistics;
|
mod statistics;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
mod stack;
|
||||||
|
|
||||||
|
pub use stack::*;
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
use crate::statistics::{GPXStatistics, GlobalStatistics};
|
use crate::statistics::{GPXStatistics, GlobalStatistics, sum_options};
|
||||||
|
|
||||||
pub struct Buffer {
|
pub struct Buffer {
|
||||||
pub total_distance: Vec<f64>,
|
pub total_distance: Vec<f64>,
|
||||||
|
pub moving_distance: Vec<f64>,
|
||||||
pub total_time: Vec<i64>,
|
pub total_time: Vec<i64>,
|
||||||
pub moving_time: Vec<i64>,
|
pub moving_time: Vec<i64>,
|
||||||
pub speed: Vec<f64>,
|
pub speed: Vec<f64>,
|
||||||
@@ -15,6 +16,7 @@ pub struct Buffer {
|
|||||||
impl Buffer {
|
impl Buffer {
|
||||||
pub fn update(&mut self, stats: &[&GPXStatistics]) {
|
pub fn update(&mut self, stats: &[&GPXStatistics]) {
|
||||||
self.total_distance.clear();
|
self.total_distance.clear();
|
||||||
|
self.moving_distance.clear();
|
||||||
self.total_time.clear();
|
self.total_time.clear();
|
||||||
self.moving_time.clear();
|
self.moving_time.clear();
|
||||||
self.speed.clear();
|
self.speed.clear();
|
||||||
@@ -26,8 +28,32 @@ impl Buffer {
|
|||||||
|
|
||||||
let mut cumul_stats = GlobalStatistics::default();
|
let mut cumul_stats = GlobalStatistics::default();
|
||||||
for stats in stats {
|
for stats in stats {
|
||||||
// add stats
|
for trkpt_stats in stats.local.iter() {
|
||||||
// merge global ones into cumul
|
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);
|
cumul_stats.merge(&stats.global);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
mod buffer;
|
mod buffer;
|
||||||
mod statistics;
|
mod statistics;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
pub use buffer::*;
|
pub use buffer::*;
|
||||||
pub use statistics::*;
|
pub use statistics::*;
|
||||||
|
pub use utils::*;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
use std::ops::Add;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
algorithm::ramer_douglas_peucker,
|
algorithm::ramer_douglas_peucker,
|
||||||
for_each_window,
|
for_each_window,
|
||||||
gpx::{LngLat, LngLatBounds, TrackSegment, Trackpoint},
|
gpx::{LngLat, LngLatBounds, TrackSegment, Trackpoint},
|
||||||
|
statistics::sum_options,
|
||||||
utils::{distance, slope, speed},
|
utils::{distance, slope, speed},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -15,22 +14,15 @@ pub struct GPXStatistics {
|
|||||||
|
|
||||||
impl GPXStatistics {
|
impl GPXStatistics {
|
||||||
pub fn total_time(&self) -> Option<i64> {
|
pub fn total_time(&self) -> Option<i64> {
|
||||||
self.global
|
self.global.total_time()
|
||||||
.start_time
|
|
||||||
.zip(self.global.end_time)
|
|
||||||
.map(|(t1, t2)| t2 - t1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn total_speed(&self) -> Option<f64> {
|
pub fn total_speed(&self) -> Option<f64> {
|
||||||
self.total_time()
|
self.global.total_speed()
|
||||||
.map(|t| speed(self.global.total_distance, t))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn moving_speed(&self) -> Option<f64> {
|
pub fn moving_speed(&self) -> Option<f64> {
|
||||||
self.global
|
self.global.moving_speed()
|
||||||
.moving_distance
|
|
||||||
.zip(self.global.moving_time)
|
|
||||||
.map(|(d, t)| speed(d, t))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute(trkseg: &TrackSegment) -> Self {
|
pub fn compute(trkseg: &TrackSegment) -> Self {
|
||||||
@@ -244,19 +236,21 @@ pub struct GlobalStatistics {
|
|||||||
pub bounds: LngLatBounds,
|
pub bounds: LngLatBounds,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sum_options<T>(a: Option<T>, b: Option<T>) -> Option<T>
|
impl GlobalStatistics {
|
||||||
where
|
pub fn total_time(&self) -> Option<i64> {
|
||||||
T: Add<Output = T>,
|
self.start_time.zip(self.end_time).map(|(t1, t2)| t2 - t1)
|
||||||
{
|
|
||||||
match (a, b) {
|
|
||||||
(Some(a), Some(b)) => Some(a + b),
|
|
||||||
(Some(a), None) => Some(a),
|
|
||||||
(None, Some(b)) => Some(b),
|
|
||||||
(None, None) => None,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn total_speed(&self) -> Option<f64> {
|
||||||
|
self.total_time().map(|t| speed(self.total_distance, t))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn moving_speed(&self) -> Option<f64> {
|
||||||
|
self.moving_distance
|
||||||
|
.zip(self.moving_time)
|
||||||
|
.map(|(d, t)| speed(d, t))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalStatistics {
|
|
||||||
pub fn merge(&mut self, other: &GlobalStatistics) {
|
pub fn merge(&mut self, other: &GlobalStatistics) {
|
||||||
self.total_distance += other.total_distance;
|
self.total_distance += other.total_distance;
|
||||||
self.moving_distance = sum_options(self.moving_distance, other.moving_distance);
|
self.moving_distance = sum_options(self.moving_distance, other.moving_distance);
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
use std::ops::Add;
|
||||||
|
|
||||||
|
pub fn sum_options<T>(a: Option<T>, b: Option<T>) -> Option<T>
|
||||||
|
where
|
||||||
|
T: Add<Output = T>,
|
||||||
|
{
|
||||||
|
match (a, b) {
|
||||||
|
(Some(a), Some(b)) => Some(a + b),
|
||||||
|
(Some(a), None) => Some(a),
|
||||||
|
(None, Some(b)) => Some(b),
|
||||||
|
(None, None) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user