|
@@ -1,18 +1,14 @@
|
|
|
extern crate chrono;
|
|
extern crate chrono;
|
|
|
extern crate quick_xml;
|
|
extern crate quick_xml;
|
|
|
-extern crate xml;
|
|
|
|
|
|
|
|
|
|
use chrono::DateTime;
|
|
use chrono::DateTime;
|
|
|
use chrono::Duration;
|
|
use chrono::Duration;
|
|
|
use chrono::TimeZone;
|
|
use chrono::TimeZone;
|
|
|
use chrono::Utc;
|
|
use chrono::Utc;
|
|
|
-use std::fs::File;
|
|
|
|
|
-use std::io::BufReader;
|
|
|
|
|
use std::time::Duration as stdDuration;
|
|
use std::time::Duration as stdDuration;
|
|
|
|
|
|
|
|
use quick_xml::events::Event;
|
|
use quick_xml::events::Event;
|
|
|
use quick_xml::Reader;
|
|
use quick_xml::Reader;
|
|
|
-use xml::reader::{EventReader, XmlEvent};
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
#[derive(Debug, Clone)]
|
|
|
struct Point {
|
|
struct Point {
|
|
@@ -115,10 +111,8 @@ impl Track {
|
|
|
|
|
|
|
|
fn dist(p1: &Point, p2: &Point) -> f64 {
|
|
fn dist(p1: &Point, p2: &Point) -> f64 {
|
|
|
let r = 6371.0;
|
|
let r = 6371.0;
|
|
|
- // println!("analyzing p1 {:?} p2 {:?}", p1, p2);
|
|
|
|
|
let d_lat = (p1.lat - p2.lat).to_radians();
|
|
let d_lat = (p1.lat - p2.lat).to_radians();
|
|
|
let d_long = (p1.long - p2.long).to_radians();
|
|
let d_long = (p1.long - p2.long).to_radians();
|
|
|
-
|
|
|
|
|
let a = (d_lat / 2.0).sin() * (d_lat / 2.0).sin()
|
|
let a = (d_lat / 2.0).sin() * (d_lat / 2.0).sin()
|
|
|
+ p1.lat.to_radians().cos()
|
|
+ p1.lat.to_radians().cos()
|
|
|
* p2.lat.to_radians().cos()
|
|
* p2.lat.to_radians().cos()
|
|
@@ -129,16 +123,10 @@ fn dist(p1: &Point, p2: &Point) -> f64 {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
fn main() {
|
|
|
- // let file = File::open("data/Day1-1.gpx").unwrap();
|
|
|
|
|
- // let file = BufReader::new(file);
|
|
|
|
|
-
|
|
|
|
|
- // let mut trk = Track {
|
|
|
|
|
- // ..Default::default()
|
|
|
|
|
- // };
|
|
|
|
|
|
|
|
|
|
- // println!("open {:?}", file);
|
|
|
|
|
- // let parser = EventReader::new(file);
|
|
|
|
|
- // println!("done.");
|
|
|
|
|
|
|
+ let mut trk = Track {
|
|
|
|
|
+ ..Default::default()
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
// Records for the pull parser
|
|
// Records for the pull parser
|
|
|
let mut current_point = Point::new();
|
|
let mut current_point = Point::new();
|
|
@@ -146,129 +134,8 @@ fn main() {
|
|
|
|
|
|
|
|
println!("XML parse start.");
|
|
println!("XML parse start.");
|
|
|
|
|
|
|
|
- // for e in parser {
|
|
|
|
|
- // match e {
|
|
|
|
|
-
|
|
|
|
|
- // Ok(XmlEvent::StartElement {
|
|
|
|
|
- // name, attributes, ..
|
|
|
|
|
- // }) => {
|
|
|
|
|
- // if name.local_name == "trkpt" {
|
|
|
|
|
- // 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();
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // // Parse time
|
|
|
|
|
- // if name.local_name == "time" {
|
|
|
|
|
- // match Utc.datetime_from_str(current_data.as_str(), "%FT%H:%M:%S%.3fZ") {
|
|
|
|
|
- // Ok(time) => current_point.time = time,
|
|
|
|
|
- // Err(err) => println!("=== TIME ERROR === {:?}", err),
|
|
|
|
|
- // }
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // // The track name
|
|
|
|
|
- // if name.local_name == "name" {
|
|
|
|
|
- // trk.name = current_data.clone();
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // //Track point end event
|
|
|
|
|
- // if name.local_name == "trkpt" {
|
|
|
|
|
- // // push a copy of the point to the track
|
|
|
|
|
- // trk.points.push(current_point.clone());
|
|
|
|
|
- // }
|
|
|
|
|
- // }
|
|
|
|
|
- // Err(e) => {
|
|
|
|
|
- // println!("Error: {}", e);
|
|
|
|
|
- // break;
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // _ => {}
|
|
|
|
|
- // }
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // for e in parser {
|
|
|
|
|
- // match e {
|
|
|
|
|
-
|
|
|
|
|
- // Ok(XmlEvent::StartElement {
|
|
|
|
|
- // name, attributes, ..
|
|
|
|
|
- // }) => {
|
|
|
|
|
- // if name.local_name == "trkpt" {
|
|
|
|
|
- // 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();
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // // Parse time
|
|
|
|
|
- // if name.local_name == "time" {
|
|
|
|
|
- // match Utc.datetime_from_str(current_data.as_str(), "%FT%H:%M:%S%.3fZ") {
|
|
|
|
|
- // Ok(time) => current_point.time = time,
|
|
|
|
|
- // Err(err) => println!("=== TIME ERROR === {:?}", err),
|
|
|
|
|
- // }
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // // The track name
|
|
|
|
|
- // if name.local_name == "name" {
|
|
|
|
|
- // trk.name = current_data.clone();
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // //Track point end event
|
|
|
|
|
- // if name.local_name == "trkpt" {
|
|
|
|
|
- // // push a copy of the point to the track
|
|
|
|
|
- // trk.points.push(current_point.clone());
|
|
|
|
|
- // }
|
|
|
|
|
- // }
|
|
|
|
|
- // Err(e) => {
|
|
|
|
|
- // println!("Error: {}", e);
|
|
|
|
|
- // break;
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // _ => {}
|
|
|
|
|
- // }
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
let mut reader = Reader::from_file("data/Day1-1.gpx").unwrap();
|
|
let mut reader = Reader::from_file("data/Day1-1.gpx").unwrap();
|
|
|
- // let mut reader = Reader::from_file("data/test.xml").unwrap();
|
|
|
|
|
-
|
|
|
|
|
reader.trim_text(true);
|
|
reader.trim_text(true);
|
|
|
-
|
|
|
|
|
- let mut count = 0;
|
|
|
|
|
- let mut txt = Vec::new();
|
|
|
|
|
let mut buf = Vec::new();
|
|
let mut buf = Vec::new();
|
|
|
|
|
|
|
|
// The `Reader` does not implement `Iterator` because it outputs borrowed data (`Cow`s)
|
|
// The `Reader` does not implement `Iterator` because it outputs borrowed data (`Cow`s)
|
|
@@ -281,39 +148,66 @@ fn main() {
|
|
|
b"trkpt" => {
|
|
b"trkpt" => {
|
|
|
for a in e.attributes() {
|
|
for a in e.attributes() {
|
|
|
let unwrapped_attr = a.unwrap();
|
|
let unwrapped_attr = a.unwrap();
|
|
|
- let k = reader.decode(unwrapped_attr.key);
|
|
|
|
|
- let v = unwrapped_attr.unescape_and_decode_value(&reader).unwrap();
|
|
|
|
|
- if k == "lat" {
|
|
|
|
|
- current_point.lat = v.parse().unwrap();
|
|
|
|
|
- }
|
|
|
|
|
- if k == "lon" {
|
|
|
|
|
- current_point.long = v.parse().unwrap();
|
|
|
|
|
- }
|
|
|
|
|
- // println!("{:?}: {:?}", k, v);
|
|
|
|
|
|
|
+ let key = reader.decode(unwrapped_attr.key).into_owned();
|
|
|
|
|
+ let value = unwrapped_attr.unescape_and_decode_value(&reader).unwrap();
|
|
|
|
|
+
|
|
|
|
|
+ match key.as_str() {
|
|
|
|
|
+ "lat" => current_point.lat = value.parse().unwrap(),
|
|
|
|
|
+ "lon" => current_point.long = value.parse().unwrap(),
|
|
|
|
|
+ _ => ()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
()
|
|
()
|
|
|
}
|
|
}
|
|
|
_ => (),
|
|
_ => (),
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- Ok(Event::Text(e)) => txt.push(e.unescape_and_decode(&reader).unwrap()),
|
|
|
|
|
- // Ok(Event::End(ref e)) => (),
|
|
|
|
|
|
|
+ // current_data = text;
|
|
|
|
|
+ Ok(Event::Text(e)) => {
|
|
|
|
|
+ current_data = e.unescape_and_decode(&reader).unwrap();
|
|
|
|
|
+ // txt.push(e.unescape_and_decode(&reader).unwrap()),
|
|
|
|
|
+ }
|
|
|
|
|
+ Ok(Event::End(ref e)) => {
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ match e.name() {
|
|
|
|
|
+ b"ele" => {
|
|
|
|
|
+ current_point.ele = current_data.parse().unwrap();
|
|
|
|
|
+ },
|
|
|
|
|
+ b"name" => {
|
|
|
|
|
+ trk.name = current_data.clone();
|
|
|
|
|
+ },
|
|
|
|
|
+ b"time" => {
|
|
|
|
|
+ match Utc.datetime_from_str(current_data.as_str(), "%FT%H:%M:%S%.3fZ") {
|
|
|
|
|
+ Ok(time) => current_point.time = time,
|
|
|
|
|
+ Err(err) => println!("=== TIME ERROR === {:?}", err),
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ b"trkpt" => {
|
|
|
|
|
+ // push a copy of the point to the track
|
|
|
|
|
+ trk.points.push(current_point.clone());
|
|
|
|
|
+ },
|
|
|
|
|
+ _ => ()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
Ok(Event::Eof) => break, // exits the loop when reaching end of file
|
|
Ok(Event::Eof) => break, // exits the loop when reaching end of file
|
|
|
Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
|
|
Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
|
|
|
_ => (), // There are several other `Event`s we do not consider here
|
|
_ => (), // There are several other `Event`s we do not consider here
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // print!("{:?}\n", buf);
|
|
|
|
|
- // print!("{:?}\n", txt);
|
|
|
|
|
// if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
|
|
// if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
|
|
|
buf.clear();
|
|
buf.clear();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
println!("XML parse end.");
|
|
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!("Speed: {:?} Km/h", trk.speed());
|
|
|
|
|
|
|
+ println!("Track name: {:?}", trk.name);
|
|
|
|
|
+ println!("Distance: {:?} km", trk.len());
|
|
|
|
|
+ println!("Duration: {:?} h", trk.time().num_minutes() as f32 / 60.0);
|
|
|
|
|
+ println!("Speed: {:?} Km/h", trk.speed());
|
|
|
// trk.parse();
|
|
// trk.parse();
|
|
|
}
|
|
}
|