mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-19 09:22:12 +00:00
reorganize
This commit is contained in:
1 parent
a921d4b9cd
commit
dbe894b3a3
32 files changed
+45
-66
No files matched your search
@@ -0,0 +1,5 @@
|
||||
mod statistics_buffer;
|
||||
mod statistics_cache;
|
||||
|
||||
pub use statistics_buffer::*;
|
||||
pub use statistics_cache::*;
|
||||
@@ -0,0 +1,61 @@
|
||||
use crate::{GlobalStatistics, Statistics, sum_options};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct StatisticsBuffer {
|
||||
pub total_distance: Vec<f64>,
|
||||
pub moving_distance: Vec<f64>,
|
||||
pub total_time: Vec<i32>,
|
||||
pub moving_time: Vec<i32>,
|
||||
pub speed: Vec<f64>,
|
||||
pub elevation_gain: Vec<f64>,
|
||||
pub elevation_loss: Vec<f64>,
|
||||
pub slope: Vec<f64>,
|
||||
pub slope_segment_slope: Vec<f64>,
|
||||
pub slope_segment_distance: Vec<f64>,
|
||||
}
|
||||
|
||||
impl StatisticsBuffer {
|
||||
pub fn update(&mut self, stats: &[&Statistics]) {
|
||||
self.total_distance.clear();
|
||||
self.moving_distance.clear();
|
||||
self.total_time.clear();
|
||||
self.moving_time.clear();
|
||||
self.speed.clear();
|
||||
self.elevation_gain.clear();
|
||||
self.elevation_loss.clear();
|
||||
self.slope.clear();
|
||||
self.slope_segment_slope.clear();
|
||||
self.slope_segment_distance.clear();
|
||||
|
||||
let mut cumul_stats = GlobalStatistics::default();
|
||||
for stats in stats {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
use std::{
|
||||
collections::{HashMap, HashSet, hash_map::Entry},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use crate::{File, Selection, StackEntry, Statistics, Track, TrackSegment, TrackSegmentRevisionId};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct StatisticsCache {
|
||||
map: HashMap<TrackSegmentRevisionId, Statistics>,
|
||||
}
|
||||
|
||||
impl StatisticsCache {
|
||||
pub fn update(&mut self, state: Option<&StackEntry>) {
|
||||
let mut stale: HashSet<TrackSegmentRevisionId> = self.map.keys().copied().collect();
|
||||
if let Some(state) = state {
|
||||
for file in state.values() {
|
||||
for trk in file.trk.iter() {
|
||||
for trkseg in trk.trkseg.iter() {
|
||||
match self.map.entry(trkseg.rev_id) {
|
||||
Entry::Occupied(_) => {
|
||||
stale.remove(&trkseg.rev_id);
|
||||
}
|
||||
Entry::Vacant(e) => {
|
||||
e.insert(Statistics::compute(trkseg));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for id in stale.iter() {
|
||||
self.map.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<'a>(
|
||||
&'a self,
|
||||
state: Option<&StackEntry>,
|
||||
selection: &Selection,
|
||||
) -> Vec<&'a Statistics> {
|
||||
let mut stats = vec![];
|
||||
if let Some(state) = state {
|
||||
match selection {
|
||||
Selection::Empty => (),
|
||||
Selection::File(s) => {
|
||||
for id in s.files.iter() {
|
||||
if let Some(file) = state.get(id) {
|
||||
self.add_file_stats(file, &mut stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
Selection::Track(s) => {
|
||||
if let Some(file) = state.get(&s.file) {
|
||||
for trk in file.trk.iter() {
|
||||
if s.trk.contains(&trk.id) {
|
||||
self.add_track_stats(trk, &mut stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Selection::TrackSegment(s) => {
|
||||
if let Some(file) = state.get(&s.file) {
|
||||
for trk in file.trk.iter() {
|
||||
if s.trk == trk.id {
|
||||
for trkseg in trk.trkseg.iter() {
|
||||
if s.trkseg.contains(&trkseg.id) {
|
||||
self.add_segment_stats(trkseg, &mut stats);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Selection::Waypoints(s) => {
|
||||
if let Some(file) = state.get(&s.file) {
|
||||
self.add_file_stats(file, &mut stats);
|
||||
}
|
||||
}
|
||||
Selection::Waypoint(s) => {
|
||||
if let Some(file) = state.get(&s.file) {
|
||||
self.add_file_stats(file, &mut stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stats
|
||||
}
|
||||
|
||||
fn add_file_stats<'a>(&'a self, file: &Rc<File>, stats: &mut Vec<&'a Statistics>) {
|
||||
for trk in file.trk.iter() {
|
||||
self.add_track_stats(trk, stats);
|
||||
}
|
||||
}
|
||||
|
||||
fn add_track_stats<'a>(&'a self, trk: &Track, stats: &mut Vec<&'a Statistics>) {
|
||||
for trkseg in trk.trkseg.iter() {
|
||||
self.add_segment_stats(trkseg, stats);
|
||||
}
|
||||
}
|
||||
|
||||
fn add_segment_stats<'a>(&'a self, trkseg: &TrackSegment, stats: &mut Vec<&'a Statistics>) {
|
||||
if let Some(s) = self.map.get(&trkseg.rev_id) {
|
||||
stats.push(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user