|
|
@@ -1,18 +1,16 @@
|
|
|
extern crate chrono;
|
|
|
extern crate xml;
|
|
|
|
|
|
-
|
|
|
use chrono::DateTime;
|
|
|
+use chrono::Duration;
|
|
|
use chrono::TimeZone;
|
|
|
use chrono::Utc;
|
|
|
-use chrono::Duration;
|
|
|
use std::fs::File;
|
|
|
use std::io::BufReader;
|
|
|
use std::time::Duration as stdDuration;
|
|
|
|
|
|
use xml::reader::{EventReader, XmlEvent};
|
|
|
|
|
|
-
|
|
|
#[derive(Debug, Clone)]
|
|
|
struct Point {
|
|
|
lat: f64,
|
|
|
@@ -21,6 +19,18 @@ struct Point {
|
|
|
time: chrono::DateTime<Utc>,
|
|
|
}
|
|
|
|
|
|
+impl Point {
|
|
|
+ fn new() -> Point {
|
|
|
+ Point {
|
|
|
+ lat: 0.0,
|
|
|
+ long: 0.0,
|
|
|
+ ele: 0.0,
|
|
|
+ time: Utc.timestamp(1, 1),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Default)]
|
|
|
struct Track {
|
|
|
name: String,
|
|
|
points: Vec<Point>,
|
|
|
@@ -43,14 +53,13 @@ impl Track {
|
|
|
|
|
|
fn time(&self) -> chrono::Duration {
|
|
|
// let timespan = &self.points[0].time.signed_duration_since(self.points[1].time);
|
|
|
- let mut sum = Duration::from_std(stdDuration::new(0,0)).unwrap();
|
|
|
+ let mut sum = Duration::from_std(stdDuration::new(0, 0)).unwrap();
|
|
|
let mut prev_time = &self.points[0].time;
|
|
|
|
|
|
for pt in &self.points {
|
|
|
let timespan = prev_time.signed_duration_since(pt.time);
|
|
|
sum = sum.checked_sub(×pan).unwrap();
|
|
|
prev_time = &pt.time;
|
|
|
-
|
|
|
}
|
|
|
sum
|
|
|
}
|
|
|
@@ -59,28 +68,33 @@ impl Track {
|
|
|
self.len() / (self.time().num_seconds() as f64 / 3600.0)
|
|
|
}
|
|
|
|
|
|
-
|
|
|
fn parse(&mut self) {
|
|
|
- let mut sum_time = Duration::from_std(stdDuration::new(0,0)).unwrap();
|
|
|
+ let mut sum_time = Duration::from_std(stdDuration::new(0, 0)).unwrap();
|
|
|
let mut sum_dist = 0.0;
|
|
|
let mut prev_point = &self.points[0];
|
|
|
let mut prev_time = &self.points[0].time;
|
|
|
|
|
|
+ let mut fifo_track = Track {..Default::default()};
|
|
|
+
|
|
|
+ let mut i=0;
|
|
|
+
|
|
|
for pt in &self.points {
|
|
|
+ i = i+1;
|
|
|
+ if i > 10 {break;}
|
|
|
let timespan = prev_time.signed_duration_since(pt.time);
|
|
|
sum_time = sum_time.checked_sub(×pan).unwrap();
|
|
|
prev_time = &pt.time;
|
|
|
let d = dist(prev_point, pt);
|
|
|
sum_dist += d;
|
|
|
prev_point = pt;
|
|
|
+
|
|
|
+ fifo_track.points.push(pt.clone());
|
|
|
+ println!("fifo len {:?}", fifo_track.points.len());
|
|
|
+
|
|
|
}
|
|
|
-
|
|
|
- println!("{:?}", sum_time);
|
|
|
- println!("{:?}", sum_dist);
|
|
|
|
|
|
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
fn dist(p1: &Point, p2: &Point) -> f64 {
|
|
|
@@ -99,58 +113,48 @@ fn dist(p1: &Point, p2: &Point) -> f64 {
|
|
|
}
|
|
|
|
|
|
fn main() {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
let file = File::open("data/Day1-1.gpx").unwrap();
|
|
|
let file = BufReader::new(file);
|
|
|
|
|
|
+ let mut trk = Track {
|
|
|
+ ..Default::default()
|
|
|
+ };
|
|
|
|
|
|
- let mut trk = Track {points: Vec::new(), name: "yolo".to_string()};
|
|
|
-
|
|
|
-
|
|
|
+ println!("open {:?}", file);
|
|
|
let parser = EventReader::new(file);
|
|
|
+ println!("done.");
|
|
|
+
|
|
|
// Records for the pull parser
|
|
|
- let mut current_point = Point {
|
|
|
- lat: 0.0,
|
|
|
- long: 0.0,
|
|
|
- ele: 0.0,
|
|
|
- time: Utc.timestamp(1, 1),
|
|
|
- };
|
|
|
+ let mut current_point = Point::new();
|
|
|
let mut current_data = "".to_string();
|
|
|
|
|
|
+ println!("XML parse start.");
|
|
|
+
|
|
|
for e in parser {
|
|
|
match e {
|
|
|
+
|
|
|
Ok(XmlEvent::StartElement {
|
|
|
- name,
|
|
|
- attributes,
|
|
|
- ..
|
|
|
+ name, attributes, ..
|
|
|
}) => {
|
|
|
if name.local_name == "trkpt" {
|
|
|
- // println!("ADDING POINT --- --- --- ---", )
|
|
|
- } else {
|
|
|
- // println!(">>>{:?}", name.local_name);
|
|
|
- }
|
|
|
-
|
|
|
- for attr in attributes {
|
|
|
- // println!("A\t{:?}={:?}", attr.name.local_name, attr.value);
|
|
|
- if attr.name.local_name == "lat" {
|
|
|
- current_point.lat = attr.value.parse().unwrap();
|
|
|
- }
|
|
|
- if attr.name.local_name == "lon" {
|
|
|
- current_point.long = attr.value.parse().unwrap();
|
|
|
+ for attr in attributes {
|
|
|
+ // println!("A\t{:?}={:?}", attr.name.local_name, attr.value);
|
|
|
+ if attr.name.local_name == "lat" {
|
|
|
+ current_point.lat = attr.value.parse().unwrap();
|
|
|
+ }
|
|
|
+ if attr.name.local_name == "lon" {
|
|
|
+ current_point.long = attr.value.parse().unwrap();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
Ok(XmlEvent::Characters(text)) => {
|
|
|
// This event is the text between tags, such as <foo>text</foo>
|
|
|
current_data = text;
|
|
|
}
|
|
|
|
|
|
Ok(XmlEvent::EndElement { name, .. }) => {
|
|
|
-
|
|
|
// Elevation
|
|
|
if name.local_name == "ele" {
|
|
|
current_point.ele = current_data.parse().unwrap();
|
|
|
@@ -179,15 +183,15 @@ fn main() {
|
|
|
println!("Error: {}", e);
|
|
|
break;
|
|
|
}
|
|
|
+
|
|
|
_ => {}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ println!("XML parse end.");
|
|
|
|
|
|
println!("Track name: {:?}", trk.name);
|
|
|
println!("Distance: {:?} km", trk.len());
|
|
|
- println!("Duration: {:?} h", trk.time().num_minutes()as f32/60.0);
|
|
|
+ println!("Duration: {:?} h", trk.time().num_minutes() as f32 / 60.0);
|
|
|
println!("Speed: {:?} Km/h", trk.speed());
|
|
|
-
|
|
|
-
|
|
|
+ trk.parse();
|
|
|
}
|